From 26ab706e87280f2f1bf7b3dd0de334658e0c429c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 8 Nov 2019 16:44:52 +0100 Subject: [PATCH 0001/1191] DATAES-688 - Remove unneeded SearchQuery subinterface. Original PR: #343 --- .../core/ElasticsearchOperations.java | 39 +++--- .../core/ElasticsearchRestTemplate.java | 47 ++++---- .../core/ElasticsearchTemplate.java | 45 +++---- .../core/ReactiveElasticsearchTemplate.java | 13 +- .../core/query/NativeSearchQuery.java | 10 +- .../elasticsearch/core/query/SearchQuery.java | 59 --------- .../repository/ElasticsearchRepository.java | 5 +- .../AbstractElasticsearchRepository.java | 16 +-- .../data/elasticsearch/NestedObjectTests.java | 10 +- .../core/ElasticsearchTemplateTests.java | 114 +++++++++--------- .../elasticsearch/core/LogEntityTests.java | 8 +- .../ReactiveElasticsearchTemplateTests.java | 8 +- ...ElasticsearchTemplateAggregationTests.java | 4 +- .../ElasticsearchTemplateFacetTests.java | 36 +++--- .../core/index/MappingBuilderTests.java | 6 +- ...ettingAndMappingEntityRepositoryTests.java | 28 +++-- ...ldDynamicMappingEntityRepositoryTests.java | 25 ++-- .../UUIDElasticsearchRepositoryTests.java | 42 ++++--- .../SimpleElasticsearchRepositoryTests.java | 54 +++++---- src/test/resources/dynamic-settings-test.xml | 19 --- .../resources/uuidkeyed-repository-test.xml | 19 --- 21 files changed, 264 insertions(+), 343 deletions(-) delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/SearchQuery.java delete mode 100644 src/test/resources/dynamic-settings-test.xml delete mode 100644 src/test/resources/uuidkeyed-repository-test.xml diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 49b37c0ae..cff479445 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -24,16 +24,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.query.AliasQuery; -import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.CriteriaQuery; -import org.springframework.data.elasticsearch.core.query.DeleteQuery; -import org.springframework.data.elasticsearch.core.query.GetQuery; -import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; -import org.springframework.data.elasticsearch.core.query.SearchQuery; -import org.springframework.data.elasticsearch.core.query.StringQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; @@ -169,7 +160,7 @@ public interface ElasticsearchOperations { */ List queryForAlias(String indexName); - T query(SearchQuery query, ResultsExtractor resultsExtractor); + T query(NativeSearchQuery query, ResultsExtractor resultsExtractor); /** * Execute the query against elasticsearch and return the first returned object @@ -205,7 +196,7 @@ public interface ElasticsearchOperations { * @param clazz * @return */ - Page queryForPage(SearchQuery query, Class clazz); + Page queryForPage(NativeSearchQuery query, Class clazz); /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} @@ -214,7 +205,7 @@ public interface ElasticsearchOperations { * @param clazz * @return */ - List> queryForPage(List queries, Class clazz); + List> queryForPage(List queries, Class clazz); /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} @@ -223,7 +214,7 @@ public interface ElasticsearchOperations { * @param classes * @return */ - List> queryForPage(List queries, List> classes); + List> queryForPage(List queries, List> classes); /** * Execute the query against elasticsearch and return result as {@link Page} @@ -258,7 +249,7 @@ public interface ElasticsearchOperations { CloseableIterator stream(CriteriaQuery query, Class clazz); /** - * Executes the given {@link SearchQuery} against elasticsearch and return result as {@link CloseableIterator}. + * Executes the given {@link NativeSearchQuery} against elasticsearch and return result as {@link CloseableIterator}. *

* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * error. @@ -269,7 +260,7 @@ public interface ElasticsearchOperations { * @return * @since 1.3 */ - CloseableIterator stream(SearchQuery query, Class clazz); + CloseableIterator stream(NativeSearchQuery query, Class clazz); /** * Execute the criteria query against elasticsearch and return result as {@link List} @@ -299,7 +290,7 @@ public interface ElasticsearchOperations { * @param * @return */ - List queryForList(SearchQuery query, Class clazz); + List queryForList(NativeSearchQuery query, Class clazz); /** * Execute the multi search query against elasticsearch and return result as {@link List} @@ -309,7 +300,7 @@ public interface ElasticsearchOperations { * @param * @return */ - default List> queryForList(List queries, Class clazz) { + default List> queryForList(List queries, Class clazz) { return queryForPage(queries, clazz).stream().map(Page::getContent).collect(Collectors.toList()); } @@ -320,7 +311,7 @@ default List> queryForList(List queries, Class clazz * @param classes * @return */ - default List> queryForList(List queries, List> classes) { + default List> queryForList(List queries, List> classes) { return queryForPage(queries, classes).stream().map(Page::getContent).collect(Collectors.toList()); } @@ -330,7 +321,7 @@ default List> queryForList(List queries, List> cla * @param query * @return */ - List queryForIds(SearchQuery query); + List queryForIds(NativeSearchQuery query); /** * return number of elements found by given query @@ -356,7 +347,7 @@ default List> queryForList(List queries, List> cla * @param clazz * @return */ - long count(SearchQuery query, Class clazz); + long count(NativeSearchQuery query, Class clazz); /** * return number of elements found by given query @@ -364,7 +355,7 @@ default List> queryForList(List queries, List> cla * @param query * @return */ - long count(SearchQuery query); + long count(NativeSearchQuery query); /** * Execute a multiGet against elasticsearch for the given ids @@ -373,7 +364,7 @@ default List> queryForList(List queries, List> cla * @param clazz * @return */ - List multiGet(SearchQuery searchQuery, Class clazz); + List multiGet(NativeSearchQuery searchQuery, Class clazz); /** * Index an object. Will do save or update @@ -535,7 +526,7 @@ default void bulkUpdate(List queries) { * @param clazz The class of entity to retrieve. * @return The scan id for input query. */ - ScrolledPage startScroll(long scrollTimeInMillis, SearchQuery query, Class clazz); + ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery query, Class clazz); /** * Returns scrolled page for given query diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 687e94905..9fdbb7379 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -349,28 +349,29 @@ private T getObjectFromPage(Page page) { } @Override - public AggregatedPage queryForPage(SearchQuery query, Class clazz) { + public AggregatedPage queryForPage(NativeSearchQuery query, Class clazz) { SearchResponse response = doSearch(prepareSearch(query, clazz), query); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } - private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { + private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); List> res = new ArrayList<>(queries.size()); int c = 0; - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, query.getPageable())); } return res; } - private List> doMultiSearch(List queries, List> classes, MultiSearchRequest request) { + private List> doMultiSearch(List queries, List> classes, + MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); List> res = new ArrayList<>(queries.size()); int c = 0; Iterator> it = classes.iterator(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), query.getPageable())); } @@ -390,26 +391,26 @@ private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest reque } @Override - public List> queryForPage(List queries, Class clazz) { + public List> queryForPage(List queries, Class clazz) { MultiSearchRequest request = new MultiSearchRequest(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { request.add(prepareSearch(prepareSearch(query, clazz), query)); } return doMultiSearch(queries, clazz, request); } @Override - public List> queryForPage(List queries, List> classes) { + public List> queryForPage(List queries, List> classes) { MultiSearchRequest request = new MultiSearchRequest(); Iterator> it = classes.iterator(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { request.add(prepareSearch(prepareSearch(query, it.next()), query)); } return doMultiSearch(queries, classes, request); } @Override - public T query(SearchQuery query, ResultsExtractor resultsExtractor) { + public T query(NativeSearchQuery query, ResultsExtractor resultsExtractor) { SearchResponse response = doSearch(prepareSearch(query, Optional.ofNullable(query.getQuery()), null), query); return resultsExtractor.extract(response); } @@ -425,12 +426,12 @@ public List queryForList(StringQuery query, Class clazz) { } @Override - public List queryForList(SearchQuery query, Class clazz) { + public List queryForList(NativeSearchQuery query, Class clazz) { return queryForPage(query, clazz).getContent(); } @Override - public List queryForIds(SearchQuery query) { + public List queryForIds(NativeSearchQuery query) { SearchRequest request = prepareSearch(query, Optional.ofNullable(query.getQuery()), null); request.source().query(query.getQuery()); if (query.getFilter() != null) { @@ -502,7 +503,7 @@ public CloseableIterator stream(CriteriaQuery query, Class clazz) { } @Override - public CloseableIterator stream(SearchQuery query, Class clazz) { + public CloseableIterator stream(NativeSearchQuery query, Class clazz) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); } @@ -527,7 +528,7 @@ public long count(CriteriaQuery criteriaQuery, Class clazz) { } @Override - public long count(SearchQuery searchQuery, Class clazz) { + public long count(NativeSearchQuery searchQuery, Class clazz) { QueryBuilder elasticsearchQuery = searchQuery.getQuery(); QueryBuilder elasticsearchFilter = searchQuery.getFilter(); @@ -545,7 +546,7 @@ public long count(CriteriaQuery query) { } @Override - public long count(SearchQuery query) { + public long count(NativeSearchQuery query) { return count(query, null); } @@ -599,7 +600,7 @@ private SearchRequest prepareCount(Query query, Class clazz) { } @Override - public List multiGet(SearchQuery searchQuery, Class clazz) { + public List multiGet(NativeSearchQuery searchQuery, Class clazz) { return elasticsearchConverter.mapDocuments(DocumentAdapters.from(getMultiResponse(searchQuery, clazz)), clazz); } @@ -915,8 +916,8 @@ private SearchRequest prepareScroll(Query query, long scrollTimeInMillis, request.indicesOptions(query.getIndicesOptions()); } - if (query instanceof SearchQuery) { - SearchQuery searchQuery = (SearchQuery) query; + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); @@ -963,7 +964,7 @@ private SearchResponse doScroll(SearchRequest request, CriteriaQuery criteriaQue } } - private SearchResponse doScroll(SearchRequest request, SearchQuery searchQuery) { + private SearchResponse doScroll(SearchRequest request, NativeSearchQuery searchQuery) { Assert.notNull(searchQuery.getIndices(), "No index defined for Query"); Assert.notNull(searchQuery.getTypes(), "No type define for Query"); Assert.notNull(searchQuery.getPageable(), "Query.pageable is required for scan & scroll"); @@ -993,7 +994,7 @@ private SearchResponse doScroll(SearchRequest request, SearchQuery searchQuery) } @Override - public ScrolledPage startScroll(long scrollTimeInMillis, SearchQuery searchQuery, Class clazz) { + public ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery searchQuery, Class clazz) { SearchResponse response = doScroll(prepareScroll(searchQuery, scrollTimeInMillis, clazz), searchQuery); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); } @@ -1071,7 +1072,7 @@ public Page moreLikeThis(MoreLikeThisQuery query, Class clazz) { return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz); } - private SearchResponse doSearch(SearchRequest searchRequest, SearchQuery searchQuery) { + private SearchResponse doSearch(SearchRequest searchRequest, NativeSearchQuery searchQuery) { prepareSearch(searchRequest, searchQuery); try { @@ -1081,7 +1082,7 @@ private SearchResponse doSearch(SearchRequest searchRequest, SearchQuery searchQ } } - private SearchRequest prepareSearch(SearchRequest searchRequest, SearchQuery searchQuery) { + private SearchRequest prepareSearch(SearchRequest searchRequest, NativeSearchQuery searchQuery) { if (searchQuery.getFilter() != null) { searchRequest.source().postFilter(searchQuery.getFilter()); } @@ -1239,7 +1240,7 @@ private SearchRequest prepareSearch(Query query, Class clazz) { return prepareSearch(query, Optional.empty(), clazz); } - private SearchRequest prepareSearch(SearchQuery query, Class clazz) { + private SearchRequest prepareSearch(NativeSearchQuery query, Class clazz) { setPersistentEntityIndexAndType(query, clazz); return prepareSearch(query, Optional.ofNullable(query.getQuery()), clazz); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 9911cc184..593fdf418 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -281,37 +281,38 @@ private T getObjectFromPage(Page page) { } @Override - public AggregatedPage queryForPage(SearchQuery query, Class clazz) { + public AggregatedPage queryForPage(NativeSearchQuery query, Class clazz) { SearchResponse response = doSearch(prepareSearch(query, clazz), query); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public List> queryForPage(List queries, Class clazz) { + public List> queryForPage(List queries, Class clazz) { MultiSearchRequest request = new MultiSearchRequest(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { request.add(prepareSearch(prepareSearch(query, clazz), query)); } return doMultiSearch(queries, clazz, request); } - private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { + private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); List> res = new ArrayList<>(queries.size()); int c = 0; - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, query.getPageable())); } return res; } - private List> doMultiSearch(List queries, List> classes, MultiSearchRequest request) { + private List> doMultiSearch(List queries, List> classes, + MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); List> res = new ArrayList<>(queries.size()); int c = 0; Iterator> it = classes.iterator(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), query.getPageable())); } @@ -327,18 +328,18 @@ private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest reque } @Override - public List> queryForPage(List queries, List> classes) { + public List> queryForPage(List queries, List> classes) { Assert.isTrue(queries.size() == classes.size(), "Queries should have same length with classes"); MultiSearchRequest request = new MultiSearchRequest(); Iterator> it = classes.iterator(); - for (SearchQuery query : queries) { + for (NativeSearchQuery query : queries) { request.add(prepareSearch(prepareSearch(query, it.next()), query)); } return doMultiSearch(queries, classes, request); } @Override - public T query(SearchQuery query, ResultsExtractor resultsExtractor) { + public T query(NativeSearchQuery query, ResultsExtractor resultsExtractor) { SearchResponse response = doSearch(prepareSearch(query, (ElasticsearchPersistentEntity) null), query); return resultsExtractor.extract(response); } @@ -354,12 +355,12 @@ public List queryForList(StringQuery query, Class clazz) { } @Override - public List queryForList(SearchQuery query, Class clazz) { + public List queryForList(NativeSearchQuery query, Class clazz) { return queryForPage(query, clazz).getContent(); } @Override - public List queryForIds(SearchQuery query) { + public List queryForIds(NativeSearchQuery query) { SearchRequestBuilder request = prepareSearch(query, (ElasticsearchPersistentEntity) null) .setQuery(query.getQuery()); if (query.getFilter() != null) { @@ -410,7 +411,7 @@ public CloseableIterator stream(CriteriaQuery query, Class clazz) { } @Override - public CloseableIterator stream(SearchQuery query, Class clazz) { + public CloseableIterator stream(NativeSearchQuery query, Class clazz) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); } @@ -435,7 +436,7 @@ public long count(CriteriaQuery criteriaQuery, Class clazz) { } @Override - public long count(SearchQuery searchQuery, Class clazz) { + public long count(NativeSearchQuery searchQuery, Class clazz) { QueryBuilder elasticsearchQuery = searchQuery.getQuery(); QueryBuilder elasticsearchFilter = searchQuery.getFilter(); @@ -453,7 +454,7 @@ public long count(CriteriaQuery query) { } @Override - public long count(SearchQuery query) { + public long count(NativeSearchQuery query) { return count(query, null); } @@ -497,7 +498,7 @@ private SearchRequestBuilder prepareCount(Query query, Class clazz) { } @Override - public List multiGet(SearchQuery searchQuery, Class clazz) { + public List multiGet(NativeSearchQuery searchQuery, Class clazz) { return elasticsearchConverter.mapDocuments(DocumentAdapters.from(getMultiResponse(searchQuery, clazz)), clazz); } @@ -763,8 +764,8 @@ private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis, requestBuilder.setIndicesOptions(query.getIndicesOptions()); } - if (query instanceof SearchQuery) { - SearchQuery searchQuery = (SearchQuery) query; + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); @@ -805,7 +806,7 @@ private SearchResponse doScroll(SearchRequestBuilder requestBuilder, CriteriaQue return getSearchResponse(requestBuilder); } - private SearchResponse doScroll(SearchRequestBuilder requestBuilder, SearchQuery searchQuery) { + private SearchResponse doScroll(SearchRequestBuilder requestBuilder, NativeSearchQuery searchQuery) { Assert.notNull(searchQuery.getIndices(), "No index defined for Query"); Assert.notNull(searchQuery.getTypes(), "No type define for Query"); Assert.notNull(searchQuery.getPageable(), "Query.pageable is required for scan & scroll"); @@ -824,7 +825,7 @@ private SearchResponse doScroll(SearchRequestBuilder requestBuilder, SearchQuery } @Override - public ScrolledPage startScroll(long scrollTimeInMillis, SearchQuery searchQuery, Class clazz) { + public ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery searchQuery, Class clazz) { SearchResponse response = doScroll(prepareScroll(searchQuery, scrollTimeInMillis, clazz), searchQuery); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); } @@ -890,12 +891,12 @@ public Page moreLikeThis(MoreLikeThisQuery query, Class clazz) { return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz); } - private SearchResponse doSearch(SearchRequestBuilder searchRequest, SearchQuery searchQuery) { + private SearchResponse doSearch(SearchRequestBuilder searchRequest, NativeSearchQuery searchQuery) { SearchRequestBuilder requestBuilder = prepareSearch(searchRequest, searchQuery); return getSearchResponse(requestBuilder); } - private SearchRequestBuilder prepareSearch(SearchRequestBuilder searchRequest, SearchQuery searchQuery) { + private SearchRequestBuilder prepareSearch(SearchRequestBuilder searchRequest, NativeSearchQuery searchQuery) { if (searchQuery.getFilter() != null) { searchRequest.setPostFilter(searchQuery.getFilter()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 9f69c08a3..47e1137af 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -66,7 +66,6 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; @@ -273,8 +272,8 @@ private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntit searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); } - if (query instanceof SearchQuery && ((SearchQuery) query).getCollapseBuilder() != null) { - searchSourceBuilder.collapse(((SearchQuery) query).getCollapseBuilder()); + if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { + searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); } sort(query, entity).forEach(searchSourceBuilder::sort); @@ -312,8 +311,8 @@ private SearchRequest buildSearchRequest(Query query, ElasticsearchPersistentEnt searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); } - if (query instanceof SearchQuery && ((SearchQuery) query).getCollapseBuilder() != null) { - searchSourceBuilder.collapse(((SearchQuery) query).getCollapseBuilder()); + if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { + searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); } sort(query, entity).forEach(searchSourceBuilder::sort); @@ -747,8 +746,8 @@ private QueryBuilder mappedQuery(Query query, ElasticsearchPersistentEntity e @Nullable private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntity entity) { - if (query instanceof SearchQuery) { - return ((SearchQuery) query).getFilter(); + if (query instanceof NativeSearchQuery) { + return ((NativeSearchQuery) query).getFilter(); } return null; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java index 32e2a3985..385b0e23e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java @@ -34,8 +34,9 @@ * @author Artur Konczak * @author Jean-Baptiste Nizet * @author Martin Choraine + * @author Peter-Josef Meisch */ -public class NativeSearchQuery extends AbstractQuery implements SearchQuery { +public class NativeSearchQuery extends AbstractQuery { private QueryBuilder query; private QueryBuilder filter; @@ -97,17 +98,14 @@ public List getElasticsearchSorts() { return sorts; } - @Override public HighlightBuilder getHighlightBuilder() { return highlightBuilder; } - @Override public HighlightBuilder.Field[] getHighlightFields() { return highlightFields; } - @Override public List getScriptFields() { return scriptFields; } @@ -120,7 +118,6 @@ public void addScriptField(ScriptField... scriptField) { scriptFields.addAll(Arrays.asList(scriptField)); } - @Override public CollapseBuilder getCollapseBuilder() { return collapseBuilder; } @@ -142,12 +139,10 @@ public void setFacets(List facets) { this.facets = facets; } - @Override public List getFacets() { return facets; } - @Override public List getAggregations() { return aggregations; } @@ -165,7 +160,6 @@ public void setAggregations(List aggregations) { this.aggregations = aggregations; } - @Override public List getIndicesBoost() { return indicesBoost; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SearchQuery.java deleted file mode 100644 index 3570d0879..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SearchQuery.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2013-2019 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.query; - -import java.util.List; - -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.collapse.CollapseBuilder; -import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; -import org.elasticsearch.search.sort.SortBuilder; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - -/** - * NativeSearchQuery - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jean-Baptiste Nizet - * @author Martin Choraine - */ -public interface SearchQuery extends Query { - - QueryBuilder getQuery(); - - QueryBuilder getFilter(); - - List getElasticsearchSorts(); - - @Deprecated - List getFacets(); - - List getAggregations(); - - HighlightBuilder getHighlightBuilder(); - - HighlightBuilder.Field[] getHighlightFields(); - - List getIndicesBoost(); - - List getScriptFields(); - - CollapseBuilder getCollapseBuilder(); - -} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index 232e3355b..3a7dcd53d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -18,7 +18,7 @@ import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.repository.NoRepositoryBean; /** @@ -28,6 +28,7 @@ * @author Mohsin Husen * @author Sascha Woo * @author Murali Chevuri + * @author Peter-Josef Meisch */ @NoRepositoryBean public interface ElasticsearchRepository extends ElasticsearchCrudRepository { @@ -45,7 +46,7 @@ public interface ElasticsearchRepository extends ElasticsearchCrudReposit Page search(QueryBuilder query, Pageable pageable); - Page search(SearchQuery searchQuery); + Page search(NativeSearchQuery searchQuery); Page searchSimilar(T entity, String[] fields, Pageable pageable); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 0a1f4e2b7..3ca4db976 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -40,8 +40,8 @@ import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.util.Streamable; import org.springframework.util.Assert; @@ -134,7 +134,7 @@ public Iterable findAll() { @Override public Page findAll(Pageable pageable) { - SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); return elasticsearchOperations.queryForPage(query, getEntityClass()); } @@ -147,7 +147,7 @@ public Iterable findAll(Sort sort) { return new PageImpl<>(Collections. emptyList()); } - SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); return elasticsearchOperations.queryForPage(query, getEntityClass()); @@ -158,7 +158,7 @@ public Iterable findAllById(Iterable ids) { Assert.notNull(ids, "ids can't be null."); - SearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); return elasticsearchOperations.multiGet(query, getEntityClass()); } @@ -166,7 +166,7 @@ public Iterable findAllById(Iterable ids) { @Override public long count() { - SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); return elasticsearchOperations.count(query, getEntityClass()); } @@ -230,7 +230,7 @@ public boolean existsById(ID id) { @Override public Iterable search(QueryBuilder query) { - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass()); if (count == 0) { return new PageImpl<>(Collections. emptyList()); @@ -244,13 +244,13 @@ public Iterable search(QueryBuilder query) { @Override public Page search(QueryBuilder query, Pageable pageable) { - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); return elasticsearchOperations.queryForPage(searchQuery, getEntityClass()); } @Override - public Page search(SearchQuery query) { + public Page search(NativeSearchQuery query) { return elasticsearchOperations.queryForPage(query, getEntityClass()); } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 0994dd468..ca0bda9ab 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -47,8 +47,8 @@ import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -128,7 +128,7 @@ public void shouldIndexInitialLevelNestedObject() { QueryBuilder builder = nestedQuery("car", boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class); assertThat(persons).hasSize(1); @@ -186,7 +186,7 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { builder.must(nestedQuery("girlFriends", termQuery("girlFriends.type", "temp"), ScoreMode.None)).must( nestedQuery("girlFriends.cars", termQuery("girlFriends.cars.name", "Ford".toLowerCase()), ScoreMode.None)); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); Page personIndexed = elasticsearchTemplate.queryForPage(searchQuery, PersonMultipleLevelNested.class); @@ -323,7 +323,7 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { // when QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class); // then @@ -369,7 +369,7 @@ public void shouldIndexAndSearchMapAsNestedType() { elasticsearchTemplate.refresh(Book.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder() + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); Page books = elasticsearchTemplate.queryForPage(searchQuery, Book.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index e4da91ce0..3436cfa09 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -172,7 +172,7 @@ public void shouldReturnCountForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -221,7 +221,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { elasticsearchTemplate.refresh(SampleEntity.class); // when - SearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class); // then @@ -250,7 +250,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { elasticsearchTemplate.refresh(SampleEntity.class); // when - SearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)) + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)) .withFields("message", "type").build(); List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class); @@ -271,7 +271,7 @@ public void shouldReturnPageForGivenSearchQuery() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); @@ -294,7 +294,7 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQueryWithValidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQueryWithValidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_local").build(); // when @@ -319,7 +319,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQueryWithInvalidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQueryWithInvalidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_only_nodes:oops").build(); // when @@ -343,7 +343,7 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { elasticsearchTemplate.refresh(INDEX_1_NAME); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); Page entities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); @@ -375,7 +375,7 @@ public void shouldDoBulkIndex() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -431,7 +431,7 @@ public void shouldDeleteDocumentForGivenId() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -453,7 +453,7 @@ public void shouldDeleteEntityForGivenId() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -478,7 +478,7 @@ public void shouldDeleteDocumentForGivenQuery() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -516,7 +516,7 @@ public void shouldDeleteAcrossIndex() { elasticsearchTemplate.refresh(INDEX_2_NAME); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")) .withIndices(INDEX_1_NAME, INDEX_2_NAME) // .build(); @@ -556,7 +556,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { elasticsearchTemplate.refresh(INDEX_2_NAME); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")) .withIndices(INDEX_1_NAME, INDEX_2_NAME) // .build(); @@ -575,7 +575,7 @@ public void shouldFilterSearchResultsForGivenFilter() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when @@ -610,7 +610,7 @@ public void shouldSortResultsGivenSortCriteria() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); // when @@ -646,7 +646,7 @@ public void shouldSortResultsGivenMultipleSortCriteria() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").order(SortOrder.ASC)).build(); @@ -685,7 +685,7 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); // when @@ -723,7 +723,7 @@ public void shouldSortResultsGivenNullLastSortCriteria() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); // when @@ -747,7 +747,7 @@ public void shouldSortResultsByScore() { elasticsearchTemplate.bulkIndex(getIndexQueries(entities)); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder() // + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(matchQuery("message", "green")) // .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("_score")))) // .build(); @@ -805,7 +805,7 @@ public void shouldUseScriptedFields() { params.put("factor", 2); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( new ScriptField("scriptedRate", new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params))) .build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); @@ -961,7 +961,7 @@ public void shouldReturnSpecifiedFields() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").build(); // when @@ -993,7 +993,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { FetchSourceFilterBuilder sourceFilter = new FetchSourceFilterBuilder(); sourceFilter.withIncludes("message"); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withSourceFilter(sourceFilter.build()).build(); // when @@ -1080,7 +1080,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); @@ -1133,7 +1133,7 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); @@ -1188,7 +1188,7 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); @@ -1240,7 +1240,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); @@ -1504,7 +1504,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { elasticsearchTemplate.refresh(INDEX_1_NAME); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); List entities = new ArrayList<>(); @@ -1539,7 +1539,7 @@ public void shouldReturnSameEntityForMultiSearch() { elasticsearchTemplate.refresh(SampleEntity.class); // when - List queries = new ArrayList<>(); + List queries = new ArrayList<>(); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "bc")).build()); @@ -1572,7 +1572,7 @@ public void shouldReturnDifferentEntityForMultiSearch() { elasticsearchTemplate.refresh(clazz); // when - List queries = new ArrayList<>(); + List queries = new ArrayList<>(); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("description", "bc")).build()); @@ -1609,7 +1609,7 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -1628,7 +1628,7 @@ public void shouldIndexDocumentForSpecifiedSource() { // when elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); // then @@ -1658,7 +1658,7 @@ public void shouldReturnIds() { // when elasticsearchTemplate.bulkIndex(entities); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 100)).build(); // then List ids = elasticsearchTemplate.queryForIds(searchQuery); @@ -1678,7 +1678,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { elasticsearchTemplate.refresh(SampleEntity.class); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder() + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withMinScore(2.0F).build(); @@ -1703,7 +1703,7 @@ public void shouldReturnScores() { elasticsearchTemplate.refresh(SampleEntity.class); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) .withSort(SortBuilders.fieldSort("message")).withTrackScores(true).build(); Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); @@ -1766,7 +1766,7 @@ public void shouldDoBulkIndexWithoutId() { elasticsearchTemplate.refresh(SampleEntity.class); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); @@ -1814,8 +1814,8 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME) - .withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) + .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, Map.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); @@ -1839,8 +1839,8 @@ public void shouldIndexGteEntityWithVersionType() { elasticsearchTemplate.index(indexQueryBuilder.build()); elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME) - .withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) + .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); // when Page entities = elasticsearchTemplate.queryForPage(searchQuery, GTEVersionEntity.class); // then @@ -1871,8 +1871,8 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME) - .withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) + .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); @@ -1914,7 +1914,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).build(); // when @@ -1957,7 +1957,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearch IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); // when @@ -2023,7 +2023,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { elasticsearchTemplate.refresh(INDEX_1_NAME); elasticsearchTemplate.refresh(INDEX_2_NAME); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); // when @@ -2125,7 +2125,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd elasticsearchTemplate.refresh(INDEX_1_NAME); elasticsearchTemplate.refresh(INDEX_2_NAME); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(INDEX_1_NAME) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(INDEX_1_NAME) .build(); // when @@ -2165,7 +2165,7 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when assertThatThrownBy(() -> { @@ -2263,7 +2263,7 @@ public void shouldTestResultsAcrossMultipleIndices() { elasticsearchTemplate.refresh(INDEX_1_NAME); elasticsearchTemplate.refresh(INDEX_2_NAME); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); // when @@ -2293,7 +2293,7 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { elasticsearchTemplate.refresh(INDEX_2_NAME); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withTypes("hetro") + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withTypes("hetro") .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); Page page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class); @@ -2371,7 +2371,7 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { // then // document with id "remainingDocumentId" should still be indexed - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); @@ -2402,7 +2402,7 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { // then // document with id "remainingDocumentId" should still be indexed - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); @@ -2431,7 +2431,7 @@ public void shouldDeleteDocumentForGivenIdOnly() { // then // document with id "remainingDocumentId" should still be indexed - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); @@ -2492,7 +2492,7 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { elasticsearchTemplate.refresh(SampleEntity.class); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); @@ -2522,7 +2522,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { // then SourceFilter sourceFilter = new FetchSourceFilter(new String[] { "id" }, new String[] {}); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)) .withSourceFilter(sourceFilter).build(); @@ -2565,7 +2565,7 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); @@ -2611,7 +2611,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable( PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "rate").and(Sort.by(Sort.Direction.DESC, "message")))) .build(); @@ -2649,7 +2649,7 @@ public void shouldReturnDocumentWithCollapsedField() { elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withCollapseField("rate").build(); // when @@ -2785,7 +2785,7 @@ public void shouldAddAliasWithGivenRoutingValue() { elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); - SearchQuery query = new NativeSearchQueryBuilder() // + NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // .withIndices(alias) // .withTypes(TYPE_NAME) // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 5d9790494..0e033a625 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -35,8 +35,8 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -81,7 +81,7 @@ public void before() throws ParseException { public void shouldIndexGivenLogEntityWithIPFieldType() { // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); List entities = template.queryForList(searchQuery, LogEntity.class); // then @@ -92,7 +92,7 @@ public void shouldIndexGivenLogEntityWithIPFieldType() { public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); assertThatThrownBy(() -> { List entities = template.queryForList(searchQuery, LogEntity.class); @@ -103,7 +103,7 @@ public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { public void shouldReturnLogsForGivenIPRanges() { // when - SearchQuery searchQuery = new NativeSearchQueryBuilder() + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build(); List entities = template.queryForList(searchQuery, LogEntity.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 255daf908..1ef1c729e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -57,8 +57,8 @@ import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -589,7 +589,7 @@ public void shouldDeleteAcrossIndex() { restTemplate.refresh(thisIndex); restTemplate.refresh(thatIndex); - SearchQuery searchQuery = new NativeSearchQueryBuilder() // + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "test")) // .withIndices(indexPrefix + "*") // .build(); @@ -619,7 +619,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { restTemplate.refresh(thisIndex); restTemplate.refresh(thatIndex); - SearchQuery searchQuery = new NativeSearchQueryBuilder() // + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "negative")) // .withIndices(indexPrefix + "*") // .build(); @@ -671,7 +671,7 @@ public void shouldReturnDocumentWithCollapsedField() { entity3.setRate(1); index(entity1, entity2, entity3); - SearchQuery query = new NativeSearchQueryBuilder() // + NativeSearchQuery query = new NativeSearchQueryBuilder() // .withIndices(DEFAULT_INDEX) // .withQuery(matchAllQuery()) // .withCollapseField("rate") // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index 1c44aa6c0..3789e67e0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -42,8 +42,8 @@ import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -106,7 +106,7 @@ public void after() { public void shouldReturnAggregatedResponseForGivenSearchQuery() { // given - SearchQuery searchQuery = new NativeSearchQueryBuilder() // + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // .withSearchType(SearchType.DEFAULT) // .withIndices(INDEX_NAME).withTypes("article") // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java b/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java index 2ed3acf06..9b73cfda8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java @@ -49,8 +49,8 @@ import org.springframework.data.elasticsearch.core.facet.result.Term; import org.springframework.data.elasticsearch.core.facet.result.TermResult; import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -104,7 +104,7 @@ public void shouldReturnFacetedAuthorsForGivenQueryWithDefaultOrder() { // given String facetName = "fauthors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").build()).build(); // when @@ -139,7 +139,7 @@ public void shouldReturnFacetedAuthorsForGivenFilteredQuery() { // given String facetName = "fauthors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").build()) .build(); // when @@ -171,7 +171,7 @@ public void shouldExcludeTermsFromFacetedAuthorsForGivenQuery() { // given String facetName = "fauthors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched") .excludeTerms(RIZWAN_IDREES, ARTUR_KONCZAK).build()) .build(); @@ -204,7 +204,7 @@ public void shouldReturnFacetedAuthorsForGivenQueryOrderedByTerm() { // given String facetName = "fauthors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascTerm().build()).build(); // when @@ -240,7 +240,7 @@ public void shouldReturnFacetedAuthorsForGivenQueryOrderedByCountAsc() { // given String facetName = "fauthors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascCount().build()).build(); // when @@ -276,7 +276,7 @@ public void shouldReturnFacetedYearsForGivenQuery() { // given String facetName = "fyears"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(facetName).fields("publishedYears").descCount().build()).build(); // when @@ -310,7 +310,7 @@ public void shouldReturnExistingFacetedYearsForGivenQuery() { // given String facetName = "fyears"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet( new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("publishedYears").descCount().build()) .build(); @@ -347,7 +347,7 @@ public void shouldThrowExeptionsForMultiFieldFacet() { // given String facetName = "fyears"; assertThatThrownBy(() -> { - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet( new TermFacetRequestBuilder(facetName).fields("publishedYears", "authors.untouched").ascTerm().build()) .build(); @@ -360,7 +360,7 @@ public void shouldReturnFacetedYearsAndFacetedAuthorsForGivenQuery() { // given String numberFacetName = "fAuthors"; String stringFacetName = "fyears"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new TermFacetRequestBuilder(numberFacetName).fields("publishedYears").ascTerm().build()) .withFacet(new TermFacetRequestBuilder(stringFacetName).fields("authors.untouched").ascTerm().build()).build(); @@ -413,7 +413,7 @@ public void shouldThrowExceptionForNativeFacets() { // given String facetName = "fyears"; assertThatThrownBy(() -> { - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new NativeFacetRequest()).build(); }).isInstanceOf(UnsupportedOperationException.class); } @@ -423,7 +423,7 @@ public void shouldFilterResultByRegexForGivenQuery() { // given String facetName = "regex_authors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFacet( + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFacet( new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").regex("Art.*").build()) .build(); @@ -451,7 +451,7 @@ public void shouldReturnAllTermsForGivenQuery() { // given String facetName = "all_authors"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet( new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").allTerms().build()) .build(); @@ -476,7 +476,7 @@ public void shouldReturnRangeFacetForGivenQuery() { // given String facetName = "rangeYears"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new RangeFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).to(YEAR_2000) .range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()) .build(); @@ -514,7 +514,7 @@ public void shouldReturnKeyValueRangeFacetForStringValuesInGivenQuery() { // given String facetName = "rangeScoreOverYears"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score").to(YEAR_2000) .range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()) .build(); @@ -552,7 +552,7 @@ public void shouldReturnStatisticalFacetForGivenQuery() { // given String facetName = "statPublishedYear"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new StatisticalFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).build()).build(); // when @@ -572,7 +572,7 @@ public void shouldReturnHistogramFacetForGivenQuery() { // given String facetName = "numberPublicationPerYear"; - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFacet(new HistogramFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).interval(1).build()).build(); // when @@ -600,7 +600,7 @@ public void shouldReturnHistogramFacetForGivenQuery() { @Test public void shouldNotThrowExceptionForNoFacets() { - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); AggregatedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); assertThat(result.hasFacets()).isEqualTo(false); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index e48a5081f..f2bbab71c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -54,8 +54,8 @@ import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.geo.Box; @@ -143,7 +143,7 @@ public void shouldAddStockPriceDocumentToIndex() { .index(buildIndex(StockPrice.builder().id(id).symbol(symbol).price(BigDecimal.valueOf(price)).build())); elasticsearchTemplate.refresh(StockPrice.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); List result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class); // Then @@ -190,7 +190,7 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() { .index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex()); elasticsearchTemplate.refresh(SampleInheritedEntity.class); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); List result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class); // then diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index a9c92f9e7..65ae990f5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -22,21 +22,24 @@ import org.apache.commons.lang.RandomStringUtils; import org.elasticsearch.index.query.QueryBuilders; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * DynamicSettingAndMappingEntityRepositoryTests @@ -45,15 +48,22 @@ * @author Ilkang Na * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:dynamic-settings-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { DynamicSettingAndMappingEntityRepositoryTests.Config.class }) public class DynamicSettingAndMappingEntityRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repositories.setting.dynamic" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private DynamicSettingAndMappingEntityRepository repository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, DynamicSettingAndMappingEntity.class); } @@ -94,7 +104,7 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() repository.save(dynamicSettingAndMappingEntity2); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder() + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build(); long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index a02263882..9693a4050 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -19,19 +19,21 @@ import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * FieldDynamicMappingEntityRepositoryTests @@ -39,15 +41,22 @@ * @author Ted Liang * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:field-dynamic-settings-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { FieldDynamicMappingEntityRepositoryTests.Config.class }) public class FieldDynamicMappingEntityRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repositories.setting.fielddynamic" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private FieldDynamicMappingEntityRepository repository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, FieldDynamicMappingEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 08a7c54a8..27a7608c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -29,11 +29,11 @@ import java.util.Optional; import java.util.UUID; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Page; @@ -46,12 +46,14 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Gad Akuka @@ -62,15 +64,21 @@ * @author Michael Wirth * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:/uuidkeyed-repository-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { UUIDElasticsearchRepositoryTests.Config.class }) public class UUIDElasticsearchRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.uuidkeyed" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private SampleUUIDKeyedElasticsearchRepository repository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, SampleEntityUUIDKeyed.class); @@ -198,7 +206,7 @@ public void shouldSearchDocumentsGivenSearchQuery() { sampleEntityUUIDKeyed.setVersion(System.currentTimeMillis()); repository.save(sampleEntityUUIDKeyed); - SearchQuery query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "test")).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "test")).build(); // when Page page = repository.search(query); @@ -319,7 +327,7 @@ public void shouldDeleteAll() { repository.deleteAll(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(0L); } @@ -339,7 +347,8 @@ public void shouldDeleteById() { long result = repository.deleteSampleEntityUUIDKeyedById(documentId); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())) + .build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(0); assertThat(result).isEqualTo(1L); @@ -377,7 +386,7 @@ public void shouldDeleteByMessageAndReturnList() { // then assertThat(result).hasSize(2); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); } @@ -411,7 +420,7 @@ public void shouldDeleteByListForMessage() { // then assertThat(result).hasSize(1); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -444,7 +453,7 @@ public void shouldDeleteByType() { repository.refresh(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -465,7 +474,8 @@ public void shouldDeleteEntity() { repository.refresh(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())) + .build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 2f1572888..506c56b87 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -33,29 +33,28 @@ import java.util.Optional; import org.elasticsearch.action.ActionRequestValidationException; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; -import org.springframework.data.elasticsearch.RestElasticsearchTestConfiguration; -import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.SearchQuery; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Rizwan Idrees @@ -66,18 +65,22 @@ * @author Peter-Josef Meisch * @author Murali Chevuri */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = { SimpleElasticsearchRepositoryTests.class, RestElasticsearchTestConfiguration.class }) -@EnableElasticsearchRepositories(considerNestedRepositories = true) +@SpringIntegrationTest +@ContextConfiguration(classes = { SimpleElasticsearchRepositoryTests.Config.class }) public class SimpleElasticsearchRepositoryTests { - @ClassRule public static TestNodeResource testNodeResource = new TestNodeResource(); + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repository.support.simple" }, + considerNestedRepositories = true) + static class Config {} @Autowired private SampleElasticsearchRepository repository; @Autowired private ElasticsearchOperations elasticsearchOperations; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchOperations, SampleEntity.class); } @@ -127,7 +130,7 @@ public void shouldSaveDocument() { assertThat(entityFromElasticSearch).isPresent(); } - @Test(expected = ActionRequestValidationException.class) + @Test public void throwExceptionWhenTryingToInsertWithVersionButWithoutId() { // given @@ -136,10 +139,9 @@ public void throwExceptionWhenTryingToInsertWithVersionButWithoutId() { sampleEntity.setVersion(System.currentTimeMillis()); // when - repository.save(sampleEntity); - - // then - assertThat(sampleEntity.getId()).isNotNull(); + assertThatThrownBy(() -> { + repository.save(sampleEntity); + }).isInstanceOf(ActionRequestValidationException.class); } @Test @@ -219,7 +221,7 @@ public void shouldSearchDocumentsGivenSearchQuery() { sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - SearchQuery query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "test")).build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "test")).build(); // when Page page = repository.search(query); @@ -342,7 +344,7 @@ public void shouldReturnResultsForGivenSearchQuery() { repository.save(sampleEntity); // when - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = repository.search(searchQuery); // then @@ -356,7 +358,7 @@ public void shouldDeleteAll() { repository.deleteAll(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(0L); } @@ -377,7 +379,7 @@ public void shouldDeleteById() { repository.refresh(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(0L); assertThat(result).isEqualTo(1L); @@ -415,7 +417,7 @@ public void shouldDeleteByMessageAndReturnList() { // then assertThat(result).hasSize(2); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); } @@ -449,7 +451,7 @@ public void shouldDeleteByListForMessage() { // then assertThat(result).hasSize(1); - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(2L); } @@ -482,7 +484,7 @@ public void shouldDeleteByType() { repository.refresh(); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(2L); } @@ -502,7 +504,7 @@ public void shouldDeleteEntity() { repository.delete(sampleEntity); // then - SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = repository.search(searchQuery); assertThat(sampleEntities.getTotalElements()).isEqualTo(0L); } diff --git a/src/test/resources/dynamic-settings-test.xml b/src/test/resources/dynamic-settings-test.xml deleted file mode 100644 index c042b3e98..000000000 --- a/src/test/resources/dynamic-settings-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/uuidkeyed-repository-test.xml b/src/test/resources/uuidkeyed-repository-test.xml deleted file mode 100644 index 48de5880d..000000000 --- a/src/test/resources/uuidkeyed-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - From 8bc133d9551ac4a8a3417952c32f07140447e06b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 9 Nov 2019 20:54:44 +0100 Subject: [PATCH 0002/1191] DATAES-148 - Dynamic mapping setting. Original PR: #344 --- .../annotations/DynamicMapping.java | 37 +++++++++++++++++++ .../annotations/DynamicMappingValue.java | 26 +++++++++++++ .../core/index/MappingBuilder.java | 28 ++++++++------ .../core/index/MappingBuilderTests.java | 36 ++++++++++++++++++ 4 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java new file mode 100644 index 000000000..3d79732ec --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java @@ -0,0 +1,37 @@ +/* + * Copyright 2019 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to set the dynamic mapping mode + * {@see elasticsearch doc} + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.FIELD }) +@Documented +public @interface DynamicMapping { + + DynamicMappingValue value() default DynamicMappingValue.True; +} diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java new file mode 100644 index 000000000..3cec02048 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java @@ -0,0 +1,26 @@ +/* + * Copyright 2019 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.annotations; + +/** + * values for the {@link DynamicMapping annotation} + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public enum DynamicMappingValue { + True, False, Strict +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 7e3753176..7355a9511 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -33,6 +33,7 @@ import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.CompletionContext; import org.springframework.data.elasticsearch.annotations.CompletionField; +import org.springframework.data.elasticsearch.annotations.DynamicMapping; import org.springframework.data.elasticsearch.annotations.DynamicTemplates; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; @@ -86,6 +87,7 @@ public class MappingBuilder { private static final String COMPLETION_MAX_INPUT_LENGTH = "max_input_length"; private static final String COMPLETION_CONTEXTS = "contexts"; + private static final String TYPE_DYNAMIC = "dynamic"; private static final String TYPE_VALUE_KEYWORD = "keyword"; private static final String TYPE_VALUE_GEO_POINT = "geo_point"; private static final String TYPE_VALUE_COMPLETION = "completion"; @@ -120,13 +122,9 @@ public String buildPropertyMapping(Class clazz) throws IOException { builder.startObject(FIELD_PARENT).field(FIELD_PARAM_TYPE, parentType).endObject(); } - // Properties - builder.startObject(FIELD_PROPERTIES); - - mapEntity(builder, entity, true, "", false, FieldType.Auto, null); + mapEntity(builder, entity, true, "", false, FieldType.Auto, null, entity.findAnnotation(DynamicMapping.class)); - builder.endObject() // FIELD_PROPERTIES - .endObject() // indexType + builder.endObject() // indexType .endObject() // root object .close(); @@ -135,7 +133,7 @@ public String buildPropertyMapping(Class clazz) throws IOException { private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersistentEntity entity, boolean isRootObject, String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType, - @Nullable Field parentFieldAnnotation) throws IOException { + @Nullable Field parentFieldAnnotation, @Nullable DynamicMapping dynamicMapping) throws IOException { boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField); if (writeNestedProperties) { @@ -146,14 +144,17 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten if (nestedOrObjectField && FieldType.Nested == fieldType && parentFieldAnnotation != null && parentFieldAnnotation.includeInParent()) { - builder.field("include_in_parent", parentFieldAnnotation.includeInParent()); } + } - builder.startObject(FIELD_PROPERTIES); + if (dynamicMapping != null) { + builder.field(TYPE_DYNAMIC, dynamicMapping.value().name().toLowerCase()); } - if (entity != null) { + builder.startObject(FIELD_PROPERTIES); + + if (entity != null) { entity.doWithProperties((PropertyHandler) property -> { try { if (property.isAnnotationPresent(Transient.class) || isInIgnoreFields(property, parentFieldAnnotation)) { @@ -167,9 +168,12 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten }); } + builder.endObject(); + if (writeNestedProperties) { - builder.endObject().endObject(); + builder.endObject(); } + } private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject, @@ -205,7 +209,7 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject, : null; mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty, - fieldAnnotation.type(), fieldAnnotation); + fieldAnnotation.type(), fieldAnnotation, property.findAnnotation(DynamicMapping.class)); if (isNestedOrObjectProperty) { return; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index f2bbab71c..f6cdd63bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -514,6 +514,27 @@ public void shouldSetFieldMappingProperties() throws JSONException, IOException assertEquals(expected, mapping, true); } + @Test + void shouldWriteDynamicMappingSettings() throws IOException, JSONException { + + String expected = "{\n" + // + " \"dms\": {\n" + // + " \"dynamic\": \"false\",\n" + // + " \"properties\": {\n" + // + " \"author\": {\n" + // + " \"dynamic\": \"strict\",\n" + // + " \"type\": \"object\",\n" + // + " \"properties\": {}\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + "}\n"; + + String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class); + + assertEquals(expected, mapping, true); + } + /** * @author Xiao Yu */ @@ -948,4 +969,19 @@ static class FieldMappingParameters { @Field(termVector = TermVector.with_offsets) private String termVectorWithOffsets; @Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat; } + + @Document(indexName = "test-index-configure-dynamic-mapping", type = "dms") + @DynamicMapping(DynamicMappingValue.False) + static class ConfigureDynamicMappingEntity { + + @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author; + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } + } } From 3f821087340adf0838bb5ca4d8dd50a539aa475d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 9 Nov 2019 21:40:48 +0100 Subject: [PATCH 0003/1191] DATAES-675 - Migrate tests to JUnit 5. OriginalPR: #345 --- ...ImmutableElasticsearchRepositoryTests.java | 23 +++++++++++------ .../ComplexCustomMethodRepositoryTests.java | 25 +++++++++++++------ .../CustomMethodRepositoryBaseTests.java | 4 ++- .../CustomMethodRepositoryRestTests.java | 20 ++++++++++----- .../CustomMethodRepositoryTests.java | 20 ++++++++++----- .../geo/SpringDataGeoRepositoryTests.java | 23 +++++++++++------ .../QueryKeywordsRepositoryTests.java | 23 +++++++---------- .../QueryKeywordsRestRepositoryTests.java | 16 ++++++------ .../query/keywords/QueryKeywordsTests.java | 11 ++++---- .../complex-custom-method-repository-test.xml | 18 ------------- .../custom-method-repository-rest-test.xml | 21 ---------------- .../custom-method-repository-test.xml | 19 -------------- .../resources/immutable-repository-test.xml | 19 -------------- .../repository-spring-data-geo-support.xml | 18 ------------- 14 files changed, 103 insertions(+), 157 deletions(-) delete mode 100644 src/test/resources/complex-custom-method-repository-test.xml delete mode 100644 src/test/resources/custom-method-repository-rest-test.xml delete mode 100644 src/test/resources/custom-method-repository-test.xml delete mode 100644 src/test/resources/immutable-repository-test.xml delete mode 100644 src/test/resources/repository-spring-data-geo-support.xml diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index e3c96f25f..3a20fe679 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -22,15 +22,18 @@ import java.util.Optional; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.repository.CrudRepository; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Young Gu @@ -39,14 +42,20 @@ * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:immutable-repository-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { ImmutableElasticsearchRepositoryTests.Config.class }) public class ImmutableElasticsearchRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.immutable" }, + considerNestedRepositories = true) + static class Config {} + @Autowired ImmutableElasticsearchRepository repository; @Autowired ElasticsearchOperations operations; - @Before + @BeforeEach public void before() { operations.deleteIndex(ImmutableEntity.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index a64bbb73a..3b7273a19 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -20,33 +20,42 @@ import lombok.Data; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Artur Konczak * @author Mohsin Husen * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:complex-custom-method-repository-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { ComplexCustomMethodRepositoryTests.Config.class }) public class ComplexCustomMethodRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repositories.complex.custommethod.autowiring" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private ComplexElasticsearchRepository complexRepository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index cb8115db8..7374bfcf2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -32,7 +32,7 @@ import java.util.UUID; import java.util.stream.Stream; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; @@ -46,6 +46,7 @@ import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.geo.Box; import org.springframework.data.geo.Distance; @@ -62,6 +63,7 @@ * @author Peter-Josef Meisch * @author Rasmus Faber-Espensen */ +@SpringIntegrationTest public abstract class CustomMethodRepositoryBaseTests { @Autowired private SampleCustomMethodRepository repository; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java index 27ed650d8..2089a5f6b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java @@ -15,26 +15,34 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import org.junit.Before; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Don Wellington * @author Mark Paluch * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:custom-method-repository-rest-test.xml") +@ContextConfiguration(classes = { CustomMethodRepositoryRestTests.Config.class }) public class CustomMethodRepositoryRestTests extends CustomMethodRepositoryBaseTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repositories.custommethod" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private ElasticsearchRestTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java index 03700aa34..2a4eb13a4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java @@ -15,26 +15,34 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import org.junit.Before; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Don Wellington * @author Mark Paluch * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:custom-method-repository-test.xml") +@ContextConfiguration(classes = { CustomMethodRepositoryTests.Config.class }) public class CustomMethodRepositoryTests extends CustomMethodRepositoryBaseTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repositories.custommethod" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 5a9d2efca..2ee6fe916 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -26,38 +26,47 @@ import java.util.Locale; import java.util.Optional; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Mark Paluch * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:/repository-spring-data-geo-support.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { SpringDataGeoRepositoryTests.Config.class }) public class SpringDataGeoRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.geo" }, + considerNestedRepositories = true) + static class Config {} + @Autowired ElasticsearchTemplate template; @Autowired SpringDataGeoRepository repository; - @Before + @BeforeEach public void init() { IndexInitializer.init(template, GeoEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java index 7c8bbe3e2..034f9955c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java @@ -15,11 +15,9 @@ */ package org.springframework.data.elasticsearch.repository.query.keywords; -import org.junit.ClassRule; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.ElasticsearchTestConfiguration; -import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.test.context.ContextConfiguration; @@ -28,16 +26,13 @@ * * @author Peter-Josef Meisch */ -@ContextConfiguration(classes = { QueryKeywordsRepositoryTests.class, ElasticsearchTestConfiguration.class }) -@Configuration -@EnableElasticsearchRepositories(considerNestedRepositories = true) +@ContextConfiguration(classes = { QueryKeywordsRepositoryTests.Config.class}) public class QueryKeywordsRepositoryTests extends QueryKeywordsTests { - @ClassRule public static TestNodeResource testNodeResource = new TestNodeResource(); - - // needed by the ElasticsearchTestConfiguration. - @Bean - public TestNodeResource nodeResource() { - return testNodeResource; - } + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repository.query.keywords" }, + considerNestedRepositories = true) + static class Config {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java index 382840378..5f73e9e3e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java @@ -15,10 +15,9 @@ */ package org.springframework.data.elasticsearch.repository.query.keywords; -import org.junit.ClassRule; import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.RestElasticsearchTestConfiguration; -import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.test.context.ContextConfiguration; @@ -27,10 +26,13 @@ * * @author Peter-Josef Meisch */ -@ContextConfiguration(classes = { QueryKeywordsRestRepositoryTests.class, RestElasticsearchTestConfiguration.class }) -@Configuration -@EnableElasticsearchRepositories(considerNestedRepositories = true) +@ContextConfiguration(classes = { QueryKeywordsRestRepositoryTests.Config.class }) public class QueryKeywordsRestRepositoryTests extends QueryKeywordsTests { - @ClassRule public static TestNodeResource testNodeResource = new TestNodeResource(); + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories( + basePackages = { "org.springframework.data.elasticsearch.repository.query.keywords" }, + considerNestedRepositories = true) + static class Config {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index a1a4df6b9..a70d839c5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -28,18 +28,17 @@ import java.util.List; import java.util.stream.Collectors; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; 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.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.utils.IndexInitializer; -import org.springframework.test.context.junit4.SpringRunner; /** * base class for query keyword tests. Implemented by subclasses using ElasticsearchClient and ElasticsearchRestClient @@ -49,14 +48,14 @@ * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) +@SpringIntegrationTest abstract class QueryKeywordsTests { @Autowired private ProductRepository repository; @Autowired private ElasticsearchOperations elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, Product.class); diff --git a/src/test/resources/complex-custom-method-repository-test.xml b/src/test/resources/complex-custom-method-repository-test.xml deleted file mode 100644 index 14d470471..000000000 --- a/src/test/resources/complex-custom-method-repository-test.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/custom-method-repository-rest-test.xml b/src/test/resources/custom-method-repository-rest-test.xml deleted file mode 100644 index 76544a06f..000000000 --- a/src/test/resources/custom-method-repository-rest-test.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/test/resources/custom-method-repository-test.xml b/src/test/resources/custom-method-repository-test.xml deleted file mode 100644 index a1384b753..000000000 --- a/src/test/resources/custom-method-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/immutable-repository-test.xml b/src/test/resources/immutable-repository-test.xml deleted file mode 100644 index 897adf938..000000000 --- a/src/test/resources/immutable-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/repository-spring-data-geo-support.xml b/src/test/resources/repository-spring-data-geo-support.xml deleted file mode 100644 index 5dafbab32..000000000 --- a/src/test/resources/repository-spring-data-geo-support.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - From 8e5f0dd3411fb1fd2fc6fc28eca89eb79b1b884f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 18 Nov 2019 12:00:42 +0100 Subject: [PATCH 0004/1191] DATAES-683 - Updated changelog. --- src/main/resources/changelog.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 0b63bd05d..8125cb1d0 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.13.RELEASE (2019-11-18) +---------------------------------------------- +* DATAES-683 - Release 3.1.13 (Lovelace SR13). + + Changes in version 3.2.1.RELEASE (2019-11-04) --------------------------------------------- * DATAES-679 - Upgrade to Elasticsearch 6.8.4. From eba23eeb17435494982044eb3d4a597586299617 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 18 Nov 2019 12:31:52 +0100 Subject: [PATCH 0005/1191] DATAES-685 - Updated changelog. --- src/main/resources/changelog.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 8125cb1d0..4ede9e2f7 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,13 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.2.RELEASE (2019-11-18) +--------------------------------------------- +* DATAES-685 - Release 3.2.2 (Moore SR2). +* DATAES-684 - Implement Bulk Request for Reactive. +* DATAES-680 - ReactiveElasticsearchTemplate should use the count API. + + Changes in version 3.1.13.RELEASE (2019-11-18) ---------------------------------------------- * DATAES-683 - Release 3.1.13 (Lovelace SR13). From 79d75f814cabe87df3d986f4f9da84742ce92025 Mon Sep 17 00:00:00 2001 From: MassimilianoPoggi Date: Mon, 18 Nov 2019 20:31:35 +0100 Subject: [PATCH 0006/1191] DATAES-693 - Support for source fetching in update operations. Original PR: #346 --- .../core/ElasticsearchRestTemplate.java | 4 ++- .../core/ElasticsearchRestTemplateTests.java | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 9fdbb7379..e30081661 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -145,6 +145,7 @@ * @author Peter-Josef Meisch * @author Mathias Teier * @author Gyula Attila Csorogi + * @author Massimiliano Poggi */ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate implements EsClient, ApplicationContextAware { @@ -685,7 +686,8 @@ private UpdateRequest prepareUpdate(UpdateQuery query) { .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // .scriptedUpsert(queryUpdateRequest.scriptedUpsert()) // - .docAsUpsert(queryUpdateRequest.docAsUpsert()); + .docAsUpsert(queryUpdateRequest.docAsUpsert()) // + .fetchSource(queryUpdateRequest.fetchSource()); if (query.DoUpsert()) { updateRequest.docAsUpsert(true); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index c0837bacf..64d836449 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -31,6 +31,7 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @@ -55,6 +56,7 @@ * @author Sascha Woo * @author Don Wellington * @author Peter-Josef Meisch + * @author Massimiliano Poggi */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @@ -100,6 +102,31 @@ public void shouldUseUpsertOnUpdate() throws IOException { assertThat(request.upsertRequest()).isNotNull(); } + @Test // DATAES-693 + public void shouldReturnSourceWhenRequested() throws IOException { + // given + Map doc = new HashMap<>(); + doc.put("id", "1"); + doc.put("message", "test"); + + UpdateRequest updateRequest = new UpdateRequest() + .doc(doc) + .fetchSource(FetchSourceContext.FETCH_SOURCE); + + UpdateQuery updateQuery = new UpdateQueryBuilder() // + .withClass(SampleEntity.class) // + .withId("1") // + .withUpdateRequest(updateRequest).build(); + + // when + UpdateRequest request = (UpdateRequest) ReflectionTestUtils // + .invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery); + + // then + assertThat(request).isNotNull(); + assertThat(request.fetchSource()).isEqualTo(FetchSourceContext.FETCH_SOURCE); + } + @Data @Builder @Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0, From 2cd18178e3b15bb1c531ef4cd59379a23b735c99 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 28 Nov 2019 23:41:13 +0100 Subject: [PATCH 0007/1191] DATAES-631 - Consolidate query objects. Original PR: #340 --- .../core/AbstractElasticsearchTemplate.java | 250 +++- .../core/ElasticsearchOperations.java | 328 ++--- .../core/ElasticsearchRestTemplate.java | 1186 ++--------------- .../core/ElasticsearchTemplate.java | 1056 ++------------- .../elasticsearch/core/EntityOperations.java | 20 +- .../data/elasticsearch/core/EsClient.java | 26 - .../data/elasticsearch/core/FacetedPage.java | 37 - .../elasticsearch/core/FacetedPageImpl.java | 171 --- .../elasticsearch/core/IndexCoordinates.java | 84 ++ .../core/ReactiveElasticsearchTemplate.java | 6 +- .../elasticsearch/core/RequestFactory.java | 855 ++++++++++++ .../core/aggregation/AggregatedPage.java | 4 +- .../aggregation/impl/AggregatedPageImpl.java | 20 +- .../core/facet/AbstractFacetRequest.java | 50 - .../core/facet/AbstractFacetResult.java | 47 - .../core/facet/FacetRequest.java | 33 - .../elasticsearch/core/facet/FacetResult.java | 32 - .../elasticsearch/core/facet/FacetType.java | 27 - .../facet/request/HistogramFacetRequest.java | 72 - .../request/HistogramFacetRequestBuilder.java | 58 - .../facet/request/NativeFacetRequest.java | 43 - .../core/facet/request/RangeFacetRequest.java | 132 -- .../request/RangeFacetRequestBuilder.java | 85 -- .../request/StatisticalFacetRequest.java | 52 - .../StatisticalFacetRequestBuilder.java | 52 - .../core/facet/request/TermFacetOrder.java | 27 - .../core/facet/request/TermFacetRequest.java | 109 -- .../request/TermFacetRequestBuilder.java | 88 -- .../core/facet/result/HistogramResult.java | 39 - .../core/facet/result/IntervalUnit.java | 92 -- .../core/facet/result/Range.java | 79 -- .../core/facet/result/RangeResult.java | 44 - .../core/facet/result/StatisticalResult.java | 86 -- .../elasticsearch/core/facet/result/Term.java | 44 - .../core/facet/result/TermResult.java | 63 - .../ElasticsearchPersistentEntity.java | 3 +- .../core/query/AliasBuilder.java | 8 +- .../elasticsearch/core/query/AliasQuery.java | 10 +- .../elasticsearch/core/query/DeleteQuery.java | 19 +- .../elasticsearch/core/query/IndexQuery.java | 18 - .../core/query/IndexQueryBuilder.java | 15 +- .../core/query/NativeSearchQuery.java | 19 - .../core/query/NativeSearchQueryBuilder.java | 11 - .../data/elasticsearch/core/query/Query.java | 4 + .../elasticsearch/core/query/UpdateQuery.java | 28 +- .../core/query/UpdateQueryBuilder.java | 22 +- .../query/ElasticsearchPartQuery.java | 30 +- .../query/ElasticsearchStringQuery.java | 9 +- .../AbstractElasticsearchRepository.java | 108 +- .../data/elasticsearch/NestedObjectTests.java | 32 +- .../core/ElasticsearchRestTemplateTests.java | 66 +- ...ElasticsearchTemplateParentChildTests.java | 18 +- .../core/ElasticsearchTemplateTests.java | 618 +++++---- .../ElasticsearchTransportTemplateTests.java | 5 +- .../core/IndexCoordinatesTest.java | 54 + .../elasticsearch/core/LogEntityTests.java | 9 +- .../ReactiveElasticsearchTemplateTests.java | 42 +- ...ElasticsearchTemplateAggregationTests.java | 12 +- .../ElasticsearchTemplateCompletionTests.java | 17 +- ...chTemplateCompletionWithContextsTests.java | 10 +- .../ElasticsearchTemplateFacetTests.java | 695 ---------- .../geo/ElasticsearchTemplateGeoTests.java | 44 +- .../core/index/MappingBuilderTests.java | 19 +- .../core/query/CriteriaQueryTests.java | 82 +- ...ettingAndMappingEntityRepositoryTests.java | 7 +- .../repositories/spel/SpELEntityTests.java | 5 +- .../synonym/SynonymRepositoryTests.java | 27 +- 67 files changed, 2143 insertions(+), 5320 deletions(-) delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/EsClient.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/FacetedPage.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/FacetedPageImpl.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetResult.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/FacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/FacetResult.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/FacetType.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequestBuilder.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/NativeFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequestBuilder.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetOrder.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequest.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequestBuilder.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/HistogramResult.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/IntervalUnit.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/Range.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/RangeResult.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/StatisticalResult.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/Term.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/facet/result/TermResult.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index d11a3e02c..83ee37678 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -1,13 +1,43 @@ package org.springframework.data.elasticsearch.core; +import static org.springframework.util.StringUtils.*; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.search.MultiSearchRequest; +import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.index.MappingBuilder; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -16,11 +46,22 @@ * @author Sascha Woo * @author Peter-Josef Meisch */ -public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations { +public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class); protected ElasticsearchConverter elasticsearchConverter; + protected RequestFactory requestFactory; + + public RequestFactory getRequestFactory() { + return requestFactory; + } + + protected void initialize(ElasticsearchConverter elasticsearchConverter) { + Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); + this.elasticsearchConverter = elasticsearchConverter; + this.requestFactory = new RequestFactory(elasticsearchConverter); + } protected ElasticsearchConverter createElasticsearchConverter() { MappingElasticsearchConverter mappingElasticsearchConverter = new MappingElasticsearchConverter( @@ -29,6 +70,13 @@ protected ElasticsearchConverter createElasticsearchConverter() { return mappingElasticsearchConverter; } + @Override + public void setApplicationContext(ApplicationContext context) throws BeansException { + if (elasticsearchConverter instanceof ApplicationContextAware) { + ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context); + } + } + protected String buildMapping(Class clazz) { // load mapping specified in Mapping annotation if present @@ -53,8 +101,208 @@ protected String buildMapping(Class clazz) { } } + @Override + public boolean createIndex(String indexName) { + return createIndexIfNotCreated(indexName); + } + + private boolean createIndexIfNotCreated(String indexName) { + return indexExists(indexName) || createIndex(indexName, null); + } + + @Override + public boolean createIndex(Class clazz) { + return createIndexIfNotCreated(clazz); + } + + private boolean createIndexIfNotCreated(Class clazz) { + return indexExists(getPersistentEntityFor(clazz).getIndexName()) || createIndexWithSettings(clazz); + } + + private boolean createIndexWithSettings(Class clazz) { + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + if (hasText(settingPath)) { + String settings = ResourceUtil.readFileFromClasspath(settingPath); + if (hasText(settings)) { + return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); + } + } else { + LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); + } + } + return createIndex(getPersistentEntityFor(clazz).getIndexName(), getDefaultSettings(getPersistentEntityFor(clazz))); + } + + @Override + public boolean createIndex(Class clazz, Object settings) { + return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); + } + + @Override + public void delete(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query, "Query must not be null."); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + DeleteQuery deleteQuery = new DeleteQuery(); + deleteQuery.setQuery(searchRequest.source().query()); + delete(deleteQuery, index); + } + + @Override + public Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { + Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); + MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index); + return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); + } + + protected static String[] toArray(List values) { + String[] valuesAsArray = new String[values.size()]; + return values.toArray(valuesAsArray); + } + @Override public ElasticsearchConverter getElasticsearchConverter() { return elasticsearchConverter; } + + @Override + public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { + Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() + + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); + return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); + } + + private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { + + if (persistentEntity.isUseServerConfiguration()) + return new HashMap(); + + return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) + .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) + .put("index.refresh_interval", persistentEntity.getRefreshInterval()) + .put("index.store.type", persistentEntity.getIndexStoreType()).map(); + } + + protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { + if (bulkResponse.hasFailures()) { + Map failedDocuments = new HashMap<>(); + for (BulkItemResponse item : bulkResponse.getItems()) { + if (item.isFailed()) + failedDocuments.put(item.getId(), item.getFailureMessage()); + } + throw new ElasticsearchException( + "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + + failedDocuments + "]", + failedDocuments); + } + } + + /** + * @param query + * @param clazz + * @deprecated index names and types should not be set in query + */ + @Deprecated + protected void setPersistentEntityIndexAndType(Query query, Class clazz) { + if (query.getIndices().isEmpty()) { + String[] indices = retrieveIndexNameFromPersistentEntity(clazz); + + if (indices != null) { + query.addIndices(indices); + } + } + if (query.getTypes().isEmpty()) { + String[] types = retrieveTypeFromPersistentEntity(clazz); + + if (types != null) { + query.addTypes(types); + } + } + } + + private String[] retrieveIndexNameFromPersistentEntity(Class clazz) { + if (clazz != null) { + return new String[] { getPersistentEntityFor(clazz).getIndexName() }; + } + return null; + } + + private String[] retrieveTypeFromPersistentEntity(Class clazz) { + if (clazz != null) { + return new String[] { getPersistentEntityFor(clazz).getIndexType() }; + } + return null; + } + + @Override + public List> queryForPage(List queries, Class clazz, IndexCoordinates index) { + MultiSearchRequest request = new MultiSearchRequest(); + for (Query query : queries) { + request.add(requestFactory.searchRequest(query, clazz, index)); + } + return doMultiSearch(queries, clazz, request); + } + + @Override + public List> queryForPage(List queries, List> classes, IndexCoordinates index) { + MultiSearchRequest request = new MultiSearchRequest(); + Iterator> it = classes.iterator(); + for (Query query : queries) { + request.add(requestFactory.searchRequest(query, it.next(), index)); + } + return doMultiSearch(queries, classes, request); + } + + private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { + MultiSearchResponse.Item[] items = getMultiSearchResult(request); + List> res = new ArrayList<>(queries.size()); + int c = 0; + for (Query query : queries) { + res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, + query.getPageable())); + } + return res; + } + + private List> doMultiSearch(List queries, List> classes, + MultiSearchRequest request) { + MultiSearchResponse.Item[] items = getMultiSearchResult(request); + List> res = new ArrayList<>(queries.size()); + int c = 0; + Iterator> it = classes.iterator(); + for (Query query : queries) { + res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), + query.getPageable())); + } + return res; + } + + @Override + public boolean putMapping(Class clazz) { + return putMapping(clazz, buildMapping(clazz)); + } + + @Override + public boolean putMapping(Class clazz, Object mapping) { + return putMapping(getIndexCoordinatesFor(clazz), mapping); + } + + @Override + public boolean putMapping(IndexCoordinates index, Class clazz) { + return putMapping(index, buildMapping(clazz)); + } + + abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); + + protected void setPersistentEntityId(Object entity, String id) { + + ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); + ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); + + // Only deal with text because ES generated Ids are strings ! + + if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { + persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id); + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index cff479445..88625292a 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -22,9 +22,17 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.springframework.data.domain.Page; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; @@ -44,28 +52,22 @@ public interface ElasticsearchOperations { * adding new alias * * @param query + * @param index * @return */ - boolean addAlias(AliasQuery query); + boolean addAlias(AliasQuery query, IndexCoordinates index); /** * removing previously created alias * * @param query + * @param index * @return */ - boolean removeAlias(AliasQuery query); + boolean removeAlias(AliasQuery query, IndexCoordinates index); /** - * Create an index for a class - * - * @param clazz - * @param - */ - boolean createIndex(Class clazz); - - /** - * Create an index for given indexName + * Create an index for given indexName if it does not already exist * * @param indexName */ @@ -79,6 +81,14 @@ public interface ElasticsearchOperations { */ boolean createIndex(String indexName, Object settings); + /** + * Create an index for a class if it does not already exist + * + * @param clazz + * @param + */ + boolean createIndex(Class clazz); + /** * Create an index for given class and Settings * @@ -96,23 +106,21 @@ public interface ElasticsearchOperations { boolean putMapping(Class clazz); /** - * Create mapping for the given class and put the mapping to the given indexName and type. + * Create mapping for the given class and put the mapping to the given index * - * @param indexName - * @param type + * @param index * @param clazz * @since 3.2 */ - boolean putMapping(String indexName, String type, Class clazz); + boolean putMapping(IndexCoordinates index, Class clazz); /** - * Create mapping for a given indexName and type - * - * @param indexName - * @param type + * Create mapping for a given index + * @param index * @param mappings + * @param index */ - boolean putMapping(String indexName, String type, Object mappings); + boolean putMapping(IndexCoordinates index, Object mappings); /** * Create mapping for a class @@ -126,17 +134,17 @@ public interface ElasticsearchOperations { * Get mapping for a class * * @param clazz - * @param */ - Map getMapping(Class clazz); + default Map getMapping(Class clazz) { + return getMapping(getIndexCoordinatesFor(clazz)); + } /** - * Get mapping for a given indexName and type + * Get mapping for a given index coordinates * - * @param indexName - * @param type + * @param index */ - Map getMapping(String indexName, String type); + Map getMapping(IndexCoordinates index); /** * Get settings for a given indexName @@ -160,34 +168,30 @@ public interface ElasticsearchOperations { */ List queryForAlias(String indexName); - T query(NativeSearchQuery query, ResultsExtractor resultsExtractor); + T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index); /** - * Execute the query against elasticsearch and return the first returned object + * Retrieves an object from an index * - * @param query - * @param clazz - * @return the first matching object + * @param query the query defining the id of the object to get + * @param clazz the type of the object to be returned + * @param index the index from which the object is read. + * @return the found object */ - T queryForObject(GetQuery query, Class clazz); - - /** - * Execute the query against elasticsearch and return the first returned object - * - * @param query - * @param clazz - * @return the first matching object - */ - T queryForObject(CriteriaQuery query, Class clazz); + T get(GetQuery query, Class clazz, IndexCoordinates index); /** * Execute the query against elasticsearch and return the first returned object * * @param query * @param clazz + * @param index * @return the first matching object */ - T queryForObject(StringQuery query, Class clazz); + default T queryForObject(Query query, Class clazz, IndexCoordinates index) { + List content = queryForPage(query, clazz, index).getContent(); + return content.isEmpty() ? null : content.get(0); + } /** * Execute the query against elasticsearch and return result as {@link Page} @@ -196,60 +200,30 @@ public interface ElasticsearchOperations { * @param clazz * @return */ - Page queryForPage(NativeSearchQuery query, Class clazz); + AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index); /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} * * @param queries * @param clazz + * @param index * @return */ - List> queryForPage(List queries, Class clazz); + List> queryForPage(List queries, Class clazz, IndexCoordinates index); /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} * * @param queries * @param classes + * @param index * @return */ - List> queryForPage(List queries, List> classes); - - /** - * Execute the query against elasticsearch and return result as {@link Page} - * - * @param query - * @param clazz - * @return - */ - Page queryForPage(CriteriaQuery query, Class clazz); - - /** - * Execute the query against elasticsearch and return result as {@link Page} - * - * @param query - * @param clazz - * @return - */ - Page queryForPage(StringQuery query, Class clazz); - - /** - * Executes the given {@link CriteriaQuery} against elasticsearch and return result as {@link CloseableIterator}. - *

- * Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of - * error. - * - * @param element return type - * @param query - * @param clazz - * @return - * @since 1.3 - */ - CloseableIterator stream(CriteriaQuery query, Class clazz); + List> queryForPage(List queries, List> classes, IndexCoordinates index); /** - * Executes the given {@link NativeSearchQuery} against elasticsearch and return result as {@link CloseableIterator}. + * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. *

* Returns a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * error. @@ -257,51 +231,34 @@ public interface ElasticsearchOperations { * @param element return type * @param query * @param clazz + * @param index * @return * @since 1.3 */ - CloseableIterator stream(NativeSearchQuery query, Class clazz); + CloseableIterator stream(Query query, Class clazz, IndexCoordinates index); /** * Execute the criteria query against elasticsearch and return result as {@link List} * * @param query * @param clazz + * @param index * @param * @return */ - List queryForList(CriteriaQuery query, Class clazz); - - /** - * Execute the string query against elasticsearch and return result as {@link List} - * - * @param query - * @param clazz - * @param - * @return - */ - List queryForList(StringQuery query, Class clazz); - - /** - * Execute the search query against elasticsearch and return result as {@link List} - * - * @param query - * @param clazz - * @param - * @return - */ - List queryForList(NativeSearchQuery query, Class clazz); + List queryForList(Query query, Class clazz, IndexCoordinates index); /** * Execute the multi search query against elasticsearch and return result as {@link List} * + * @param * @param queries * @param clazz - * @param + * @param index * @return */ - default List> queryForList(List queries, Class clazz) { - return queryForPage(queries, clazz).stream().map(Page::getContent).collect(Collectors.toList()); + default List> queryForList(List queries, Class clazz, IndexCoordinates index) { + return queryForPage(queries, clazz, index).stream().map(Page::getContent).collect(Collectors.toList()); } /** @@ -309,62 +266,53 @@ default List> queryForList(List queries, Class * * @param queries * @param classes + * @param index * @return */ - default List> queryForList(List queries, List> classes) { - return queryForPage(queries, classes).stream().map(Page::getContent).collect(Collectors.toList()); + default List> queryForList(List queries, List> classes, IndexCoordinates index) { + return queryForPage(queries, classes, index).stream().map(Page::getContent).collect(Collectors.toList()); } /** * Execute the query against elasticsearch and return ids * * @param query - * @return - */ - List queryForIds(NativeSearchQuery query); - - /** - * return number of elements found by given query - * - * @param query * @param clazz + * @param index * @return */ - long count(CriteriaQuery query, Class clazz); - - /** - * return number of elements found by given query - * - * @param query - * @return - */ - long count(CriteriaQuery query); + List queryForIds(Query query, Class clazz, IndexCoordinates index); /** * return number of elements found by given query * - * @param query - * @param clazz - * @return + * @param query the query to execute + * @param index the index to run the query against + * @return count */ - long count(NativeSearchQuery query, Class clazz); + default long count(Query query, IndexCoordinates index) { + return count(query, null, index); + } /** * return number of elements found by given query * - * @param query - * @return + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return count */ - long count(NativeSearchQuery query); + long count(Query query, @Nullable Class clazz, IndexCoordinates index); /** * Execute a multiGet against elasticsearch for the given ids * - * @param searchQuery + * @param query * @param clazz + * @param index * @return */ - List multiGet(NativeSearchQuery searchQuery, Class clazz); + List multiGet(Query query, Class clazz, IndexCoordinates index); /** * Index an object. Will do save or update @@ -372,7 +320,7 @@ default List> queryForList(List queries, List> queryForList(List queries, List queries) { - bulkIndex(queries, BulkOptions.defaultOptions()); + default void bulkIndex(List queries, IndexCoordinates index) { + bulkIndex(queries, BulkOptions.defaultOptions(), index); } /** @@ -398,15 +346,15 @@ default void bulkIndex(List queries) { * @param bulkOptions options to be added to the bulk request * @since 3.2 */ - void bulkIndex(List queries, BulkOptions bulkOptions); + void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); /** * Bulk update all objects. Will do update * * @param queries the queries to execute in bulk */ - default void bulkUpdate(List queries) { - bulkUpdate(queries, BulkOptions.defaultOptions()); + default void bulkUpdate(List queries, IndexCoordinates index) { + bulkUpdate(queries, BulkOptions.defaultOptions(), index); } /** @@ -416,58 +364,43 @@ default void bulkUpdate(List queries) { * @param bulkOptions options to be added to the bulk request * @since 3.2 */ - void bulkUpdate(List queries, BulkOptions bulkOptions); + void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index); /** - * Delete the one object with provided id + * Delete the one object with provided id. * - * @param indexName - * @param type - * @param id + * @param id the document ot delete + * @param index the index from which to delete * @return documentId of the document deleted */ - String delete(String indexName, String type, String id); + String delete(String id, IndexCoordinates index); /** * Delete all records matching the criteria - * - * @param clazz - * @param criteriaQuery - */ - void delete(CriteriaQuery criteriaQuery, Class clazz); - - /** - * Delete the one object with provided id - * - * @param clazz - * @param id - * @return documentId of the document deleted - */ - String delete(Class clazz, String id); - - /** - * Delete all records matching the query - * - * @param clazz + * * @param query + * @param clazz + * @param index */ - void delete(DeleteQuery query, Class clazz); + void delete(Query query, Class clazz, IndexCoordinates index); /** * Delete all records matching the query * * @param query + * @param index the index where to delete the records */ - void delete(DeleteQuery query); + void delete(DeleteQuery query, IndexCoordinates index); /** * Deletes an index for given entity * * @param clazz - * @param * @return */ - boolean deleteIndex(Class clazz); + default boolean deleteIndex(Class clazz) { + return deleteIndex(getPersistentEntityFor(clazz).getIndexName()); + } /** * Deletes an index for given indexName @@ -481,10 +414,11 @@ default void bulkUpdate(List queries) { * check if index is exists * * @param clazz - * @param * @return */ - boolean indexExists(Class clazz); + default boolean indexExists(Class clazz) { + return indexExists(getIndexCoordinatesFor(clazz).getIndexName()); + } /** * check if index is exists for given IndexName @@ -495,49 +429,32 @@ default void bulkUpdate(List queries) { boolean indexExists(String indexName); /** - * check if type is exists in an index + * refresh the index(es) * * @param index - * @param type - * @return - */ - boolean typeExists(String index, String type); - - /** - * refresh the index - * - * @param indexName */ - void refresh(String indexName); + void refresh(IndexCoordinates index); /** * refresh the index * * @param clazz */ - void refresh(Class clazz); - - /** - * Returns scrolled page for given query - * - * @param query The search query. - * @param scrollTimeInMillis The time in millisecond for scroll feature - * {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}. - * @param clazz The class of entity to retrieve. - * @return The scan id for input query. - */ - ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery query, Class clazz); + default void refresh(Class clazz) { + refresh(getIndexCoordinatesFor(clazz)); + } /** * Returns scrolled page for given query * - * @param criteriaQuery The search query. * @param scrollTimeInMillis The time in millisecond for scroll feature * {@link org.elasticsearch.action.search.SearchRequestBuilder#setScroll(org.elasticsearch.common.unit.TimeValue)}. + * @param query The search query. * @param clazz The class of entity to retrieve. + * @param index * @return The scan id for input query. */ - ScrolledPage startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class clazz); + ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index); ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz); @@ -546,17 +463,18 @@ default void bulkUpdate(List queries) { * * @param scrollId */ - void clearScroll(String scrollId); + void clearScroll(String scrollId); /** * more like this query to search for documents that are "like" a specific document. * * @param query * @param clazz + * @param index * @param * @return */ - Page moreLikeThis(MoreLikeThisQuery query, Class clazz); + Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz); @@ -564,4 +482,20 @@ default void bulkUpdate(List queries) { * @return Converter in use */ ElasticsearchConverter getElasticsearchConverter(); + + /** + * @since 4.0 + */ + RequestFactory getRequestFactory(); + + /** + * @param clazz + * @return the IndexCoordinates defined on the entity. + * @since 4.0 + */ + default IndexCoordinates getIndexCoordinatesFor(Class clazz) { + ElasticsearchPersistentEntity entity = getPersistentEntityFor(clazz); + return IndexCoordinates.of(entity.getIndexName()).withTypes(entity.getIndexType()); + } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index e30081661..6b37bb967 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -16,31 +16,21 @@ package org.springframework.data.elasticsearch.core; import static org.elasticsearch.client.Requests.*; -import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.springframework.util.CollectionUtils.isEmpty; -import static org.springframework.util.StringUtils.*; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import org.apache.http.util.EntityUtils; -import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; -import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; @@ -48,7 +38,6 @@ import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.ClearScrollRequest; -import org.elasticsearch.action.search.ClearScrollResponse; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; @@ -58,58 +47,34 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Requests; import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; -import org.elasticsearch.search.sort.FieldSortBuilder; -import org.elasticsearch.search.sort.ScoreSortBuilder; -import org.elasticsearch.search.sort.SortBuilder; -import org.elasticsearch.search.sort.SortBuilders; -import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.suggest.SuggestBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.client.support.AliasData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.support.SearchHitsUtil; import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; @@ -147,13 +112,9 @@ * @author Gyula Attila Csorogi * @author Massimiliano Poggi */ -public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate - implements EsClient, ApplicationContextAware { - - private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); +public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { private RestHighLevelClient client; - private String searchTimeout; public ElasticsearchRestTemplate(RestHighLevelClient client) { initialize(client, createElasticsearchConverter()); @@ -164,44 +125,14 @@ public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConver } private void initialize(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { - Assert.notNull(client, "Client must not be null!"); - Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null."); - this.client = client; - this.elasticsearchConverter = elasticsearchConverter; - } - - @Override - public RestHighLevelClient getClient() { - return client; - } - - public void setSearchTimeout(String searchTimeout) { - this.searchTimeout = searchTimeout; + initialize(elasticsearchConverter); } @Override - public boolean addAlias(AliasQuery query) { - Assert.notNull(query.getIndexName(), "No index defined for Alias"); - Assert.notNull(query.getAliasName(), "No alias defined"); - IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.add() - .alias(query.getAliasName()).index(query.getIndexName()); - - if (query.getFilterBuilder() != null) { - aliasAction.filter(query.getFilterBuilder()); - } else if (query.getFilter() != null) { - aliasAction.filter(query.getFilter()); - } else if (hasText(query.getRouting())) { - aliasAction.routing(query.getRouting()); - } else if (hasText(query.getSearchRouting())) { - aliasAction.searchRouting(query.getSearchRouting()); - } else if (hasText(query.getIndexRouting())) { - aliasAction.indexRouting(query.getIndexRouting()); - } - - IndicesAliasesRequest request = new IndicesAliasesRequest(); - request.addAliasAction(aliasAction); + public boolean addAlias(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); try { return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); } catch (IOException e) { @@ -210,95 +141,52 @@ public boolean addAlias(AliasQuery query) { } @Override - public boolean removeAlias(AliasQuery query) { - - Assert.notNull(query.getIndexName(), "No index defined for Alias"); + public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); - AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() // - .index(query.getIndexName()) // - .alias(query.getAliasName()); - - IndicesAliasesRequest request = Requests.indexAliasesRequest() // - .addAliasAction(aliasAction); - + IndicesAliasesRequest indicesAliasesRequest = requestFactory.indicesRemoveAliasesRequest(query, index); try { - return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); + return client.indices().updateAliases(indicesAliasesRequest, RequestOptions.DEFAULT).isAcknowledged(); } catch (IOException e) { - throw new ElasticsearchException("failed to update aliases with request: " + request, e); + throw new ElasticsearchException("failed to update aliases with indicesRemoveAliasesRequest: " + indicesAliasesRequest, e); } } @Override - public boolean createIndex(Class clazz) { - return createIndexIfNotCreated(clazz); - } - - @Override - public boolean createIndex(String indexName) { - Assert.notNull(indexName, "No index defined for Query"); + public boolean createIndex(String indexName, Object settings) { + CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); try { - return client.indices().create(createIndexRequest(indexName), RequestOptions.DEFAULT).isAcknowledged(); - } catch (Exception e) { - throw new ElasticsearchException("Failed to create index " + indexName, e); + return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException("Error for creating index: " + request.toString(), e); } } @Override - public boolean putMapping(Class clazz) { - return putMapping(clazz, buildMapping(clazz)); - } - - @Override - public boolean putMapping(Class clazz, Object mapping) { - return putMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType(), - mapping); - } - - @Override - public boolean putMapping(String indexName, String type, Class clazz) { - return putMapping(indexName, type, buildMapping(clazz)); - } - - @Override - public boolean putMapping(String indexName, String type, Object mapping) { - Assert.notNull(indexName, "No index defined for putMapping()"); - Assert.notNull(type, "No type defined for putMapping()"); - PutMappingRequest request = new PutMappingRequest(indexName).type(type); - if (mapping instanceof String) { - request.source(String.valueOf(mapping), XContentType.JSON); - } else if (mapping instanceof Map) { - request.source((Map) mapping); - } else if (mapping instanceof XContentBuilder) { - request.source((XContentBuilder) mapping); - } + public boolean putMapping(IndexCoordinates index, Object mapping) { + Assert.notNull(index, "No index defined for putMapping()"); + PutMappingRequest request = requestFactory.putMappingRequest(index, mapping); try { return client.indices().putMapping(request, RequestOptions.DEFAULT).isAcknowledged(); } catch (IOException e) { - throw new ElasticsearchException("Failed to put mapping for " + indexName, e); + throw new ElasticsearchException("Failed to put mapping for " + index.getIndexName(), e); } } @Override - public Map getMapping(String indexName, String type) { - Assert.notNull(indexName, "No index defined for getMapping()"); - Assert.notNull(type, "No type defined for getMapping()"); - Map mappings = null; + public Map getMapping(IndexCoordinates index) { + Assert.notNull(index, "No index defined for getMapping()"); RestClient restClient = client.getLowLevelClient(); try { - Request request = new Request("GET", '/' + indexName + "/_mapping/" + type + "?include_type_name=true"); + Request request = new Request("GET", + '/' + index.getIndexName() + "/_mapping/" + index.getTypeName() + "?include_type_name=true"); Response response = restClient.performRequest(request); - mappings = convertMappingResponse(EntityUtils.toString(response.getEntity()), type); + return convertMappingResponse(EntityUtils.toString(response.getEntity()), index.getTypeName()); } catch (Exception e) { - throw new ElasticsearchException( - "Error while getting mapping for indexName : " + indexName + " type : " + type + " ", e); + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() + + " type : " + index.getTypeName() + ' ', e); } - return mappings; - } - - @Override - public Map getMapping(Class clazz) { - return getMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType()); } private Map convertMappingResponse(String mappingResponse, String type) { @@ -319,29 +207,16 @@ private Map convertMappingResponse(String mappingResponse, Strin } @Override - public T queryForObject(GetQuery query, Class clazz) { - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - GetRequest request = new GetRequest(persistentEntity.getIndexName(), persistentEntity.getIndexType(), - query.getId()); - GetResponse response; + public T get(GetQuery query, Class clazz, IndexCoordinates index) { + GetRequest request = requestFactory.getRequest(query, index); try { - response = client.get(request, RequestOptions.DEFAULT); + GetResponse response = client.get(request, RequestOptions.DEFAULT); return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); } catch (IOException e) { throw new ElasticsearchException("Error while getting for request: " + request.toString(), e); } } - @Override - public T queryForObject(CriteriaQuery query, Class clazz) { - return getObjectFromPage(queryForPage(query, clazz)); - } - - @Override - public T queryForObject(StringQuery query, Class clazz) { - return getObjectFromPage(queryForPage(query, clazz)); - } - @Nullable private T getObjectFromPage(Page page) { int contentSize = page.getContent().size(); @@ -350,36 +225,7 @@ private T getObjectFromPage(Page page) { } @Override - public AggregatedPage queryForPage(NativeSearchQuery query, Class clazz) { - SearchResponse response = doSearch(prepareSearch(query, clazz), query); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); - } - - private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { - MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); - int c = 0; - for (NativeSearchQuery query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, - query.getPageable())); - } - return res; - } - - private List> doMultiSearch(List queries, List> classes, - MultiSearchRequest request) { - MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); - int c = 0; - Iterator> it = classes.iterator(); - for (NativeSearchQuery query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), - query.getPageable())); - } - return res; - } - - private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { + protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { MultiSearchResponse response; try { response = client.multiSearch(request, RequestOptions.DEFAULT); @@ -392,121 +238,48 @@ private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest reque } @Override - public List> queryForPage(List queries, Class clazz) { - MultiSearchRequest request = new MultiSearchRequest(); - for (NativeSearchQuery query : queries) { - request.add(prepareSearch(prepareSearch(query, clazz), query)); - } - return doMultiSearch(queries, clazz, request); - } - - @Override - public List> queryForPage(List queries, List> classes) { - MultiSearchRequest request = new MultiSearchRequest(); - Iterator> it = classes.iterator(); - for (NativeSearchQuery query : queries) { - request.add(prepareSearch(prepareSearch(query, it.next()), query)); - } - return doMultiSearch(queries, classes, request); - } - - @Override - public T query(NativeSearchQuery query, ResultsExtractor resultsExtractor) { - SearchResponse response = doSearch(prepareSearch(query, Optional.ofNullable(query.getQuery()), null), query); - return resultsExtractor.extract(response); - } - - @Override - public List queryForList(CriteriaQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); - } - - @Override - public List queryForList(StringQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); - } - - @Override - public List queryForList(NativeSearchQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); - } - - @Override - public List queryForIds(NativeSearchQuery query) { - SearchRequest request = prepareSearch(query, Optional.ofNullable(query.getQuery()), null); - request.source().query(query.getQuery()); - if (query.getFilter() != null) { - request.source().postFilter(query.getFilter()); - } + public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); SearchResponse response; try { - response = client.search(request, RequestOptions.DEFAULT); + response = client.search(searchRequest, RequestOptions.DEFAULT); } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + request.toString(), e); + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } - return extractIds(response); + return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public Page queryForPage(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - SearchRequest request = prepareSearch(criteriaQuery, clazz); - SearchSourceBuilder sourceBuilder = request.source(); - - if (elasticsearchQuery != null) { - sourceBuilder.query(elasticsearchQuery); - } else { - sourceBuilder.query(QueryBuilders.matchAllQuery()); - } - - if (criteriaQuery.isLimiting()) { - sourceBuilder.size(criteriaQuery.getMaxResults()); - } - - if (criteriaQuery.getMinScore() > 0) { - sourceBuilder.minScore(criteriaQuery.getMinScore()); - } - - if (elasticsearchFilter != null) - sourceBuilder.postFilter(elasticsearchFilter); - if (logger.isDebugEnabled()) { - logger.debug("doSearch query:\n" + request.toString()); - } - - SearchResponse response; + public T query(Query query, ResultsExtractor resultsExtractor, @Nullable Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); try { - response = client.search(request, RequestOptions.DEFAULT); + SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); + return resultsExtractor.extract(result); } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + request.toString(), e); + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, criteriaQuery.getPageable()); } @Override - public Page queryForPage(StringQuery query, Class clazz) { - SearchRequest request = prepareSearch(query, clazz); - request.source().query((wrapperQuery(query.getSource()))); - SearchResponse response; - try { - response = client.search(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + request.toString(), e); - } - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); + public List queryForList(Query query, Class clazz, IndexCoordinates index) { + return queryForPage(query, clazz, index).getContent(); } @Override - public CloseableIterator stream(CriteriaQuery query, Class clazz) { - long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); + public List queryForIds(Query query, Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + try { + SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); + return extractIds(response); + } catch (IOException e) { + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); + } } @Override - public CloseableIterator stream(NativeSearchQuery query, Class clazz) { + public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); + return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, index), clazz); } private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage page, Class clazz) { @@ -515,149 +288,50 @@ private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage< } @Override - public long count(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - - if (elasticsearchFilter == null) { - return doCount(prepareCount(criteriaQuery, clazz), elasticsearchQuery); - } else { - // filter could not be set into CountRequestBuilder, convert request into search request - return doCount(prepareSearch(criteriaQuery, clazz), elasticsearchQuery, elasticsearchFilter); - } - } - - @Override - public long count(NativeSearchQuery searchQuery, Class clazz) { - QueryBuilder elasticsearchQuery = searchQuery.getQuery(); - QueryBuilder elasticsearchFilter = searchQuery.getFilter(); - - if (elasticsearchFilter == null) { - return doCount(prepareCount(searchQuery, clazz), elasticsearchQuery); - } else { - // filter could not be set into CountRequestBuilder, convert request into search request - return doCount(prepareSearch(searchQuery, clazz), elasticsearchQuery, elasticsearchFilter); - } - } + public long count(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(index, "index must not be null"); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + searchRequest.source().size(0); - @Override - public long count(CriteriaQuery query) { - return count(query, null); - } - - @Override - public long count(NativeSearchQuery query) { - return count(query, null); - } - - private long doCount(SearchRequest countRequest, QueryBuilder elasticsearchQuery) { - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - if (elasticsearchQuery != null) { - sourceBuilder.query(elasticsearchQuery); - } - countRequest.source(sourceBuilder); - - try { - return SearchHitsUtil.getTotalCount(client.search(countRequest, RequestOptions.DEFAULT).getHits()); - } catch (IOException e) { - throw new ElasticsearchException("Error while searching for request: " + countRequest.toString(), e); - } - } - - private long doCount(SearchRequest searchRequest, QueryBuilder elasticsearchQuery, QueryBuilder elasticsearchFilter) { - if (elasticsearchQuery != null) { - searchRequest.source().query(elasticsearchQuery); - } else { - searchRequest.source().query(QueryBuilders.matchAllQuery()); - } - if (elasticsearchFilter != null) { - searchRequest.source().postFilter(elasticsearchFilter); - } - SearchResponse response; try { - response = client.search(searchRequest, RequestOptions.DEFAULT); + return SearchHitsUtil.getTotalCount(client.search(searchRequest, RequestOptions.DEFAULT).getHits()); } catch (IOException e) { throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } - return SearchHitsUtil.getTotalCount(response.getHits()); - } - - private SearchRequest prepareCount(Query query, Class clazz) { - String[] indexName = !isEmpty(query.getIndices()) - ? query.getIndices().toArray(new String[query.getIndices().size()]) - : retrieveIndexNameFromPersistentEntity(clazz); - String[] types = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()]) - : retrieveTypeFromPersistentEntity(clazz); - - Assert.notNull(indexName, "No index defined for Query"); - - SearchRequest countRequestBuilder = new SearchRequest(indexName); - - if (types != null) { - countRequestBuilder.types(types); - } - return countRequestBuilder; } @Override - public List multiGet(NativeSearchQuery searchQuery, Class clazz) { - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(getMultiResponse(searchQuery, clazz)), clazz); - } - - private MultiGetResponse getMultiResponse(Query searchQuery, Class clazz) { - - String indexName = !isEmpty(searchQuery.getIndices()) ? searchQuery.getIndices().get(0) - : getPersistentEntityFor(clazz).getIndexName(); - String type = !isEmpty(searchQuery.getTypes()) ? searchQuery.getTypes().get(0) - : getPersistentEntityFor(clazz).getIndexType(); - - Assert.notNull(indexName, "No index defined for Query"); - Assert.notNull(type, "No type define for Query"); - Assert.notEmpty(searchQuery.getIds(), "No Id define for Query"); - - MultiGetRequest request = new MultiGetRequest(); - - if (searchQuery.getFields() != null && !searchQuery.getFields().isEmpty()) { - searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null)); - } - - for (String id : searchQuery.getIds()) { - - MultiGetRequest.Item item = new MultiGetRequest.Item(indexName, type, id); - - if (searchQuery.getRoute() != null) { - item = item.routing(searchQuery.getRoute()); - } - - request.add(item); - } + public List multiGet(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(index, "index must not be null"); + Assert.notEmpty(query.getIds(), "No Id define for Query"); + MultiGetRequest request = requestFactory.multiGetRequest(query, index); try { - return client.multiGet(request, RequestOptions.DEFAULT); + MultiGetResponse result = client.mget(request, RequestOptions.DEFAULT); + return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); } catch (IOException e) { throw new ElasticsearchException("Error while multiget for request: " + request.toString(), e); } } @Override - public String index(IndexQuery query) { - String documentId; - IndexRequest request = prepareIndex(query); + public String index(IndexQuery query, IndexCoordinates index) { + IndexRequest request = requestFactory.indexRequest(query, index); try { - documentId = client.index(request, RequestOptions.DEFAULT).getId(); + String documentId = client.index(request, RequestOptions.DEFAULT).getId(); + + // We should call this because we are not going through a mapper. + if (query.getObject() != null) { + setPersistentEntityId(query.getObject(), documentId); + } + return documentId; } catch (IOException e) { throw new ElasticsearchException("Error while index for request: " + request.toString(), e); } - // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); - } - return documentId; } @Override - public UpdateResponse update(UpdateQuery query) { - UpdateRequest request = prepareUpdate(query); + public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { + UpdateRequest request = requestFactory.updateRequest(query, index); try { return client.update(request, RequestOptions.DEFAULT); } catch (IOException e) { @@ -665,128 +339,34 @@ public UpdateResponse update(UpdateQuery query) { } } - private UpdateRequest prepareUpdate(UpdateQuery query) { - - String indexName = hasText(query.getIndexName()) ? query.getIndexName() - : getPersistentEntityFor(query.getClazz()).getIndexName(); - String type = hasText(query.getType()) ? query.getType() : getPersistentEntityFor(query.getClazz()).getIndexType(); - - Assert.notNull(indexName, "No index defined for Query"); - Assert.notNull(type, "No type define for Query"); - Assert.notNull(query.getId(), "No Id define for Query"); - Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); - - UpdateRequest queryUpdateRequest = query.getUpdateRequest(); - - UpdateRequest updateRequest = new UpdateRequest(indexName, type, query.getId()) // - .routing(queryUpdateRequest.routing()) // - .retryOnConflict(queryUpdateRequest.retryOnConflict()) // - .timeout(queryUpdateRequest.timeout()) // - .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // - .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .scriptedUpsert(queryUpdateRequest.scriptedUpsert()) // - .docAsUpsert(queryUpdateRequest.docAsUpsert()) // - .fetchSource(queryUpdateRequest.fetchSource()); - - if (query.DoUpsert()) { - updateRequest.docAsUpsert(true); - } - if (queryUpdateRequest.script() != null) { - updateRequest.script(queryUpdateRequest.script()); - } - if (queryUpdateRequest.doc() != null) { - updateRequest.doc(queryUpdateRequest.doc()); - } - if (queryUpdateRequest.upsertRequest() != null) { - updateRequest.upsert(queryUpdateRequest.upsertRequest()); - } - - return updateRequest; - } - @Override - public void bulkIndex(List queries, BulkOptions bulkOptions) { - + public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - BulkRequest bulkRequest = new BulkRequest(); - setBulkOptions(bulkRequest, bulkOptions); - for (IndexQuery query : queries) { - bulkRequest.add(prepareIndex(query)); - } - try { - checkForBulkUpdateFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); - } catch (IOException e) { - throw new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e); - } + doBulkOperation(queries, bulkOptions, index); } @Override - public void bulkUpdate(List queries, BulkOptions bulkOptions) { - + public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of UpdateQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - BulkRequest bulkRequest = new BulkRequest(); - setBulkOptions(bulkRequest, bulkOptions); - for (UpdateQuery query : queries) { - bulkRequest.add(prepareUpdate(query)); - } + doBulkOperation(queries, bulkOptions, index); + } + + private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); try { - checkForBulkUpdateFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); + checkForBulkOperationFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); } catch (IOException e) { throw new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e); } } - private static void setBulkOptions(BulkRequest bulkRequest, BulkOptions bulkOptions) { - - if (bulkOptions.getTimeout() != null) { - bulkRequest.timeout(bulkOptions.getTimeout()); - } - - if (bulkOptions.getRefreshPolicy() != null) { - bulkRequest.setRefreshPolicy(bulkOptions.getRefreshPolicy()); - } - - if (bulkOptions.getWaitForActiveShards() != null) { - bulkRequest.waitForActiveShards(bulkOptions.getWaitForActiveShards()); - } - - if (bulkOptions.getPipeline() != null) { - bulkRequest.pipeline(bulkOptions.getPipeline()); - } - - if (bulkOptions.getRoutingId() != null) { - bulkRequest.routing(bulkOptions.getRoutingId()); - } - } - - private void checkForBulkUpdateFailure(BulkResponse bulkResponse) { - if (bulkResponse.hasFailures()) { - Map failedDocuments = new HashMap<>(); - for (BulkItemResponse item : bulkResponse.getItems()) { - if (item.isFailed()) - failedDocuments.put(item.getId(), item.getFailureMessage()); - } - throw new ElasticsearchException( - "Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" - + failedDocuments + "]", - failedDocuments); - } - } - - @Override - public boolean indexExists(Class clazz) { - return indexExists(getPersistentEntityFor(clazz).getIndexName()); - } - @Override public boolean indexExists(String indexName) { - GetIndexRequest request = new GetIndexRequest(); - request.indices(indexName); + GetIndexRequest request = new GetIndexRequest(indexName); try { return client.indices().exists(request, RequestOptions.DEFAULT); } catch (IOException e) { @@ -794,23 +374,6 @@ public boolean indexExists(String indexName) { } } - @Override - public boolean typeExists(String index, String type) { - RestClient restClient = client.getLowLevelClient(); - try { - Response response = restClient.performRequest(new Request("HEAD", index + "/_mapping/" + type)); - return (response.getStatusLine().getStatusCode() == 200); - } catch (Exception e) { - throw new ElasticsearchException("Error while checking type exists for index: " + index + " type : " + type + " ", - e); - } - } - - @Override - public boolean deleteIndex(Class clazz) { - return deleteIndex(getPersistentEntityFor(clazz).getIndexName()); - } - @Override public boolean deleteIndex(String indexName) { Assert.notNull(indexName, "No index defined for delete operation"); @@ -826,8 +389,8 @@ public boolean deleteIndex(String indexName) { } @Override - public String delete(String indexName, String type, String id) { - DeleteRequest request = new DeleteRequest(indexName, type, id); + public String delete(String id, IndexCoordinates index) { + DeleteRequest request = new DeleteRequest(index.getIndexName(), index.getTypeName(), id); try { return client.delete(request, RequestOptions.DEFAULT).getId(); } catch (IOException e) { @@ -836,31 +399,8 @@ public String delete(String indexName, String type, String id) { } @Override - public String delete(Class clazz, String id) { - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - return delete(persistentEntity.getIndexName(), persistentEntity.getIndexType(), id); - } - - @Override - public void delete(DeleteQuery deleteQuery, Class clazz) { - - String indexName = hasText(deleteQuery.getIndex()) ? deleteQuery.getIndex() - : getPersistentEntityFor(clazz).getIndexName(); - String typeName = hasText(deleteQuery.getType()) ? deleteQuery.getType() - : getPersistentEntityFor(clazz).getIndexType(); - - DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(indexName) // - .setDocTypes(typeName) // - .setQuery(deleteQuery.getQuery()) // - .setAbortOnVersionConflict(false) // - .setRefresh(true); - - if (deleteQuery.getPageSize() != null) - deleteByQueryRequest.setBatchSize(deleteQuery.getPageSize()); - - if (deleteQuery.getScrollTimeInMillis() != null) - deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); - + public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { + DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(deleteQuery, index); try { client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); } catch (IOException e) { @@ -869,144 +409,19 @@ public void delete(DeleteQuery deleteQuery, Class clazz) { } @Override - public void delete(DeleteQuery deleteQuery) { - Assert.notNull(deleteQuery.getIndex(), "No index defined for Query"); - Assert.notNull(deleteQuery.getType(), "No type define for Query"); - delete(deleteQuery, null); - } - - @Override - public void delete(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - Assert.notNull(elasticsearchQuery, "Query can not be null."); - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(elasticsearchQuery); - delete(deleteQuery, clazz); - } - - private SearchRequest prepareScroll(Query query, long scrollTimeInMillis, Class clazz) { - setPersistentEntityIndexAndType(query, clazz); - ElasticsearchPersistentEntity entity = getPersistentEntity(clazz); - return prepareScroll(query, scrollTimeInMillis, entity); - } - - private SearchRequest prepareScroll(Query query, long scrollTimeInMillis, - @Nullable ElasticsearchPersistentEntity entity) { - SearchRequest request = new SearchRequest(toArray(query.getIndices())); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - request.types(toArray(query.getTypes())); - request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - - if (query.getPageable().isPaged()) { - searchSourceBuilder.size(query.getPageable().getPageSize()); - } - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - searchSourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (!isEmpty(query.getFields())) { - searchSourceBuilder.fetchSource(toArray(query.getFields()), null); - } - - if (query.getSort() != null) { - prepareSort(query, searchSourceBuilder, entity); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); - } - - if (query instanceof NativeSearchQuery) { - NativeSearchQuery searchQuery = (NativeSearchQuery) query; - - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); - } - } - searchSourceBuilder.highlighter(highlightBuilder); - } - } - - request.source(searchSourceBuilder); - return request; - } - - private SearchResponse doScroll(SearchRequest request, CriteriaQuery criteriaQuery) { - Assert.notNull(criteriaQuery.getIndices(), "No index defined for Query"); - Assert.notNull(criteriaQuery.getTypes(), "No type define for Query"); - Assert.notNull(criteriaQuery.getPageable(), "Query.pageable is required for scan & scroll"); - - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - - if (elasticsearchQuery != null) { - request.source().query(elasticsearchQuery); - } else { - request.source().query(QueryBuilders.matchAllQuery()); - } - - if (elasticsearchFilter != null) { - request.source().postFilter(elasticsearchFilter); - } - request.source().version(true); + public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + searchRequest.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); try { - return client.search(request, RequestOptions.DEFAULT); + SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); + return elasticsearchConverter.mapResults(SearchDocumentResponse.from(result), clazz, null); } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + request.toString(), e); - } - } - - private SearchResponse doScroll(SearchRequest request, NativeSearchQuery searchQuery) { - Assert.notNull(searchQuery.getIndices(), "No index defined for Query"); - Assert.notNull(searchQuery.getTypes(), "No type define for Query"); - Assert.notNull(searchQuery.getPageable(), "Query.pageable is required for scan & scroll"); - - if (searchQuery.getQuery() != null) { - request.source().query(searchQuery.getQuery()); - } else { - request.source().query(QueryBuilders.matchAllQuery()); - } - - if (searchQuery.getFilter() != null) { - request.source().postFilter(searchQuery.getFilter()); - } - request.source().version(true); - - if (!isEmpty(searchQuery.getElasticsearchSorts())) { - for (SortBuilder sort : searchQuery.getElasticsearchSorts()) { - request.source().sort(sort); - } - } - - try { - return client.search(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + request.toString(), e); + throw new ElasticsearchException("Error for search request with scroll: " + searchRequest.toString(), e); } } - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery searchQuery, Class clazz) { - SearchResponse response = doScroll(prepareScroll(searchQuery, scrollTimeInMillis, clazz), searchQuery); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); - } - - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class clazz) { - SearchResponse response = doScroll(prepareScroll(criteriaQuery, scrollTimeInMillis, clazz), criteriaQuery); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); - } - @Override public ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { SearchScrollRequest request = new SearchScrollRequest(scrollId); @@ -1025,177 +440,12 @@ public void clearScroll(String scrollId) { ClearScrollRequest request = new ClearScrollRequest(); request.addScrollId(scrollId); try { - // TODO: Something useful with the response. - ClearScrollResponse response = client.clearScroll(request, RequestOptions.DEFAULT); + client.clearScroll(request, RequestOptions.DEFAULT); } catch (IOException e) { throw new ElasticsearchException("Error for search request with scroll: " + request.toString(), e); } } - @Override - public Page moreLikeThis(MoreLikeThisQuery query, Class clazz) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - String indexName = hasText(query.getIndexName()) ? query.getIndexName() : persistentEntity.getIndexName(); - String type = hasText(query.getType()) ? query.getType() : persistentEntity.getIndexType(); - - Assert.notNull(indexName, "No 'indexName' defined for MoreLikeThisQuery"); - Assert.notNull(type, "No 'type' defined for MoreLikeThisQuery"); - Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); - - MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = moreLikeThisQuery( - toArray(new MoreLikeThisQueryBuilder.Item(indexName, type, query.getId()))); - - if (query.getMinTermFreq() != null) { - moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq()); - } - if (query.getMaxQueryTerms() != null) { - moreLikeThisQueryBuilder.maxQueryTerms(query.getMaxQueryTerms()); - } - if (!isEmpty(query.getStopWords())) { - moreLikeThisQueryBuilder.stopWords(toArray(query.getStopWords())); - } - if (query.getMinDocFreq() != null) { - moreLikeThisQueryBuilder.minDocFreq(query.getMinDocFreq()); - } - if (query.getMaxDocFreq() != null) { - moreLikeThisQueryBuilder.maxDocFreq(query.getMaxDocFreq()); - } - if (query.getMinWordLen() != null) { - moreLikeThisQueryBuilder.minWordLength(query.getMinWordLen()); - } - if (query.getMaxWordLen() != null) { - moreLikeThisQueryBuilder.maxWordLength(query.getMaxWordLen()); - } - if (query.getBoostTerms() != null) { - moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms()); - } - - return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz); - } - - private SearchResponse doSearch(SearchRequest searchRequest, NativeSearchQuery searchQuery) { - prepareSearch(searchRequest, searchQuery); - - try { - return client.search(searchRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + searchRequest.toString(), e); - } - } - - private SearchRequest prepareSearch(SearchRequest searchRequest, NativeSearchQuery searchQuery) { - if (searchQuery.getFilter() != null) { - searchRequest.source().postFilter(searchQuery.getFilter()); - } - - if (!isEmpty(searchQuery.getElasticsearchSorts())) { - for (SortBuilder sort : searchQuery.getElasticsearchSorts()) { - searchRequest.source().sort(sort); - } - } - - if (!searchQuery.getScriptFields().isEmpty()) { - // _source should be return all the time - // searchRequest.addStoredField("_source"); - for (ScriptField scriptedField : searchQuery.getScriptFields()) { - searchRequest.source().scriptField(scriptedField.fieldName(), scriptedField.script()); - } - } - - if (searchQuery.getCollapseBuilder() != null) { - searchRequest.source().collapse(searchQuery.getCollapseBuilder()); - } - - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); - } - } - searchRequest.source().highlighter(highlightBuilder); - } - - if (!isEmpty(searchQuery.getIndicesBoost())) { - for (IndexBoost indexBoost : searchQuery.getIndicesBoost()) { - searchRequest.source().indexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); - } - } - - if (!isEmpty(searchQuery.getAggregations())) { - for (AbstractAggregationBuilder aggregationBuilder : searchQuery.getAggregations()) { - searchRequest.source().aggregation(aggregationBuilder); - } - } - - if (!isEmpty(searchQuery.getFacets())) { - for (FacetRequest aggregatedFacet : searchQuery.getFacets()) { - searchRequest.source().aggregation(aggregatedFacet.getFacet()); - } - } - return searchRequest; - } - - private SearchResponse getSearchResponse(ActionFuture response) { - return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout); - } - - private boolean createIndexIfNotCreated(Class clazz) { - return indexExists(getPersistentEntityFor(clazz).getIndexName()) || createIndexWithSettings(clazz); - } - - private boolean createIndexWithSettings(Class clazz) { - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - if (hasText(settingPath)) { - String settings = ResourceUtil.readFileFromClasspath(settingPath); - if (hasText(settings)) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); - } - } else { - logger.info("settingPath in @Setting has to be defined. Using default instead."); - } - } - return createIndex(getPersistentEntityFor(clazz).getIndexName(), getDefaultSettings(getPersistentEntityFor(clazz))); - } - - @Override - public boolean createIndex(String indexName, Object settings) { - CreateIndexRequest request = new CreateIndexRequest(indexName); - if (settings instanceof String) { - request.settings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); - } else if (settings instanceof Map) { - request.settings((Map) settings); - } else if (settings instanceof XContentBuilder) { - request.settings((XContentBuilder) settings); - } - try { - return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Error for creating index: " + request.toString(), e); - } - } - - @Override - public boolean createIndex(Class clazz, Object settings) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); - } - - private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { - - if (persistentEntity.isUseServerConfiguration()) - return new HashMap(); - - return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) - .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) - .put("index.refresh_interval", persistentEntity.getRefreshInterval()) - .put("index.store.type", persistentEntity.getIndexStoreType()).map(); - } - @Override public Map getSetting(Class clazz) { return getSetting(getPersistentEntityFor(clazz).getIndexName()); @@ -1237,154 +487,16 @@ private Map convertSettingResponse(String settingResponse, Strin } - private SearchRequest prepareSearch(Query query, Class clazz) { - setPersistentEntityIndexAndType(query, clazz); - return prepareSearch(query, Optional.empty(), clazz); - } - - private SearchRequest prepareSearch(NativeSearchQuery query, Class clazz) { - setPersistentEntityIndexAndType(query, clazz); - return prepareSearch(query, Optional.ofNullable(query.getQuery()), clazz); - } - - private SearchRequest prepareSearch(Query query, Optional builder, @Nullable Class clazz) { - Assert.notNull(query.getIndices(), "No index defined for Query"); - Assert.notNull(query.getTypes(), "No type defined for Query"); - - int startRecord = 0; - SearchRequest request = new SearchRequest(toArray(query.getIndices())); - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - request.types(toArray(query.getTypes())); - sourceBuilder.version(true); - sourceBuilder.trackScores(query.getTrackScores()); - - if (builder.isPresent()) { - sourceBuilder.query(builder.get()); - } - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (query.getPageable().isPaged()) { - startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); - sourceBuilder.size(query.getPageable().getPageSize()); - } - sourceBuilder.from(startRecord); - - if (!query.getFields().isEmpty()) { - sourceBuilder.fetchSource(toArray(query.getFields()), null); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); - } - - if (query.getSort() != null) { - prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); - } - - if (query.getMinScore() > 0) { - sourceBuilder.minScore(query.getMinScore()); - } - - if (query.getPreference() != null) { - request.preference(query.getPreference()); - } - - if (query.getSearchType() != null) { - request.searchType(query.getSearchType()); - } - - request.source(sourceBuilder); - return request; - } - - private void prepareSort(Query query, SearchSourceBuilder sourceBuilder, - @Nullable ElasticsearchPersistentEntity entity) { - - for (Sort.Order order : query.getSort()) { - SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC; - - if (ScoreSortBuilder.NAME.equals(order.getProperty())) { - ScoreSortBuilder sort = SortBuilders // - .scoreSort() // - .order(sortOrder); - - sourceBuilder.sort(sort); - } else { - ElasticsearchPersistentProperty property = (entity != null) // - ? entity.getPersistentProperty(order.getProperty()) // - : null; - String fieldName = property != null ? property.getFieldName() : order.getProperty(); - - FieldSortBuilder sort = SortBuilders // - .fieldSort(fieldName) // - .order(sortOrder); - - if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { - sort.missing("_first"); - } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { - sort.missing("_last"); - } - - sourceBuilder.sort(sort); - } - } - } - - private IndexRequest prepareIndex(IndexQuery query) { - String indexName = StringUtils.isEmpty(query.getIndexName()) - ? retrieveIndexNameFromPersistentEntity(query.getObject().getClass())[0] - : query.getIndexName(); - String type = StringUtils.isEmpty(query.getType()) - ? retrieveTypeFromPersistentEntity(query.getObject().getClass())[0] - : query.getType(); - - IndexRequest indexRequest = null; - - if (query.getObject() != null) { - String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); - // If we have a query id and a document id, do not ask ES to generate one. - if (id != null) { - indexRequest = new IndexRequest(indexName, type, id); - } else { - indexRequest = new IndexRequest(indexName, type); - } - indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE); - } else if (query.getSource() != null) { - indexRequest = new IndexRequest(indexName, type, query.getId()).source(query.getSource(), - Requests.INDEX_CONTENT_TYPE); - } else { - throw new ElasticsearchException( - "object or source is null, failed to index the document [id: " + query.getId() + "]"); - } - if (query.getVersion() != null) { - indexRequest.version(query.getVersion()); - VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); - indexRequest.versionType(versionType); - } - - return indexRequest; - } - @Override - public void refresh(String indexName) { - Assert.notNull(indexName, "No index defined for refresh()"); + public void refresh(IndexCoordinates index) { + Assert.notNull(index, "No index defined for refresh()"); try { - // TODO: Do something with the response. - client.indices().refresh(refreshRequest(indexName), RequestOptions.DEFAULT); + client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT); } catch (IOException e) { - throw new ElasticsearchException("failed to refresh index: " + indexName, e); + throw new ElasticsearchException("failed to refresh index: " + index, e); } } - @Override - public void refresh(Class clazz) { - refresh(getPersistentEntityFor(clazz).getIndexName()); - } - @Override public List queryForAlias(String indexName) { List aliases = null; @@ -1393,7 +505,7 @@ public List queryForAlias(String indexName) { String aliasResponse; try { - response = restClient.performRequest(new Request("GET", "/" + indexName + "/_alias/*")); + response = restClient.performRequest(new Request("GET", '/' + indexName + "/_alias/*")); aliasResponse = EntityUtils.toString(response.getEntity()); } catch (Exception e) { throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName, e); @@ -1438,72 +550,6 @@ private List convertAliasResponse(String aliasResponse) { } } - @Nullable - private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class clazz) { - return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null; - } - - @Override - public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { - Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() - + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); - return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); - } - - private String getPersistentEntityId(Object entity) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - Object identifier = persistentEntity.getIdentifierAccessor(entity).getIdentifier(); - - if (identifier != null) { - return identifier.toString(); - } - - return null; - } - - private void setPersistentEntityId(Object entity, String id) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); - - // Only deal with text because ES generated Ids are strings ! - - if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { - persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id); - } - } - - private void setPersistentEntityIndexAndType(Query query, Class clazz) { - if (query.getIndices().isEmpty()) { - query.addIndices(retrieveIndexNameFromPersistentEntity(clazz)); - } - if (query.getTypes().isEmpty()) { - query.addTypes(retrieveTypeFromPersistentEntity(clazz)); - } - } - - private String[] retrieveIndexNameFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexName() }; - } - return null; - } - - private String[] retrieveTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexType() }; - } - return null; - } - - private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return getPersistentEntityFor(clazz).getVersionType(); - } - return VersionType.EXTERNAL; - } - private List extractIds(SearchResponse response) { List ids = new ArrayList<>(); for (SearchHit hit : response.getHits()) { @@ -1514,29 +560,8 @@ private List extractIds(SearchResponse response) { return ids; } - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - if (elasticsearchConverter instanceof ApplicationContextAware) { - ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context); - } - } - - private static String[] toArray(List values) { - String[] valuesAsArray = new String[values.size()]; - return values.toArray(valuesAsArray); - } - - private static MoreLikeThisQueryBuilder.Item[] toArray(MoreLikeThisQueryBuilder.Item... values) { - return values; - } - - @Deprecated - public static String readFileFromClasspath(String url) { - return ResourceUtil.readFileFromClasspath(url); - } - - public SearchResponse suggest(SuggestBuilder suggestion, String... indices) { - SearchRequest searchRequest = new SearchRequest(indices); + public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { + SearchRequest searchRequest = new SearchRequest(index.getIndexNames()); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.suggest(suggestion); searchRequest.source(sourceBuilder); @@ -1547,9 +572,4 @@ public SearchResponse suggest(SuggestBuilder suggestion, String... indices) { throw new ElasticsearchException("Could not execute search request : " + searchRequest.toString(), e); } } - - public SearchResponse suggest(SuggestBuilder suggestion, Class clazz) { - return suggest(suggestion, retrieveIndexNameFromPersistentEntity(clazz)); - } - } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 593fdf418..7a8ddade5 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -16,12 +16,8 @@ package org.springframework.data.elasticsearch.core; import static org.elasticsearch.client.Requests.*; -import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.springframework.util.CollectionUtils.*; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -34,68 +30,45 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; -import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; -import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; -import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetRequestBuilder; -import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Client; -import org.elasticsearch.client.Requests; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.index.VersionType; -import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.reindex.DeleteByQueryAction; -import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder; import org.elasticsearch.search.SearchHit; -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; -import org.elasticsearch.search.sort.FieldSortBuilder; -import org.elasticsearch.search.sort.ScoreSortBuilder; -import org.elasticsearch.search.sort.SortBuilder; -import org.elasticsearch.search.sort.SortBuilders; -import org.elasticsearch.search.sort.SortOrder; import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.SearchHitsUtil; import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * ElasticsearchTemplate @@ -126,12 +99,10 @@ * @deprecated as of 4.0 */ @Deprecated -public class ElasticsearchTemplate extends AbstractElasticsearchTemplate - implements EsClient, ApplicationContextAware { +public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { private static final Logger QUERY_LOGGER = LoggerFactory .getLogger("org.springframework.data.elasticsearch.core.QUERY"); - private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchTemplate.class); private Client client; private String searchTimeout; @@ -146,15 +117,8 @@ public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearch private void initialize(Client client, ElasticsearchConverter elasticsearchConverter) { Assert.notNull(client, "Client must not be null!"); - Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); - this.client = client; - this.elasticsearchConverter = elasticsearchConverter; - } - - @Override - public Client getClient() { - return client; + initialize(elasticsearchConverter); } public void setSearchTimeout(String searchTimeout) { @@ -162,117 +126,54 @@ public void setSearchTimeout(String searchTimeout) { } @Override - public boolean addAlias(AliasQuery query) { - Assert.notNull(query.getIndexName(), "No index defined for Alias"); - Assert.notNull(query.getAliasName(), "No alias defined"); - IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.add() - .alias(query.getAliasName()).index(query.getIndexName()); - - if (query.getFilterBuilder() != null) { - aliasAction.filter(query.getFilterBuilder()); - } else if (query.getFilter() != null) { - aliasAction.filter(query.getFilter()); - } else if (!StringUtils.isEmpty(query.getRouting())) { - aliasAction.routing(query.getRouting()); - } else if (!StringUtils.isEmpty(query.getSearchRouting())) { - aliasAction.searchRouting(query.getSearchRouting()); - } else if (!StringUtils.isEmpty(query.getIndexRouting())) { - aliasAction.indexRouting(query.getIndexRouting()); - } + public boolean addAlias(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest.AliasActions aliasAction = requestFactory.aliasAction(query, index); return client.admin().indices().prepareAliases().addAliasAction(aliasAction).execute().actionGet().isAcknowledged(); } @Override - public boolean removeAlias(AliasQuery query) { - Assert.notNull(query.getIndexName(), "No index defined for Alias"); + public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); - return client.admin().indices().prepareAliases().removeAlias(query.getIndexName(), query.getAliasName()).execute() + return client.admin().indices().prepareAliases().removeAlias(index.getIndexName(), query.getAliasName()).execute() .actionGet().isAcknowledged(); } @Override - public boolean createIndex(Class clazz) { - return createIndexIfNotCreated(clazz); - } - - @Override - public boolean createIndex(String indexName) { - Assert.notNull(indexName, "No index defined for Query"); - return client.admin().indices().create(Requests.createIndexRequest(indexName)).actionGet().isAcknowledged(); - } - - @Override - public boolean putMapping(Class clazz) { - return putMapping(clazz, buildMapping(clazz)); - } - - @Override - public boolean putMapping(Class clazz, Object mapping) { - return putMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType(), - mapping); - } - - @Override - public boolean putMapping(String indexName, String type, Class clazz) { - return putMapping(indexName, type, buildMapping(clazz)); + public boolean createIndex(String indexName, Object settings) { + CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, indexName, + settings); + return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); } @Override - public boolean putMapping(String indexName, String type, Object mapping) { - Assert.notNull(indexName, "No index defined for putMapping()"); - Assert.notNull(type, "No type defined for putMapping()"); - PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(indexName).setType(type); - if (mapping instanceof String) { - requestBuilder.setSource(String.valueOf(mapping), XContentType.JSON); - } else if (mapping instanceof Map) { - requestBuilder.setSource((Map) mapping); - } else if (mapping instanceof XContentBuilder) { - requestBuilder.setSource((XContentBuilder) mapping); - } + public boolean putMapping(IndexCoordinates index, Object mapping) { + Assert.notNull(index, "No index defined for putMapping()"); + PutMappingRequestBuilder requestBuilder = requestFactory.putMappingRequestBuilder(client, index, mapping); return requestBuilder.execute().actionGet().isAcknowledged(); } @Override - public Map getMapping(String indexName, String type) { - Assert.notNull(indexName, "No index defined for putMapping()"); - Assert.notNull(type, "No type defined for putMapping()"); - Map mappings = null; + public Map getMapping(IndexCoordinates index) { + Assert.notNull(index, "No index defined for putMapping()"); try { - mappings = client.admin().indices().getMappings(new GetMappingsRequest().indices(indexName).types(type)) - .actionGet().getMappings().get(indexName).get(type).getSourceAsMap(); + return client.admin().indices() + .getMappings(new GetMappingsRequest().indices(index.getIndexNames()).types(index.getTypeNames())).actionGet() + .getMappings().get(index.getIndexName()).get(index.getTypeName()).getSourceAsMap(); } catch (Exception e) { - throw new ElasticsearchException( - "Error while getting mapping for indexName : " + indexName + " type : " + type + " " + e.getMessage()); + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() + + " type : " + index.getTypeName() + ' ' + e.getMessage()); } - return mappings; } @Override - public Map getMapping(Class clazz) { - return getMapping(getPersistentEntityFor(clazz).getIndexName(), getPersistentEntityFor(clazz).getIndexType()); - } - - @Override - public T queryForObject(GetQuery query, Class clazz) { - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - GetResponse response = client - .prepareGet(persistentEntity.getIndexName(), persistentEntity.getIndexType(), query.getId()).execute() - .actionGet(); - + public T get(GetQuery query, Class clazz, IndexCoordinates index) { + GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, query, index); + GetResponse response = getRequestBuilder.execute().actionGet(); T entity = elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); return entity; } - @Override - public T queryForObject(CriteriaQuery query, Class clazz) { - return getObjectFromPage(queryForPage(query, clazz)); - } - - @Override - public T queryForObject(StringQuery query, Class clazz) { - return getObjectFromPage(queryForPage(query, clazz)); - } - @Nullable private T getObjectFromPage(Page page) { int contentSize = page.getContent().size(); @@ -281,45 +182,7 @@ private T getObjectFromPage(Page page) { } @Override - public AggregatedPage queryForPage(NativeSearchQuery query, Class clazz) { - SearchResponse response = doSearch(prepareSearch(query, clazz), query); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); - } - - @Override - public List> queryForPage(List queries, Class clazz) { - MultiSearchRequest request = new MultiSearchRequest(); - for (NativeSearchQuery query : queries) { - request.add(prepareSearch(prepareSearch(query, clazz), query)); - } - return doMultiSearch(queries, clazz, request); - } - - private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { - MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); - int c = 0; - for (NativeSearchQuery query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, - query.getPageable())); - } - return res; - } - - private List> doMultiSearch(List queries, List> classes, - MultiSearchRequest request) { - MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); - int c = 0; - Iterator> it = classes.iterator(); - for (NativeSearchQuery query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), - query.getPageable())); - } - return res; - } - - private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { + protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { ActionFuture future = client.multiSearch(request); MultiSearchResponse response = future.actionGet(); MultiSearchResponse.Item[] items = response.getResponses(); @@ -328,92 +191,35 @@ private MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest reque } @Override - public List> queryForPage(List queries, List> classes) { - Assert.isTrue(queries.size() == classes.size(), "Queries should have same length with classes"); - MultiSearchRequest request = new MultiSearchRequest(); - Iterator> it = classes.iterator(); - for (NativeSearchQuery query : queries) { - request.add(prepareSearch(prepareSearch(query, it.next()), query)); - } - return doMultiSearch(queries, classes, request); - } - - @Override - public T query(NativeSearchQuery query, ResultsExtractor resultsExtractor) { - SearchResponse response = doSearch(prepareSearch(query, (ElasticsearchPersistentEntity) null), query); + public T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + SearchResponse response = getSearchResponse(searchRequestBuilder); return resultsExtractor.extract(response); } @Override - public List queryForList(CriteriaQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); - } - - @Override - public List queryForList(StringQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); - } - - @Override - public List queryForList(NativeSearchQuery query, Class clazz) { - return queryForPage(query, clazz).getContent(); + public List queryForList(Query query, Class clazz, IndexCoordinates index) { + return queryForPage(query, clazz, index).getContent(); } @Override - public List queryForIds(NativeSearchQuery query) { - SearchRequestBuilder request = prepareSearch(query, (ElasticsearchPersistentEntity) null) - .setQuery(query.getQuery()); - if (query.getFilter() != null) { - request.setPostFilter(query.getFilter()); - } - SearchResponse response = getSearchResponse(request); + public List queryForIds(Query query, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + SearchResponse response = getSearchResponse(searchRequestBuilder); return extractIds(response); } @Override - public Page queryForPage(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - SearchRequestBuilder searchRequestBuilder = prepareSearch(criteriaQuery, clazz); - - if (elasticsearchQuery != null) { - searchRequestBuilder.setQuery(elasticsearchQuery); - } else { - searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); - } - - if (criteriaQuery.isLimiting()) { - searchRequestBuilder.setSize(criteriaQuery.getMaxResults()); - } - - if (criteriaQuery.getMinScore() > 0) { - searchRequestBuilder.setMinScore(criteriaQuery.getMinScore()); - } - - if (elasticsearchFilter != null) - searchRequestBuilder.setPostFilter(elasticsearchFilter); - + public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); SearchResponse response = getSearchResponse(searchRequestBuilder); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, criteriaQuery.getPageable()); - } - - @Override - public Page queryForPage(StringQuery query, Class clazz) { - SearchResponse response = getSearchResponse(prepareSearch(query, clazz).setQuery(wrapperQuery(query.getSource()))); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public CloseableIterator stream(CriteriaQuery query, Class clazz) { + public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); - } - - @Override - public CloseableIterator stream(NativeSearchQuery query, Class clazz) { - long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz), clazz); + return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, index), clazz); } private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage page, Class clazz) { @@ -422,119 +228,26 @@ private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage< } @Override - public long count(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - - if (elasticsearchFilter == null) { - return doCount(prepareCount(criteriaQuery, clazz), elasticsearchQuery); - } else { - // filter could not be set into CountRequestBuilder, convert request into search request - return doCount(prepareSearch(criteriaQuery, clazz), elasticsearchQuery, elasticsearchFilter); - } - } - - @Override - public long count(NativeSearchQuery searchQuery, Class clazz) { - QueryBuilder elasticsearchQuery = searchQuery.getQuery(); - QueryBuilder elasticsearchFilter = searchQuery.getFilter(); - - if (elasticsearchFilter == null) { - return doCount(prepareCount(searchQuery, clazz), elasticsearchQuery); - } else { - // filter could not be set into CountRequestBuilder, convert request into search request - return doCount(prepareSearch(searchQuery, clazz), elasticsearchQuery, elasticsearchFilter); - } - } - - @Override - public long count(CriteriaQuery query) { - return count(query, null); - } - - @Override - public long count(NativeSearchQuery query) { - return count(query, null); - } - - private long doCount(SearchRequestBuilder countRequestBuilder, QueryBuilder elasticsearchQuery) { + public long count(Query query, @Nullable Class clazz, IndexCoordinates index) { + Assert.notNull(index, "index must not be null"); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + searchRequestBuilder.setSize(0); - if (elasticsearchQuery != null) { - countRequestBuilder.setQuery(elasticsearchQuery); - } - return SearchHitsUtil.getTotalCount(countRequestBuilder.execute().actionGet().getHits()); - } - - private long doCount(SearchRequestBuilder searchRequestBuilder, QueryBuilder elasticsearchQuery, - QueryBuilder elasticsearchFilter) { - if (elasticsearchQuery != null) { - searchRequestBuilder.setQuery(elasticsearchQuery); - } else { - searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); - } - if (elasticsearchFilter != null) { - searchRequestBuilder.setPostFilter(elasticsearchFilter); - } - return SearchHitsUtil.getTotalCount(searchRequestBuilder.execute().actionGet().getHits()); - } - - private SearchRequestBuilder prepareCount(Query query, Class clazz) { - String indexName[] = !isEmpty(query.getIndices()) - ? query.getIndices().toArray(new String[query.getIndices().size()]) - : retrieveIndexNameFromPersistentEntity(clazz); - String types[] = !isEmpty(query.getTypes()) ? query.getTypes().toArray(new String[query.getTypes().size()]) - : retrieveTypeFromPersistentEntity(clazz); - - Assert.notNull(indexName, "No index defined for Query"); - - SearchRequestBuilder countRequestBuilder = client.prepareSearch(indexName); - - if (types != null) { - countRequestBuilder.setTypes(types); - } - countRequestBuilder.setSize(0); - return countRequestBuilder; + return SearchHitsUtil.getTotalCount(getSearchResponse(searchRequestBuilder).getHits()); } @Override - public List multiGet(NativeSearchQuery searchQuery, Class clazz) { - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(getMultiResponse(searchQuery, clazz)), clazz); - } - - private MultiGetResponse getMultiResponse(Query searchQuery, Class clazz) { - - String indexName = !isEmpty(searchQuery.getIndices()) ? searchQuery.getIndices().get(0) - : getPersistentEntityFor(clazz).getIndexName(); - String type = !isEmpty(searchQuery.getTypes()) ? searchQuery.getTypes().get(0) - : getPersistentEntityFor(clazz).getIndexType(); - - Assert.notNull(indexName, "No index defined for Query"); - Assert.notNull(type, "No type define for Query"); - Assert.notEmpty(searchQuery.getIds(), "No Id define for Query"); - - MultiGetRequestBuilder builder = client.prepareMultiGet(); - - if (searchQuery.getFields() != null && !searchQuery.getFields().isEmpty()) { - searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null)); - } - - for (String id : searchQuery.getIds()) { - - MultiGetRequest.Item item = new MultiGetRequest.Item(indexName, type, id); - - if (searchQuery.getRoute() != null) { - item = item.routing(searchQuery.getRoute()); - } - - builder.add(item); - } - return builder.execute().actionGet(); + public List multiGet(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(index, "index must not be null"); + Assert.notEmpty(query.getIds(), "No Id define for Query"); + MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); + return elasticsearchConverter.mapDocuments(DocumentAdapters.from(builder.execute().actionGet()), clazz); } @Override - public String index(IndexQuery query) { - String documentId = prepareIndex(query).execute().actionGet().getId(); + public String index(IndexQuery query, IndexCoordinates index) { + IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); + String documentId = indexRequestBuilder.execute().actionGet().getId(); // We should call this because we are not going through a mapper. if (query.getObject() != null) { setPersistentEntityId(query.getObject(), documentId); @@ -543,118 +256,30 @@ public String index(IndexQuery query) { } @Override - public UpdateResponse update(UpdateQuery query) { - return this.prepareUpdate(query).execute().actionGet(); - } - - private UpdateRequestBuilder prepareUpdate(UpdateQuery query) { - - String indexName = !StringUtils.isEmpty(query.getIndexName()) ? query.getIndexName() - : getPersistentEntityFor(query.getClazz()).getIndexName(); - String type = !StringUtils.isEmpty(query.getType()) ? query.getType() - : getPersistentEntityFor(query.getClazz()).getIndexType(); - - Assert.notNull(indexName, "No index defined for Query"); - Assert.notNull(type, "No type define for Query"); - Assert.notNull(query.getId(), "No Id define for Query"); - Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); - - UpdateRequest queryUpdateRequest = query.getUpdateRequest(); - - UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, type, query.getId()) // - .setRouting(queryUpdateRequest.routing()) // - .setRetryOnConflict(queryUpdateRequest.retryOnConflict()) // - .setTimeout(queryUpdateRequest.timeout()) // - .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // - .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setScriptedUpsert(queryUpdateRequest.scriptedUpsert()) // - .setDocAsUpsert(queryUpdateRequest.docAsUpsert()); - - if (query.DoUpsert()) { - updateRequestBuilder.setDocAsUpsert(true); - } - if (queryUpdateRequest.script() != null) { - updateRequestBuilder.setScript(queryUpdateRequest.script()); - } - if (queryUpdateRequest.doc() != null) { - updateRequestBuilder.setDoc(queryUpdateRequest.doc()); - } - if (queryUpdateRequest.upsertRequest() != null) { - updateRequestBuilder.setUpsert(queryUpdateRequest.upsertRequest()); - } - - return updateRequestBuilder; + public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { + UpdateRequestBuilder updateRequestBuilder = requestFactory.updateRequestBuilderFor(client, query, index); + return updateRequestBuilder.execute().actionGet(); } @Override - public void bulkIndex(List queries, BulkOptions bulkOptions) { - + public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - BulkRequestBuilder bulkRequest = client.prepareBulk(); - setBulkOptions(bulkRequest, bulkOptions); - for (IndexQuery query : queries) { - bulkRequest.add(prepareIndex(query)); - } - checkForBulkUpdateFailure(bulkRequest.execute().actionGet()); + doBulkOperation(queries, bulkOptions, index); } @Override - public void bulkUpdate(List queries, BulkOptions bulkOptions) { - + public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of UpdateQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - BulkRequestBuilder bulkRequest = client.prepareBulk(); - setBulkOptions(bulkRequest, bulkOptions); - for (UpdateQuery query : queries) { - bulkRequest.add(prepareUpdate(query)); - } - checkForBulkUpdateFailure(bulkRequest.execute().actionGet()); - } - - private static void setBulkOptions(BulkRequestBuilder bulkRequest, BulkOptions bulkOptions) { - - if (bulkOptions.getTimeout() != null) { - bulkRequest.setTimeout(bulkOptions.getTimeout()); - } - - if (bulkOptions.getRefreshPolicy() != null) { - bulkRequest.setRefreshPolicy(bulkOptions.getRefreshPolicy()); - } - - if (bulkOptions.getWaitForActiveShards() != null) { - bulkRequest.setWaitForActiveShards(bulkOptions.getWaitForActiveShards()); - } - - if (bulkOptions.getPipeline() != null) { - bulkRequest.pipeline(bulkOptions.getPipeline()); - } - - if (bulkOptions.getRoutingId() != null) { - bulkRequest.routing(bulkOptions.getRoutingId()); - } - } - - private void checkForBulkUpdateFailure(BulkResponse bulkResponse) { - if (bulkResponse.hasFailures()) { - Map failedDocuments = new HashMap<>(); - for (BulkItemResponse item : bulkResponse.getItems()) { - if (item.isFailed()) - failedDocuments.put(item.getId(), item.getFailureMessage()); - } - throw new ElasticsearchException( - "Bulk indexing has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" - + failedDocuments + "]", - failedDocuments); - } + doBulkOperation(queries, bulkOptions, index); } - @Override - public boolean indexExists(Class clazz) { - return indexExists(getPersistentEntityFor(clazz).getIndexName()); + private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); + checkForBulkOperationFailure(bulkRequest.execute().actionGet()); } @Override @@ -662,17 +287,6 @@ public boolean indexExists(String indexName) { return client.admin().indices().exists(indicesExistsRequest(indexName)).actionGet().isExists(); } - @Override - public boolean typeExists(String index, String type) { - return client.admin().cluster().prepareState().execute().actionGet().getState().metaData().index(index) - .getMappings().containsKey(type); - } - - @Override - public boolean deleteIndex(Class clazz) { - return deleteIndex(getPersistentEntityFor(clazz).getIndexName()); - } - @Override public boolean deleteIndex(String indexName) { Assert.notNull(indexName, "No index defined for delete operation"); @@ -683,162 +297,27 @@ public boolean deleteIndex(String indexName) { } @Override - public String delete(String indexName, String type, String id) { - return client.prepareDelete(indexName, type, id).execute().actionGet().getId(); - } - - @Override - public String delete(Class clazz, String id) { - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - return delete(persistentEntity.getIndexName(), persistentEntity.getIndexType(), id); + public String delete(String id, IndexCoordinates index) { + return client.prepareDelete(index.getIndexName(), index.getTypeName(), id).execute().actionGet().getId(); } @Override - public void delete(DeleteQuery deleteQuery, Class clazz) { - - String indexName = !StringUtils.isEmpty(deleteQuery.getIndex()) ? deleteQuery.getIndex() - : getPersistentEntityFor(clazz).getIndexName(); - String typeName = !StringUtils.isEmpty(deleteQuery.getType()) ? deleteQuery.getType() - : getPersistentEntityFor(clazz).getIndexType(); - - DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) // - .source(indexName) // - .filter(deleteQuery.getQuery()) // - .abortOnVersionConflict(false) // - .refresh(true); - - SearchRequestBuilder source = requestBuilder.source() // - .setTypes(typeName); - - if (deleteQuery.getScrollTimeInMillis() != null) - source.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); - - requestBuilder.get(); + public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { + requestFactory.deleteByQueryRequestBuilder(client, deleteQuery, index).get(); } @Override - public void delete(DeleteQuery deleteQuery) { - Assert.notNull(deleteQuery.getIndex(), "No index defined for Query"); - Assert.notNull(deleteQuery.getType(), "No type define for Query"); - delete(deleteQuery, null); - } - - @Override - public void delete(CriteriaQuery criteriaQuery, Class clazz) { - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - Assert.notNull(elasticsearchQuery, "Query can not be null."); - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(elasticsearchQuery); - delete(deleteQuery, clazz); - } - - private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis, Class clazz) { - setPersistentEntityIndexAndType(query, clazz); - return prepareScroll(query, scrollTimeInMillis, getPersistentEntity(clazz)); - } - - private SearchRequestBuilder prepareScroll(Query query, long scrollTimeInMillis, - @Nullable ElasticsearchPersistentEntity entity) { - SearchRequestBuilder requestBuilder = client.prepareSearch(toArray(query.getIndices())) - .setTypes(toArray(query.getTypes())).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).setFrom(0) - .setVersion(true); - - if (query.getPageable().isPaged()) { - requestBuilder.setSize(query.getPageable().getPageSize()); - } - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - requestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (!isEmpty(query.getFields())) { - requestBuilder.setFetchSource(toArray(query.getFields()), null); - } - - if (query.getSort() != null) { - prepareSort(query, requestBuilder, entity); - } - - if (query.getIndicesOptions() != null) { - requestBuilder.setIndicesOptions(query.getIndicesOptions()); - } - - if (query instanceof NativeSearchQuery) { - NativeSearchQuery searchQuery = (NativeSearchQuery) query; - - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); - } - } - requestBuilder.highlighter(highlightBuilder); - } - } - - return requestBuilder; - } - - private SearchResponse doScroll(SearchRequestBuilder requestBuilder, CriteriaQuery criteriaQuery) { - Assert.notNull(criteriaQuery.getIndices(), "No index defined for Query"); - Assert.notNull(criteriaQuery.getTypes(), "No type define for Query"); - Assert.notNull(criteriaQuery.getPageable(), "Query.pageable is required for scan & scroll"); - - QueryBuilder elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); - QueryBuilder elasticsearchFilter = new CriteriaFilterProcessor() - .createFilterFromCriteria(criteriaQuery.getCriteria()); - - if (elasticsearchQuery != null) { - requestBuilder.setQuery(elasticsearchQuery); - } else { - requestBuilder.setQuery(QueryBuilders.matchAllQuery()); - } - - if (elasticsearchFilter != null) { - requestBuilder.setPostFilter(elasticsearchFilter); - } - - return getSearchResponse(requestBuilder); - } - - private SearchResponse doScroll(SearchRequestBuilder requestBuilder, NativeSearchQuery searchQuery) { - Assert.notNull(searchQuery.getIndices(), "No index defined for Query"); - Assert.notNull(searchQuery.getTypes(), "No type define for Query"); - Assert.notNull(searchQuery.getPageable(), "Query.pageable is required for scan & scroll"); - - if (searchQuery.getFilter() != null) { - requestBuilder.setPostFilter(searchQuery.getFilter()); - } - - if (!isEmpty(searchQuery.getElasticsearchSorts())) { - for (SortBuilder sort : searchQuery.getElasticsearchSorts()) { - requestBuilder.addSort(sort); - } - } - - return getSearchResponse(requestBuilder.setQuery(searchQuery.getQuery())); - } - - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, NativeSearchQuery searchQuery, Class clazz) { - SearchResponse response = doScroll(prepareScroll(searchQuery, scrollTimeInMillis, clazz), searchQuery); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); - } - - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, CriteriaQuery criteriaQuery, Class clazz) { - SearchResponse response = doScroll(prepareScroll(criteriaQuery, scrollTimeInMillis, clazz), criteriaQuery); + public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + searchRequestBuilder.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)); + SearchResponse response = getSearchResponse(searchRequestBuilder); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); } @Override public ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { - SearchResponse response = getSearchResponse( + SearchResponse response = getSearchResponseWithTimeout( client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, Pageable.unpaged()); } @@ -848,172 +327,18 @@ public void clearScroll(String scrollId) { client.prepareClearScroll().addScrollId(scrollId).execute().actionGet(); } - @Override - public Page moreLikeThis(MoreLikeThisQuery query, Class clazz) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(clazz); - String indexName = !StringUtils.isEmpty(query.getIndexName()) ? query.getIndexName() - : persistentEntity.getIndexName(); - String type = !StringUtils.isEmpty(query.getType()) ? query.getType() : persistentEntity.getIndexType(); - - Assert.notNull(indexName, "No 'indexName' defined for MoreLikeThisQuery"); - Assert.notNull(type, "No 'type' defined for MoreLikeThisQuery"); - Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); - - MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = moreLikeThisQuery( - toArray(new MoreLikeThisQueryBuilder.Item(indexName, type, query.getId()))); - - if (query.getMinTermFreq() != null) { - moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq()); - } - if (query.getMaxQueryTerms() != null) { - moreLikeThisQueryBuilder.maxQueryTerms(query.getMaxQueryTerms()); - } - if (!isEmpty(query.getStopWords())) { - moreLikeThisQueryBuilder.stopWords(toArray(query.getStopWords())); - } - if (query.getMinDocFreq() != null) { - moreLikeThisQueryBuilder.minDocFreq(query.getMinDocFreq()); - } - if (query.getMaxDocFreq() != null) { - moreLikeThisQueryBuilder.maxDocFreq(query.getMaxDocFreq()); - } - if (query.getMinWordLen() != null) { - moreLikeThisQueryBuilder.minWordLength(query.getMinWordLen()); - } - if (query.getMaxWordLen() != null) { - moreLikeThisQueryBuilder.maxWordLength(query.getMaxWordLen()); - } - if (query.getBoostTerms() != null) { - moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms()); - } - - return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz); - } - - private SearchResponse doSearch(SearchRequestBuilder searchRequest, NativeSearchQuery searchQuery) { - SearchRequestBuilder requestBuilder = prepareSearch(searchRequest, searchQuery); - return getSearchResponse(requestBuilder); - } - - private SearchRequestBuilder prepareSearch(SearchRequestBuilder searchRequest, NativeSearchQuery searchQuery) { - if (searchQuery.getFilter() != null) { - searchRequest.setPostFilter(searchQuery.getFilter()); - } - - if (!isEmpty(searchQuery.getElasticsearchSorts())) { - for (SortBuilder sort : searchQuery.getElasticsearchSorts()) { - searchRequest.addSort(sort); - } - } - - if (!searchQuery.getScriptFields().isEmpty()) { - // _source should be return all the time - // searchRequest.addStoredField("_source"); - for (ScriptField scriptedField : searchQuery.getScriptFields()) { - searchRequest.addScriptField(scriptedField.fieldName(), scriptedField.script()); - } - } - - if (searchQuery.getCollapseBuilder() != null) { - searchRequest.setCollapse(searchQuery.getCollapseBuilder()); - } - - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - HighlightBuilder highlightBuilder = searchQuery.getHighlightBuilder(); - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); - } - } - searchRequest.highlighter(highlightBuilder); - } - - if (!isEmpty(searchQuery.getIndicesBoost())) { - for (IndexBoost indexBoost : searchQuery.getIndicesBoost()) { - searchRequest.addIndexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); - } - } - - if (!isEmpty(searchQuery.getAggregations())) { - for (AbstractAggregationBuilder aggregationBuilder : searchQuery.getAggregations()) { - searchRequest.addAggregation(aggregationBuilder); - } - } - - if (!isEmpty(searchQuery.getFacets())) { - for (FacetRequest aggregatedFacet : searchQuery.getFacets()) { - searchRequest.addAggregation(aggregatedFacet.getFacet()); - } - } - - return searchRequest.setQuery(searchQuery.getQuery()); - } - private SearchResponse getSearchResponse(SearchRequestBuilder requestBuilder) { if (QUERY_LOGGER.isDebugEnabled()) { QUERY_LOGGER.debug(requestBuilder.toString()); } - - return getSearchResponse(requestBuilder.execute()); + return getSearchResponseWithTimeout(requestBuilder.execute()); } - private SearchResponse getSearchResponse(ActionFuture response) { + private SearchResponse getSearchResponseWithTimeout(ActionFuture response) { return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout); } - private boolean createIndexIfNotCreated(Class clazz) { - return indexExists(getPersistentEntityFor(clazz).getIndexName()) || createIndexWithSettings(clazz); - } - - private boolean createIndexWithSettings(Class clazz) { - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - if (!StringUtils.isEmpty(settingPath)) { - String settings = ResourceUtil.readFileFromClasspath(settingPath); - if (!StringUtils.isEmpty(settings)) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); - } - } else { - LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); - } - } - return createIndex(getPersistentEntityFor(clazz).getIndexName(), getDefaultSettings(getPersistentEntityFor(clazz))); - } - - @Override - public boolean createIndex(String indexName, Object settings) { - CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); - if (settings instanceof String) { - createIndexRequestBuilder.setSettings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); - } else if (settings instanceof Map) { - createIndexRequestBuilder.setSettings((Map) settings); - } else if (settings instanceof XContentBuilder) { - createIndexRequestBuilder.setSettings((XContentBuilder) settings); - } - return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); - } - - @Override - public boolean createIndex(Class clazz, Object settings) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); - } - - private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { - - if (persistentEntity.isUseServerConfiguration()) - return new HashMap<>(); - - return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) - .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) - .put("index.refresh_interval", persistentEntity.getRefreshInterval()) - .put("index.store.type", persistentEntity.getIndexStoreType()).map(); - } - @Override public Map getSetting(Class clazz) { return getSetting(getPersistentEntityFor(clazz).getIndexName()); @@ -1027,130 +352,10 @@ public Map getSetting(String indexName) { return settings.keySet().stream().collect(Collectors.toMap((key) -> key, (key) -> settings.get(key))); } - private SearchRequestBuilder prepareSearch(Query query, Class clazz) { - setPersistentEntityIndexAndType(query, clazz); - return prepareSearch(query, getPersistentEntity(clazz)); - } - - private SearchRequestBuilder prepareSearch(Query query, @Nullable ElasticsearchPersistentEntity entity) { - Assert.notNull(query.getIndices(), "No index defined for Query"); - Assert.notNull(query.getTypes(), "No type defined for Query"); - - int startRecord = 0; - SearchRequestBuilder searchRequestBuilder = client.prepareSearch(toArray(query.getIndices())) - .setSearchType(query.getSearchType()).setTypes(toArray(query.getTypes())).setVersion(true) - .setTrackScores(query.getTrackScores()); - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (query.getPageable().isPaged()) { - startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); - searchRequestBuilder.setSize(query.getPageable().getPageSize()); - } - searchRequestBuilder.setFrom(startRecord); - - if (!query.getFields().isEmpty()) { - searchRequestBuilder.setFetchSource(toArray(query.getFields()), null); - } - - if (query.getIndicesOptions() != null) { - searchRequestBuilder.setIndicesOptions(query.getIndicesOptions()); - } - - if (query.getSort() != null) { - prepareSort(query, searchRequestBuilder, entity); - } - - if (query.getMinScore() > 0) { - searchRequestBuilder.setMinScore(query.getMinScore()); - } - - if (query.getPreference() != null) { - searchRequestBuilder.setPreference(query.getPreference()); - } - - return searchRequestBuilder; - } - - private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder, - @Nullable ElasticsearchPersistentEntity entity) { - for (Sort.Order order : query.getSort()) { - SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC; - - if (ScoreSortBuilder.NAME.equals(order.getProperty())) { - ScoreSortBuilder sort = SortBuilders // - .scoreSort() // - .order(sortOrder); - - searchRequestBuilder.addSort(sort); - } else { - ElasticsearchPersistentProperty property = entity != null // - ? entity.getPersistentProperty(order.getProperty()) // - : null; - String fieldName = property != null ? property.getFieldName() : order.getProperty(); - FieldSortBuilder sort = SortBuilders // - .fieldSort(fieldName) // - .order(sortOrder); - - if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { - sort.missing("_first"); - } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { - sort.missing("_last"); - } - - searchRequestBuilder.addSort(sort); - } - } - } - - private IndexRequestBuilder prepareIndex(IndexQuery query) { - String indexName = StringUtils.isEmpty(query.getIndexName()) - ? retrieveIndexNameFromPersistentEntity(query.getObject().getClass())[0] - : query.getIndexName(); - String type = StringUtils.isEmpty(query.getType()) - ? retrieveTypeFromPersistentEntity(query.getObject().getClass())[0] - : query.getType(); - - IndexRequestBuilder indexRequestBuilder = null; - - if (query.getObject() != null) { - String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); - // If we have a query id and a document id, do not ask ES to generate one. - if (id != null) { - indexRequestBuilder = client.prepareIndex(indexName, type, id); - } else { - indexRequestBuilder = client.prepareIndex(indexName, type); - } - indexRequestBuilder.setSource(elasticsearchConverter.mapObject(query.getObject()).toJson(), - Requests.INDEX_CONTENT_TYPE); - } else if (query.getSource() != null) { - indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource(), - Requests.INDEX_CONTENT_TYPE); - } else { - throw new ElasticsearchException( - "object or source is null, failed to index the document [id: " + query.getId() + "]"); - } - if (query.getVersion() != null) { - indexRequestBuilder.setVersion(query.getVersion()); - VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); - indexRequestBuilder.setVersionType(versionType); - } - - return indexRequestBuilder; - } - - @Override - public void refresh(String indexName) { - Assert.notNull(indexName, "No index defined for refresh()"); - client.admin().indices().refresh(refreshRequest(indexName)).actionGet(); - } - @Override - public void refresh(Class clazz) { - refresh(getPersistentEntityFor(clazz).getIndexName()); + public void refresh(IndexCoordinates index) { + Assert.notNull(index, "No index defined for refresh()"); + client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet(); } @Override @@ -1159,72 +364,6 @@ public List queryForAlias(String indexName) { .get(indexName); } - @Nullable - private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class clazz) { - return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null; - } - - @Override - public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { - Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() - + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); - return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); - } - - private String getPersistentEntityId(Object entity) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - Object identifier = persistentEntity.getIdentifierAccessor(entity).getIdentifier(); - - if (identifier != null) { - return identifier.toString(); - } - - return null; - } - - private void setPersistentEntityId(Object entity, String id) { - - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); - ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); - - // Only deal with text because ES generated Ids are strings ! - - if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { - persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id); - } - } - - private void setPersistentEntityIndexAndType(Query query, Class clazz) { - if (query.getIndices().isEmpty()) { - query.addIndices(retrieveIndexNameFromPersistentEntity(clazz)); - } - if (query.getTypes().isEmpty()) { - query.addTypes(retrieveTypeFromPersistentEntity(clazz)); - } - } - - private String[] retrieveIndexNameFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexName() }; - } - return null; - } - - private String[] retrieveTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexType() }; - } - return null; - } - - private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return getPersistentEntityFor(clazz).getVersionType(); - } - return VersionType.EXTERNAL; - } - private List extractIds(SearchResponse response) { List ids = new ArrayList<>(); for (SearchHit hit : response.getHits()) { @@ -1235,33 +374,8 @@ private List extractIds(SearchResponse response) { return ids; } - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - if (elasticsearchConverter instanceof ApplicationContextAware) { - ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context); - } - } - - private static String[] toArray(List values) { - String[] valuesAsArray = new String[values.size()]; - return values.toArray(valuesAsArray); - } - - private static MoreLikeThisQueryBuilder.Item[] toArray(MoreLikeThisQueryBuilder.Item... values) { - return values; - } - - @Deprecated - public static String readFileFromClasspath(String url) { - return ResourceUtil.readFileFromClasspath(url); - } - - public SearchResponse suggest(SuggestBuilder suggestion, String... indices) { - return client.prepareSearch(indices).suggest(suggestion).get(); - } - - public SearchResponse suggest(SuggestBuilder suggestion, Class clazz) { - return suggest(suggestion, retrieveIndexNameFromPersistentEntity(clazz)); + public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { + return client.prepareSearch(index.getIndexNames()).suggest(suggestion).get(); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 2343ea266..f1aebbfc2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.core; import lombok.AccessLevel; -import lombok.Getter; import lombok.NonNull; import lombok.RequiredArgsConstructor; @@ -38,13 +37,18 @@ * * @author Mark Paluch * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ -@RequiredArgsConstructor class EntityOperations { private static final String ID_FIELD = "id"; + public EntityOperations( + @NonNull MappingContext, ElasticsearchPersistentProperty> context) { + this.context = context; + } + private final @NonNull MappingContext, ElasticsearchPersistentProperty> context; /** @@ -116,7 +120,7 @@ IndexCoordinates determineIndex(Entity entity, @Nullable String index, @Nulla */ IndexCoordinates determineIndex(ElasticsearchPersistentEntity persistentEntity, @Nullable String index, @Nullable String type) { - return new IndexCoordinates(indexName(persistentEntity, index), typeName(persistentEntity, type)); + return IndexCoordinates.of(indexName(persistentEntity, index)).withTypes(typeName(persistentEntity, type)); } private static String indexName(@Nullable ElasticsearchPersistentEntity entity, @Nullable String index) { @@ -615,14 +619,4 @@ public T incrementVersion() { } } - /** - * Value object encapsulating index name and index type. - */ - @RequiredArgsConstructor(access = AccessLevel.PROTECTED) - @Getter - static class IndexCoordinates { - - private final String indexName; - private final String typeName; - } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EsClient.java b/src/main/java/org/springframework/data/elasticsearch/core/EsClient.java deleted file mode 100644 index e29cb8525..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/EsClient.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2018-2019 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; - -/** - * EsClient interface. Specify what client an ElasticSearchTemplate will return from getClient(). - * - * @author Don Wellington - * @param - */ -public interface EsClient { - C getClient(); -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/FacetedPage.java b/src/main/java/org/springframework/data/elasticsearch/core/FacetedPage.java deleted file mode 100644 index c60cd3b3d..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/FacetedPage.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2014-2019 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; - -import java.util.List; - -import org.springframework.data.domain.Page; -import org.springframework.data.elasticsearch.core.facet.FacetResult; - -/** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public interface FacetedPage extends Page { - - boolean hasFacets(); - - List getFacets(); - - FacetResult getFacet(String name); -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/FacetedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/FacetedPageImpl.java deleted file mode 100644 index bd47f5df7..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/FacetedPageImpl.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2014-2019 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; - -import static java.util.Optional.*; - -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.elasticsearch.search.aggregations.Aggregation; -import org.elasticsearch.search.aggregations.Aggregations; -import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; -import org.elasticsearch.search.aggregations.bucket.range.Range; -import org.elasticsearch.search.aggregations.bucket.terms.Terms; -import org.elasticsearch.search.aggregations.metrics.ExtendedStats; -import org.elasticsearch.search.aggregations.metrics.Sum; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; -import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest; -import org.springframework.data.elasticsearch.core.facet.FacetResult; -import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequest; -import org.springframework.data.elasticsearch.core.facet.result.HistogramResult; -import org.springframework.data.elasticsearch.core.facet.result.IntervalUnit; -import org.springframework.data.elasticsearch.core.facet.result.RangeResult; -import org.springframework.data.elasticsearch.core.facet.result.StatisticalResult; -import org.springframework.data.elasticsearch.core.facet.result.Term; -import org.springframework.data.elasticsearch.core.facet.result.TermResult; - -/** - * Container for query result and facet results - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - * @author Philipp Kräutli - * @author Remco Zigterman - * @author Peter-Josef Meisch - */ -@Deprecated -public abstract class FacetedPageImpl extends PageImpl implements FacetedPage, AggregatedPage { - - private List facets; - private Map mapOfFacets = new HashMap<>(); - - public FacetedPageImpl(List content) { - super(content); - } - - public FacetedPageImpl(List content, Pageable pageable, long total) { - super(content, ofNullable(pageable).orElse(Pageable.unpaged()), total); - } - - @Override - public boolean hasFacets() { - processAggregations(); - return facets != null && facets.size() > 0; - } - - @Override - public List getFacets() { - processAggregations(); - return facets; - } - - @Override - public FacetResult getFacet(String name) { - processAggregations(); - return mapOfFacets.get(name); - } - - private void addFacet(FacetResult facetResult) { - facets.add(facetResult); - mapOfFacets.put(facetResult.getName(), facetResult); - } - - /** - * Lazy conversion from aggregation to old facets - */ - private void processAggregations() { - if (facets != null) { - return; - } - facets = new ArrayList<>(); - Aggregations aggregations = getAggregations(); - if (aggregations == null) { - return; - } - for (Aggregation agg : aggregations) { - processAggregation(agg); - } - } - - private void processAggregation(Aggregation agg) { - if (agg instanceof Terms) { - processTermAggregation((Terms) agg); - } - if (agg instanceof Range) { - processRangeAggregation((Range) agg); - } - if (agg instanceof ExtendedStats) { - processExtendedStatsAggregation((ExtendedStats) agg); - } - if (agg instanceof Histogram) { - processHistogramAggregation((Histogram) agg); - } - } - - private void processTermAggregation(Terms agg) { - List terms = new ArrayList<>(); - for (Terms.Bucket t : agg.getBuckets()) { - terms.add(new Term(t.getKeyAsString(), t.getDocCount())); - } - addFacet(new TermResult(agg.getName(), terms, terms.size(), agg.getSumOfOtherDocCounts(), 0)); - } - - private void processRangeAggregation(Range agg) { - List buckets = ((Range) agg).getBuckets(); - List ranges = new ArrayList<>(); - for (Range.Bucket b : buckets) { - ExtendedStats rStats = b.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS); - if (rStats != null) { - Sum sum = b.getAggregations().get(RangeFacetRequest.RANGE_INTERNAL_SUM); - ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), - (Double) b.getTo(), b.getDocCount(), sum != null ? sum.getValue() : rStats.getSum(), rStats.getCount(), - rStats.getMin(), rStats.getMax())); - } else { - ranges.add(new org.springframework.data.elasticsearch.core.facet.result.Range((Double) b.getFrom(), - (Double) b.getTo(), b.getDocCount(), 0, 0, 0, 0)); - } - } - addFacet(new RangeResult(agg.getName(), ranges)); - } - - private void processExtendedStatsAggregation(ExtendedStats agg) { - addFacet(new StatisticalResult(agg.getName(), agg.getCount(), agg.getMax(), agg.getMin(), agg.getAvg(), - agg.getStdDeviation(), agg.getSumOfSquares(), agg.getSum(), agg.getVariance())); - } - - private void processHistogramAggregation(Histogram agg) { - List intervals = new ArrayList<>(); - for (Histogram.Bucket h : agg.getBuckets()) { - ExtendedStats hStats = h.getAggregations().get(AbstractFacetRequest.INTERNAL_STATS); - if (hStats != null) { - intervals.add(new IntervalUnit(((ZonedDateTime) h.getKey()).toInstant().toEpochMilli(), h.getDocCount(), - h.getDocCount(), hStats.getSum(), hStats.getAvg(), hStats.getMin(), hStats.getMax())); - } else { - intervals.add(new IntervalUnit(((ZonedDateTime) h.getKey()).toInstant().toEpochMilli(), h.getDocCount(), - h.getDocCount(), 0, 0, 0, 0)); - } - } - addFacet(new HistogramResult(agg.getName(), intervals)); - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java new file mode 100644 index 000000000..0cf73c76e --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java @@ -0,0 +1,84 @@ +/* + * Copyright 2019 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; + +import java.util.Arrays; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Immutable Value object encapsulating index name(s) and index type(s). Type names are supported but deprecated as + * Elasticsearch does not support types anymore. + * + * @author Mark Paluch + * @author Christoph Strobl + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class IndexCoordinates { + + private final String[] indexNames; + private final String[] typeNames; + + public static IndexCoordinates of(String... indexNames) { + Assert.notNull(indexNames, "indexNames must not be null"); + return new IndexCoordinates(indexNames, null); + } + + private IndexCoordinates(String[] indexNames, @Nullable String[] typeNames) { + Assert.notEmpty(indexNames, "indexNames may not be null or empty"); + this.indexNames = indexNames; + this.typeNames = typeNames != null ? typeNames : new String[] {}; + } + + /** + * Using Index types is deprecated in Elasticsearch. + * + * @param typeNames + * @return + */ + @Deprecated + public IndexCoordinates withTypes(String... typeNames) { + Assert.notEmpty(typeNames, "typeNames must not be null"); + return new IndexCoordinates(this.indexNames, typeNames); + } + + public String getIndexName() { + return indexNames[0]; + } + + public String[] getIndexNames() { + return Arrays.copyOf(indexNames, indexNames.length); + } + + @Deprecated + @Nullable + public String getTypeName() { + return typeNames.length > 0 ? typeNames[0] : null; + } + + @Deprecated + public String[] getTypeNames() { + return Arrays.copyOf(typeNames, typeNames.length); + } + + @Override + public String toString() { + return "IndexCoordinates{" + "indexNames=" + Arrays.toString(indexNames) + ", typeNames=" + + Arrays.toString(typeNames) + '}'; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 47e1137af..f837f014f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -56,7 +56,6 @@ import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity; import org.springframework.data.elasticsearch.core.EntityOperations.Entity; -import org.springframework.data.elasticsearch.core.EntityOperations.IndexCoordinates; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; @@ -346,6 +345,7 @@ private SearchRequest buildSearchRequest(Query query, ElasticsearchPersistentEnt searchSourceBuilder.size(pageable.getPageSize()); request.source(searchSourceBuilder); + request.source(searchSourceBuilder); } else if (query.isLimiting()) { searchSourceBuilder.from(0); searchSourceBuilder.size(query.getMaxResults()); @@ -356,10 +356,6 @@ private SearchRequest buildSearchRequest(Query query, ElasticsearchPersistentEnt } return request; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#count(Query, Class, String, String) - */ /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java new file mode 100644 index 000000000..00e94d0a1 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -0,0 +1,855 @@ +/* + * Copyright 2019 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; + +import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.springframework.util.CollectionUtils.*; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkRequestBuilder; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetRequestBuilder; +import org.elasticsearch.action.get.MultiGetRequest; +import org.elasticsearch.action.get.MultiGetRequestBuilder; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.action.update.UpdateRequestBuilder; +import org.elasticsearch.client.Client; +import org.elasticsearch.client.Requests; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentType; +import org.elasticsearch.index.VersionType; +import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.index.reindex.DeleteByQueryAction; +import org.elasticsearch.index.reindex.DeleteByQueryRequest; +import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder; +import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.elasticsearch.search.sort.FieldSortBuilder; +import org.elasticsearch.search.sort.ScoreSortBuilder; +import org.elasticsearch.search.sort.SortBuilder; +import org.elasticsearch.search.sort.SortBuilders; +import org.elasticsearch.search.sort.SortOrder; +import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Factory class to create Elasticsearch request instances from Spring Data Elasticsearch query objects. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +class RequestFactory { + private final ElasticsearchConverter elasticsearchConverter; + + public RequestFactory(ElasticsearchConverter elasticsearchConverter) { + this.elasticsearchConverter = elasticsearchConverter; + } + + public IndicesAliasesRequest.AliasActions aliasAction(AliasQuery query, IndexCoordinates index) { + Assert.notNull(index, "No index defined for Alias"); + Assert.notNull(query.getAliasName(), "No alias defined"); + IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.add() + .alias(query.getAliasName()).index(index.getIndexName()); + + if (query.getFilterBuilder() != null) { + aliasAction.filter(query.getFilterBuilder()); + } else if (query.getFilter() != null) { + aliasAction.filter(query.getFilter()); + } else if (!StringUtils.isEmpty(query.getRouting())) { + aliasAction.routing(query.getRouting()); + } else if (!StringUtils.isEmpty(query.getSearchRouting())) { + aliasAction.searchRouting(query.getSearchRouting()); + } else if (!StringUtils.isEmpty(query.getIndexRouting())) { + aliasAction.indexRouting(query.getIndexRouting()); + } + return aliasAction; + } + + public BulkRequest bulkRequest(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + BulkRequest bulkRequest = new BulkRequest(); + + if (bulkOptions.getTimeout() != null) { + bulkRequest.timeout(bulkOptions.getTimeout()); + } + + if (bulkOptions.getRefreshPolicy() != null) { + bulkRequest.setRefreshPolicy(bulkOptions.getRefreshPolicy()); + } + + if (bulkOptions.getWaitForActiveShards() != null) { + bulkRequest.waitForActiveShards(bulkOptions.getWaitForActiveShards()); + } + + if (bulkOptions.getPipeline() != null) { + bulkRequest.pipeline(bulkOptions.getPipeline()); + } + + if (bulkOptions.getRoutingId() != null) { + bulkRequest.routing(bulkOptions.getRoutingId()); + } + + queries.forEach(query -> { + + if (query instanceof IndexQuery) { + bulkRequest.add(indexRequest((IndexQuery) query, index)); + } else if (query instanceof UpdateQuery) { + bulkRequest.add(updateRequest((UpdateQuery) query, index)); + } + }); + return bulkRequest; + } + + public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, BulkOptions bulkOptions, + IndexCoordinates index) { + BulkRequestBuilder bulkRequestBuilder = client.prepareBulk(); + + if (bulkOptions.getTimeout() != null) { + bulkRequestBuilder.setTimeout(bulkOptions.getTimeout()); + } + + if (bulkOptions.getRefreshPolicy() != null) { + bulkRequestBuilder.setRefreshPolicy(bulkOptions.getRefreshPolicy()); + } + + if (bulkOptions.getWaitForActiveShards() != null) { + bulkRequestBuilder.setWaitForActiveShards(bulkOptions.getWaitForActiveShards()); + } + + if (bulkOptions.getPipeline() != null) { + bulkRequestBuilder.pipeline(bulkOptions.getPipeline()); + } + + if (bulkOptions.getRoutingId() != null) { + bulkRequestBuilder.routing(bulkOptions.getRoutingId()); + } + + queries.forEach(query -> { + + if (query instanceof IndexQuery) { + bulkRequestBuilder.add(indexRequestBuilder(client, (IndexQuery) query, index)); + } else if (query instanceof UpdateQuery) { + bulkRequestBuilder.add(updateRequestBuilderFor(client, (UpdateQuery) query, index)); + } + }); + + return bulkRequestBuilder; + } + + public CreateIndexRequest createIndexRequest(String indexName, Object settings) { + CreateIndexRequest request = new CreateIndexRequest(indexName); + if (settings instanceof String) { + request.settings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); + } else if (settings instanceof Map) { + request.settings((Map) settings); + } else if (settings instanceof XContentBuilder) { + request.settings((XContentBuilder) settings); + } + return request; + } + + public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, Object settings) { + CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); + if (settings instanceof String) { + createIndexRequestBuilder.setSettings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); + } else if (settings instanceof Map) { + createIndexRequestBuilder.setSettings((Map) settings); + } else if (settings instanceof XContentBuilder) { + createIndexRequestBuilder.setSettings((XContentBuilder) settings); + } + return createIndexRequestBuilder; + } + + public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexCoordinates index) { + DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) // + .setDocTypes(index.getTypeNames()) // + .setQuery(deleteQuery.getQuery()) // + .setAbortOnVersionConflict(false) // + .setRefresh(true); + + if (deleteQuery.getPageSize() != null) + deleteByQueryRequest.setBatchSize(deleteQuery.getPageSize()); + + if (deleteQuery.getScrollTimeInMillis() != null) + deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); + + return deleteByQueryRequest; + } + + public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, DeleteQuery deleteQuery, + IndexCoordinates index) { + DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) // + .source(index.getIndexNames()) // + .filter(deleteQuery.getQuery()) // + .abortOnVersionConflict(false) // + .refresh(true); + + SearchRequestBuilder source = requestBuilder.source() // + .setTypes(index.getTypeNames()); + + if (deleteQuery.getScrollTimeInMillis() != null) + source.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); + + return requestBuilder; + } + + public GetRequest getRequest(GetQuery query, IndexCoordinates index) { + return new GetRequest(index.getIndexName(), index.getTypeName(), query.getId()); + } + + public GetRequestBuilder getRequestBuilder(Client client, GetQuery query, IndexCoordinates index) { + return client.prepareGet(index.getIndexName(), index.getTypeName(), query.getId()); + } + + public HighlightBuilder highlightBuilder(Query query) { + HighlightBuilder highlightBuilder = null; + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; + + if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { + highlightBuilder = searchQuery.getHighlightBuilder(); + + if (highlightBuilder == null) { + highlightBuilder = new HighlightBuilder(); + } + + if (searchQuery.getHighlightFields() != null) { + for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { + highlightBuilder.field(highlightField); + } + } + } + } + return highlightBuilder; + } + + public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { + String indexName = index.getIndexName(); + String type = index.getTypeName(); + + IndexRequest indexRequest; + + if (query.getObject() != null) { + String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); + // If we have a query id and a document id, do not ask ES to generate one. + if (id != null) { + indexRequest = new IndexRequest(indexName, type, id); + } else { + indexRequest = new IndexRequest(indexName, type); + } + indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE); + } else if (query.getSource() != null) { + indexRequest = new IndexRequest(indexName, type, query.getId()).source(query.getSource(), + Requests.INDEX_CONTENT_TYPE); + } else { + throw new ElasticsearchException( + "object or source is null, failed to index the document [id: " + query.getId() + "]"); + } + if (query.getVersion() != null) { + indexRequest.version(query.getVersion()); + VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); + indexRequest.versionType(versionType); + } + + return indexRequest; + } + + public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, IndexCoordinates index) { + String indexName = index.getIndexName(); + String type = index.getTypeName(); + + IndexRequestBuilder indexRequestBuilder; + + if (query.getObject() != null) { + String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); + // If we have a query id and a document id, do not ask ES to generate one. + if (id != null) { + indexRequestBuilder = client.prepareIndex(indexName, type, id); + } else { + indexRequestBuilder = client.prepareIndex(indexName, type); + } + indexRequestBuilder.setSource(elasticsearchConverter.mapObject(query.getObject()).toJson(), + Requests.INDEX_CONTENT_TYPE); + } else if (query.getSource() != null) { + indexRequestBuilder = client.prepareIndex(indexName, type, query.getId()).setSource(query.getSource(), + Requests.INDEX_CONTENT_TYPE); + } else { + throw new ElasticsearchException( + "object or source is null, failed to index the document [id: " + query.getId() + "]"); + } + if (query.getVersion() != null) { + indexRequestBuilder.setVersion(query.getVersion()); + VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); + indexRequestBuilder.setVersionType(versionType); + } + + return indexRequestBuilder; + } + + public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) { + MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), index.getTypeName(), + query.getId()); + + MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders + .moreLikeThisQuery(new MoreLikeThisQueryBuilder.Item[] { item }); + + if (query.getMinTermFreq() != null) { + moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq()); + } + + if (query.getMaxQueryTerms() != null) { + moreLikeThisQueryBuilder.maxQueryTerms(query.getMaxQueryTerms()); + } + + if (!isEmpty(query.getStopWords())) { + moreLikeThisQueryBuilder.stopWords(query.getStopWords()); + } + + if (query.getMinDocFreq() != null) { + moreLikeThisQueryBuilder.minDocFreq(query.getMinDocFreq()); + } + + if (query.getMaxDocFreq() != null) { + moreLikeThisQueryBuilder.maxDocFreq(query.getMaxDocFreq()); + } + + if (query.getMinWordLen() != null) { + moreLikeThisQueryBuilder.minWordLength(query.getMinWordLen()); + } + + if (query.getMaxWordLen() != null) { + moreLikeThisQueryBuilder.maxWordLength(query.getMaxWordLen()); + } + + if (query.getBoostTerms() != null) { + moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms()); + } + return moreLikeThisQueryBuilder; + } + + public SearchRequest searchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { + + SearchRequest searchRequest = prepareSearchRequest(query, clazz, index); + QueryBuilder elasticsearchQuery = getQuery(query); + QueryBuilder elasticsearchFilter = getFilter(query); + + if (elasticsearchQuery != null) { + searchRequest.source().query(elasticsearchQuery); + } else { + searchRequest.source().query(QueryBuilders.matchAllQuery()); + } + + if (elasticsearchFilter != null) { + searchRequest.source().postFilter(elasticsearchFilter); + } + + return searchRequest; + + } + + public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nullable Class clazz, + IndexCoordinates index) { + + SearchRequestBuilder searchRequestBuilder = prepareSearchRequestBuilder(query, client, clazz, index); + QueryBuilder elasticsearchQuery = getQuery(query); + QueryBuilder elasticsearchFilter = getFilter(query); + + if (elasticsearchQuery != null) { + searchRequestBuilder.setQuery(elasticsearchQuery); + } else { + searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); + } + + if (elasticsearchFilter != null) { + searchRequestBuilder.setPostFilter(elasticsearchFilter); + } + + return searchRequestBuilder; + } + + public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { + + Assert.notNull(query.getId(), "No Id define for Query"); + Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); + + UpdateRequest queryUpdateRequest = query.getUpdateRequest(); + + UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), index.getTypeName(), query.getId()) // + .routing(queryUpdateRequest.routing()) // + .retryOnConflict(queryUpdateRequest.retryOnConflict()) // + .timeout(queryUpdateRequest.timeout()) // + .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // + .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // + .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // + .scriptedUpsert(queryUpdateRequest.scriptedUpsert()) // + .docAsUpsert(queryUpdateRequest.docAsUpsert()); + + if (query.DoUpsert()) { + updateRequest.docAsUpsert(true); + } + + if (queryUpdateRequest.script() != null) { + updateRequest.script(queryUpdateRequest.script()); + } + + if (queryUpdateRequest.doc() != null) { + updateRequest.doc(queryUpdateRequest.doc()); + } + + if (queryUpdateRequest.upsertRequest() != null) { + updateRequest.upsert(queryUpdateRequest.upsertRequest()); + } + + if (queryUpdateRequest.fetchSource() != null) { + updateRequest.fetchSource(queryUpdateRequest.fetchSource()); + } + + return updateRequest; + } + + public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery query, IndexCoordinates index) { + + Assert.notNull(query.getId(), "No Id define for Query"); + Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); + + UpdateRequest queryUpdateRequest = query.getUpdateRequest(); + + UpdateRequestBuilder updateRequestBuilder = client + .prepareUpdate(index.getIndexName(), index.getTypeName(), query.getId()) // + .setRouting(queryUpdateRequest.routing()) // + .setRetryOnConflict(queryUpdateRequest.retryOnConflict()) // + .setTimeout(queryUpdateRequest.timeout()) // + .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // + .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // + .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // + .setScriptedUpsert(queryUpdateRequest.scriptedUpsert()) // + .setDocAsUpsert(queryUpdateRequest.docAsUpsert()); + + if (query.DoUpsert()) { + updateRequestBuilder.setDocAsUpsert(true); + } + + if (queryUpdateRequest.script() != null) { + updateRequestBuilder.setScript(queryUpdateRequest.script()); + } + + if (queryUpdateRequest.doc() != null) { + updateRequestBuilder.setDoc(queryUpdateRequest.doc()); + } + + if (queryUpdateRequest.upsertRequest() != null) { + updateRequestBuilder.setUpsert(queryUpdateRequest.upsertRequest()); + } + + FetchSourceContext fetchSourceContext = queryUpdateRequest.fetchSource(); + if (fetchSourceContext != null) { + updateRequestBuilder.setFetchSource(fetchSourceContext.includes(), fetchSourceContext.excludes()); + } + + return updateRequestBuilder; + } + + private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { + return prepareSearchRequest(query, Optional.empty(), clazz, index); + } + + public PutMappingRequest putMappingRequest(IndexCoordinates index, Object mapping) { + PutMappingRequest request = new PutMappingRequest(index.getIndexName()).type(index.getTypeName()); + if (mapping instanceof String) { + request.source(String.valueOf(mapping), XContentType.JSON); + } else if (mapping instanceof Map) { + request.source((Map) mapping); + } else if (mapping instanceof XContentBuilder) { + request.source((XContentBuilder) mapping); + } + return request; + } + + public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Object mapping) { + PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(index.getIndexName()) + .setType(index.getTypeName()); + if (mapping instanceof String) { + requestBuilder.setSource(String.valueOf(mapping), XContentType.JSON); + } else if (mapping instanceof Map) { + requestBuilder.setSource((Map) mapping); + } else if (mapping instanceof XContentBuilder) { + requestBuilder.setSource((XContentBuilder) mapping); + } + return requestBuilder; + } + + public MultiGetRequest multiGetRequest(Query query, IndexCoordinates index) { + MultiGetRequest multiGetRequest = new MultiGetRequest(); + getMultiRequestItems(query, index).forEach(multiGetRequest::add); + return multiGetRequest; + } + + public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, IndexCoordinates index) { + MultiGetRequestBuilder multiGetRequestBuilder = client.prepareMultiGet(); + getMultiRequestItems(searchQuery, index).forEach(multiGetRequestBuilder::add); + return multiGetRequestBuilder; + } + + private List getMultiRequestItems(Query searchQuery, IndexCoordinates index) { + List items = new ArrayList<>(); + if (!isEmpty(searchQuery.getFields())) { + searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null)); + } + + for (String id : searchQuery.getIds()) { + MultiGetRequest.Item item = new MultiGetRequest.Item(index.getIndexName(), index.getTypeName(), id); + + if (searchQuery.getRoute() != null) { + item = item.routing(searchQuery.getRoute()); + } + items.add(item); + } + return items; + } + + private SearchRequest prepareSearchRequest(Query query, Optional builder, @Nullable Class clazz, + IndexCoordinates index) { + Assert.notNull(index.getIndexNames(), "No index defined for Query"); + Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); + Assert.notNull(index.getTypeNames(), "No type defined for Query"); + + int startRecord = 0; + SearchRequest request = new SearchRequest(index.getIndexNames()); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + request.types(index.getTypeNames()); + sourceBuilder.version(true); + sourceBuilder.trackScores(query.getTrackScores()); + + builder.ifPresent(sourceBuilder::query); + + if (query.getSourceFilter() != null) { + SourceFilter sourceFilter = query.getSourceFilter(); + sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); + } + + if (query.getPageable().isPaged()) { + startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); + sourceBuilder.size(query.getPageable().getPageSize()); + } + sourceBuilder.from(startRecord); + + if (!query.getFields().isEmpty()) { + sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); + } + + if (query.getIndicesOptions() != null) { + request.indicesOptions(query.getIndicesOptions()); + } + + if (query.isLimiting()) { + sourceBuilder.size(query.getMaxResults()); + } + + if (query.getMinScore() > 0) { + sourceBuilder.minScore(query.getMinScore()); + } + + if (query.getPreference() != null) { + request.preference(query.getPreference()); + } + + if (query.getSearchType() != null) { + request.searchType(query.getSearchType()); + } + + prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); + + HighlightBuilder highlightBuilder = highlightBuilder(query); + + if (highlightBuilder != null) { + sourceBuilder.highlighter(highlightBuilder); + } + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query; + + if (!nativeSearchQuery.getScriptFields().isEmpty()) { + for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { + sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script()); + } + } + + if (nativeSearchQuery.getCollapseBuilder() != null) { + sourceBuilder.collapse(nativeSearchQuery.getCollapseBuilder()); + } + + } + + request.source(sourceBuilder); + return request; + } + + private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, + @Nullable ElasticsearchPersistentEntity entity, IndexCoordinates index) { + Assert.notNull(index.getIndexNames(), "No index defined for Query"); + Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); + Assert.notNull(index.getTypeNames(), "No type defined for Query"); + + int startRecord = 0; + SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index.getIndexNames()) // + .setSearchType(query.getSearchType()) // + .setTypes(index.getTypeNames()) // + .setVersion(true) // + .setTrackScores(query.getTrackScores()); + + if (query.getSourceFilter() != null) { + SourceFilter sourceFilter = query.getSourceFilter(); + searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); + } + + if (query.getPageable().isPaged()) { + startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); + searchRequestBuilder.setSize(query.getPageable().getPageSize()); + } + searchRequestBuilder.setFrom(startRecord); + + if (!query.getFields().isEmpty()) { + searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null); + } + + if (query.getIndicesOptions() != null) { + searchRequestBuilder.setIndicesOptions(query.getIndicesOptions()); + } + + if (query.isLimiting()) { + searchRequestBuilder.setSize(query.getMaxResults()); + } + + if (query.getMinScore() > 0) { + searchRequestBuilder.setMinScore(query.getMinScore()); + } + + if (query.getPreference() != null) { + searchRequestBuilder.setPreference(query.getPreference()); + } + + prepareSort(query, searchRequestBuilder, entity); + + HighlightBuilder highlightBuilder = highlightBuilder(query); + + if (highlightBuilder != null) { + searchRequestBuilder.highlighter(highlightBuilder); + } + + if (query instanceof NativeSearchQuery) { + prepareNativeSearch(searchRequestBuilder, (NativeSearchQuery) query); + } + + return searchRequestBuilder; + } + + private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, NativeSearchQuery nativeSearchQuery) { + if (!isEmpty(nativeSearchQuery.getScriptFields())) { + for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { + searchRequestBuilder.addScriptField(scriptedField.fieldName(), scriptedField.script()); + } + } + + if (nativeSearchQuery.getCollapseBuilder() != null) { + searchRequestBuilder.setCollapse(nativeSearchQuery.getCollapseBuilder()); + } + + if (!isEmpty(nativeSearchQuery.getIndicesBoost())) { + for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) { + searchRequestBuilder.addIndexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); + } + } + + if (!isEmpty(nativeSearchQuery.getAggregations())) { + for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) { + searchRequestBuilder.addAggregation(aggregationBuilder); + } + } + } + + private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class clazz, + IndexCoordinates index) { + return prepareSearchRequestBuilder(query, client, getPersistentEntity(clazz), index); + } + + private void prepareSort(Query query, SearchSourceBuilder sourceBuilder, + @Nullable ElasticsearchPersistentEntity entity) { + + if (query.getSort() != null) { + query.getSort().forEach(order -> sourceBuilder.sort(getSortBuilder(order, entity))); + } + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query; + List sorts = nativeSearchQuery.getElasticsearchSorts(); + if (sorts != null) { + sorts.forEach(sourceBuilder::sort); + } + } + } + + private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder, + @Nullable ElasticsearchPersistentEntity entity) { + if (query.getSort() != null) { + query.getSort().forEach(order -> searchRequestBuilder.addSort(getSortBuilder(order, entity))); + } + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query; + List sorts = nativeSearchQuery.getElasticsearchSorts(); + if (sorts != null) { + sorts.forEach(searchRequestBuilder::addSort); + } + } + } + + private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchPersistentEntity entity) { + SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC; + + if (ScoreSortBuilder.NAME.equals(order.getProperty())) { + return SortBuilders // + .scoreSort() // + .order(sortOrder); + } else { + ElasticsearchPersistentProperty property = (entity != null) // + ? entity.getPersistentProperty(order.getProperty()) // + : null; + String fieldName = property != null ? property.getFieldName() : order.getProperty(); + + FieldSortBuilder sort = SortBuilders // + .fieldSort(fieldName) // + .order(sortOrder); + + if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { + sort.missing("_first"); + } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { + sort.missing("_last"); + } + + return sort; + } + } + + private QueryBuilder getQuery(Query query) { + QueryBuilder elasticsearchQuery; + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; + elasticsearchQuery = searchQuery.getQuery(); + } else if (query instanceof CriteriaQuery) { + CriteriaQuery criteriaQuery = (CriteriaQuery) query; + elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); + } else if (query instanceof StringQuery) { + StringQuery stringQuery = (StringQuery) query; + elasticsearchQuery = wrapperQuery(stringQuery.getSource()); + } else { + throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName()); + } + + return elasticsearchQuery; + } + + public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest.AliasActions aliasAction = aliasAction(query, index); + IndicesAliasesRequest request = new IndicesAliasesRequest(); + request.addAliasAction(aliasAction); + return request; + } + + public IndicesAliasesRequest indicesRemoveAliasesRequest(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() // + .index(index.getIndexName()) // + .alias(query.getAliasName()); + + return Requests.indexAliasesRequest() // + .addAliasAction(aliasAction); + } + + private QueryBuilder getFilter(Query query) { + QueryBuilder elasticsearchFilter; + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; + elasticsearchFilter = searchQuery.getFilter(); + } else if (query instanceof CriteriaQuery) { + CriteriaQuery criteriaQuery = (CriteriaQuery) query; + elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria()); + } else if (query instanceof StringQuery) { + elasticsearchFilter = null; + } else { + throw new IllegalArgumentException("unhandled Query implementation " + query.getClass().getName()); + } + + return elasticsearchFilter; + } + + @Nullable + private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class clazz) { + return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null; + } + + private String getPersistentEntityId(Object entity) { + + Object identifier = elasticsearchConverter.getMappingContext() // + .getRequiredPersistentEntity(entity.getClass()) // + .getIdentifierAccessor(entity).getIdentifier(); + + if (identifier != null) { + return identifier.toString(); + } + + return null; + } + + private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { + + if (clazz != null) { + return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz).getVersionType(); + } + return VersionType.EXTERNAL; + } + + private String[] toArray(List values) { + String[] valuesAsArray = new String[values.size()]; + return values.toArray(valuesAsArray); + } + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java index c1ff7500d..617b0ddb3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java @@ -2,15 +2,15 @@ import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregations; -import org.springframework.data.elasticsearch.core.FacetedPage; import org.springframework.data.elasticsearch.core.ScoredPage; import org.springframework.data.elasticsearch.core.ScrolledPage; /** * @author Petar Tahchiev * @author Sascha Woo + * @author Peter-Josef Meisch */ -public interface AggregatedPage extends FacetedPage, ScrolledPage, ScoredPage { +public interface AggregatedPage extends ScrolledPage, ScoredPage { boolean hasAggregations(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java index 957e9e4d8..5250bdc1d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java @@ -15,12 +15,14 @@ */ package org.springframework.data.elasticsearch.core.aggregation.impl; +import static java.util.Optional.*; + import java.util.List; import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.FacetedPageImpl; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -31,12 +33,16 @@ * @author Sascha Woo * @author Peter-Josef Meisch */ -public class AggregatedPageImpl extends FacetedPageImpl implements AggregatedPage { +public class AggregatedPageImpl extends PageImpl implements AggregatedPage { private Aggregations aggregations; private String scrollId; private float maxScore; + private static Pageable pageableOrUnpaged(Pageable pageable) { + return ofNullable(pageable).orElse(Pageable.unpaged()); + } + public AggregatedPageImpl(List content) { super(content); } @@ -57,26 +63,26 @@ public AggregatedPageImpl(List content, String scrollId, float maxScore) { } public AggregatedPageImpl(List content, Pageable pageable, long total) { - super(content, pageable, total); + super(content, pageableOrUnpaged(pageable), total); } public AggregatedPageImpl(List content, Pageable pageable, long total, float maxScore) { - super(content, pageable, total); + super(content, pageableOrUnpaged(pageable), total); this.maxScore = maxScore; } public AggregatedPageImpl(List content, Pageable pageable, long total, String scrollId) { - super(content, pageable, total); + super(content, pageableOrUnpaged(pageable), total); this.scrollId = scrollId; } public AggregatedPageImpl(List content, Pageable pageable, long total, String scrollId, float maxScore) { - this(content, pageable, total, scrollId); + this(content, pageableOrUnpaged(pageable), total, scrollId); this.maxScore = maxScore; } public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations) { - super(content, pageable, total); + super(content, pageableOrUnpaged(pageable), total); this.aggregations = aggregations; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetRequest.java deleted file mode 100644 index b4d5b9626..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetRequest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2014-2019 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.facet; - -import org.springframework.util.Assert; - - -/** - * @author Artur Konczak - */ -@Deprecated -public abstract class AbstractFacetRequest implements FacetRequest { - - public static final String INTERNAL_STATS = "internal-stats"; - - private String name; - private boolean applyQueryFilter; - - public AbstractFacetRequest(String name) { - Assert.hasText(name, "Facet can't be null or empty !!!"); - this.name = name; - } - - protected String getName() { - return name; - } - - public void setApplyQueryFilter(boolean applyQueryFilter) { - this.applyQueryFilter = applyQueryFilter; - } - - @Override - public boolean applyQueryFilter() { - return applyQueryFilter; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetResult.java deleted file mode 100644 index f08099ff8..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/AbstractFacetResult.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2014-2019 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.facet; - -import org.springframework.util.Assert; - -/** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public class AbstractFacetResult implements FacetResult { - - private final String name; - private final FacetType type; - - protected AbstractFacetResult(String name, FacetType type) { - Assert.hasText(name, "Facet name can't be null and should have a value"); - this.name = name; - this.type = type; - } - - @Override - public String getName() { - return name; - } - - @Override - public FacetType getType() { - return type; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetRequest.java deleted file mode 100644 index 66ff37207..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetRequest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2014-2019 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.facet; - -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; - -/** - * @author Artur Koczak - */ -@Deprecated -public interface FacetRequest { - - public static final String FIELD_UNTOUCHED = "untouched"; - public static final String FIELD_SORT = "sort"; - - AbstractAggregationBuilder getFacet(); - - boolean applyQueryFilter(); -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetResult.java deleted file mode 100644 index cbbce7897..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetResult.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2014-2019 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.facet; - -/** - * Generic interface for all facets - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public interface FacetResult { - - String getName(); - - FacetType getType(); -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetType.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetType.java deleted file mode 100644 index 18d3b0d25..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/FacetType.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2014-2019 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.facet; - -/** - * @author Artur Konczak - * @author Petar Tahchiev - */ -@Deprecated -public enum FacetType { - - term, range, histogram, statistical - -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequest.java deleted file mode 100644 index 83e83351c..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder; -import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; -import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * @author Artur Konczak - * @author Mohsin Husen - */ -@Deprecated -public class HistogramFacetRequest extends AbstractFacetRequest { - - private String field; - private long interval; - private DateHistogramInterval timeUnit; - - public HistogramFacetRequest(String name) { - super(name); - } - - public void setField(String field) { - this.field = field; - } - - public void setInterval(long interval) { - this.interval = interval; - } - - public void setTimeUnit(DateHistogramInterval timeUnit) { - this.timeUnit = timeUnit; - } - - public AbstractAggregationBuilder getFacet() { - Assert.notNull(getName(), "Facet name can't be a null !!!"); - Assert.isTrue(!StringUtils.isEmpty(field), "Please select field on which to build the facet !!!"); - Assert.isTrue(interval > 0, "Please provide interval as positive value greater them zero !!!"); - - DateHistogramAggregationBuilder dateHistogramBuilder = AggregationBuilders.dateHistogram(getName()); - dateHistogramBuilder.field(field); - - if (timeUnit != null) { - dateHistogramBuilder.dateHistogramInterval(timeUnit); - } else { - dateHistogramBuilder.interval(interval); - } - - dateHistogramBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field)); - - return dateHistogramBuilder; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequestBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequestBuilder.java deleted file mode 100644 index 87978e812..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/HistogramFacetRequestBuilder.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - - -/** - * @author Artur Konczak - */ -@Deprecated -public class HistogramFacetRequestBuilder { - - HistogramFacetRequest result; - - public HistogramFacetRequestBuilder(String name) { - result = new HistogramFacetRequest(name); - } - - public HistogramFacetRequestBuilder field(String field) { - result.setField(field); - return this; - } - - public HistogramFacetRequestBuilder interval(long interval) { - result.setInterval(interval); - return this; - } - - public HistogramFacetRequestBuilder timeUnit(DateHistogramInterval timeUnit) { - result.setTimeUnit(timeUnit); - return this; - } - - public FacetRequest build() { - return result; - } - - public HistogramFacetRequestBuilder applyQueryFilter() { - result.setApplyQueryFilter(true); - return this; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/NativeFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/NativeFacetRequest.java deleted file mode 100644 index 4fc1bc99d..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/NativeFacetRequest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - - -/** - * @author Artur Konczak - * @author Mohsin Husen - */ -@Deprecated -public class NativeFacetRequest implements FacetRequest { - - public NativeFacetRequest() { - throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation"); - } - - @Override - public AbstractAggregationBuilder getFacet() { - return null; - } - - @Override - public boolean applyQueryFilter() { - return false; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java deleted file mode 100644 index 26254a766..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequest.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import java.util.ArrayList; -import java.util.List; - -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder; -import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Range facet for numeric fields - * - * @author Artur Konczak - * @author Akos Bordas - */ -@Deprecated -public class RangeFacetRequest extends AbstractFacetRequest { - - public static final String RANGE_INTERNAL_SUM = "range-internal-sum"; - private String field; - private String keyField; - private String valueField; - - private List entries = new ArrayList<>(); - - public RangeFacetRequest(String name) { - super(name); - } - - public void setField(String field) { - this.field = field; - } - - public void setFields(String keyField, String valueField) { - this.keyField = keyField; - this.valueField = valueField; - } - - public void range(Double from, Double to) { - entries.add(new DoubleEntry(from, to)); - } - - public void range(String from, String to) { - throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation"); - } - - public void addRange(Double from, Double to) { - entries.add(new DoubleEntry(from, to)); - } - - public void addRange(String from, String to) { - throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation"); - } - - @Override - public AbstractAggregationBuilder getFacet() { - Assert.notNull(getName(), "Facet name can't be a null !!!"); - - RangeAggregationBuilder rangeBuilder = AggregationBuilders.range(getName()); - final String field = !StringUtils.isEmpty(keyField) ? keyField : this.field; - rangeBuilder.field(field); - - for (Entry entry : entries) { - DoubleEntry doubleEntry = (DoubleEntry) entry; - rangeBuilder.addRange(validateValue(doubleEntry.getFrom(), Double.NEGATIVE_INFINITY), validateValue(doubleEntry.getTo(), Double.POSITIVE_INFINITY)); - } - - rangeBuilder.subAggregation(AggregationBuilders.extendedStats(INTERNAL_STATS).field(field)); - if(!StringUtils.isEmpty(valueField)){ - rangeBuilder.subAggregation(AggregationBuilders.sum(RANGE_INTERNAL_SUM).field(valueField)); - } - - return rangeBuilder; - } - - private double validateValue(Double value, double defaultValue) { - return value == null ? defaultValue : value; - } - - static class DoubleEntry extends Entry { - - DoubleEntry(Double from, Double to) { - super(from, to); - } - } - - static class StringEntry extends Entry { - - StringEntry(String from, String to) { - super(from, to); - } - } - - static class Entry { - - T from; - T to; - - Entry(T from, T to) { - this.from = from; - this.to = to; - } - - public T getFrom() { - return from; - } - - public T getTo() { - return to; - } - } -} - diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java deleted file mode 100644 index 1b3470394..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/RangeFacetRequestBuilder.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - - -/** - * Basic range facet - * - * @author Artur Konczak - */ -@Deprecated -public class RangeFacetRequestBuilder { - - RangeFacetRequest result; - - public RangeFacetRequestBuilder(String name) { - result = new RangeFacetRequest(name); - } - - public RangeFacetRequestBuilder field(String field) { - result.setField(field); - return this; - } - - public RangeFacetRequestBuilder fields(String keyField, String valueField) { - result.setFields(keyField, valueField); - return this; - } - - - public RangeFacetRequestBuilder range(double from, double to) { - result.range(from, to); - return this; - } - - public RangeFacetRequestBuilder range(String from, String to) { - result.range(from, to); - return this; - } - - public RangeFacetRequestBuilder from(double from) { - result.range(from, null); - return this; - } - - public RangeFacetRequestBuilder to(double to) { - result.range(null, to); - return this; - } - - public RangeFacetRequestBuilder from(String from) { - result.range(from, null); - return this; - } - - public RangeFacetRequestBuilder to(String to) { - result.range(null, to); - return this; - } - - public RangeFacetRequestBuilder applyQueryFilter() { - result.setApplyQueryFilter(true); - return this; - } - - public FacetRequest build() { - return result; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequest.java deleted file mode 100644 index 22bf30767..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * @author Petar Tahchiev - */ -@Deprecated -public class StatisticalFacetRequest extends AbstractFacetRequest { - - private String field; - - private String[] fields; - - public StatisticalFacetRequest(String name) { - super(name); - } - - public void setField(String field) { - this.field = field; - } - - public void setFields(String... fields) { - throw new UnsupportedOperationException("Native Facet are not supported in Elasticsearch 2.x - use Aggregation"); - } - - public AbstractAggregationBuilder getFacet() { - Assert.notNull(getName(), "Facet name can't be a null !!!"); - Assert.isTrue(!StringUtils.isEmpty(field) && fields == null, "Please select field or fields on which to build the facets !!!"); - return AggregationBuilders.extendedStats(getName()).field(field); - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequestBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequestBuilder.java deleted file mode 100644 index 91dd40ba7..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/StatisticalFacetRequestBuilder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - - -/** - * @author Petar Tahchiev - */ -@Deprecated -public class StatisticalFacetRequestBuilder { - - StatisticalFacetRequest result; - - public StatisticalFacetRequestBuilder(String name) { - result = new StatisticalFacetRequest(name); - } - - public StatisticalFacetRequestBuilder field(String field) { - result.setField(field); - return this; - } - - public StatisticalFacetRequestBuilder fields(String... fields) { - result.setFields(fields); - return this; - } - - public StatisticalFacetRequestBuilder applyQueryFilter() { - result.setApplyQueryFilter(true); - return this; - } - - public FacetRequest build() { - return result; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetOrder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetOrder.java deleted file mode 100644 index bf0d5756c..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetOrder.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -/** - * @author Artur Konczak - * @author Mohsin Husen - */ -@Deprecated -public enum TermFacetOrder { - - ascTerm, descTerm, ascCount, descCount; - -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequest.java deleted file mode 100644 index 8e301df1a..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.apache.lucene.util.automaton.RegExp; -import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.BucketOrder; -import org.elasticsearch.search.aggregations.bucket.terms.IncludeExclude; -import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; -import org.springframework.data.elasticsearch.core.facet.AbstractFacetRequest; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * Term facet - * - * @author Artur Konczak - * @author Ilkang Na - */ -@Deprecated -public class TermFacetRequest extends AbstractFacetRequest { - - private String[] fields; - private String[] excludeTerms; - private int size = 10; - private TermFacetOrder order = TermFacetOrder.descCount; - private boolean allTerms = false; - private String regex = null; - - public TermFacetRequest(String name) { - super(name); - } - - public void setFields(String... fields) { - Assert.isTrue(!ObjectUtils.isEmpty(fields), "Term agg need one field only"); - Assert.isTrue(fields.length == 1, "Term agg need one field only"); - this.fields = fields; - } - - public void setSize(int size) { - Assert.isTrue(size >= 0, "Size should be bigger then zero !!!"); - this.size = size; - } - - public void setOrder(TermFacetOrder order) { - this.order = order; - } - - public void setExcludeTerms(String... excludeTerms) { - this.excludeTerms = excludeTerms; - } - - public void setAllTerms(boolean allTerms) { - this.allTerms = allTerms; - } - - public void setRegex(String regex) { - this.regex = regex; - } - - @Override - public AbstractAggregationBuilder getFacet() { - Assert.notEmpty(fields, "Please select at last one field !!!"); - final TermsAggregationBuilder termsBuilder = AggregationBuilders.terms(getName()).field(fields[0]).size(this.size); - - switch (order) { - case descTerm: - termsBuilder.order(BucketOrder.key(false)); - break; - case ascTerm: - termsBuilder.order(BucketOrder.key(true)); - break; - case descCount: - termsBuilder.order(BucketOrder.count(false)); - break; - default: - termsBuilder.order(BucketOrder.count(true)); - } - if (!ObjectUtils.isEmpty(excludeTerms)) { - termsBuilder.includeExclude(new IncludeExclude(null, excludeTerms)); - } - - if (allTerms) { - termsBuilder.size(Integer.MAX_VALUE); - } - - if (!StringUtils.isEmpty(regex)) { - termsBuilder.includeExclude(new IncludeExclude(new RegExp(regex), null)); - } - - return termsBuilder; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequestBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequestBuilder.java deleted file mode 100644 index 0c672bc71..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/request/TermFacetRequestBuilder.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.request; - -import org.springframework.data.elasticsearch.core.facet.FacetRequest; - -/** - * Basic term facet - * - * @author Artur Konczak - */ -@Deprecated -public class TermFacetRequestBuilder { - - private TermFacetRequest result; - - public TermFacetRequestBuilder(String name) { - result = new TermFacetRequest(name); - } - - public TermFacetRequestBuilder fields(String... fields) { - result.setFields(fields); - return this; - } - - public TermFacetRequestBuilder size(int size) { - result.setSize(size); - return this; - } - - public TermFacetRequestBuilder excludeTerms(String... terms) { - result.setExcludeTerms(terms); - return this; - } - - public TermFacetRequestBuilder allTerms() { - result.setAllTerms(true); - return this; - } - - public TermFacetRequestBuilder regex(String regex) { - result.setRegex(regex); - return this; - } - - public TermFacetRequestBuilder ascTerm() { - result.setOrder(TermFacetOrder.ascTerm); - return this; - } - - public TermFacetRequestBuilder descTerm() { - result.setOrder(TermFacetOrder.descTerm); - return this; - } - - public TermFacetRequestBuilder ascCount() { - result.setOrder(TermFacetOrder.ascCount); - return this; - } - - public TermFacetRequestBuilder descCount() { - result.setOrder(TermFacetOrder.descCount); - return this; - } - - public TermFacetRequestBuilder applyQueryFilter() { - result.setApplyQueryFilter(true); - return this; - } - - public FacetRequest build() { - return result; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/HistogramResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/HistogramResult.java deleted file mode 100644 index f56cb0bf1..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/HistogramResult.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -import java.util.List; - -import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult; -import org.springframework.data.elasticsearch.core.facet.FacetType; - -/** - * @author Artur Konczak - */ -@Deprecated -public class HistogramResult extends AbstractFacetResult { - - private List terms; - - public HistogramResult(String name, List terms) { - super(name, FacetType.term); - this.terms = terms; - } - - public List getIntervalUnit() { - return terms; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/IntervalUnit.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/IntervalUnit.java deleted file mode 100644 index 892c4b731..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/IntervalUnit.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -import java.text.SimpleDateFormat; -import java.util.Date; - -/** - * Single term - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public class IntervalUnit { - - private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - - long key; - long count; - long totalCount; - double total; - double mean; - double min; - double max; - - public IntervalUnit(long key, long count, long totalCount, double total, double mean, double min, double max) { - this.key = key; - this.count = count; - this.totalCount = totalCount; - this.total = total; - this.mean = mean; - this.min = min; - this.max = max; - } - - public long getKey() { - return key; - } - - public long getCount() { - return count; - } - - public long getTotalCount() { - return totalCount; - } - - public double getTotal() { - return total; - } - - public double getMean() { - return mean; - } - - public double getMin() { - return min; - } - - public double getMax() { - return max; - } - - @Override - public String toString() { - return "IntervalUnit{" + - "key=" + format.format(new Date(key)) + - ", count=" + count + - ", totalCount=" + totalCount + - ", total=" + total + - ", mean=" + mean + - ", min=" + min + - ", max=" + max + - '}'; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Range.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Range.java deleted file mode 100644 index 9f8819a5b..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Range.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -/** - * Single range - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public class Range { - - private Double from; - private Double to; - private long count; - private double total; - private double totalCount; - private double min = Double.POSITIVE_INFINITY; - private double max = Double.NEGATIVE_INFINITY; - - public Range(Double from, Double to, long count, double total, double totalCount, double min, double max) { - this.from = from; - this.to = to; - this.count = count; - this.total = total; - this.totalCount = totalCount; - this.min = min; - this.max = max; - } - - public Double getFrom() { - return from; - } - - public Double getTo() { - return to; - } - - /** - * Return number of documents in range - * - * @return - */ - public long getCount() { - return count; - } - - public double getTotal() { - return total; - } - - public double getTotalCount() { - return totalCount; - } - - public double getMin() { - return min; - } - - public double getMax() { - return max; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/RangeResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/RangeResult.java deleted file mode 100644 index 6c52af053..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/RangeResult.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -import java.util.List; - -import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult; -import org.springframework.data.elasticsearch.core.facet.FacetType; - -/** - * Basic term facet result - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public class RangeResult extends AbstractFacetResult { - - private List ranges; - - public RangeResult(String name, List ranges) { - super(name, FacetType.range); - this.ranges = ranges; - } - - public List getRanges() { - return ranges; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/StatisticalResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/StatisticalResult.java deleted file mode 100644 index f59df54d8..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/StatisticalResult.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult; -import org.springframework.data.elasticsearch.core.facet.FacetType; - -/** - * @author Petar Tahchiev - */ -@Deprecated -public class StatisticalResult extends AbstractFacetResult { - - private long count; - - private double max; - - private double min; - - private double mean; - - private double stdDeviation; - - private double sumOfSquares; - - private double total; - - private double variance; - - public StatisticalResult(String name, long count, double max, double min, double mean, double stdDeviation, double sumOfSquares, double total, double variance) { - super(name, FacetType.statistical); - this.count = count; - this.max = max; - this.min = min; - this.mean = mean; - this.stdDeviation = stdDeviation; - this.sumOfSquares = sumOfSquares; - this.total = total; - this.variance = variance; - } - - public long getCount() { - return count; - } - - public double getMax() { - return max; - } - - public double getMin() { - return min; - } - - public double getMean() { - return mean; - } - - public double getStdDeviation() { - return stdDeviation; - } - - public double getSumOfSquares() { - return sumOfSquares; - } - - public double getTotal() { - return total; - } - - public double getVariance() { - return variance; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Term.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Term.java deleted file mode 100644 index 7ee1d353b..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/Term.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -/** - * Single term - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - */ -@Deprecated -public class Term { - - private String term; - private long count; - - public Term(String term, long count) { - this.term = term; - this.count = count; - } - - public String getTerm() { - return term; - } - - public long getCount() { - return count; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/TermResult.java b/src/main/java/org/springframework/data/elasticsearch/core/facet/result/TermResult.java deleted file mode 100644 index ab01bfce4..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/facet/result/TermResult.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014-2019 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.facet.result; - -import java.util.List; - -import org.springframework.data.elasticsearch.core.facet.AbstractFacetResult; -import org.springframework.data.elasticsearch.core.facet.FacetType; - -/** - * Basic term facet result - * - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Artur Konczak - * @author Jonathan Yan - * @author Matija Obreza - */ -@Deprecated -public class TermResult extends AbstractFacetResult { - - private List terms; - private long total; - private long other; - private long missing; - - public TermResult(String name, List terms, long total, long other, long missing) { - super(name, FacetType.term); - this.terms = terms; - this.total = total; - this.other = other; - this.missing = missing; - } - - public List getTerms() { - return terms; - } - - public long getTotal() { - return total; - } - - public long getOther() { - return other; - } - - public long getMissing() { - return missing; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index a1abad01b..e1be3d558 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -28,6 +28,7 @@ * @author Sascha Woo * @author Oliver Gierke * @author Ivan Greene + * @author Peter-Josef Meisch */ public interface ElasticsearchPersistentEntity extends PersistentEntity { @@ -58,7 +59,7 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity filter; @@ -32,11 +32,6 @@ public class AliasBuilder { private String indexRouting; private String routing; - public AliasBuilder withIndexName(String indexName) { - this.indexName = indexName; - return this; - } - public AliasBuilder withAliasName(String aliasName) { this.aliasName = aliasName; return this; @@ -69,7 +64,6 @@ public AliasBuilder withRouting(String routing) { public AliasQuery build() { AliasQuery aliasQuery = new AliasQuery(); - aliasQuery.setIndexName(indexName); aliasQuery.setAliasName(aliasName); aliasQuery.setFilterBuilder(filterBuilder); aliasQuery.setFilter(filter); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java index 81c2912c2..459e98c06 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java @@ -23,10 +23,10 @@ * AliasQuery is useful for creating new alias or deleting existing ones * * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class AliasQuery { - private String indexName; private String aliasName; private QueryBuilder filterBuilder; private Map filter; @@ -34,14 +34,6 @@ public class AliasQuery { private String indexRouting; private String routing; - public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - public String getAliasName() { return aliasName; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java index f04d18ca1..d1a5f82a5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java @@ -22,12 +22,11 @@ * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class DeleteQuery { private QueryBuilder query; - private String index; - private String type; private Integer pageSize; private Long scrollTimeInMillis; @@ -39,22 +38,6 @@ public void setQuery(QueryBuilder query) { this.query = query; } - public String getIndex() { - return index; - } - - public void setIndex(String index) { - this.index = index; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - public Integer getPageSize() { return pageSize; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index 5790f1ffd..4abe51385 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -28,8 +28,6 @@ public class IndexQuery { private String id; private Object object; private Long version; - private String indexName; - private String type; private String source; private String parentId; @@ -57,22 +55,6 @@ public void setVersion(Long version) { this.version = version; } - public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - public String getSource() { return source; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 753003d32..1dcd9a30d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -20,14 +20,13 @@ * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class IndexQueryBuilder { private String id; private Object object; private Long version; - private String indexName; - private String type; private String source; private String parentId; @@ -46,16 +45,6 @@ public IndexQueryBuilder withVersion(Long version) { return this; } - public IndexQueryBuilder withIndexName(String indexName) { - this.indexName = indexName; - return this; - } - - public IndexQueryBuilder withType(String type) { - this.type = type; - return this; - } - public IndexQueryBuilder withSource(String source) { this.source = source; return this; @@ -69,8 +58,6 @@ public IndexQueryBuilder withParentId(String parentId) { public IndexQuery build() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(id); - indexQuery.setIndexName(indexName); - indexQuery.setType(type); indexQuery.setObject(object); indexQuery.setParentId(parentId); indexQuery.setSource(source); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java index 385b0e23e..dc376232f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java @@ -24,7 +24,6 @@ import org.elasticsearch.search.collapse.CollapseBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortBuilder; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; /** * NativeSearchQuery @@ -43,7 +42,6 @@ public class NativeSearchQuery extends AbstractQuery { private List sorts; private final List scriptFields = new ArrayList<>(); private CollapseBuilder collapseBuilder; - private List facets; private List aggregations; private HighlightBuilder highlightBuilder; private HighlightBuilder.Field[] highlightFields; @@ -126,23 +124,6 @@ public void setCollapseBuilder(CollapseBuilder collapseBuilder) { this.collapseBuilder = collapseBuilder; } - public void addFacet(FacetRequest facetRequest) { - - if (facets == null) { - facets = new ArrayList<>(); - } - - facets.add(facetRequest); - } - - public void setFacets(List facets) { - this.facets = facets; - } - - public List getFacets() { - return facets; - } - public List getAggregations() { return aggregations; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java index 10ff21222..5a8412549 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java @@ -29,7 +29,6 @@ import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortBuilder; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.facet.FacetRequest; /** * NativeSearchQuery @@ -50,7 +49,6 @@ public class NativeSearchQueryBuilder { private QueryBuilder filterBuilder; private List scriptFields = new ArrayList<>(); private List sortBuilders = new ArrayList<>(); - private List facetRequests = new ArrayList<>(); private List aggregationBuilders = new ArrayList<>(); private HighlightBuilder highlightBuilder; private HighlightBuilder.Field[] highlightFields; @@ -99,11 +97,6 @@ public NativeSearchQueryBuilder addAggregation(AbstractAggregationBuilder aggreg return this; } - public NativeSearchQueryBuilder withFacet(FacetRequest facetRequest) { - facetRequests.add(facetRequest); - return this; - } - public NativeSearchQueryBuilder withHighlightBuilder(HighlightBuilder highlightBuilder) { this.highlightBuilder = highlightBuilder; return this; @@ -219,10 +212,6 @@ public NativeSearchQuery build() { nativeSearchQuery.setCollapseBuilder(collapseBuilder); } - if (!isEmpty(facetRequests)) { - nativeSearchQuery.setFacets(facetRequests); - } - if (!isEmpty(aggregationBuilders)) { nativeSearchQuery.setAggregations(aggregationBuilders); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index b21428a68..29ca79549 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -86,6 +86,7 @@ static Query findAll() { * * @return */ + @Deprecated List getIndices(); /** @@ -93,6 +94,7 @@ static Query findAll() { * * @param indices */ + @Deprecated void addIndices(String... indices); /** @@ -100,6 +102,7 @@ static Query findAll() { * * @param types */ + @Deprecated void addTypes(String... types); /** @@ -107,6 +110,7 @@ static Query findAll() { * * @return */ + @Deprecated List getTypes(); /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index 173bb4171..961c7d164 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -21,14 +21,12 @@ /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class UpdateQuery { private String id; private UpdateRequest updateRequest; - private String indexName; - private String type; - private Class clazz; private boolean doUpsert; public String getId() { @@ -47,30 +45,6 @@ public void setUpdateRequest(UpdateRequest updateRequest) { this.updateRequest = updateRequest; } - public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Class getClazz() { - return clazz; - } - - public void setClazz(Class clazz) { - this.clazz = clazz; - } - public boolean DoUpsert() { return doUpsert; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java index 37942b728..e7075a56f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java @@ -21,15 +21,13 @@ /** * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class UpdateQueryBuilder { private String id; private UpdateRequest updateRequest; private IndexRequest indexRequest; - private String indexName; - private String type; - private Class clazz; private boolean doUpsert; public UpdateQueryBuilder withId(String id) { @@ -47,21 +45,6 @@ public UpdateQueryBuilder withIndexRequest(IndexRequest indexRequest) { return this; } - public UpdateQueryBuilder withIndexName(String indexName) { - this.indexName = indexName; - return this; - } - - public UpdateQueryBuilder withType(String type) { - this.type = type; - return this; - } - - public UpdateQueryBuilder withClass(Class clazz) { - this.clazz = clazz; - return this; - } - public UpdateQueryBuilder withDoUpsert(boolean doUpsert) { this.doUpsert = doUpsert; return this; @@ -70,9 +53,6 @@ public UpdateQueryBuilder withDoUpsert(boolean doUpsert) { public UpdateQuery build() { UpdateQuery updateQuery = new UpdateQuery(); updateQuery.setId(id); - updateQuery.setIndexName(indexName); - updateQuery.setType(type); - updateQuery.setClazz(clazz); if (this.indexRequest != null) { if (this.updateRequest == null) { updateRequest = new UpdateRequest(); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index b9c480e5e..5ee079d33 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -17,6 +17,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator; @@ -57,6 +58,8 @@ public Object execute(Object[] parameters) { ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); CriteriaQuery query = createQuery(accessor); Assert.notNull(query, "unsupported query"); + Class clazz = queryMethod.getEntityInformation().getJavaType(); + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); if (tree.isLimiting()) { query.setMaxResults(tree.getMaxResults()); @@ -64,55 +67,60 @@ public Object execute(Object[] parameters) { if (tree.isDelete()) { Object result = countOrGetDocumentsForDelete(query, accessor); - elasticsearchOperations.delete(query, queryMethod.getEntityInformation().getJavaType()); + elasticsearchOperations.delete(query, clazz, index); return result; } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); - return elasticsearchOperations.queryForPage(query, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForPage(query, clazz, index); } else if (queryMethod.isStreamQuery()) { - Class entityType = queryMethod.getEntityInformation().getJavaType(); + Class entityType = clazz; if (accessor.getPageable().isUnpaged()) { query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE)); } else { query.setPageable(accessor.getPageable()); } return StreamUtils - .createStreamFromIterator((CloseableIterator) elasticsearchOperations.stream(query, entityType)); + .createStreamFromIterator((CloseableIterator) elasticsearchOperations.stream(query, entityType, index)); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { - int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); + int itemCount = (int) elasticsearchOperations.count(query, clazz, + index); query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); } else { query.setPageable(accessor.getPageable()); } - return elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForList(query, clazz, index); } else if (tree.isCountProjection()) { - return elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.count(query, clazz, index); } - return elasticsearchOperations.queryForObject(query, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForObject(query, clazz, index); } private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) { Object result = null; + Class clazz = queryMethod.getEntityInformation().getJavaType(); + IndexCoordinates index = elasticsearchOperations + .getIndexCoordinatesFor(clazz); if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { - int itemCount = (int) elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); + int itemCount = (int) elasticsearchOperations.count(query, clazz, + index); query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); } else { query.setPageable(accessor.getPageable()); } - result = elasticsearchOperations.queryForList(query, queryMethod.getEntityInformation().getJavaType()); + result = elasticsearchOperations.queryForList(query, clazz, index); } if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) { - result = elasticsearchOperations.count(query, queryMethod.getEntityInformation().getJavaType()); + result = elasticsearchOperations.count(query, clazz, index); } return result; } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 031f63fe1..49166c0b9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -20,6 +20,7 @@ import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.convert.DateTimeConverters; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.repository.query.ParametersParameterAccessor; @@ -68,17 +69,19 @@ public ElasticsearchStringQuery(ElasticsearchQueryMethod queryMethod, Elasticsea public Object execute(Object[] parameters) { ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); StringQuery stringQuery = createQuery(accessor); + Class clazz = queryMethod.getEntityInformation().getJavaType(); + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); if (queryMethod.isPageQuery()) { stringQuery.setPageable(accessor.getPageable()); - return elasticsearchOperations.queryForPage(stringQuery, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForPage(stringQuery, clazz, index); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isPaged()) { stringQuery.setPageable(accessor.getPageable()); } - return elasticsearchOperations.queryForList(stringQuery, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForList(stringQuery, clazz, index); } - return elasticsearchOperations.queryForObject(stringQuery, queryMethod.getEntityInformation().getJavaType()); + return elasticsearchOperations.queryForObject(stringQuery, clazz, index); } protected StringQuery createQuery(ParametersParameterAccessor parameterAccessor) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 3ca4db976..8edc1f135 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -36,6 +36,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -72,7 +73,6 @@ public abstract class AbstractElasticsearchRepository implements Elastics public AbstractElasticsearchRepository() {} public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) { - Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!"); this.setElasticsearchOperations(elasticsearchOperations); @@ -80,7 +80,6 @@ public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOper public AbstractElasticsearchRepository(ElasticsearchEntityInformation metadata, ElasticsearchOperations elasticsearchOperations) { - this(elasticsearchOperations); Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); @@ -98,124 +97,99 @@ public AbstractElasticsearchRepository(ElasticsearchEntityInformation met } private void createIndex() { - elasticsearchOperations.createIndex(getEntityClass()); } private void putMapping() { - elasticsearchOperations.putMapping(getEntityClass()); } private boolean createIndexAndMapping() { - return elasticsearchOperations.getPersistentEntityFor(getEntityClass()).isCreateIndexAndMapping(); } @Override public Optional findById(ID id) { - GetQuery query = new GetQuery(); query.setId(stringIdRepresentation(id)); - return Optional.ofNullable(elasticsearchOperations.queryForObject(query, getEntityClass())); + return Optional.ofNullable(elasticsearchOperations.get(query, getEntityClass(), getIndexCoordinates())); } @Override public Iterable findAll() { - int itemCount = (int) this.count(); + if (itemCount == 0) { return new PageImpl<>(Collections. emptyList()); } - return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); } @Override public Page findAll(Pageable pageable) { - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); - - return elasticsearchOperations.queryForPage(query, getEntityClass()); + return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override public Iterable findAll(Sort sort) { - int itemCount = (int) this.count(); + if (itemCount == 0) { return new PageImpl<>(Collections. emptyList()); } - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); - - return elasticsearchOperations.queryForPage(query, getEntityClass()); + return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override public Iterable findAllById(Iterable ids) { - Assert.notNull(ids, "ids can't be null."); - NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); - - return elasticsearchOperations.multiGet(query, getEntityClass()); + return elasticsearchOperations.multiGet(query, getEntityClass(), getIndexCoordinates()); } @Override public long count() { - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - - return elasticsearchOperations.count(query, getEntityClass()); + return elasticsearchOperations.count(query, getEntityClass(), getIndexCoordinates()); } @Override public S save(S entity) { - Assert.notNull(entity, "Cannot save 'null' entity."); - - elasticsearchOperations.index(createIndexQuery(entity)); - elasticsearchOperations.refresh(entityInformation.getIndexName()); - + elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates()); + elasticsearchOperations.refresh(getIndexCoordinates()); return entity; } public List save(List entities) { - Assert.notNull(entities, "Cannot insert 'null' as a List."); - return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); } @Override public S index(S entity) { - return save(entity); } @Override public S indexWithoutRefresh(S entity) { - Assert.notNull(entity, "Cannot save 'null' entity."); - - elasticsearchOperations.index(createIndexQuery(entity)); - + elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates()); return entity; } @Override public Iterable saveAll(Iterable entities) { - Assert.notNull(entities, "Cannot insert 'null' as a List."); - List queries = Streamable.of(entities).stream().map(this::createIndexQuery) .collect(Collectors.toList()); if (!queries.isEmpty()) { - elasticsearchOperations.bulkIndex(queries); - elasticsearchOperations.refresh(entityInformation.getIndexName()); + elasticsearchOperations.bulkIndex(queries, getIndexCoordinates()); + elasticsearchOperations.refresh(getIndexCoordinates()); } return entities; @@ -223,76 +197,64 @@ public Iterable saveAll(Iterable entities) { @Override public boolean existsById(ID id) { - return findById(id).isPresent(); } @Override public Iterable search(QueryBuilder query) { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); - int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass()); + int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass(), getIndexCoordinates()); + if (count == 0) { return new PageImpl<>(Collections. emptyList()); } - searchQuery.setPageable(PageRequest.of(0, count)); - - return elasticsearchOperations.queryForPage(searchQuery, getEntityClass()); + return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); } @Override public Page search(QueryBuilder query, Pageable pageable) { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); - - return elasticsearchOperations.queryForPage(searchQuery, getEntityClass()); + return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); } @Override public Page search(NativeSearchQuery query) { - - return elasticsearchOperations.queryForPage(query, getEntityClass()); + return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override public Page searchSimilar(T entity, String[] fields, Pageable pageable) { - Assert.notNull(entity, "Cannot search similar records for 'null'."); Assert.notNull(pageable, "'pageable' cannot be 'null'"); - MoreLikeThisQuery query = new MoreLikeThisQuery(); query.setId(stringIdRepresentation(extractIdFromBean(entity))); query.setPageable(pageable); + if (fields != null) { query.addFields(fields); } - return elasticsearchOperations.moreLikeThis(query, getEntityClass()); + return elasticsearchOperations.moreLikeThis(query, getEntityClass(), getIndexCoordinates()); } @Override public void deleteById(ID id) { - Assert.notNull(id, "Cannot delete entity with id 'null'."); - - elasticsearchOperations.delete(entityInformation.getIndexName(), entityInformation.getType(), - stringIdRepresentation(id)); - elasticsearchOperations.refresh(entityInformation.getIndexName()); + IndexCoordinates indexCoordinates = getIndexCoordinates(); + elasticsearchOperations.delete(stringIdRepresentation(id), indexCoordinates); + elasticsearchOperations.refresh(indexCoordinates); } @Override public void delete(T entity) { - Assert.notNull(entity, "Cannot delete 'null' entity."); - deleteById(extractIdFromBean(entity)); - elasticsearchOperations.refresh(entityInformation.getIndexName()); + elasticsearchOperations.refresh(getIndexCoordinates()); } @Override public void deleteAll(Iterable entities) { - Assert.notNull(entities, "Cannot delete 'null' list."); for (T entity : entities) { delete(entity); @@ -301,21 +263,19 @@ public void deleteAll(Iterable entities) { @Override public void deleteAll() { - DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(matchAllQuery()); - elasticsearchOperations.delete(deleteQuery, getEntityClass()); - elasticsearchOperations.refresh(entityInformation.getIndexName()); + IndexCoordinates indexCoordinates = getIndexCoordinates(); + elasticsearchOperations.delete(deleteQuery, indexCoordinates); + elasticsearchOperations.refresh(indexCoordinates); } @Override public void refresh() { - elasticsearchOperations.refresh(getEntityClass()); } private IndexQuery createIndexQuery(T entity) { - IndexQuery query = new IndexQuery(); query.setObject(entity); query.setId(stringIdRepresentation(extractIdFromBean(entity))); @@ -326,14 +286,13 @@ private IndexQuery createIndexQuery(T entity) { @SuppressWarnings("unchecked") private Class resolveReturnedClassFromGenericType() { - ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass()); return (Class) parameterizedType.getActualTypeArguments()[0]; } private ParameterizedType resolveReturnedClassFromGenericType(Class clazz) { - Object genericSuperclass = clazz.getGenericSuperclass(); + if (genericSuperclass instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; Type rawtype = parameterizedType.getRawType(); @@ -355,25 +314,20 @@ public Class getEntityClass() { throw new InvalidDataAccessApiUsageException("Unable to resolve EntityClass. Please use according setter!", e); } } - return entityClass; } private boolean isEntityClassSet() { - return entityClass != null; } public final void setEntityClass(Class entityClass) { - Assert.notNull(entityClass, "EntityClass must not be null."); this.entityClass = entityClass; } public final void setElasticsearchOperations(ElasticsearchOperations elasticsearchOperations) { - Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null."); - this.elasticsearchOperations = elasticsearchOperations; } @@ -382,9 +336,7 @@ protected ID extractIdFromBean(T entity) { } private List stringIdsRepresentation(Iterable ids) { - Assert.notNull(ids, "ids can't be null."); - List stringIds = new ArrayList<>(); for (ID id : ids) { stringIds.add(stringIdRepresentation(id)); @@ -402,4 +354,8 @@ private Long extractVersionFromBean(T entity) { private String extractParentIdFromBean(T entity) { return entityInformation.getParentId(entity); } + + private IndexCoordinates getIndexCoordinates() { + return elasticsearchOperations.getIndexCoordinatesFor(getEntityClass()); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index ca0bda9ab..5e9a37e7a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -45,6 +45,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -122,14 +123,15 @@ public void shouldIndexInitialLevelNestedObject() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user"); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Person.class); QueryBuilder builder = nestedQuery("car", boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class); + List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index); assertThat(persons).hasSize(1); } @@ -141,14 +143,15 @@ public void shouldIndexMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); // then GetQuery getQuery = new GetQuery(); getQuery.setId("1"); - PersonMultipleLevelNested personIndexed = elasticsearchTemplate.queryForObject(getQuery, - PersonMultipleLevelNested.class); + PersonMultipleLevelNested personIndexed = elasticsearchTemplate.get(getQuery, PersonMultipleLevelNested.class, + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); assertThat(personIndexed).isNotNull(); } @@ -159,7 +162,8 @@ public void shouldIndexMultipleLevelNestedObjectWithIncludeInParent() { List indexQueries = createPerson(); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); // then Map mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class); @@ -178,7 +182,9 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - elasticsearchTemplate.bulkIndex(indexQueries); + IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"); + elasticsearchTemplate.bulkIndex(indexQueries, + index); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); // then @@ -189,7 +195,7 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); Page personIndexed = elasticsearchTemplate.queryForPage(searchQuery, - PersonMultipleLevelNested.class); + PersonMultipleLevelNested.class, index); assertThat(personIndexed).isNotNull(); assertThat(personIndexed.getTotalElements()).isEqualTo(1); assertThat(personIndexed.getContent().get(0).getId()).isEqualTo("1"); @@ -317,14 +323,15 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user"); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Person.class); // when QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class); + List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index); // then assertThat(persons).hasSize(1); @@ -365,13 +372,14 @@ public void shouldIndexAndSearchMapAsNestedType() { indexQueries.add(indexQuery2); // when - elasticsearchTemplate.bulkIndex(indexQueries); + IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes( "book"); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Book.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); - Page books = elasticsearchTemplate.queryForPage(searchQuery, Book.class); + Page books = elasticsearchTemplate.queryForPage(searchQuery, Book.class, index); assertThat(books.getContent()).hasSize(1); assertThat(books.getContent().get(0).getId()).isEqualTo(book2.getId()); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 64d836449..407e0efee 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -22,16 +22,9 @@ import lombok.Builder; import lombok.Data; -import java.io.IOException; -import java.lang.Object; -import java.util.HashMap; -import java.util.Map; - import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; @@ -41,7 +34,6 @@ import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.util.ReflectionTestUtils; /** * @author Rizwan Idrees @@ -56,7 +48,6 @@ * @author Sascha Woo * @author Don Wellington * @author Peter-Josef Meisch - * @author Massimiliano Poggi */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @@ -68,65 +59,12 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() // when IndexRequest indexRequest = new IndexRequest(); indexRequest.source("{}", XContentType.JSON); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class) - .withIndexRequest(indexRequest).build(); + UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); assertThatThrownBy(() -> { - elasticsearchTemplate.update(updateQuery); + elasticsearchTemplate.update(updateQuery, index); }).isInstanceOf(ElasticsearchStatusException.class); } - @Test // DATAES-227 - @Override - public void shouldUseUpsertOnUpdate() throws IOException { - - // given - Map doc = new HashMap<>(); - doc.put("id", "1"); - doc.put("message", "test"); - - UpdateRequest updateRequest = new UpdateRequest() // - .doc(doc) // - .upsert(doc); - - UpdateQuery updateQuery = new UpdateQueryBuilder() // - .withClass(SampleEntity.class) // - .withId("1") // - .withUpdateRequest(updateRequest).build(); - - // when - UpdateRequest request = (UpdateRequest) ReflectionTestUtils // - .invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery); - - // then - assertThat(request).isNotNull(); - assertThat(request.upsertRequest()).isNotNull(); - } - - @Test // DATAES-693 - public void shouldReturnSourceWhenRequested() throws IOException { - // given - Map doc = new HashMap<>(); - doc.put("id", "1"); - doc.put("message", "test"); - - UpdateRequest updateRequest = new UpdateRequest() - .doc(doc) - .fetchSource(FetchSourceContext.FETCH_SOURCE); - - UpdateQuery updateQuery = new UpdateQueryBuilder() // - .withClass(SampleEntity.class) // - .withId("1") // - .withUpdateRequest(updateRequest).build(); - - // when - UpdateRequest request = (UpdateRequest) ReflectionTestUtils // - .invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery); - - // then - assertThat(request).isNotNull(); - assertThat(request.fetchSource()).isEqualTo(FetchSourceContext.FETCH_SOURCE); - } - @Data @Builder @Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0, diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateParentChildTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateParentChildTests.java index a84c9b41f..d4d186d97 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateParentChildTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateParentChildTests.java @@ -83,7 +83,7 @@ public void shouldIndexParentChildEntity() { // find all parents that have the first child QueryBuilder query = hasChildQuery(ParentEntity.CHILD_TYPE, QueryBuilders.termQuery("name", child1name.toLowerCase()), ScoreMode.None); - List parents = elasticsearchTemplate.queryForList(new NativeSearchQuery(query), ParentEntity.class); + List parents = elasticsearchTemplate.queryForList(new NativeSearchQuery(query), ParentEntity.class, IndexCoordinates.of(ParentEntity.INDEX)); // we're expecting only the first parent as result assertThat(parents).hasSize(1); @@ -105,7 +105,7 @@ public void shouldUpdateChild() throws Exception { XContentBuilder builder; builder = jsonBuilder().startObject().field("name", newChildName).endObject(); updateRequest.doc(builder); - UpdateResponse response = update(updateRequest); + UpdateResponse response = update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); assertThat(response.getShardInfo().getSuccessful()).isEqualTo(1); } @@ -124,7 +124,7 @@ public void shouldFailWithRoutingMissingExceptionOnUpdateChildIfNotRoutingSetOnU XContentBuilder builder; builder = jsonBuilder().startObject().field("name", newChildName).endObject(); updateRequest.doc(builder); - update(updateRequest); + update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); } @Ignore(value = "DATAES-421") @@ -142,7 +142,7 @@ public void shouldFailWithRoutingMissingExceptionOnUpdateChildIfRoutingOnlySetOn builder = jsonBuilder().startObject().field("name", newChildName).endObject(); updateRequest.doc(builder); updateRequest.doc().routing(parent.getId()); - update(updateRequest); + update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); } private ParentEntity index(String parentId, String name) { @@ -151,7 +151,7 @@ private ParentEntity index(String parentId, String name) { IndexQuery index = new IndexQuery(); index.setId(parent.getId()); index.setObject(parent); - elasticsearchTemplate.index(index); + elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.PARENT_TYPE)); return parent; } @@ -163,19 +163,17 @@ private ChildEntity index(String childId, String parentId, String name) { index.setId(child.getId()); index.setObject(child); index.setParentId(child.getParentId()); - elasticsearchTemplate.index(index); + elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); return child; } - private UpdateResponse update(UpdateRequest updateRequest) { + private UpdateResponse update(UpdateRequest updateRequest, IndexCoordinates index) { UpdateQuery update = new UpdateQuery(); update.setId(updateRequest.id()); - update.setType(updateRequest.type()); - update.setIndexName(updateRequest.index()); update.setUpdateRequest(updateRequest); - return elasticsearchTemplate.update(update); + return elasticsearchTemplate.update(update, index); } /** diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 3436cfa09..5c6971cc3 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -45,11 +45,11 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.update.UpdateRequest; -import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.index.VersionType; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; @@ -75,7 +75,6 @@ import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.CloseableIterator; -import org.springframework.test.util.ReflectionTestUtils; /** * Base for testing rest/transport templates. Contains the test common to both implementing classes. @@ -108,6 +107,8 @@ public abstract class ElasticsearchTemplateTests { private static final String INDEX_3_NAME = "test-index-3"; private static final String TYPE_NAME = "test-type"; + protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME); + @Autowired protected ElasticsearchOperations elasticsearchTemplate; @BeforeEach @@ -149,13 +150,13 @@ public void shouldReturnCountForGivenCriteriaQuery() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class); + long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -170,13 +171,13 @@ public void shouldReturnCountForGivenSearchQuery() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class); + long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); } @@ -189,12 +190,12 @@ public void shouldReturnObjectForGivenId() { SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); // when GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); + SampleEntity sampleEntity1 = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -217,12 +218,12 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); - List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class); + List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(2); @@ -246,13 +247,13 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)) .withFields("message", "type").build(); - List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class); + List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(2); @@ -268,13 +269,13 @@ public void shouldReturnPageForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -291,7 +292,7 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQueryWithValidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -299,7 +300,7 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQueryWithValidPreference, - SampleEntity.class); + SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -316,7 +317,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQueryWithInvalidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -324,7 +325,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { // when assertThatThrownBy(() -> { - elasticsearchTemplate.queryForPage(searchQueryWithInvalidPreference, SampleEntity.class); + elasticsearchTemplate.queryForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); }).isInstanceOf(Exception.class); } @@ -336,16 +337,16 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery idxQuery = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(sampleEntity.getId()) - .withObject(sampleEntity).build(); + IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery); - elasticsearchTemplate.refresh(INDEX_1_NAME); + elasticsearchTemplate.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - Page entities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page entities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, + IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(entities).isNotNull(); @@ -371,12 +372,12 @@ public void shouldDoBulkIndex() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -393,24 +394,23 @@ public void shouldDoBulkUpdate() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", messageAfterUpdate); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withClass(SampleEntity.class) - .withIndexRequest(indexRequest).build(); + UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withIndexRequest(indexRequest).build(); List queries = new ArrayList<>(); queries.add(updateQuery); // when - elasticsearchTemplate.bulkUpdate(queries); + elasticsearchTemplate.bulkUpdate(queries, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); + SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -424,15 +424,15 @@ public void shouldDeleteDocumentForGivenId() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); // when - elasticsearchTemplate.delete(INDEX_NAME_SAMPLE_ENTITY, TYPE_NAME, documentId); + elasticsearchTemplate.delete(documentId, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -446,15 +446,15 @@ public void shouldDeleteEntityForGivenId() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); // when - elasticsearchTemplate.delete(SampleEntity.class, documentId); + elasticsearchTemplate.delete(documentId, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -468,18 +468,18 @@ public void shouldDeleteDocumentForGivenQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("id", documentId)); - elasticsearchTemplate.delete(deleteQuery, SampleEntity.class); + elasticsearchTemplate.delete(deleteQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -492,35 +492,31 @@ public void shouldDeleteAcrossIndex() { .version(System.currentTimeMillis()) // .build(); - IndexQuery idxQuery1 = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(randomNumeric(5)) - .withObject(sampleEntity).build(); + IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery1); - elasticsearchTemplate.refresh(INDEX_1_NAME); + elasticsearchTemplate.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - IndexQuery idxQuery2 = new IndexQueryBuilder().withIndexName(INDEX_2_NAME).withId(randomNumeric(5)) - .withObject(sampleEntity).build(); + IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery2); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(typeQuery(TYPE_NAME)); - deleteQuery.setType(TYPE_NAME); - deleteQuery.setIndex("test-index-*"); - elasticsearchTemplate.delete(deleteQuery); + elasticsearchTemplate.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")) .withIndices(INDEX_1_NAME, INDEX_2_NAME) // .build(); - assertThat(elasticsearchTemplate.count(searchQuery)).isEqualTo(0); + assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME))).isEqualTo(0); } @Test // DATAES-547 @@ -532,35 +528,31 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .version(System.currentTimeMillis()) // .build(); - IndexQuery idxQuery1 = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(randomNumeric(5)) - .withObject(sampleEntity).build(); + IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery1); - elasticsearchTemplate.refresh(INDEX_1_NAME); + elasticsearchTemplate.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - IndexQuery idxQuery2 = new IndexQueryBuilder().withIndexName(INDEX_2_NAME).withId(randomNumeric(5)) - .withObject(sampleEntity).build(); + IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery2); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("message", "negative")); - deleteQuery.setType(TYPE_NAME); - deleteQuery.setIndex("test-index-*"); - elasticsearchTemplate.delete(deleteQuery); + elasticsearchTemplate.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")) .withIndices(INDEX_1_NAME, INDEX_2_NAME) // .build(); - assertThat(elasticsearchTemplate.count(searchQuery)).isEqualTo(2); + assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of("test-index-*"))).isEqualTo(2); } @Test @@ -572,14 +564,14 @@ public void shouldFilterSearchResultsForGivenFilter() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -607,14 +599,14 @@ public void shouldSortResultsGivenSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -643,7 +635,7 @@ public void shouldSortResultsGivenMultipleSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -651,7 +643,7 @@ public void shouldSortResultsGivenMultipleSortCriteria() { .withSort(new FieldSortBuilder("message").order(SortOrder.ASC)).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -682,14 +674,14 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -720,14 +712,14 @@ public void shouldSortResultsGivenNullLastSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -744,7 +736,7 @@ public void shouldSortResultsByScore() { SampleEntity.builder().id("2").message("yellow green").build(), // SampleEntity.builder().id("3").message("blue").build()); - elasticsearchTemplate.bulkIndex(getIndexQueries(entities)); + elasticsearchTemplate.bulkIndex(getIndexQueries(entities), index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // @@ -753,7 +745,7 @@ public void shouldSortResultsByScore() { .build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(2); @@ -771,13 +763,13 @@ public void shouldExecuteStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -798,7 +790,7 @@ public void shouldUseScriptedFields() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); Map params = new HashMap<>(); @@ -808,7 +800,7 @@ public void shouldUseScriptedFields() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( new ScriptField("scriptedRate", new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params))) .build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -825,13 +817,13 @@ public void shouldReturnPageableResultsGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10)); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -851,14 +843,14 @@ public void shouldReturnSortedPageableResultsGivenStringQuery() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10), Sort.by(Order.asc("message"))); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -874,13 +866,13 @@ public void shouldReturnObjectMatchingGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(termQuery("id", documentId).toString()); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(stringQuery, SampleEntity.class); + SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -911,12 +903,12 @@ public void shouldExecuteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -932,17 +924,17 @@ public void shouldDeleteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when - elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class); + elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class, index); elasticsearchTemplate.refresh(SampleEntity.class); // then StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class); + List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class, index); assertThat(sampleEntities).isEmpty(); } @@ -959,13 +951,13 @@ public void shouldReturnSpecifiedFields() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -987,7 +979,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); FetchSourceFilterBuilder sourceFilter = new FetchSourceFilterBuilder(); @@ -997,7 +989,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withSourceFilter(sourceFilter.build()).build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -1021,12 +1013,14 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); String documentId2 = randomNumeric(5); - elasticsearchTemplate.index(getIndexQuery( - SampleEntity.builder().id(documentId2).message(sampleMessage).version(System.currentTimeMillis()).build())); + elasticsearchTemplate.index( + getIndexQuery( + SampleEntity.builder().id(documentId2).message(sampleMessage).version(System.currentTimeMillis()).build()), + index); elasticsearchTemplate.refresh(SampleEntity.class); MoreLikeThisQuery moreLikeThisQuery = new MoreLikeThisQuery(); @@ -1035,7 +1029,8 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { moreLikeThisQuery.setMinDocFreq(1); // when - Page sampleEntities = elasticsearchTemplate.moreLikeThis(moreLikeThisQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.moreLikeThis(moreLikeThisQuery, SampleEntity.class, + index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -1049,7 +1044,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1058,7 +1053,8 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, + index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -1075,7 +1071,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1083,7 +1079,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -1100,7 +1096,7 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1110,7 +1106,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1129,7 +1126,7 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1137,7 +1134,7 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1156,7 +1153,7 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1165,7 +1162,8 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1184,14 +1182,14 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1210,14 +1208,15 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1236,14 +1235,14 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { @@ -1262,7 +1261,7 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -1271,7 +1270,7 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); - CloseableIterator stream = elasticsearchTemplate.stream(criteriaQuery, SampleEntity.class); + CloseableIterator stream = elasticsearchTemplate.stream(criteriaQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (stream.hasNext()) { sampleEntities.add(stream.next()); @@ -1319,16 +1318,16 @@ public void shouldReturnListForGivenCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery singleCriteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); CriteriaQuery multipleCriteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").and("message").contains("message")); List sampleEntitiesForSingleCriteria = elasticsearchTemplate.queryForList(singleCriteriaQuery, - SampleEntity.class); + SampleEntity.class, index); List sampleEntitiesForAndCriteria = elasticsearchTemplate.queryForList(multipleCriteriaQuery, - SampleEntity.class); + SampleEntity.class, index); // then assertThat(sampleEntitiesForSingleCriteria).hasSize(2); assertThat(sampleEntitiesForAndCriteria).hasSize(1); @@ -1356,11 +1355,11 @@ public void shouldReturnListForGivenStringQuery() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class); + List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(3); @@ -1389,10 +1388,11 @@ public void shouldPutMappingWithCustomIndexName() throws Exception { elasticsearchTemplate.createIndex(INDEX_1_NAME); // when - elasticsearchTemplate.putMapping(INDEX_1_NAME, TYPE_NAME, entity); + elasticsearchTemplate.putMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME), entity); // then - Map mapping = elasticsearchTemplate.getMapping(INDEX_1_NAME, TYPE_NAME); + Map mapping = elasticsearchTemplate + .getMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME)); assertThat(mapping.get("properties")).isNotNull(); } @@ -1422,21 +1422,20 @@ public void shouldDoPartialUpdateForExistingDocument() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", messageAfterUpdate); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withClass(SampleEntity.class) - .withIndexRequest(indexRequest).build(); + UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withIndexRequest(indexRequest).build(); // when - elasticsearchTemplate.update(updateQuery); + elasticsearchTemplate.update(updateQuery, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); + SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -1453,20 +1452,40 @@ public void shouldUseUpsertOnUpdate() throws IOException { .upsert(doc); UpdateQuery updateQuery = new UpdateQueryBuilder() // - .withClass(SampleEntity.class) // .withId("1") // .withUpdateRequest(updateRequest).build(); // when - UpdateRequest request = ((UpdateRequestBuilder) ReflectionTestUtils // - .invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery)) // - .request(); + UpdateRequest request = elasticsearchTemplate.getRequestFactory().updateRequest(updateQuery, + IndexCoordinates.of("index")); // then assertThat(request).isNotNull(); assertThat(request.upsertRequest()).isNotNull(); } + @Test // DATAES-693 + public void shouldReturnSourceWhenRequested() throws IOException { + // given + Map doc = new HashMap<>(); + doc.put("id", "1"); + doc.put("message", "test"); + + UpdateRequest updateRequest = new UpdateRequest().doc(doc).fetchSource(FetchSourceContext.FETCH_SOURCE); + + UpdateQuery updateQuery = new UpdateQueryBuilder() // + .withId("1") // + .withUpdateRequest(updateRequest).build(); + + // when + UpdateRequest request = elasticsearchTemplate.getRequestFactory().updateRequest(updateQuery, + IndexCoordinates.of("index")); + + // then + assertThat(request).isNotNull(); + assertThat(request.fetchSource()).isEqualTo(FetchSourceContext.FETCH_SOURCE); + } + @Test public void shouldDoUpsertIfDocumentDoesNotExist() { @@ -1476,15 +1495,15 @@ public void shouldDoUpsertIfDocumentDoesNotExist() { IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", message); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withDoUpsert(true) - .withClass(SampleEntity.class).withIndexRequest(indexRequest).build(); + .withIndexRequest(indexRequest).build(); // when - elasticsearchTemplate.update(updateQuery); + elasticsearchTemplate.update(updateQuery, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); + SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(message); } @@ -1497,11 +1516,11 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery idxQuery = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(sampleEntity.getId()) - .withObject(sampleEntity).build(); + IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery); - elasticsearchTemplate.refresh(INDEX_1_NAME); + IndexCoordinates index = IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type"); + elasticsearchTemplate.index(idxQuery, index); + elasticsearchTemplate.refresh(index); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -1510,7 +1529,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { List entities = new ArrayList<>(); ScrolledPage scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery, - SampleEntity.class); + SampleEntity.class, index); entities.addAll(scroll.getContent()); @@ -1535,7 +1554,7 @@ public void shouldReturnSameEntityForMultiSearch() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when @@ -1546,7 +1565,7 @@ public void shouldReturnSameEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ac")).build()); // then - List> sampleEntities = elasticsearchTemplate.queryForPage(queries, SampleEntity.class); + List> sampleEntities = elasticsearchTemplate.queryForPage(queries, SampleEntity.class, index); for (Page sampleEntity : sampleEntities) { assertThat(sampleEntity.getTotalElements()).isEqualTo(1); } @@ -1562,23 +1581,22 @@ public void shouldReturnDifferentEntityForMultiSearch() { elasticsearchTemplate.putMapping(clazz); elasticsearchTemplate.refresh(clazz); - List indexQueries = new ArrayList<>(); - - indexQueries.add(buildIndex(SampleEntity.builder().id("1").message("ab").build())); - indexQueries.add(buildIndex(Book.builder().id("2").description("bc").build())); + IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template").withTypes("book"); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()), index); + elasticsearchTemplate.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex); elasticsearchTemplate.refresh(SampleEntity.class); elasticsearchTemplate.refresh(clazz); // when List queries = new ArrayList<>(); - queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("description", "bc")).build()); + List> pages = elasticsearchTemplate.queryForPage(queries, Lists.newArrayList(SampleEntity.class, clazz), + IndexCoordinates.of(index.getIndexName(), bookIndex.getIndexName())); + // then - List> pages = elasticsearchTemplate.queryForPage(queries, Lists.newArrayList(SampleEntity.class, clazz)); Page page0 = pages.get(0); assertThat(page0.getTotalElements()).isEqualTo(1L); assertThat(page0.getContent().get(0).getClass()).isEqualTo(SampleEntity.class); @@ -1597,20 +1615,18 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("id", documentId)); - deleteQuery.setIndex(INDEX_NAME_SAMPLE_ENTITY); - deleteQuery.setType(TYPE_NAME); - elasticsearchTemplate.delete(deleteQuery); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.delete(deleteQuery, index); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -1622,17 +1638,15 @@ public void shouldIndexDocumentForSpecifiedSource() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId("2333343434"); indexQuery.setSource(documentSource); - indexQuery.setIndexName(INDEX_NAME_SAMPLE_ENTITY); - indexQuery.setType(TYPE_NAME); // when - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); // then - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(page).isNotNull(); assertThat(page.getContent()).hasSize(1); assertThat(page.getContent().get(0).getId()).isEqualTo(indexQuery.getId()); @@ -1644,11 +1658,10 @@ public void shouldThrowElasticsearchExceptionWhenNoDocumentSpecified() { // given final IndexQuery indexQuery = new IndexQuery(); indexQuery.setId("2333343434"); - indexQuery.setIndexName(INDEX_NAME_SAMPLE_ENTITY); - indexQuery.setType(TYPE_NAME); // when - assertThatThrownBy(() -> elasticsearchTemplate.index(indexQuery)).isInstanceOf(ElasticsearchException.class); + assertThatThrownBy(() -> elasticsearchTemplate.index(indexQuery, + IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME))).isInstanceOf(ElasticsearchException.class); } @Test @@ -1656,12 +1669,12 @@ public void shouldReturnIds() { // given List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 100)).build(); // then - List ids = elasticsearchTemplate.queryForIds(searchQuery); + List ids = elasticsearchTemplate.queryForIds(searchQuery, SampleEntity.class, index); assertThat(ids).hasSize(30); } @@ -1674,7 +1687,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when @@ -1682,7 +1695,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withMinScore(2.0F).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); @@ -1699,14 +1712,14 @@ public void shouldReturnScores() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac xz hi").build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) .withSort(SortBuilders.fieldSort("message")).withTrackScores(true).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isInstanceOf(AggregatedPage.class); @@ -1727,14 +1740,14 @@ public void shouldDoIndexWithoutId() { indexQuery.setObject(sampleEntity); // when - String documentId = elasticsearchTemplate.index(indexQuery); + String documentId = elasticsearchTemplate.index(indexQuery, index); // then assertThat(sampleEntity.getId()).isEqualTo(documentId); GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity result = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); + SampleEntity result = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); assertThat(result.getId()).isEqualTo(documentId); } @@ -1762,12 +1775,12 @@ public void shouldDoBulkIndexWithoutId() { indexQueries.add(indexQuery2); // when - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); List content = sampleEntities.getContent(); @@ -1796,27 +1809,23 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { IndexQuery indexQuery1 = new IndexQuery(); indexQuery1.setId("1"); indexQuery1.setObject(person1); - indexQuery1.setIndexName(INDEX_NAME_SAMPLE_ENTITY); - indexQuery1.setType(TYPE_NAME); IndexQuery indexQuery2 = new IndexQuery(); indexQuery2.setId("2"); indexQuery2.setObject(person2); - indexQuery2.setIndexName(INDEX_NAME_SAMPLE_ENTITY); - indexQuery2.setType(TYPE_NAME); List indexQueries = new ArrayList<>(); indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); // when - elasticsearchTemplate.bulkIndex(indexQueries); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.bulkIndex(indexQueries, index); + elasticsearchTemplate.refresh(index); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, Map.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, Map.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); List content = sampleEntities.getContent(); @@ -1832,28 +1841,27 @@ public void shouldIndexGteEntityWithVersionType() { GTEVersionEntity entity = GTEVersionEntity.builder().id(documentId).name("FooBar") .version(System.currentTimeMillis()).build(); - IndexQueryBuilder indexQueryBuilder = new IndexQueryBuilder().withId(documentId) - .withIndexName(INDEX_NAME_SAMPLE_ENTITY).withType(TYPE_NAME).withVersion(entity.getVersion()) + IndexQueryBuilder indexQueryBuilder = new IndexQueryBuilder().withId(documentId).withVersion(entity.getVersion()) .withObject(entity); - elasticsearchTemplate.index(indexQueryBuilder.build()); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.index(indexQueryBuilder.build(), index); + elasticsearchTemplate.refresh(index); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); // when - Page entities = elasticsearchTemplate.queryForPage(searchQuery, GTEVersionEntity.class); + Page entities = elasticsearchTemplate.queryForPage(searchQuery, GTEVersionEntity.class, index); // then assertThat(entities).isNotNull(); assertThat(entities.getTotalElements()).isGreaterThanOrEqualTo(1); // reindex with same version - elasticsearchTemplate.index(indexQueryBuilder.build()); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.index(indexQueryBuilder.build(), index); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // reindex with version one below assertThatThrownBy(() -> { - elasticsearchTemplate.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build()); + elasticsearchTemplate.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index); }).hasMessageContaining("version").hasMessageContaining("conflict"); } @@ -1865,17 +1873,16 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery = new IndexQueryBuilder().withId(documentId).withIndexName(INDEX_NAME_SAMPLE_ENTITY) - .withType(TYPE_NAME).withObject(sampleEntity).build(); + IndexQuery indexQuery = new IndexQueryBuilder().withId(documentId).withObject(sampleEntity).build(); - elasticsearchTemplate.index(indexQuery); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -1891,13 +1898,13 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQue .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); // when - long count = elasticsearchTemplate.count(criteriaQuery); + long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -1912,13 +1919,13 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).build(); // when - long count = elasticsearchTemplate.count(searchQuery); + long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -1933,7 +1940,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); @@ -1941,7 +1948,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit // when - long count = elasticsearchTemplate.count(criteriaQuery); + long count = elasticsearchTemplate.count(criteriaQuery, index); // then assertThat(count).isEqualTo(1); } @@ -1955,13 +1962,13 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearch .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); // when - long count = elasticsearchTemplate.count(searchQuery); + long count = elasticsearchTemplate.count(searchQuery, index); // then assertThat(count).isEqualTo(1); @@ -1976,25 +1983,24 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withIndexName(INDEX_1_NAME) - .withObject(sampleEntity1).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withIndexName(INDEX_2_NAME) - .withObject(sampleEntity2).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addIndices(INDEX_1_NAME, INDEX_2_NAME); // when - long count = elasticsearchTemplate.count(criteriaQuery); + long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(count).isEqualTo(2); @@ -2009,25 +2015,24 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withIndexName(INDEX_1_NAME) - .withObject(sampleEntity1).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withIndexName(INDEX_2_NAME) - .withObject(sampleEntity2).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); // when - long count = elasticsearchTemplate.count(searchQuery); + long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(count).isEqualTo(2); @@ -2038,8 +2043,7 @@ private void cleanUpIndices() { elasticsearchTemplate.deleteIndex(INDEX_2_NAME); elasticsearchTemplate.createIndex(INDEX_1_NAME); elasticsearchTemplate.createIndex(INDEX_2_NAME); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); } @Test // DATAES-71 @@ -2078,25 +2082,24 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withIndexName(INDEX_1_NAME) - .withObject(sampleEntity1).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withIndexName(INDEX_2_NAME) - .withObject(sampleEntity2).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addIndices(INDEX_1_NAME); // when - long count = elasticsearchTemplate.count(criteriaQuery); + long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME)); // then assertThat(count).isEqualTo(1); @@ -2111,25 +2114,24 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withIndexName(INDEX_1_NAME) - .withObject(sampleEntity1).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withIndexName(INDEX_2_NAME) - .withObject(sampleEntity2).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(INDEX_1_NAME) .build(); // when - long count = elasticsearchTemplate.count(searchQuery); + long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME)); // then assertThat(count).isEqualTo(1); @@ -2144,13 +2146,13 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when assertThatThrownBy(() -> { - long count = elasticsearchTemplate.count(criteriaQuery); + elasticsearchTemplate.count(criteriaQuery, (IndexCoordinates) null); }).isInstanceOf(IllegalArgumentException.class); } @@ -2163,13 +2165,13 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when assertThatThrownBy(() -> { - elasticsearchTemplate.count(searchQuery); + elasticsearchTemplate.count(searchQuery, (IndexCoordinates) null); }).isInstanceOf(IllegalArgumentException.class); } @@ -2249,25 +2251,25 @@ public void shouldTestResultsAcrossMultipleIndices() { SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withIndexName(INDEX_1_NAME) - .withObject(sampleEntity1).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); - IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withIndexName(INDEX_2_NAME) - .withObject(sampleEntity2).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(indexQuery1, indexQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); // when - List sampleEntities = elasticsearchTemplate.queryForList(searchQuery, SampleEntity.class); + List sampleEntities = elasticsearchTemplate.queryForList(searchQuery, SampleEntity.class, + IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(sampleEntities).hasSize(2); @@ -2283,19 +2285,19 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { HetroEntity1 entity1 = new HetroEntity1(randomNumeric(3), "aFirstName"); HetroEntity2 entity2 = new HetroEntity2(randomNumeric(4), "aLastName"); - IndexQuery idxQuery1 = new IndexQueryBuilder().withIndexName(INDEX_1_NAME).withId(entity1.getId()) - .withObject(entity1).build(); - IndexQuery idxQuery2 = new IndexQueryBuilder().withIndexName(INDEX_2_NAME).withId(entity2.getId()) - .withObject(entity2).build(); + IndexQuery indexQuery1 = new IndexQueryBuilder().withId(entity1.getId()).withObject(entity1).build(); + IndexQuery indexQuery2 = new IndexQueryBuilder().withId(entity2.getId()).withObject(entity2).build(); - elasticsearchTemplate.bulkIndex(Arrays.asList(idxQuery1, idxQuery2)); - elasticsearchTemplate.refresh(INDEX_1_NAME); - elasticsearchTemplate.refresh(INDEX_2_NAME); + elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("hetro")); + elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("hetro")); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withTypes("hetro") .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class, + IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); assertThat(page.getTotalElements()).isEqualTo(2); } @@ -2315,20 +2317,6 @@ public void shouldCreateIndexUsingServerDefaultConfiguration() { assertThat(setting.get("index.number_of_replicas")).isEqualTo("1"); } - @Test - public void shouldReadFileFromClasspathRetainingNewlines() { - - // given - String settingsFile = "/settings/test-settings.yml"; - - // when - String content = ElasticsearchTemplate.readFileFromClasspath(settingsFile); - - // then - assertThat(content).isEqualTo("index:\n" + " number_of_shards: 1\n" + " number_of_replicas: 0\n" + " analysis:\n" - + " analyzer:\n" + " emailAnalyzer:\n" + " type: custom\n" + " tokenizer: uax_url_email"); - } - @Test // DATAES-531 public void shouldReturnMappingForGivenEntityClass() { @@ -2360,19 +2348,19 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(idsQuery().addIds(documentIdToDelete)); - elasticsearchTemplate.delete(deleteQuery, SampleEntity.class); + elasticsearchTemplate.delete(deleteQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2392,18 +2380,18 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("id").is(documentIdToDelete)); - elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class); + elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class, index); elasticsearchTemplate.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2422,17 +2410,17 @@ public void shouldDeleteDocumentForGivenIdOnly() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when - elasticsearchTemplate.delete(SampleEntity.class, documentIdToDelete); + elasticsearchTemplate.delete(documentIdToDelete, index); elasticsearchTemplate.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2451,7 +2439,7 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(UUID.randomUUID().toString()).message(notFindableMessage) .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when @@ -2460,7 +2448,8 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, + index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -2488,14 +2477,14 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(UUID.randomUUID().toString()).message(notFindableMessage) .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -2516,7 +2505,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { List entities = createSampleEntitiesWithMessage("Test message", 3); // when - elasticsearchTemplate.bulkIndex(entities); + elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); // then @@ -2526,7 +2515,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)) .withSourceFilter(sourceFilter).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -2562,7 +2551,7 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -2570,7 +2559,7 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); // when - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -2608,7 +2597,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -2617,7 +2606,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { .build(); // when - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); + ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); @@ -2641,19 +2630,19 @@ public void shouldReturnDocumentWithCollapsedField() { .version(System.currentTimeMillis()).build(); SampleEntity sampleEntity2 = SampleEntity.builder().id(randomNumeric(5)).message("message 2").rate(2) .version(System.currentTimeMillis()).build(); - SampleEntity sampleEntit3 = SampleEntity.builder().id(randomNumeric(5)).message("message 1").rate(1) + SampleEntity sampleEntity3 = SampleEntity.builder().id(randomNumeric(5)).message("message 1").rate(1) .version(System.currentTimeMillis()).build(); - List indexQueries = getIndexQueries(Arrays.asList(sampleEntity, sampleEntity2, sampleEntit3)); + List indexQueries = getIndexQueries(Arrays.asList(sampleEntity, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withCollapseField("rate").build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -2682,12 +2671,11 @@ public void shouldAddAlias() { // given String aliasName = "test-alias"; AliasQuery aliasQuery = new AliasBuilder() // - .withIndexName(INDEX_NAME_SAMPLE_ENTITY) // .withAliasName(aliasName) // .build(); // when - elasticsearchTemplate.addAlias(aliasQuery); + elasticsearchTemplate.addAlias(aliasQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // then List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); @@ -2703,20 +2691,19 @@ public void shouldAddAliasForVariousRoutingValues() { String alias2 = "test-alias-2"; AliasQuery aliasQuery1 = new AliasBuilder() // - .withIndexName(INDEX_NAME_SAMPLE_ENTITY) // .withAliasName(alias1) // .withIndexRouting("0") // .build(); AliasQuery aliasQuery2 = new AliasBuilder() // - .withIndexName(INDEX_NAME_SAMPLE_ENTITY) // .withAliasName(alias2) // .withSearchRouting("1") // .build(); // when - elasticsearchTemplate.addAlias(aliasQuery1); - elasticsearchTemplate.addAlias(aliasQuery2); + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.addAlias(aliasQuery1, index); + elasticsearchTemplate.addAlias(aliasQuery2, index); String documentId = randomNumeric(5); SampleEntity entity = SampleEntity.builder() // @@ -2726,13 +2713,11 @@ public void shouldAddAliasForVariousRoutingValues() { .build(); IndexQuery indexQuery = new IndexQueryBuilder() // - .withIndexName(alias1) // - .withType(TYPE_NAME) // .withId(entity.getId()) // .withObject(entity) // .build(); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(alias1).withTypes(TYPE_NAME)); // then List aliasMetaData = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); @@ -2749,8 +2734,8 @@ public void shouldAddAliasForVariousRoutingValues() { assertThat(aliasMetaData2.searchRouting()).isEqualTo("1"); // cleanup - elasticsearchTemplate.removeAlias(aliasQuery1); - elasticsearchTemplate.removeAlias(aliasQuery2); + elasticsearchTemplate.removeAlias(aliasQuery1, index); + elasticsearchTemplate.removeAlias(aliasQuery2, index); } @Test // DATAES-70 @@ -2758,15 +2743,15 @@ public void shouldAddAliasWithGivenRoutingValue() { // given String alias = "test-alias"; + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); AliasQuery aliasQuery = new AliasBuilder() // - .withIndexName(INDEX_NAME_SAMPLE_ENTITY) // .withAliasName(alias) // .withRouting("0") // .build(); // when - elasticsearchTemplate.addAlias(aliasQuery); + elasticsearchTemplate.addAlias(aliasQuery, index); String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder() // @@ -2776,14 +2761,12 @@ public void shouldAddAliasWithGivenRoutingValue() { .build(); IndexQuery indexQuery = new IndexQueryBuilder() // - .withIndexName(alias) // .withId(sampleEntity.getId()) // - .withType(TYPE_NAME) // .withObject(sampleEntity) // .build(); - elasticsearchTemplate.index(indexQuery); - elasticsearchTemplate.refresh(INDEX_NAME_SAMPLE_ENTITY); + elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(alias).withTypes(TYPE_NAME)); + elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // @@ -2791,7 +2774,7 @@ public void shouldAddAliasWithGivenRoutingValue() { .withTypes(TYPE_NAME) // .build(); - long count = elasticsearchTemplate.count(query); + long count = elasticsearchTemplate.count(query, IndexCoordinates.of(alias)); // then List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); @@ -2803,7 +2786,7 @@ public void shouldAddAliasWithGivenRoutingValue() { assertThat(count).isEqualTo(1); // cleanup - elasticsearchTemplate.removeAlias(aliasQuery); + elasticsearchTemplate.removeAlias(aliasQuery, index); } @Test // DATAES-541 @@ -2811,19 +2794,20 @@ public void shouldRemoveAlias() { // given String aliasName = "test-alias"; + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); + AliasQuery aliasQuery = new AliasBuilder() // - .withIndexName(INDEX_NAME_SAMPLE_ENTITY) // .withAliasName(aliasName) // .build(); // when - elasticsearchTemplate.addAlias(aliasQuery); + elasticsearchTemplate.addAlias(aliasQuery, index); List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); // then - elasticsearchTemplate.removeAlias(aliasQuery); + elasticsearchTemplate.removeAlias(aliasQuery, index); aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isEmpty(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index c47d839bd..f5ffc790f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -46,10 +46,9 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() // when IndexRequest indexRequest = new IndexRequest(); indexRequest.source("{}", XContentType.JSON); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withClass(SampleEntity.class) - .withIndexRequest(indexRequest).build(); + UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); assertThatThrownBy(() -> { - elasticsearchTemplate.update(updateQuery); + elasticsearchTemplate.update(updateQuery, index); }).isInstanceOf(DocumentMissingException.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java new file mode 100644 index 000000000..1d7650622 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2019 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; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +/** + * @author Peter-Josef Meisch + */ +class IndexCoordinatesTest { + + @Test + void cannotBeInitializedWithNullIndexName() { + assertThatThrownBy(() -> { + IndexCoordinates.of(null); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void cannotBeInitializedWithNullIndexNames() { + assertThatThrownBy(() -> { + IndexCoordinates.of((String[]) null); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void cannotBeInitializedWithEmptyIndexNames() { + assertThatThrownBy(() -> { + IndexCoordinates.of(new String[] {}); + }).isInstanceOf(IllegalArgumentException.class); + } + + @Test + void shouldHaveEmptyTypesWhenNotSet() { + IndexCoordinates indexCoordinates = IndexCoordinates.of("test"); + + assertThat(indexCoordinates.getTypeNames()).isEmpty(); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 0e033a625..be4a527f6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -53,6 +53,7 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class LogEntityTests { + private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes( "test-log-type"); @Autowired private ElasticsearchTemplate template; @BeforeEach @@ -73,7 +74,7 @@ public void before() throws ParseException { IndexQuery indexQuery4 = new LogEntityBuilder("4").action("update").date(dateFormatter.parse("2013-10-19 18:04")) .code(2).ip("10.10.10.4").buildIndex(); - template.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4)); + template.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index); template.refresh(LogEntity.class); } @@ -82,7 +83,7 @@ public void shouldIndexGivenLogEntityWithIPFieldType() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); - List entities = template.queryForList(searchQuery, LogEntity.class); + List entities = template.queryForList(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(1); @@ -95,7 +96,7 @@ public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); assertThatThrownBy(() -> { - List entities = template.queryForList(searchQuery, LogEntity.class); + List entities = template.queryForList(searchQuery, LogEntity.class, index); }).isInstanceOf(SearchPhaseExecutionException.class); } @@ -105,7 +106,7 @@ public void shouldReturnLogsForGivenIPRanges() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build(); - List entities = template.queryForList(searchQuery, LogEntity.class); + List entities = template.queryForList(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(3); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 1ef1c729e..e33821692 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -61,9 +61,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.test.context.ContextConfiguration; import org.springframework.util.StringUtils; /** @@ -76,7 +74,6 @@ * @author Martin Choraine */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) public class ReactiveElasticsearchTemplateTests { static final String DEFAULT_INDEX = "reactive-template-test-index"; @@ -139,8 +136,9 @@ public void insertWithIdShouldWork() { restTemplate.refresh(SampleEntity.class); - List result = restTemplate - .queryForList(new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class); + List result = restTemplate.queryForList( + new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, + IndexCoordinates.of(DEFAULT_INDEX)); assertThat(result).hasSize(1); } @@ -171,8 +169,8 @@ public void insertWithExplicitIndexNameShouldOverwriteMetadata() { .expectNextCount(1)// .verifyComplete(); - restTemplate.refresh(DEFAULT_INDEX); - restTemplate.refresh(ALTERNATE_INDEX); + restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); + restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX)); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse(); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue(); @@ -192,8 +190,9 @@ public void insertShouldAcceptPlainMapStructureAsSource() { @Test // DATAES-504 public void insertShouldErrorOnNullEntity() { - assertThatThrownBy(() -> template.save(null)).isInstanceOf(IllegalArgumentException.class); - + assertThatThrownBy(() -> { + template.save(null); + }).isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-519 @@ -245,7 +244,9 @@ public void findByIdShouldCompleteWhenNotingFound() { @Test // DATAES-504 public void findByIdShouldErrorForNullId() { - assertThatThrownBy(() -> template.findById(null, SampleEntity.class)).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> { + template.findById(null, SampleEntity.class); + }).isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-504 @@ -254,13 +255,12 @@ public void findByIdWithExplicitIndexNameShouldOverwriteMetadata() { SampleEntity sampleEntity = randomEntity("some message"); IndexQuery indexQuery = getIndexQuery(sampleEntity); - indexQuery.setIndexName(ALTERNATE_INDEX); - restTemplate.index(indexQuery); + restTemplate.index(indexQuery, IndexCoordinates.of(ALTERNATE_INDEX).withTypes( "test-type")); restTemplate.refresh(SampleEntity.class); - restTemplate.refresh(DEFAULT_INDEX); - restTemplate.refresh(ALTERNATE_INDEX); + restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); + restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX)); template.findById(sampleEntity.getId(), SampleEntity.class) // .as(StepVerifier::create) // @@ -586,8 +586,8 @@ public void shouldDeleteAcrossIndex() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(thisIndex); - restTemplate.refresh(thatIndex); + restTemplate.refresh(IndexCoordinates.of(thisIndex)); + restTemplate.refresh(IndexCoordinates.of(thatIndex)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "test")) // @@ -616,8 +616,8 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(thisIndex); - restTemplate.refresh(thatIndex); + restTemplate.refresh(IndexCoordinates.of(thisIndex)); + restTemplate.refresh(IndexCoordinates.of(thatIndex)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "negative")) // @@ -725,10 +725,12 @@ private List getIndexQueries(SampleEntity... sampleEntities) { private void index(SampleEntity... entities) { + IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes( "test-type"); + if (entities.length == 1) { - restTemplate.index(getIndexQuery(entities[0])); + restTemplate.index(getIndexQuery(entities[0]), indexCoordinates); } else { - restTemplate.bulkIndex(getIndexQueries(entities)); + restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates); } restTemplate.refresh(SampleEntity.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index 3789e67e0..af2005791 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -89,10 +90,11 @@ public void before() { .addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000) .score(40).buildIndex(); - elasticsearchTemplate.index(article1); - elasticsearchTemplate.index(article2); - elasticsearchTemplate.index(article3); - elasticsearchTemplate.index(article4); + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes( "article"); + elasticsearchTemplate.index(article1, index); + elasticsearchTemplate.index(article2, index); + elasticsearchTemplate.index(article3, index); + elasticsearchTemplate.index(article4, index); elasticsearchTemplate.refresh(ArticleEntity.class); } @@ -118,7 +120,7 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { public Aggregations extract(SearchResponse response) { return response.getAggregations(); } - }); + }, null, IndexCoordinates.of(INDEX_NAME).withTypes("article")); // then assertThat(aggregations).isNotNull(); assertThat(aggregations.asMap().get("subjects")).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 3a0f85696..5a554b07c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -32,6 +32,7 @@ import org.springframework.data.elasticsearch.annotations.CompletionField; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -66,7 +67,7 @@ private void loadCompletionObjectEntities() { indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[] { "Artur", "Konczak" }) .buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); elasticsearchTemplate.refresh(CompletionEntity.class); } @@ -88,7 +89,8 @@ private void loadAnnotatedCompletionObjectEntities() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class); } @@ -106,7 +108,8 @@ private void loadAnnotatedCompletionObjectEntitiesWithWeights() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4") .suggest(new String[] { "Mewes Kochheim4" }, Integer.MAX_VALUE).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class); } @@ -132,7 +135,8 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() { // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( - new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), CompletionEntity.class); + new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), + IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -152,7 +156,8 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEn // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( - new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), CompletionEntity.class); + new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), + IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -173,7 +178,7 @@ public void shouldFindSuggestionsWithWeightsForGivenCriteriaQueryUsingAnnotatedC // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - AnnotatedCompletionEntity.class); + IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index fbab48eb0..b29564e77 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.CompletionField; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -86,7 +87,8 @@ private void loadContextCompletionObjectEntities() { indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }, context4).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); elasticsearchTemplate.refresh(ContextCompletionEntity.class); } @@ -123,7 +125,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - ContextCompletionEntity.class); + IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -155,7 +157,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - ContextCompletionEntity.class); + IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -187,7 +189,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = elasticsearchTemplate.suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - ContextCompletionEntity.class); + IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java b/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java deleted file mode 100644 index 9b73cfda8..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/core/facet/ElasticsearchTemplateFacetTests.java +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright 2013-2019 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.facet; - -import static org.assertj.core.api.Assertions.*; -import static org.elasticsearch.index.query.QueryBuilders.*; - -import lombok.Data; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.annotation.Id; -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.InnerField; -import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.core.FacetedPage; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; -import org.springframework.data.elasticsearch.core.facet.request.HistogramFacetRequestBuilder; -import org.springframework.data.elasticsearch.core.facet.request.NativeFacetRequest; -import org.springframework.data.elasticsearch.core.facet.request.RangeFacetRequestBuilder; -import org.springframework.data.elasticsearch.core.facet.request.StatisticalFacetRequestBuilder; -import org.springframework.data.elasticsearch.core.facet.request.TermFacetRequestBuilder; -import org.springframework.data.elasticsearch.core.facet.result.HistogramResult; -import org.springframework.data.elasticsearch.core.facet.result.IntervalUnit; -import org.springframework.data.elasticsearch.core.facet.result.Range; -import org.springframework.data.elasticsearch.core.facet.result.RangeResult; -import org.springframework.data.elasticsearch.core.facet.result.StatisticalResult; -import org.springframework.data.elasticsearch.core.facet.result.Term; -import org.springframework.data.elasticsearch.core.facet.result.TermResult; -import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; -import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.utils.IndexInitializer; -import org.springframework.test.context.ContextConfiguration; - -/** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Jonathan Yan - * @author Artur Konczak - * @author Peter-Josef Meisch - */ -@SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) -public class ElasticsearchTemplateFacetTests { - - private static final String RIZWAN_IDREES = "Rizwan Idrees"; - private static final String MOHSIN_HUSEN = "Mohsin Husen"; - private static final String JONATHAN_YAN = "Jonathan Yan"; - private static final String ARTUR_KONCZAK = "Artur Konczak"; - private static final int YEAR_2002 = 2002; - private static final int YEAR_2001 = 2001; - private static final int YEAR_2000 = 2000; - private static final String PUBLISHED_YEARS = "publishedYears"; - - @Autowired private ElasticsearchTemplate elasticsearchTemplate; - - @BeforeEach - public void before() { - - IndexInitializer.init(elasticsearchTemplate, ArticleEntity.class); - - IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").addAuthor(RIZWAN_IDREES) - .addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10).buildIndex(); - IndexQuery article2 = new ArticleEntityBuilder("2").title("article three").addAuthor(RIZWAN_IDREES) - .addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addPublishedYear(YEAR_2000).score(20).buildIndex(); - IndexQuery article3 = new ArticleEntityBuilder("3").title("article two").addAuthor(RIZWAN_IDREES) - .addAuthor(ARTUR_KONCZAK).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(30).buildIndex(); - IndexQuery article4 = new ArticleEntityBuilder("4").title("article one").addAuthor(RIZWAN_IDREES) - .addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000).score(40).buildIndex(); - - elasticsearchTemplate.index(article1); - elasticsearchTemplate.index(article2); - elasticsearchTemplate.index(article3); - elasticsearchTemplate.index(article4); - elasticsearchTemplate.refresh(ArticleEntity.class); - } - - @Test - public void shouldReturnFacetedAuthorsForGivenQueryWithDefaultOrder() { - - // given - String facetName = "fauthors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES); - assertThat(term.getCount()).isEqualTo(4); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(term.getCount()).isEqualTo(2); - - term = facet.getTerms().get(3); - assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN); - assertThat(term.getCount()).isEqualTo(1); - - assertThat(facet.getTotal()).isEqualTo(4); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnFacetedAuthorsForGivenFilteredQuery() { - - // given - String facetName = "fauthors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").build()) - .build(); - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES); - assertThat(term.getCount()).isEqualTo(4); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(term.getCount()).isEqualTo(2); - - assertThat(facet.getTotal()).isEqualTo(4); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldExcludeTermsFromFacetedAuthorsForGivenQuery() { - - // given - String facetName = "fauthors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched") - .excludeTerms(RIZWAN_IDREES, ARTUR_KONCZAK).build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - - assertThat(facet.getTerms()).hasSize(2); - - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(term.getCount()).isEqualTo(2); - - Term term1 = facet.getTerms().get(1); - assertThat(term1.getTerm()).isEqualTo(JONATHAN_YAN); - assertThat(term1.getCount()).isEqualTo(1); - - assertThat(facet.getTotal()).isEqualTo(2); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnFacetedAuthorsForGivenQueryOrderedByTerm() { - - // given - String facetName = "fauthors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascTerm().build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN); - assertThat(term.getCount()).isEqualTo(1); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(term.getCount()).isEqualTo(2); - - term = facet.getTerms().get(3); - assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES); - assertThat(term.getCount()).isEqualTo(4); - - assertThat(facet.getTotal()).isEqualTo(4); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnFacetedAuthorsForGivenQueryOrderedByCountAsc() { - - // given - String facetName = "fauthors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).fields("authors.untouched").ascCount().build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(JONATHAN_YAN); - assertThat(term.getCount()).isEqualTo(1); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(term.getCount()).isEqualTo(2); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(3); - assertThat(term.getTerm()).isEqualTo(RIZWAN_IDREES); - assertThat(term.getCount()).isEqualTo(4); - - assertThat(facet.getTotal()).isEqualTo(4); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnFacetedYearsForGivenQuery() { - - // given - String facetName = "fyears"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(facetName).fields("publishedYears").descCount().build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - assertThat(facet.getTerms()).hasSize(3); - - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2000)); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2001)); - assertThat(term.getCount()).isEqualTo(2); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2002)); - assertThat(term.getCount()).isEqualTo(1); - - assertThat(facet.getTotal()).isEqualTo(3); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnExistingFacetedYearsForGivenQuery() { - - // given - String facetName = "fyears"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet( - new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("publishedYears").descCount().build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - assertThat(facet.getTerms()).hasSize(3); - - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2000)); - assertThat(term.getCount()).isEqualTo(3); - - term = facet.getTerms().get(1); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2001)); - assertThat(term.getCount()).isEqualTo(2); - - term = facet.getTerms().get(2); - assertThat(term.getTerm()).isEqualTo(Long.toString(YEAR_2002)); - assertThat(term.getCount()).isEqualTo(1); - - assertThat(facet.getTotal()).isEqualTo(3); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldThrowExeptionsForMultiFieldFacet() { - - // given - String facetName = "fyears"; - assertThatThrownBy(() -> { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet( - new TermFacetRequestBuilder(facetName).fields("publishedYears", "authors.untouched").ascTerm().build()) - .build(); - }).isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void shouldReturnFacetedYearsAndFacetedAuthorsForGivenQuery() { - - // given - String numberFacetName = "fAuthors"; - String stringFacetName = "fyears"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new TermFacetRequestBuilder(numberFacetName).fields("publishedYears").ascTerm().build()) - .withFacet(new TermFacetRequestBuilder(stringFacetName).fields("authors.untouched").ascTerm().build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult numberFacet = (TermResult) result.getFacet(numberFacetName); - assertThat(numberFacet.getTerms()).hasSize(3); - - Term numberTerm = numberFacet.getTerms().get(0); - assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2000)); - assertThat(numberTerm.getCount()).isEqualTo(3); - - numberTerm = numberFacet.getTerms().get(1); - assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2001)); - assertThat(numberTerm.getCount()).isEqualTo(2); - - numberTerm = numberFacet.getTerms().get(2); - assertThat(numberTerm.getTerm()).isEqualTo(Long.toString(YEAR_2002)); - assertThat(numberTerm.getCount()).isEqualTo(1); - - TermResult stringFacet = (TermResult) result.getFacet(stringFacetName); - Term stringTerm = stringFacet.getTerms().get(0); - assertThat(stringTerm.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(stringTerm.getCount()).isEqualTo(3); - - stringTerm = stringFacet.getTerms().get(1); - assertThat(stringTerm.getTerm()).isEqualTo(JONATHAN_YAN); - assertThat(stringTerm.getCount()).isEqualTo(1); - - stringTerm = stringFacet.getTerms().get(2); - assertThat(stringTerm.getTerm()).isEqualTo(MOHSIN_HUSEN); - assertThat(stringTerm.getCount()).isEqualTo(2); - - stringTerm = stringFacet.getTerms().get(3); - assertThat(stringTerm.getTerm()).isEqualTo(RIZWAN_IDREES); - assertThat(stringTerm.getCount()).isEqualTo(4); - - assertThat(stringFacet.getTotal()).isEqualTo(4); - assertThat(stringFacet.getOther()).isEqualTo(0); - assertThat(stringFacet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldThrowExceptionForNativeFacets() { - - // given - String facetName = "fyears"; - assertThatThrownBy(() -> { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new NativeFacetRequest()).build(); - }).isInstanceOf(UnsupportedOperationException.class); - } - - @Test - public void shouldFilterResultByRegexForGivenQuery() { - - // given - String facetName = "regex_authors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFacet( - new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").regex("Art.*").build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - - assertThat(facet.getTerms()).hasSize(1); - - Term term = facet.getTerms().get(0); - assertThat(term.getTerm()).isEqualTo(ARTUR_KONCZAK); - assertThat(term.getCount()).isEqualTo(3); - - assertThat(facet.getTotal()).isEqualTo(1); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnAllTermsForGivenQuery() { - - // given - String facetName = "all_authors"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet( - new TermFacetRequestBuilder(facetName).applyQueryFilter().fields("authors.untouched").allTerms().build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - TermResult facet = (TermResult) result.getFacet(facetName); - - assertThat(facet.getTerms()).hasSize(4); - - assertThat(facet.getTotal()).isEqualTo(4); - assertThat(facet.getOther()).isEqualTo(0); - assertThat(facet.getMissing()).isEqualTo(0); - } - - @Test - public void shouldReturnRangeFacetForGivenQuery() { - - // given - String facetName = "rangeYears"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new RangeFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).to(YEAR_2000) - .range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - RangeResult facet = (RangeResult) result.getFacet(facetName); - assertThat(facet.getRanges()).hasSize(3); - - Range range = facet.getRanges().get(0); - assertThat(range.getFrom()).isEqualTo(Double.NEGATIVE_INFINITY); - assertThat(range.getTo()).isEqualTo((double) YEAR_2000); - assertThat(range.getCount()).isEqualTo(0); - assertThat(range.getTotal()).isEqualTo(0.0); - - range = facet.getRanges().get(1); - assertThat(range.getFrom()).isEqualTo((double) YEAR_2000); - assertThat(range.getTo()).isEqualTo((double) YEAR_2002); - assertThat(range.getCount()).isEqualTo(3); - assertThat(range.getTotal()).isEqualTo(12004.0); - - range = facet.getRanges().get(2); - assertThat(range.getFrom()).isEqualTo((double) YEAR_2002); - assertThat(range.getTo()).isEqualTo(Double.POSITIVE_INFINITY); - assertThat(range.getCount()).isEqualTo(1); - assertThat(range.getTotal()).isEqualTo(6003.0); - } - - @Test - public void shouldReturnKeyValueRangeFacetForStringValuesInGivenQuery() { - - // given - String facetName = "rangeScoreOverYears"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new RangeFacetRequestBuilder(facetName).fields(PUBLISHED_YEARS, "score").to(YEAR_2000) - .range(YEAR_2000, YEAR_2002).from(YEAR_2002).build()) - .build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - RangeResult facet = (RangeResult) result.getFacet(facetName); - assertThat(facet.getRanges()).hasSize(3); - - Range range = facet.getRanges().get(0); - assertThat(range.getFrom()).isEqualTo(Double.NEGATIVE_INFINITY); - assertThat(range.getTo()).isEqualTo((double) YEAR_2000); - assertThat(range.getCount()).isEqualTo(0); - assertThat(range.getTotal()).isEqualTo(0.0); - - range = facet.getRanges().get(1); - assertThat(range.getFrom()).isEqualTo((double) YEAR_2000); - assertThat(range.getTo()).isEqualTo((double) YEAR_2002); - assertThat(range.getCount()).isEqualTo(3); - assertThat(range.getTotal()).isEqualTo(90.0); - - range = facet.getRanges().get(2); - assertThat(range.getFrom()).isEqualTo((double) YEAR_2002); - assertThat(range.getTo()).isEqualTo(Double.POSITIVE_INFINITY); - assertThat(range.getCount()).isEqualTo(1); - assertThat(range.getTotal()).isEqualTo(40.0); - } - - @Test - public void shouldReturnStatisticalFacetForGivenQuery() { - - // given - String facetName = "statPublishedYear"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new StatisticalFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - StatisticalResult facet = (StatisticalResult) result.getFacet(facetName); - assertThat(facet.getCount()).isEqualTo(6); - assertThat(facet.getMax()).isEqualTo(2002.0); - assertThat(facet.getMin()).isEqualTo(2000.0); - } - - @Test - public void shouldReturnHistogramFacetForGivenQuery() { - - // given - String facetName = "numberPublicationPerYear"; - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withFacet(new HistogramFacetRequestBuilder(facetName).field(PUBLISHED_YEARS).interval(1).build()).build(); - - // when - FacetedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - // then - assertThat(result.getNumberOfElements()).isEqualTo(4); - - HistogramResult facet = (HistogramResult) result.getFacet(facetName); - assertThat(facet.getIntervalUnit()).hasSize(3); - - IntervalUnit unit = facet.getIntervalUnit().get(0); - assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2000)); - assertThat(unit.getCount()).isEqualTo(3); - - unit = facet.getIntervalUnit().get(1); - assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2001)); - assertThat(unit.getCount()).isEqualTo(2); - - unit = facet.getIntervalUnit().get(2); - assertThat(unit.getKey()).isEqualTo(Long.valueOf(YEAR_2002)); - assertThat(unit.getCount()).isEqualTo(1); - } - - @Test - public void shouldNotThrowExceptionForNoFacets() { - - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - AggregatedPage result = elasticsearchTemplate.queryForPage(searchQuery, ArticleEntity.class); - - assertThat(result.hasFacets()).isEqualTo(false); - } - - /** - * Simple type to test facets - * - * @author Artur Konczak - * @author Mohsin Husen - */ - @Data - @Document(indexName = "test-index-articles-core-facet", type = "article", shards = 1, replicas = 0, - refreshInterval = "-1") - static class ArticleEntity { - - @Id private String id; - private String title; - @Field(type = FieldType.Text, fielddata = true) private String subject; - - @MultiField(mainField = @Field(type = FieldType.Text), - otherFields = { - @InnerField(suffix = "untouched", type = FieldType.Text, store = true, fielddata = true, - analyzer = "keyword"), - @InnerField(suffix = "sort", type = FieldType.Text, store = true, - analyzer = "keyword") }) private List authors = new ArrayList<>(); - - @Field(type = FieldType.Integer, store = true) private List publishedYears = new ArrayList<>(); - - private int score; - - private ArticleEntity() { - - } - - public ArticleEntity(String id) { - this.id = id; - } - } - - /** - * Simple type to test facets - * - * @author Artur Konczak - * @author Mohsin Husen - */ - static class ArticleEntityBuilder { - - private ArticleEntity result; - - public ArticleEntityBuilder(String id) { - result = new ArticleEntity(id); - } - - public ArticleEntityBuilder title(String title) { - result.setTitle(title); - return this; - } - - public ArticleEntityBuilder subject(String subject) { - result.setSubject(subject); - return this; - } - - public ArticleEntityBuilder addAuthor(String author) { - result.getAuthors().add(author); - return this; - } - - public ArticleEntityBuilder addPublishedYear(Integer year) { - result.getPublishedYears().add(year); - return this; - } - - public ArticleEntityBuilder score(int score) { - result.setScore(score); - return this; - } - - public ArticleEntity build() { - return result; - } - - public IndexQuery buildIndex() { - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(result.getId()); - indexQuery.setObject(result); - return indexQuery; - } - } - -} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index d879429db..90200df56 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -36,6 +36,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -61,6 +62,11 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class ElasticsearchTemplateGeoTests { + private final IndexCoordinates locationMarkerIndex = IndexCoordinates.of("test-index-location-marker-core-geo") + .withTypes("geo-annotation-point-type"); + private final IndexCoordinates authorMarkerIndex = IndexCoordinates.of("test-index-author-marker-core-geo") + .withTypes("geo-class-point-type"); + @Autowired private ElasticsearchTemplate elasticsearchTemplate; @BeforeEach @@ -77,7 +83,7 @@ private void loadClassBaseEntities() { .add(new AuthorMarkerEntityBuilder("1").name("Franck Marchand").location(45.7806d, 3.0875d).buildIndex()); indexQueries.add(new AuthorMarkerEntityBuilder("2").name("Mohsin Husen").location(51.5171d, 0.1062d).buildIndex()); indexQueries.add(new AuthorMarkerEntityBuilder("3").name("Rizwan Idrees").location(51.5171d, 0.1062d).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, authorMarkerIndex); elasticsearchTemplate.refresh(AuthorMarkerEntity.class); } @@ -109,7 +115,7 @@ private void loadAnnotationBaseEntities() { indexQueries.add(buildIndex(location2)); indexQueries.add(buildIndex(location3)); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, locationMarkerIndex); elasticsearchTemplate.refresh(LocationMarkerEntity.class); } @@ -134,7 +140,7 @@ public void shouldFindAuthorMarkersInRangeForGivenCriteriaQuery() { // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(1); @@ -151,7 +157,7 @@ public void shouldFindSelectedAuthorMarkerInRangeForGivenCriteriaQuery() { // when List geoAuthorsForGeoCriteria2 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery2, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria2).hasSize(1); @@ -167,7 +173,7 @@ public void shouldFindStringAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km")); // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(1); @@ -183,7 +189,7 @@ public void shouldFindDoubleAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(3); @@ -198,7 +204,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { new Criteria("locationAsArray").within("51.001000, 0.10100", "1km")); // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(3); @@ -213,7 +219,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQueryUsingGeohas // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(3); @@ -229,7 +235,7 @@ public void shouldFindAllMarkersForNativeSearchQuery() { // when List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(queryBuilder.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(3); @@ -245,7 +251,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoBox() { // when List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); @@ -263,7 +269,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeohash() { // when List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); @@ -281,7 +287,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoPoints() { // when List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); @@ -299,7 +305,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingPoints() { // when List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, - AuthorMarkerEntity.class); + AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); @@ -327,17 +333,17 @@ public void shouldFindLocationWithGeoHashPrefix() { // when List result1 = elasticsearchTemplate.queryForList(location1.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); List result2 = elasticsearchTemplate.queryForList(location2.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); List result3 = elasticsearchTemplate.queryForList(location3.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); List result4 = elasticsearchTemplate.queryForList(location4.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); List result5 = elasticsearchTemplate.queryForList(location5.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); List result11 = elasticsearchTemplate.queryForList(location11.build(), - LocationMarkerEntity.class); + LocationMarkerEntity.class, locationMarkerIndex); // then assertThat(result1).hasSize(3); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index f6cdd63bc..e9f6167cd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -51,6 +51,7 @@ import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -139,12 +140,16 @@ public void shouldAddStockPriceDocumentToIndex() { double price = 2.34; String id = "abc"; - elasticsearchTemplate - .index(buildIndex(StockPrice.builder().id(id).symbol(symbol).price(BigDecimal.valueOf(price)).build())); + IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes( "price"); + elasticsearchTemplate.index(buildIndex(StockPrice.builder() // + .id(id) // + .symbol(symbol) // + .price(BigDecimal.valueOf(price)) // + .build()), index); elasticsearchTemplate.refresh(StockPrice.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - List result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class); + List result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class, index); // Then assertThat(result).hasSize(1); @@ -186,12 +191,14 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() { Date createdDate = new Date(); String message = "msg"; String id = "abc"; - elasticsearchTemplate - .index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex()); + IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes( "mapping"); + elasticsearchTemplate.index( + new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(), + index); elasticsearchTemplate.refresh(SampleInheritedEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - List result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class); + List result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class, index); // then assertThat(result).hasSize(1); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 5edc74acb..1ae67095e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; @@ -54,6 +55,7 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class CriteriaQueryTests { + private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes( "test-type"); @Autowired private ElasticsearchTemplate elasticsearchTemplate; @BeforeEach @@ -78,13 +80,13 @@ public void shouldPerformAndOperation() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("test").and("message").contains("some")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -121,13 +123,13 @@ public void shouldPerformOrOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").or("message").contains("test")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -152,13 +154,13 @@ public void shouldPerformAndOperationWithinCriteria() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -184,12 +186,12 @@ public void shouldPerformOrOperationWithinCriteria() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -213,12 +215,12 @@ public void shouldPerformIsOperation() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -255,12 +257,12 @@ public void shouldPerformMultipleIsOperations() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -297,13 +299,13 @@ public void shouldPerformEndsWithOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").endsWith("end"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -339,13 +341,13 @@ public void shouldPerformStartsWithOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").startsWith("start"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -381,12 +383,12 @@ public void shouldPerformContainsOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -422,12 +424,12 @@ public void shouldExecuteExpression() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -463,13 +465,13 @@ public void shouldExecuteCriteriaChain() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -505,12 +507,12 @@ public void shouldPerformIsNotOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().isNegating()).isTrue(); @@ -549,12 +551,12 @@ public void shouldPerformBetweenOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity).isNotNull(); @@ -591,12 +593,12 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -634,12 +636,12 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -677,12 +679,12 @@ public void shouldPerformLessThanEqualOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -720,12 +722,12 @@ public void shouldPerformGreaterThanEquals() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -763,12 +765,12 @@ public void shouldPerformBoostOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -784,14 +786,14 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("a").or(new Criteria("message").contains("b"))); criteriaQuery.setMinScore(2.0F); - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class); + Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); @@ -811,13 +813,13 @@ public void shouldEscapeValue() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery); + elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class); + SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 65ae990f5..531b90751 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -32,6 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; @@ -107,9 +108,11 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build(); - long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class); + IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping").withTypes( "test-setting-type"); + long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class, + index); List entityList = elasticsearchTemplate.queryForList(searchQuery, - DynamicSettingAndMappingEntity.class); + DynamicSettingAndMappingEntity.class, index); // then assertThat(count).isEqualTo(1L); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 95d459bfc..2e8a0e53b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -26,6 +26,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -70,7 +71,7 @@ public void shouldDo() { // then NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); nativeSearchQuery.addIndices("test-index-abz-entity"); - long count = template.count(nativeSearchQuery); + long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(2); } @@ -87,7 +88,7 @@ public void shouldSupportSpelInType() { NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); nativeSearchQuery.addIndices("test-index-abz-entity"); nativeSearchQuery.addTypes("myType"); - long count = template.count(nativeSearchQuery); + long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(1); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 1daac206c..b2bb76daf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -22,21 +22,24 @@ import java.util.List; import org.elasticsearch.index.query.QueryBuilders; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * SynonymRepositoryTests @@ -44,15 +47,21 @@ * @author Artur Konczak * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:synonym-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { SynonymRepositoryTests.Config.class }) public class SynonymRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.synonym" }, + considerNestedRepositories = true) + static class Config {} + @Autowired private SynonymRepository repository; @Autowired private ElasticsearchTemplate elasticsearchTemplate; - @Before + @BeforeEach public void before() { IndexInitializer.init(elasticsearchTemplate, SynonymEntity.class); } @@ -76,7 +85,7 @@ public void shouldDo() { List synonymEntities = elasticsearchTemplate.queryForList( new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("text", "british")).build(), - SynonymEntity.class); + SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes( "synonym-type")); assertThat(synonymEntities).hasSize(1); } From 35e9b691bd4057bbc81c2c6f3bfbbedd404183aa Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 30 Nov 2019 15:49:14 +0100 Subject: [PATCH 0008/1191] DATAES-697_-_Query-refactoring-cleanup. Original PR: #347 --- .../core/AbstractElasticsearchTemplate.java | 41 +--- .../core/ElasticsearchOperations.java | 5 - .../core/ReactiveElasticsearchOperations.java | 229 ++++-------------- .../core/ReactiveElasticsearchTemplate.java | 203 ++++------------ .../elasticsearch/core/RequestFactory.java | 39 ++- .../core/query/AbstractQuery.java | 22 -- .../core/query/MoreLikeThisQuery.java | 21 +- .../core/query/NativeSearchQueryBuilder.java | 21 +- .../data/elasticsearch/core/query/Query.java | 32 --- ...tReactiveElasticsearchRepositoryQuery.java | 19 +- .../ReactiveElasticsearchQueryExecution.java | 39 ++- ...SimpleReactiveElasticsearchRepository.java | 31 +-- .../core/ElasticsearchTemplateTests.java | 96 +++----- .../ReactiveElasticsearchTemplateTests.java | 63 ++--- ...eactiveElasticsearchTemplateUnitTests.java | 25 +- ...ElasticsearchTemplateAggregationTests.java | 3 +- .../repositories/spel/SpELEntityTests.java | 3 - 17 files changed, 265 insertions(+), 627 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 83ee37678..806d52842 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -34,7 +34,6 @@ import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.util.Assert; @@ -53,6 +52,9 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper protected ElasticsearchConverter elasticsearchConverter; protected RequestFactory requestFactory; + /** + * @since 4.0 + */ public RequestFactory getRequestFactory() { return requestFactory; } @@ -197,43 +199,6 @@ protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { } } - /** - * @param query - * @param clazz - * @deprecated index names and types should not be set in query - */ - @Deprecated - protected void setPersistentEntityIndexAndType(Query query, Class clazz) { - if (query.getIndices().isEmpty()) { - String[] indices = retrieveIndexNameFromPersistentEntity(clazz); - - if (indices != null) { - query.addIndices(indices); - } - } - if (query.getTypes().isEmpty()) { - String[] types = retrieveTypeFromPersistentEntity(clazz); - - if (types != null) { - query.addTypes(types); - } - } - } - - private String[] retrieveIndexNameFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexName() }; - } - return null; - } - - private String[] retrieveTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return new String[] { getPersistentEntityFor(clazz).getIndexType() }; - } - return null; - } - @Override public List> queryForPage(List queries, Class clazz, IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 88625292a..ef467a408 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -483,11 +483,6 @@ default void refresh(Class clazz) { */ ElasticsearchConverter getElasticsearchConverter(); - /** - * @since 4.0 - */ - RequestFactory getRequestFactory(); - /** * @param clazz * @return the IndexCoordinates defined on the entity. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java index 617e172c7..947458f49 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java @@ -23,6 +23,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.lang.Nullable; @@ -72,35 +73,7 @@ default Mono save(Mono entityPublisher) { * @return a {@link Mono} emitting the saved entity. */ default Mono save(T entity) { - return save(entity, null); - } - - /** - * Index the entity, once available, in the given {@literal index}. If the index is {@literal null} or empty the index - * name provided via entity metadata is used. - * - * @param entityPublisher must not be {@literal null}. - * @param index the name of the target index. Can be {@literal null}. - * @param - * @return a {@link Mono} emitting the saved entity. - */ - default Mono save(Mono entityPublisher, String index) { - - Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); - return entityPublisher.flatMap(it -> save(it, index)); - } - - /** - * Index the entity in the given {@literal index}. If the index is {@literal null} or empty the index name provided - * via entity metadata is used. - * - * @param entity must not be {@literal null}. - * @param index the name of the target index. Can be {@literal null}. - * @param - * @return a {@link Mono} emitting the saved entity. - */ - default Mono save(T entity, @Nullable String index) { - return save(entity, index, null); + return save(entity, getIndexCoordinatesFor(entity.getClass())); } /** @@ -109,15 +82,14 @@ default Mono save(T entity, @Nullable String index) { * {@literal type}. * * @param entityPublisher must not be {@literal null}. - * @param index the name of the target index. Can be {@literal null}. - * @param type the name of the type within the index. Can be {@literal null}. + * @param index the target index, must not be {@literal null} * @param * @return a {@link Mono} emitting the saved entity. */ - default Mono save(Mono entityPublisher, @Nullable String index, @Nullable String type) { + default Mono save(Mono entityPublisher, IndexCoordinates index) { Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); - return entityPublisher.flatMap(it -> save(it, index, type)); + return entityPublisher.flatMap(it -> save(it, index)); } /** @@ -125,12 +97,11 @@ default Mono save(Mono entityPublisher, @Nullable String ind * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. * * @param entity must not be {@literal null}. - * @param index the name of the target index. Can be {@literal null}. - * @param type the name of the type within the index. Can be {@literal null}. + * @param index the target index, must not be {@literal null} * @param * @return a {@link Mono} emitting the saved entity. */ - Mono save(T entity, @Nullable String index, @Nullable String type); + Mono save(T entity, IndexCoordinates index); /** * Find the document with the given {@literal id} mapped onto the given {@literal entityType}. @@ -141,35 +112,18 @@ default Mono save(Mono entityPublisher, @Nullable String ind * @return {@link Mono#empty()} if not found. */ default Mono findById(String id, Class entityType) { - return findById(id, entityType, null); - } - - /** - * Fetch the entity with given {@literal id}. - * - * @param id the {@literal _id} of the document to fetch. - * @param entityType the domain type used for mapping the document. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param - * @return {@link Mono#empty()} if not found. - */ - default Mono findById(String id, Class entityType, @Nullable String index) { - return findById(id, entityType, index, null); + return findById(id, entityType, getIndexCoordinatesFor(entityType)); } /** * Fetch the entity with given {@literal id}. * * @param id must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @param * @return the {@link Mono} emitting the entity or signalling completion if none found. */ - Mono findById(String id, Class entityType, @Nullable String index, @Nullable String type); + Mono findById(String id, Class entityType, IndexCoordinates index); /** * Check if an entity with given {@literal id} exists. @@ -179,33 +133,17 @@ default Mono findById(String id, Class entityType, @Nullable String in * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. */ default Mono exists(String id, Class entityType) { - return exists(id, entityType, null); - } - - /** - * Check if an entity with given {@literal id} exists. - * - * @param id the {@literal _id} of the document to look for. - * @param entityType the domain type used. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. - */ - default Mono exists(String id, Class entityType, @Nullable String index) { - return exists(id, entityType, index, null); + return exists(id, entityType, getIndexCoordinatesFor(entityType)); } /** * Check if an entity with given {@literal id} exists. * * @param id the {@literal _id} of the document to look for. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. */ - Mono exists(String id, Class entityType, @Nullable String index, @Nullable String type); + Mono exists(String id, Class entityType, IndexCoordinates index); /** * Search the index for entities matching the given {@link Query query}.
@@ -235,7 +173,7 @@ default Flux find(Query query, Class entityType) { * @return a {@link Flux} emitting matching entities one by one. */ default Flux find(Query query, Class entityType, Class returnType) { - return find(query, entityType, null, null, returnType); + return find(query, entityType, returnType, getIndexCoordinatesFor(entityType)); } /** @@ -243,27 +181,12 @@ default Flux find(Query query, Class entityType, Class returnType) * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. - * @param - * @return a {@link Flux} emitting matching entities one by one. - */ - default Flux find(Query query, Class entityType, @Nullable String index) { - return find(query, entityType, index, null); - } - - /** - * Search the index for entities matching the given {@link Query query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @param * @returnm a {@link Flux} emitting matching entities one by one. */ - default Flux find(Query query, Class entityType, @Nullable String index, @Nullable String type) { - return find(query, entityType, index, type, entityType); + default Flux find(Query query, Class entityType, IndexCoordinates index) { + return find(query, entityType, entityType, index); } /** @@ -271,16 +194,12 @@ default Flux find(Query query, Class entityType, @Nullable String inde * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. * @param resultType the projection result type. + * @param index the target index, must not be {@literal null} * @param * @return a {@link Flux} emitting matching entities one by one. */ - Flux find(Query query, Class entityType, @Nullable String index, @Nullable String type, - Class resultType); + Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index); /** * Count the number of documents matching the given {@link Query}. @@ -289,7 +208,7 @@ Flux find(Query query, Class entityType, @Nullable String index, @Null * @return a {@link Mono} emitting the nr of matching documents. */ default Mono count(Class entityType) { - return count(new StringQuery(QueryBuilders.matchAllQuery().toString()), entityType, null); + return count(new StringQuery(QueryBuilders.matchAllQuery().toString()), entityType); } /** @@ -300,20 +219,7 @@ default Mono count(Class entityType) { * @return a {@link Mono} emitting the nr of matching documents. */ default Mono count(Query query, Class entityType) { - return count(query, entityType, null); - } - - /** - * Count the number of documents matching the given {@link Query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @return a {@link Mono} emitting the nr of matching documents. - */ - default Mono count(Query query, Class entityType, @Nullable String index) { - return count(query, entityType, index, null); + return count(query, entityType, getIndexCoordinatesFor(entityType)); } /** @@ -321,13 +227,10 @@ default Mono count(Query query, Class entityType, @Nullable String inde * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the nr of matching documents. */ - Mono count(Query query, Class entityType, @Nullable String index, @Nullable String type); + Mono count(Query query, Class entityType, IndexCoordinates index); /** * Delete the given entity extracting index and type from entity metadata. @@ -336,47 +239,30 @@ default Mono count(Query query, Class entityType, @Nullable String inde * @return a {@link Mono} emitting the {@literal id} of the removed document. */ default Mono delete(Object entity) { - return delete(entity, null); + return delete(entity, getIndexCoordinatesFor(entity.getClass())); } /** * Delete the given entity extracting index and type from entity metadata. * * @param entity must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - default Mono delete(Object entity, @Nullable String index) { - return delete(entity, index, null); - } - - /** - * Delete the given entity extracting index and type from entity metadata. - * - * @param entity must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - Mono delete(Object entity, @Nullable String index, @Nullable String type); + Mono delete(Object entity, IndexCoordinates index); /** * Delete the entity with given {@literal id}. * * @param id must not be {@literal null}. - * @param index the name of the target index. - * @param type the name of the target type. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - default Mono deleteById(String id, String index, String type) { + default Mono deleteById(String id, IndexCoordinates index) { Assert.notNull(index, "Index must not be null!"); - Assert.notNull(type, "Type must not be null!"); - return deleteById(id, Object.class, index, type); + return deleteById(id, Object.class, index); } /** @@ -387,20 +273,7 @@ default Mono deleteById(String id, String index, String type) { * @return a {@link Mono} emitting the {@literal id} of the removed document. */ default Mono deleteById(String id, Class entityType) { - return deleteById(id, entityType, null); - } - - /** - * Delete the entity with given {@literal id} extracting index and type from entity metadata. - * - * @param id must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - default Mono deleteById(String id, Class entityType, @Nullable String index) { - return deleteById(id, entityType, index, null); + return deleteById(id, entityType, getIndexCoordinatesFor(entityType)); } /** @@ -408,13 +281,10 @@ default Mono deleteById(String id, Class entityType, @Nullable String * * @param id must not be {@literal null}. * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - Mono deleteById(String id, Class entityType, @Nullable String index, @Nullable String type); + Mono deleteById(String id, Class entityType, IndexCoordinates index); /** * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. @@ -424,20 +294,7 @@ default Mono deleteById(String id, Class entityType, @Nullable String * @return a {@link Mono} emitting the number of the removed documents. */ default Mono deleteBy(Query query, Class entityType) { - return deleteBy(query, entityType, null); - } - - /** - * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @return a {@link Mono} emitting the number of the removed documents. - */ - default Mono deleteBy(Query query, Class entityType, @Nullable String index) { - return deleteBy(query, entityType, index, null); + return deleteBy(query, entityType, getIndexCoordinatesFor(entityType)); } /** @@ -445,13 +302,10 @@ default Mono deleteBy(Query query, Class entityType, @Nullable String i * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. - * @param index the name of the target index. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. - * @param type the name of the target type. Overwrites document metadata from {@literal entityType} if not - * {@literal null}. + * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the number of the removed documents. */ - Mono deleteBy(Query query, Class entityType, @Nullable String index, @Nullable String type); + Mono deleteBy(Query query, Class entityType, IndexCoordinates index); /** * Get the {@link ElasticsearchConverter} used. @@ -460,6 +314,19 @@ default Mono deleteBy(Query query, Class entityType, @Nullable String i */ ElasticsearchConverter getElasticsearchConverter(); + @Nullable + ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz); + + /** + * @param clazz + * @return the IndexCoordinates defined on the entity. + * @since 4.0 + */ + default IndexCoordinates getIndexCoordinatesFor(Class clazz) { + ElasticsearchPersistentEntity entity = getPersistentEntityFor(clazz); + return IndexCoordinates.of(entity.getIndexName()).withTypes(entity.getIndexType()); + } + /** * Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on * {@link ReactiveElasticsearchClient}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index f837f014f..92ced2299 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -17,14 +17,12 @@ import static org.elasticsearch.index.VersionType.*; -import lombok.NonNull; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.function.Supplier; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; @@ -87,9 +85,10 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera private final ReactiveElasticsearchClient client; private final ElasticsearchConverter converter; - private final @NonNull MappingContext, ElasticsearchPersistentProperty> mappingContext; + private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final ElasticsearchExceptionTranslator exceptionTranslator; private final EntityOperations operations; + protected RequestFactory requestFactory; private @Nullable RefreshPolicy refreshPolicy = RefreshPolicy.IMMEDIATE; private @Nullable IndicesOptions indicesOptions = IndicesOptions.strictExpandOpenAndForbidClosedIgnoreThrottled(); @@ -99,6 +98,8 @@ public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client) { } public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client, ElasticsearchConverter converter) { + Assert.notNull(client, "client must not be null"); + Assert.notNull(converter, "converter must not be null"); this.client = client; this.converter = converter; @@ -106,6 +107,7 @@ public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client, Elastic this.exceptionTranslator = new ElasticsearchExceptionTranslator(); this.operations = new EntityOperations(this.mappingContext); + this.requestFactory = new RequestFactory(converter); } /* @@ -119,33 +121,30 @@ public Publisher execute(ClientCallback> callback) { /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#index(Object, String, String) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#index(Object, IndexCoordinates) */ @Override - public Mono save(T entity, @Nullable String index, @Nullable String type) { + public Mono save(T entity, IndexCoordinates index) { Assert.notNull(entity, "Entity must not be null!"); AdaptibleEntity adaptableEntity = operations.forEntity(entity, converter.getConversionService()); - return doIndex(entity, adaptableEntity, index, type) // + return doIndex(entity, adaptableEntity, index) // .map(it -> { return adaptableEntity.populateIdIfNecessary(it.getId()); }); } - private Mono doIndex(Object value, AdaptibleEntity entity, @Nullable String index, - @Nullable String type) { + private Mono doIndex(Object value, AdaptibleEntity entity, IndexCoordinates index) { return Mono.defer(() -> { Object id = entity.getId(); - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - IndexRequest request = id != null - ? new IndexRequest(indexCoordinates.getIndexName(), indexCoordinates.getTypeName(), converter.convertId(id)) - : new IndexRequest(indexCoordinates.getIndexName(), indexCoordinates.getTypeName()); + ? new IndexRequest(index.getIndexName(), index.getTypeName(), converter.convertId(id)) + : new IndexRequest(index.getIndexName(), index.getTypeName()); request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); @@ -165,69 +164,60 @@ private Mono doIndex(Object value, AdaptibleEntity entity, @Nu /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#findById(String, Class, String, String) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#findById(String, Class, IndexCoordinates) */ @Override - public Mono findById(String id, Class entityType, @Nullable String index, @Nullable String type) { + public Mono findById(String id, Class entityType, IndexCoordinates index) { Assert.notNull(id, "Id must not be null!"); - return doFindById(id, getPersistentEntity(entityType), index, type) + return doFindById(id, getPersistentEntityFor(entityType), index) .map(it -> converter.mapDocument(DocumentAdapters.from(it), entityType)); } - private Mono doFindById(String id, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { + private Mono doFindById(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { return Mono.defer(() -> { - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - - return doFindById(new GetRequest(indexCoordinates.getIndexName(), indexCoordinates.getTypeName(), id)); + return doFindById(new GetRequest(index.getIndexName(), index.getTypeName(), id)); }); } /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exists(String, Class, String, String) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exists(String, Class, String, String) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exists(String, Class, IndexCoordinates) */ @Override - public Mono exists(String id, Class entityType, String index, String type) { + public Mono exists(String id, Class entityType, IndexCoordinates index) { Assert.notNull(id, "Id must not be null!"); - return doExists(id, getPersistentEntity(entityType), index, type); + return doExists(id, getPersistentEntityFor(entityType), index); } - private Mono doExists(String id, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { - - return Mono.defer(() -> { - - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); + private Mono doExists(String id, ElasticsearchPersistentEntity entity, @Nullable IndexCoordinates index) { - return doExists(new GetRequest(indexCoordinates.getIndexName(), indexCoordinates.getTypeName(), id)); - }); + return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), index.getTypeName(), id))); } /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#find(Query, Class, String, String, Class) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#find(Query, Class, Class, IndexCoordinates) */ @Override - public Flux find(Query query, Class entityType, @Nullable String index, @Nullable String type, - Class resultType) { + public Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index) { - return doFind(query, getPersistentEntity(entityType), index, type) - .map(it -> converter.mapDocument(DocumentAdapters.from(it), resultType)); + return doFind(query, entityType, index).map(it -> converter.mapDocument(DocumentAdapters.from(it), resultType)); } - private Flux doFind(Query query, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { + private Flux doFind(Query query, Class clazz, IndexCoordinates index) { return Flux.defer(() -> { - SearchRequest request = prepareSearchRequest(buildSearchRequest(query, entity, index, type)); + SearchRequest request = requestFactory.searchRequest(query, clazz, index); + + if (indicesOptions != null) { + request.indicesOptions(indicesOptions); + } if (query.getPageable().isPaged() || query.isLimiting()) { return doFind(request); @@ -238,26 +228,23 @@ private Flux doFind(Query query, ElasticsearchPersistentEntity ent } @Override - public Mono count(Query query, Class entityType, String index, String type) { - return doCount(query, getPersistentEntity(entityType), index, type); + public Mono count(Query query, Class entityType, IndexCoordinates index) { + return doCount(query, getPersistentEntityFor(entityType), index); } - private Mono doCount(Query query, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { + private Mono doCount(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { return Mono.defer(() -> { - CountRequest countRequest = buildCountRequest(query, entity, index, type); + CountRequest countRequest = buildCountRequest(query, entity, index); CountRequest request = prepareCountRequest(countRequest); return doCount(request); }); } - private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { + private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - CountRequest request = new CountRequest(indices(query, indexCoordinates::getIndexName)); + CountRequest request = new CountRequest(index.getIndexNames()); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(mappedQuery(query, entity)); searchSourceBuilder.trackScores(query.getTrackScores()); @@ -292,131 +279,60 @@ private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntit return request; } - private SearchRequest buildSearchRequest(Query query, ElasticsearchPersistentEntity entity, @Nullable String index, - @Nullable String type) { - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - SearchRequest request = new SearchRequest(indices(query, indexCoordinates::getIndexName)); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - searchSourceBuilder.query(mappedQuery(query, entity)); - searchSourceBuilder.version(entity.hasVersionProperty()); - searchSourceBuilder.trackScores(query.getTrackScores()); - - QueryBuilder postFilterQuery = mappedFilterQuery(query, entity); - if (postFilterQuery != null) { - searchSourceBuilder.postFilter(postFilterQuery); - } - - if (query.getSourceFilter() != null) { - searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); - } - - if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { - searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); - } - - sort(query, entity).forEach(searchSourceBuilder::sort); - - if (query.getMinScore() > 0) { - searchSourceBuilder.minScore(query.getMinScore()); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); - } - - if (query.getPreference() != null) { - request.preference(query.getPreference()); - } - - if (query.getSearchType() != null) { - request.searchType(query.getSearchType()); - } - - Pageable pageable = query.getPageable(); - - if (pageable.isPaged()) { - - long offset = pageable.getOffset(); - if (offset > Integer.MAX_VALUE) { - throw new IllegalArgumentException(String.format("Offset must not be more than %s", Integer.MAX_VALUE)); - } - - searchSourceBuilder.from((int) offset); - searchSourceBuilder.size(pageable.getPageSize()); - - request.source(searchSourceBuilder); - request.source(searchSourceBuilder); - } else if (query.isLimiting()) { - searchSourceBuilder.from(0); - searchSourceBuilder.size(query.getMaxResults()); - - request.source(searchSourceBuilder); - } else { - request.source(searchSourceBuilder); - } - return request; - } - /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(Object, String, String) */ @Override - public Mono delete(Object entity, @Nullable String index, @Nullable String type) { + public Mono delete(Object entity, IndexCoordinates index) { Entity elasticsearchEntity = operations.forEntity(entity); return Mono.defer(() -> doDeleteById(entity, converter.convertId(elasticsearchEntity.getId()), - elasticsearchEntity.getPersistentEntity(), index, type)); + elasticsearchEntity.getPersistentEntity(), index)); } /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(String, Class, String, String) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(String, Class, IndexCoordinates) */ @Override - public Mono deleteById(String id, Class entityType, @Nullable String index, @Nullable String type) { + public Mono deleteById(String id, Class entityType, IndexCoordinates index) { Assert.notNull(id, "Id must not be null!"); - return doDeleteById(null, id, getPersistentEntity(entityType), index, type); + return doDeleteById(null, id, getPersistentEntityFor(entityType), index); } private Mono doDeleteById(@Nullable Object source, String id, ElasticsearchPersistentEntity entity, - @Nullable String index, @Nullable String type) { + IndexCoordinates index) { return Mono.defer(() -> { - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - - return doDelete(prepareDeleteRequest(source, - new DeleteRequest(indexCoordinates.getIndexName(), indexCoordinates.getTypeName(), id))); + return doDelete(prepareDeleteRequest(source, new DeleteRequest(index.getIndexName(), index.getTypeName(), id))); }); } /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#deleteBy(Query, Class, String, String) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#deleteBy(Query, Class, IndexCoordinates) */ @Override - public Mono deleteBy(Query query, Class entityType, String index, String type) { + public Mono deleteBy(Query query, Class entityType, IndexCoordinates index) { Assert.notNull(query, "Query must not be null!"); - return doDeleteBy(query, getPersistentEntity(entityType), index, type).map(BulkByScrollResponse::getDeleted) + return doDeleteBy(query, getPersistentEntityFor(entityType), index).map(BulkByScrollResponse::getDeleted) .publishNext(); } private Flux doDeleteBy(Query query, ElasticsearchPersistentEntity entity, - @Nullable String index, @Nullable String type) { + IndexCoordinates index) { return Flux.defer(() -> { - - IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); - - DeleteByQueryRequest request = new DeleteByQueryRequest(indices(query, indexCoordinates::getIndexName)); - request.types(indexTypes(query, indexCoordinates::getTypeName)); + DeleteByQueryRequest request = new DeleteByQueryRequest(index.getIndexNames()); + request.types(index.getTypeNames()); request.setQuery(mappedQuery(query, entity)); return doDeleteBy(prepareDeleteByRequest(request)); @@ -675,24 +591,6 @@ protected Mono doDeleteBy(DeleteByQueryRequest request) { // private helpers - private static String[] indices(Query query, Supplier index) { - - if (query.getIndices().isEmpty()) { - return new String[] { index.get() }; - } - - return query.getIndices().toArray(new String[0]); - } - - private static String[] indexTypes(Query query, Supplier indexType) { - - if (query.getTypes().isEmpty()) { - return new String[] { indexType.get() }; - } - - return query.getTypes().toArray(new String[0]); - } - private static List sort(Query query, ElasticsearchPersistentEntity entity) { if (query.getSort() == null || query.getSort().isUnsorted()) { @@ -749,8 +647,9 @@ private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntit return null; } + @Override @Nullable - private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class type) { + public ElasticsearchPersistentEntity getPersistentEntityFor(@Nullable Class type) { return type != null ? mappingContext.getPersistentEntity(type) : null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 00e94d0a1..e1b880015 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -604,17 +604,7 @@ private SearchRequest prepareSearchRequest(Query query, Optional b } if (query instanceof NativeSearchQuery) { - NativeSearchQuery nativeSearchQuery = (NativeSearchQuery) query; - - if (!nativeSearchQuery.getScriptFields().isEmpty()) { - for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { - sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script()); - } - } - - if (nativeSearchQuery.getCollapseBuilder() != null) { - sourceBuilder.collapse(nativeSearchQuery.getCollapseBuilder()); - } + prepareNativeSearch((NativeSearchQuery) query, sourceBuilder); } @@ -681,6 +671,33 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli return searchRequestBuilder; } + private void prepareNativeSearch(NativeSearchQuery query, SearchSourceBuilder sourceBuilder) { + NativeSearchQuery nativeSearchQuery = query; + + if (!nativeSearchQuery.getScriptFields().isEmpty()) { + for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { + sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script()); + } + } + + if (nativeSearchQuery.getCollapseBuilder() != null) { + sourceBuilder.collapse(nativeSearchQuery.getCollapseBuilder()); + } + + if (!isEmpty(nativeSearchQuery.getIndicesBoost())) { + for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) { + sourceBuilder.indexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); + } + } + + if (!isEmpty(nativeSearchQuery.getAggregations())) { + for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) { + sourceBuilder.aggregation(aggregationBuilder); + } + } + + } + private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, NativeSearchQuery nativeSearchQuery) { if (!isEmpty(nativeSearchQuery.getScriptFields())) { for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 52968b281..1c2a106d7 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -42,8 +42,6 @@ abstract class AbstractQuery implements Query { protected Pageable pageable = DEFAULT_PAGE; protected Sort sort; - protected List indices = new ArrayList<>(); - protected List types = new ArrayList<>(); protected List fields = new ArrayList<>(); protected SourceFilter sourceFilter; protected float minScore; @@ -84,26 +82,6 @@ public List getFields() { return fields; } - @Override - public List getIndices() { - return indices; - } - - @Override - public void addIndices(String... indices) { - addAll(this.indices, indices); - } - - @Override - public void addTypes(String... types) { - addAll(this.types, types); - } - - @Override - public List getTypes() { - return types; - } - @Override public void addSourceFilter(SourceFilter sourceFilter) { this.sourceFilter = sourceFilter; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java index 0eb0f5357..f8b9c3aba 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java @@ -15,7 +15,7 @@ */ package org.springframework.data.elasticsearch.core.query; -import static java.util.Collections.addAll; +import static java.util.Collections.*; import static org.springframework.data.elasticsearch.core.query.AbstractQuery.*; import java.util.ArrayList; @@ -28,12 +28,11 @@ * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class MoreLikeThisQuery { private String id; - private String indexName; - private String type; private List searchIndices = new ArrayList<>(); private List searchTypes = new ArrayList<>(); private List fields = new ArrayList<>(); @@ -57,22 +56,6 @@ public void setId(String id) { this.id = id; } - public String getIndexName() { - return indexName; - } - - public void setIndexName(String indexName) { - this.indexName = indexName; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - public List getSearchIndices() { return searchIndices; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java index 5a8412549..4c682653e 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java @@ -42,6 +42,7 @@ * @author Jean-Baptiste Nizet * @author Martin Choraine * @author Farid Azaza + * @author Peter-Josef Meisch */ public class NativeSearchQueryBuilder { @@ -53,8 +54,6 @@ public class NativeSearchQueryBuilder { private HighlightBuilder highlightBuilder; private HighlightBuilder.Field[] highlightFields; private Pageable pageable = Pageable.unpaged(); - private String[] indices; - private String[] types; private String[] fields; private SourceFilter sourceFilter; private CollapseBuilder collapseBuilder; @@ -117,16 +116,6 @@ public NativeSearchQueryBuilder withPageable(Pageable pageable) { return this; } - public NativeSearchQueryBuilder withIndices(String... indices) { - this.indices = indices; - return this; - } - - public NativeSearchQueryBuilder withTypes(String... types) { - this.types = types; - return this; - } - public NativeSearchQueryBuilder withFields(String... fields) { this.fields = fields; return this; @@ -184,14 +173,6 @@ public NativeSearchQuery build() { nativeSearchQuery.setPageable(pageable); nativeSearchQuery.setTrackScores(trackScores); - if (indices != null) { - nativeSearchQuery.addIndices(indices); - } - - if (types != null) { - nativeSearchQuery.addTypes(types); - } - if (fields != null) { nativeSearchQuery.addFields(fields); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 29ca79549..581b6734e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -81,38 +81,6 @@ static Query findAll() { */ Sort getSort(); - /** - * Get Indices to be searched - * - * @return - */ - @Deprecated - List getIndices(); - - /** - * Add Indices to be added as part of search request - * - * @param indices - */ - @Deprecated - void addIndices(String... indices); - - /** - * Add types to be searched - * - * @param types - */ - @Deprecated - void addTypes(String... types); - - /** - * Get types to be searched - * - * @return - */ - @Deprecated - List getTypes(); - /** * Add fields to be added as part of search request * diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index 345f670b8..397794ff4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -20,6 +20,7 @@ import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; @@ -36,6 +37,7 @@ * AbstractElasticsearchRepositoryQuery * * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ abstract class AbstractReactiveElasticsearchRepositoryQuery implements RepositoryQuery { @@ -79,14 +81,15 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) { Query query = createQuery( new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor)); - Class typeToRead = processor.getReturnedType().getTypeToRead(); + Class targetType = processor.getReturnedType().getTypeToRead(); String indexName = queryMethod.getEntityInformation().getIndexName(); String indexTypeName = queryMethod.getEntityInformation().getIndexTypeName(); + IndexCoordinates index = IndexCoordinates.of(indexName).withTypes(indexTypeName); ReactiveElasticsearchQueryExecution execution = getExecution(parameterAccessor, new ResultProcessingConverter(processor, elasticsearchOperations)); - return execution.execute(query, processor.getReturnedType().getDomainType(), indexName, indexTypeName, typeToRead); + return execution.execute(query, processor.getReturnedType().getDomainType(), targetType, index); } private ReactiveElasticsearchQueryExecution getExecution(ElasticsearchParameterAccessor accessor, @@ -106,15 +109,17 @@ private ReactiveElasticsearchQueryExecution getExecutionToWrap(ElasticsearchPara ReactiveElasticsearchOperations operations) { if (isDeleteQuery()) { - return (q, t, i, it, tt) -> operations.deleteBy(q, t, i, it); + return (query, type, targetType, indexCoordinates) -> operations.deleteBy(query, type, indexCoordinates); } else if (isCountQuery()) { - return (q, t, i, it, tt) -> operations.count(q, t, i, it); + return (query, type, targetType, indexCoordinates) -> operations.count(query, type, indexCoordinates); } else if (isExistsQuery()) { - return (q, t, i, it, tt) -> operations.count(q, t, i, it).map(count -> count > 0); + return (query, type, targetType, indexCoordinates) -> operations.count(query, type, indexCoordinates) + .map(count -> count > 0); } else if (queryMethod.isCollectionQuery()) { - return (q, t, i, it, tt) -> operations.find(q.setPageable(accessor.getPageable()), t, i, it, tt); + return (query, type, targetType, indexCoordinates) -> operations.find(query.setPageable(accessor.getPageable()), + type, targetType, indexCoordinates); } else { - return (q, t, i, it, tt) -> operations.find(q, t, i, it, tt); + return (query, type, targetType, indexCoordinates) -> operations.find(query, type, targetType, indexCoordinates); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java index 960a43ebf..af02d8080 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java @@ -15,39 +15,46 @@ */ package org.springframework.data.elasticsearch.repository.query; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - import org.springframework.core.convert.converter.Converter; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public interface ReactiveElasticsearchQueryExecution { - Object execute(Query query, Class type, String indexName, String indexType, @Nullable Class targetType); + Object execute(Query query, Class type, @Nullable Class targetType, IndexCoordinates indexCoordinates); /** * An {@link ReactiveElasticsearchQueryExecution} that wraps the results of the given delegate with the given result * processing. */ - @RequiredArgsConstructor final class ResultProcessingExecution implements ReactiveElasticsearchQueryExecution { - private final @NonNull ReactiveElasticsearchQueryExecution delegate; - private final @NonNull Converter converter; + private final ReactiveElasticsearchQueryExecution delegate; + private final Converter converter; + + public ResultProcessingExecution(ReactiveElasticsearchQueryExecution delegate, + Converter converter) { + Assert.notNull(delegate, "delegate must not be null"); + Assert.notNull(converter, "converter must not be null"); + this.delegate = delegate; + this.converter = converter; + } @Override - public Object execute(Query query, Class type, String indexName, String indexType, - @Nullable Class targetType) { - return converter.convert(delegate.execute(query, type, indexName, indexType, targetType)); + public Object execute(Query query, Class type, @Nullable Class targetType, + IndexCoordinates indexCoordinates) { + return converter.convert(delegate.execute(query, type, targetType, indexCoordinates)); } } @@ -56,11 +63,17 @@ public Object execute(Query query, Class type, String indexName, String index * * @author Mark Paluch */ - @RequiredArgsConstructor final class ResultProcessingConverter implements Converter { - private final @NonNull ResultProcessor processor; - private final @NonNull ReactiveElasticsearchOperations operations; + private final ResultProcessor processor; + private final ReactiveElasticsearchOperations operations; + + public ResultProcessingConverter(ResultProcessor processor, ReactiveElasticsearchOperations operations) { + Assert.notNull(processor, "processor must not be null"); + Assert.notNull(operations, "operations must not be null"); + this.processor = processor; + this.operations = operations; + } /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index fd503eb31..de2e74a47 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -20,6 +20,7 @@ import org.reactivestreams.Publisher; import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; @@ -27,12 +28,14 @@ /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class SimpleReactiveElasticsearchRepository implements ReactiveElasticsearchRepository { private final ElasticsearchEntityInformation entityInformation; private final ReactiveElasticsearchOperations elasticsearchOperations; + private final IndexCoordinates index; public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation entityInformation, ReactiveElasticsearchOperations elasticsearchOperations) { @@ -42,20 +45,20 @@ public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation findAll(Sort sort) { - return elasticsearchOperations.find(Query.findAll().addSort(sort), entityInformation.getJavaType(), - entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.find(Query.findAll().addSort(sort), entityInformation.getJavaType(), index); } @Override public Mono save(S entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.save(entity, entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.save(entity, index); } @Override @@ -76,8 +79,7 @@ public Flux saveAll(Publisher entityStream) { public Mono findById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), - entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), index); } @Override @@ -91,8 +93,7 @@ public Mono findById(Publisher id) { public Mono existsById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), - entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), index); } @Override @@ -105,8 +106,7 @@ public Mono existsById(Publisher id) { @Override public Flux findAll() { - return elasticsearchOperations.find(Query.findAll(), entityInformation.getJavaType(), - entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.find(Query.findAll(), entityInformation.getJavaType(), index); } @Override @@ -127,17 +127,14 @@ public Flux findAllById(Publisher idStream) { @Override public Mono count() { - return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), - entityInformation.getIndexName(), entityInformation.getType()); + return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), index); } @Override public Mono deleteById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations - .deleteById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexName(), - entityInformation.getType()) // + return elasticsearchOperations.deleteById(convertId(id), entityInformation.getJavaType(), index) // .then(); } @@ -152,7 +149,7 @@ public Mono deleteById(Publisher id) { public Mono delete(T entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.delete(entity, entityInformation.getIndexName(), entityInformation.getType()) // + return elasticsearchOperations.delete(entity, index) // .then(); } @@ -173,9 +170,7 @@ public Mono deleteAll(Publisher entityStream) { @Override public Mono deleteAll() { - return elasticsearchOperations - .deleteBy(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexName(), - entityInformation.getType()) // + return elasticsearchOperations.deleteBy(Query.findAll(), entityInformation.getJavaType(), index) // .then(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 5c6971cc3..67a8cf400 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -344,7 +344,7 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); + .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); Page entities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); @@ -512,9 +512,7 @@ public void shouldDeleteAcrossIndex() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")) - .withIndices(INDEX_1_NAME, INDEX_2_NAME) // - .build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")).build(); assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME))).isEqualTo(0); } @@ -548,9 +546,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")) - .withIndices(INDEX_1_NAME, INDEX_2_NAME) // - .build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")).build(); assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of("test-index-*"))).isEqualTo(2); } @@ -953,8 +949,8 @@ public void shouldReturnSpecifiedFields() { elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") + .build(); // when Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -986,7 +982,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { sourceFilter.withIncludes("message"); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withSourceFilter(sourceFilter.build()).build(); + .withSourceFilter(sourceFilter.build()).build(); // when Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -1049,8 +1045,6 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, @@ -1077,7 +1071,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); + .withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); @@ -1101,8 +1095,6 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); @@ -1130,9 +1122,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite elasticsearchTemplate.refresh(SampleEntity.class); // then - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withFields("message").withQuery(matchAllQuery()) - .withPageable(PageRequest.of(0, 10)).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") + .withQuery(matchAllQuery()).withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); @@ -1158,8 +1149,6 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, @@ -1187,7 +1176,7 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); + .withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); @@ -1266,8 +1255,6 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); CloseableIterator stream = elasticsearchTemplate.stream(criteriaQuery, SampleEntity.class, index); @@ -1456,8 +1443,8 @@ public void shouldUseUpsertOnUpdate() throws IOException { .withUpdateRequest(updateRequest).build(); // when - UpdateRequest request = elasticsearchTemplate.getRequestFactory().updateRequest(updateQuery, - IndexCoordinates.of("index")); + UpdateRequest request = ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory() + .updateRequest(updateQuery, IndexCoordinates.of("index")); // then assertThat(request).isNotNull(); @@ -1478,8 +1465,8 @@ public void shouldReturnSourceWhenRequested() throws IOException { .withUpdateRequest(updateRequest).build(); // when - UpdateRequest request = elasticsearchTemplate.getRequestFactory().updateRequest(updateQuery, - IndexCoordinates.of("index")); + UpdateRequest request = ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory() + .updateRequest(updateQuery, IndexCoordinates.of("index")); // then assertThat(request).isNotNull(); @@ -1524,7 +1511,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); + .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); List entities = new ArrayList<>(); @@ -1643,7 +1630,7 @@ public void shouldIndexDocumentForSpecifiedSource() { elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); + .build(); // then Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -1672,7 +1659,7 @@ public void shouldReturnIds() { elasticsearchTemplate.bulkIndex(entities, index); elasticsearchTemplate.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 100)).build(); + .withPageable(PageRequest.of(0, 100)).build(); // then List ids = elasticsearchTemplate.queryForIds(searchQuery, SampleEntity.class, index); assertThat(ids).hasSize(30); @@ -1693,7 +1680,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withMinScore(2.0F).build(); + .withMinScore(2.0F).build(); Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -1823,8 +1810,7 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { elasticsearchTemplate.refresh(index); // then - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) - .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, Map.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); @@ -1847,8 +1833,7 @@ public void shouldIndexGteEntityWithVersionType() { elasticsearchTemplate.index(indexQueryBuilder.build(), index); elasticsearchTemplate.refresh(index); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) - .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when Page entities = elasticsearchTemplate.queryForPage(searchQuery, GTEVersionEntity.class, index); // then @@ -1878,8 +1863,7 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withIndices(INDEX_NAME_SAMPLE_ENTITY) - .withTypes(TYPE_NAME).withQuery(matchAllQuery()).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -1901,7 +1885,6 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQue elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); // when long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class, index); @@ -1921,8 +1904,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class, index); @@ -1943,12 +1925,10 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); // when - long count = elasticsearchTemplate.count(criteriaQuery, index); + // then assertThat(count).isEqualTo(1); } @@ -1964,8 +1944,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearch IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery, index); elasticsearchTemplate.refresh(SampleEntity.class); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when long count = elasticsearchTemplate.count(searchQuery, index); @@ -1997,7 +1976,6 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_1_NAME, INDEX_2_NAME); // when long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); @@ -2028,8 +2006,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); @@ -2096,7 +2073,6 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.addIndices(INDEX_1_NAME); // when long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME)); @@ -2127,8 +2103,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(INDEX_1_NAME) - .build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME)); @@ -2264,8 +2239,7 @@ public void shouldTestResultsAcrossMultipleIndices() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when List sampleEntities = elasticsearchTemplate.queryForList(searchQuery, SampleEntity.class, @@ -2294,8 +2268,7 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withTypes("hetro") - .withIndices(INDEX_1_NAME, INDEX_2_NAME).build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); @@ -2444,8 +2417,6 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("message")); - criteriaQuery.addIndices(INDEX_NAME_SAMPLE_ENTITY); - criteriaQuery.addTypes(TYPE_NAME); criteriaQuery.setPageable(PageRequest.of(0, 10)); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, @@ -2482,7 +2453,7 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)).build(); + .withPageable(PageRequest.of(0, 10)).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); @@ -2512,8 +2483,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { SourceFilter sourceFilter = new FetchSourceFilter(new String[] { "id" }, new String[] {}); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withPageable(PageRequest.of(0, 10)) - .withSourceFilter(sourceFilter).build(); + .withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build(); ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); @@ -2638,8 +2608,8 @@ public void shouldReturnDocumentWithCollapsedField() { elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(SampleEntity.class); - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withIndices(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME).withCollapseField("rate").build(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withCollapseField("rate") + .build(); // when Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); @@ -2770,8 +2740,6 @@ public void shouldAddAliasWithGivenRoutingValue() { NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // - .withIndices(alias) // - .withTypes(TYPE_NAME) // .build(); long count = elasticsearchTemplate.count(query, IndexCoordinates.of(alias)); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index e33821692..3b3193ffd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -163,14 +163,15 @@ public void insertWithAutogeneratedIdShouldUpdateEntityId() { public void insertWithExplicitIndexNameShouldOverwriteMetadata() { SampleEntity sampleEntity = randomEntity("in another index"); + IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX); - template.save(sampleEntity, ALTERNATE_INDEX) // + template.save(sampleEntity, alternateIndex) // .as(StepVerifier::create)// .expectNextCount(1)// .verifyComplete(); restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); - restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX)); + restTemplate.refresh(alternateIndex); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse(); assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue(); @@ -181,7 +182,7 @@ public void insertShouldAcceptPlainMapStructureAsSource() { Map map = new LinkedHashMap<>(Collections.singletonMap("foo", "bar")); - template.save(map, ALTERNATE_INDEX, "singleton-map") // + template.save(map, IndexCoordinates.of(ALTERNATE_INDEX).withTypes("singleton-map")) // .as(StepVerifier::create) // .consumeNextWith(actual -> { assertThat(map).containsKey("id"); @@ -198,7 +199,7 @@ public void insertShouldErrorOnNullEntity() { @Test // DATAES-519 public void findByIdShouldCompleteWhenIndexDoesNotExist() { - template.findById("foo", SampleEntity.class, "no-such-index") // + template.findById("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // .as(StepVerifier::create) // .verifyComplete(); } @@ -256,17 +257,20 @@ public void findByIdWithExplicitIndexNameShouldOverwriteMetadata() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - restTemplate.index(indexQuery, IndexCoordinates.of(ALTERNATE_INDEX).withTypes( "test-type")); + IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type"); + IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX).withTypes("test-type"); + + restTemplate.index(indexQuery, alternateIndex); restTemplate.refresh(SampleEntity.class); - restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); - restTemplate.refresh(IndexCoordinates.of(ALTERNATE_INDEX)); + restTemplate.refresh(defaultIndex); + restTemplate.refresh(alternateIndex); - template.findById(sampleEntity.getId(), SampleEntity.class) // + template.findById(sampleEntity.getId(), SampleEntity.class, defaultIndex) // .as(StepVerifier::create) // .verifyComplete(); - template.findById(sampleEntity.getId(), SampleEntity.class, ALTERNATE_INDEX) // + template.findById(sampleEntity.getId(), SampleEntity.class, alternateIndex) // .as(StepVerifier::create)// .expectNextCount(1) // .verifyComplete(); @@ -275,7 +279,7 @@ public void findByIdWithExplicitIndexNameShouldOverwriteMetadata() { @Test // DATAES-519 public void existsShouldReturnFalseWhenIndexDoesNotExist() { - template.exists("foo", SampleEntity.class, "no-such-index") // + template.exists("foo", SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .expectNext(false) // .verifyComplete(); @@ -308,7 +312,9 @@ public void existsShouldReturnFalseWhenNotFound() { @Test // DATAES-519 public void findShouldCompleteWhenIndexDoesNotExist() { - template.find(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, "no-such-index") // + template + .find(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .verifyComplete(); } @@ -509,7 +515,7 @@ public void countShouldReturnCountMatchingDocuments() { @Test // DATAES-519 public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { - template.deleteById("does-not-exists", SampleEntity.class, "no-such-index") // + template.deleteById("does-not-exists", SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create)// .verifyComplete(); } @@ -532,7 +538,7 @@ public void deleteShouldRemoveExistingDocumentByIdUsingIndexName() { SampleEntity sampleEntity = randomEntity("test message"); index(sampleEntity); - template.deleteById(sampleEntity.getId(), DEFAULT_INDEX, "test-type") // + template.deleteById(sampleEntity.getId(), IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type")) // .as(StepVerifier::create)// .expectNext(sampleEntity.getId()) // .verifyComplete(); @@ -577,8 +583,8 @@ public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() { public void shouldDeleteAcrossIndex() { String indexPrefix = "rx-template-test-index"; - String thisIndex = indexPrefix + "-this"; - String thatIndex = indexPrefix + "-that"; + IndexCoordinates thisIndex = IndexCoordinates.of(indexPrefix + "-this"); + IndexCoordinates thatIndex = IndexCoordinates.of(indexPrefix + "-that"); template.save(randomEntity("test"), thisIndex) // .then(template.save(randomEntity("test"), thatIndex)) // @@ -586,20 +592,19 @@ public void shouldDeleteAcrossIndex() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(IndexCoordinates.of(thisIndex)); - restTemplate.refresh(IndexCoordinates.of(thatIndex)); + restTemplate.refresh(thisIndex); + restTemplate.refresh(thatIndex); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "test")) // - .withIndices(indexPrefix + "*") // .build(); - template.deleteBy(searchQuery, SampleEntity.class) // + template.deleteBy(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // .as(StepVerifier::create) // .expectNext(2L) // .verifyComplete(); - TestUtils.deleteIndex(thisIndex, thatIndex); + TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); } @Test // DATAES-547 @@ -607,8 +612,8 @@ public void shouldDeleteAcrossIndex() { public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { String indexPrefix = "rx-template-test-index"; - String thisIndex = indexPrefix + "-this"; - String thatIndex = indexPrefix + "-that"; + IndexCoordinates thisIndex = IndexCoordinates.of(indexPrefix + "-this"); + IndexCoordinates thatIndex = IndexCoordinates.of(indexPrefix + "-that"); template.save(randomEntity("positive"), thisIndex) // .then(template.save(randomEntity("positive"), thatIndex)) // @@ -616,20 +621,19 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(IndexCoordinates.of(thisIndex)); - restTemplate.refresh(IndexCoordinates.of(thatIndex)); + restTemplate.refresh(thisIndex); + restTemplate.refresh(thatIndex); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "negative")) // - .withIndices(indexPrefix + "*") // .build(); - template.deleteBy(searchQuery, SampleEntity.class) // + template.deleteBy(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // .as(StepVerifier::create) // .expectNext(0L) // .verifyComplete(); - TestUtils.deleteIndex(thisIndex, thatIndex); + TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); } @Test // DATAES-504 @@ -672,13 +676,12 @@ public void shouldReturnDocumentWithCollapsedField() { index(entity1, entity2, entity3); NativeSearchQuery query = new NativeSearchQueryBuilder() // - .withIndices(DEFAULT_INDEX) // .withQuery(matchAllQuery()) // .withCollapseField("rate") // .withPageable(PageRequest.of(0, 25)) // .build(); - template.find(query, SampleEntity.class) // + template.find(query, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // .as(StepVerifier::create) // .expectNextCount(2) // .verifyComplete(); @@ -725,7 +728,7 @@ private List getIndexQueries(SampleEntity... sampleEntities) { private void index(SampleEntity... entities) { - IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes( "test-type"); + IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type"); if (entities.length == 1) { restTemplate.index(getIndexQuery(entities[0]), indexCoordinates); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index 066b918e6..d4c4b7b43 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -57,6 +57,7 @@ import org.springframework.data.elasticsearch.core.geo.GeoPoint; 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.core.query.StringQuery; /** @@ -69,6 +70,8 @@ public class ReactiveElasticsearchTemplateUnitTests { @Mock ReactiveElasticsearchClient client; ReactiveElasticsearchTemplate template; + private IndexCoordinates index = IndexCoordinates.of("index").withTypes("type"); + @BeforeEach public void setUp() { @@ -81,7 +84,7 @@ public void insertShouldUseDefaultRefreshPolicy() { ArgumentCaptor captor = ArgumentCaptor.forClass(IndexRequest.class); when(client.index(captor.capture())).thenReturn(Mono.empty()); - template.save(Collections.singletonMap("key", "value"), "index", "type") // + template.save(Collections.singletonMap("key", "value"), index) // .as(StepVerifier::create) // .verifyComplete(); @@ -96,7 +99,7 @@ public void insertShouldApplyRefreshPolicy() { template.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL); - template.save(Collections.singletonMap("key", "value"), "index", "type") // + template.save(Collections.singletonMap("key", "value"), index) // .as(StepVerifier::create) // .verifyComplete(); @@ -124,7 +127,8 @@ public void findShouldApplyIndexOptionsIfSet() { template.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); - template.find(new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(0, 10)), SampleEntity.class) // + Query query = new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(0, 10)); + template.find(query, SampleEntity.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -137,7 +141,8 @@ public void findShouldApplyPaginationIfSet() { ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); when(client.search(captor.capture())).thenReturn(Flux.empty()); - template.find(new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(2, 50)), SampleEntity.class) // + Query query = new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(2, 50)); + template.find(query, SampleEntity.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -164,7 +169,7 @@ public void deleteShouldUseDefaultRefreshPolicy() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteRequest.class); when(client.delete(captor.capture())).thenReturn(Mono.empty()); - template.deleteById("id", "index", "type") // + template.deleteById("id", index) // .as(StepVerifier::create) // .verifyComplete(); @@ -179,7 +184,7 @@ public void deleteShouldApplyRefreshPolicy() { template.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL); - template.deleteById("id", "index", "type") // + template.deleteById("id", index) // .as(StepVerifier::create) // .verifyComplete(); @@ -192,7 +197,7 @@ public void deleteByShouldUseDefaultRefreshPolicy() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteByQueryRequest.class); when(client.deleteBy(captor.capture())).thenReturn(Mono.empty()); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, "index", "type") // + template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -207,7 +212,7 @@ public void deleteByShouldApplyRefreshPolicy() { template.setRefreshPolicy(RefreshPolicy.NONE); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, "index", "type") // + template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -220,7 +225,7 @@ public void deleteByShouldApplyIndicesOptions() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteByQueryRequest.class); when(client.deleteBy(captor.capture())).thenReturn(Mono.empty()); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, "index", "type") // + template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -235,7 +240,7 @@ public void deleteByShouldApplyIndicesOptionsIfSet() { template.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, "index", "type") // + template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index af2005791..4f0a3dbdf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -90,7 +90,7 @@ public void before() { .addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000) .score(40).buildIndex(); - IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes( "article"); + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes("article"); elasticsearchTemplate.index(article1, index); elasticsearchTemplate.index(article2, index); elasticsearchTemplate.index(article3, index); @@ -111,7 +111,6 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // .withSearchType(SearchType.DEFAULT) // - .withIndices(INDEX_NAME).withTypes("article") // .addAggregation(terms("subjects").field("subject")) // .build(); // when diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 2e8a0e53b..fe7acedc8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -70,7 +70,6 @@ public void shouldDo() { // then NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); - nativeSearchQuery.addIndices("test-index-abz-entity"); long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(2); } @@ -86,8 +85,6 @@ public void shouldSupportSpelInType() { // then NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); - nativeSearchQuery.addIndices("test-index-abz-entity"); - nativeSearchQuery.addTypes("myType"); long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(1); } From 03fd603909c7d52a1e67b15c83550492d66a8215 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 30 Nov 2019 23:00:19 +0100 Subject: [PATCH 0009/1191] DATAES-700 - Enable proxy support for RestClient. Original PR: #348 --- pom.xml | 22 ++++++++- .../client/ClientConfiguration.java | 18 ++++++- .../client/ClientConfigurationBuilder.java | 12 ++++- .../client/DefaultClientConfiguration.java | 13 ++++- .../elasticsearch/client/RestClients.java | 2 + .../client/ClientConfigurationUnitTests.java | 6 ++- .../elasticsearch/client/RestClientsTest.java | 47 +++++++++++++++++++ 7 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java diff --git a/pom.xml b/pom.xml index 3e016864d..6333b1cda 100644 --- a/pom.xml +++ b/pom.xml @@ -249,6 +249,24 @@ test + + com.github.tomakehurst + wiremock-jre8 + 2.25.1 + test + + + + commons-logging + commons-logging + + + org.ow2.asm + asm + + + + org.apache.xbean @@ -259,8 +277,8 @@ javax.servlet - servlet-api - 3.0-alpha-1 + javax.servlet-api + 3.1.0 test diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index 4d7f107f8..5e57c2af5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -153,6 +153,14 @@ static ClientConfiguration create(InetSocketAddress socketAddress) { */ String getPathPrefix(); + /** + * returns an optionally set proxy in the form host:port + * + * @return the optional proxy + * @since 4.0 + */ + Optional getProxy(); + /** * @author Christoph Strobl */ @@ -221,8 +229,8 @@ interface MaybeSecureClientConfigurationBuilder extends TerminalClientConfigurat TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext); /** - * Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier} .
- * + * Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier} + * .
* NOTE You need to leave out the protocol in * {@link ClientConfigurationBuilderWithRequiredEndpoint#connectedTo(String)}. * @@ -304,6 +312,12 @@ default TerminalClientConfigurationBuilder withSocketTimeout(long millis) { */ TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix); + /** + * @param proxy a proxy formatted as String {@literal host:port}. + * @return the {@link MaybeSecureClientConfigurationBuilder}. + */ + MaybeSecureClientConfigurationBuilder withProxy(String proxy); + /** * Build the {@link ClientConfiguration} object. * diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index 562e294ad..5d5907b38 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -55,6 +55,7 @@ class ClientConfigurationBuilder private String username; private String password; private String pathPrefix; + private String proxy; /* * (non-Javadoc) @@ -83,6 +84,13 @@ public MaybeSecureClientConfigurationBuilder connectedTo(InetSocketAddress... en return this; } + @Override + public MaybeSecureClientConfigurationBuilder withProxy(String proxy) { + Assert.hasLength(proxy, "proxy must not be null or empty"); + this.proxy = proxy; + return this; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl() @@ -199,8 +207,8 @@ public ClientConfiguration build() { headers.setBasicAuth(username, password); } - return new DefaultClientConfiguration(this.hosts, this.headers, this.useSsl, this.sslContext, this.soTimeout, - this.connectTimeout, this.pathPrefix, this.hostnameVerifier); + return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix, + hostnameVerifier, proxy); } private static InetSocketAddress parse(String hostAndPort) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index 35367456a..b8b2a3991 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -46,9 +46,11 @@ class DefaultClientConfiguration implements ClientConfiguration { private final Duration connectTimeout; private final String pathPrefix; private final @Nullable HostnameVerifier hostnameVerifier; + private final String proxy; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, - @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, @Nullable HostnameVerifier hostnameVerifier) { + @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, + @Nullable HostnameVerifier hostnameVerifier, String proxy) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -58,6 +60,7 @@ class DefaultClientConfiguration implements ClientConfiguration { this.connectTimeout = connectTimeout; this.pathPrefix = pathPrefix; this.hostnameVerifier = hostnameVerifier; + this.proxy = proxy; } /* @@ -132,4 +135,12 @@ public String getPathPrefix() { return this.pathPrefix; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getProxy() + */ + @Override + public Optional getProxy() { + return Optional.ofNullable(proxy); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java index d4055ac36..6915ca3cf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java @@ -124,6 +124,8 @@ public static ElasticsearchRestClient create(ClientConfiguration clientConfigura clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); + clientConfiguration.getProxy().map(HttpHost::create).ifPresent(clientBuilder::setProxy); + return clientBuilder; }); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java index 0b970cdc1..301bcf32f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java @@ -45,7 +45,7 @@ public void shouldCreateSimpleConfiguration() { assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("localhost", 9200)); } - @Test // DATAES-488, DATAES-504, DATAES-650 + @Test // DATAES-488, DATAES-504, DATAES-650, DATAES-700 public void shouldCreateCustomizedConfiguration() { HttpHeaders headers = new HttpHeaders(); @@ -56,7 +56,8 @@ public void shouldCreateCustomizedConfiguration() { .usingSsl() // .withDefaultHeaders(headers) // .withConnectTimeout(Duration.ofDays(1)).withSocketTimeout(Duration.ofDays(2)) // - .withPathPrefix("myPathPrefix").build(); + .withPathPrefix("myPathPrefix") // + .withProxy("localhost:8080").build(); assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200), InetSocketAddress.createUnresolved("bar", 9200)); @@ -65,6 +66,7 @@ public void shouldCreateCustomizedConfiguration() { assertThat(clientConfiguration.getConnectTimeout()).isEqualTo(Duration.ofDays(1)); assertThat(clientConfiguration.getSocketTimeout()).isEqualTo(Duration.ofDays(2)); assertThat(clientConfiguration.getPathPrefix()).isEqualTo("myPathPrefix"); + assertThat(clientConfiguration.getProxy()).contains("localhost:8080"); } @Test // DATAES-488, DATAES-504 diff --git a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java new file mode 100644 index 000000000..f460f748c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java @@ -0,0 +1,47 @@ +package org.springframework.data.elasticsearch.client; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; + +import java.io.IOException; + +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; +import org.junit.jupiter.api.Test; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.client.WireMock; + +/** + * @author Peter-Josef Meisch + */ +public class RestClientsTest { + + @Test // DATAES-700 + void shouldUseConfiguredProxy() throws IOException { + + WireMockServer wireMockServer = new WireMockServer(options() // + .dynamicPort() // + .usingFilesUnderDirectory("src/test/resources/wiremock-mappings")); // needed, otherwise Wiremock goes to + // test/resources/mappings + wireMockServer.start(); + try { + WireMock.configureFor(wireMockServer.port()); + + ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder(); + ClientConfiguration clientConfiguration = configurationBuilder // + .connectedTo("localhost:9200")// + .withProxy("localhost:" + wireMockServer.port()) // + .build(); + + RestHighLevelClient restClient = RestClients.create(clientConfiguration).rest(); + restClient.ping(RequestOptions.DEFAULT); + + verify(headRequestedFor(urlEqualTo("/"))); + + } finally { + wireMockServer.shutdown(); + } + } + +} From c3714dd6e5d2f1127bd6adc4a803bb169eedd4ef Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 1 Dec 2019 18:31:51 +0100 Subject: [PATCH 0010/1191] DATAES-675 - Migrate tests to JUnit 5. Original PR: #350 --- pom.xml | 1 - .../core/AbstractElasticsearchTemplate.java | 4 + .../data/elasticsearch/NestedObjectTests.java | 21 +- .../ElasticsearchNamespaceHandlerTests.java | 8 +- .../EnableElasticsearchRepositoriesTests.java | 8 +- ...ElasticsearchTemplateParentChildTests.java | 250 ------------------ .../elasticsearch/core/LogEntityTests.java | 30 ++- .../core/LogEntityTransportTests.java | 31 +++ ...ElasticsearchTemplateAggregationTests.java | 30 ++- ...archTemplateAggregationTransportTests.java | 33 +++ .../ElasticsearchTemplateCompletionTests.java | 53 ++-- ...earchTemplateCompletionTransportTests.java | 33 +++ ...chTemplateCompletionWithContextsTests.java | 39 +-- ...eCompletionWithContextsTransportTests.java | 34 +++ .../geo/ElasticsearchTemplateGeoTests.java | 76 +++--- ...lasticsearchTemplateGeoTransportTests.java | 33 +++ .../core/query/CriteriaQueryTests.java | 145 +++++----- .../query/CriteriaQueryTestsTransport.java | 33 +++ .../repositories/cdi/CdiRepositoryTests.java | 15 +- .../ComplexCustomMethodRepositoryTests.java | 14 +- ...xCustomMethodRepositoryTransportTests.java | 33 +++ .../ComplexElasticsearchRepositoryImpl.java | 6 +- ...stomMethodRepositoryManualWiringTests.java | 29 +- ...dRepositoryManualWiringTransportTests.java | 34 +++ ...asticsearchRepositoryManualWiringImpl.java | 15 +- .../CustomMethodRepositoryTests.java | 6 +- .../doubleid/DoubleIDRepositoryTests.java | 34 ++- .../DoubleIDRepositoryTransportTests.java | 33 +++ .../dynamicindex/DynamicIndexEntityTests.java | 55 ++-- .../DynamicIndexEntityTransportTests.java} | 16 +- .../geo/SpringDataGeoRepositoryTests.java | 13 +- ...SpringDataGeoRepositoryTransportTests.java | 33 +++ .../integer/IntegerIDRepositoryTests.java | 28 +- .../IntegerIDRepositoryTransportTests.java | 33 +++ .../nestedobject/InnerObjectTests.java | 28 +- .../InnerObjectTransportTests.java | 33 +++ ...ettingAndMappingEntityRepositoryTests.java | 44 ++- ...MappingEntityRepositoryTransportTests.java | 34 +++ ...ldDynamicMappingEntityRepositoryTests.java | 16 +- ...MappingEntityRepositoryTransportTests.java | 33 +++ .../repositories/spel/SpELEntityTests.java | 20 +- .../spel/SpELEntityTransportTests.java | 33 +++ .../synonym/SynonymRepositoryTests.java | 17 +- .../SynonymRepositoryTransportTests.java | 33 +++ .../UUIDElasticsearchRepositoryTests.java | 13 +- ...ElasticsearchRepositoryTransportTests.java | 33 +++ ...asticsearchRepositoriesRegistrarTests.java | 11 +- ...sitoryConfigurationExtensionUnitTests.java | 5 +- ...ueryKeywordsRepositoryTransportTests.java} | 8 +- .../query/keywords/QueryKeywordsTests.java | 13 +- ...m-method-repository-manual-wiring-test.xml | 23 -- .../resources/double-id-repository-test.xml | 19 -- .../dynamic-index-repository-test.xml | 19 -- .../elasticsearch-rest-template-test.xml | 17 -- .../resources/elasticsearch-template-test.xml | 13 - .../existing-index-repository-test.xml | 19 -- .../resources/field-dynamic-settings-test.xml | 19 -- src/test/resources/infrastructure.xml | 18 -- .../resources/integer-id-repository-test.xml | 19 -- .../repository-non-document-entity.xml | 24 +- .../repository-test-nested-object-books.xml | 18 -- .../repository-test-nested-object.xml | 17 -- src/test/resources/synonym-test.xml | 19 -- 63 files changed, 1018 insertions(+), 859 deletions(-) delete mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateParentChildTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java rename src/test/java/org/springframework/data/elasticsearch/{repository/query/keywords/QueryKeywordsRestRepositoryTests.java => repositories/dynamicindex/DynamicIndexEntityTransportTests.java} (65%) create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java rename src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/{QueryKeywordsRepositoryTests.java => QueryKeywordsRepositoryTransportTests.java} (80%) delete mode 100644 src/test/resources/complex-custom-method-repository-manual-wiring-test.xml delete mode 100644 src/test/resources/double-id-repository-test.xml delete mode 100644 src/test/resources/dynamic-index-repository-test.xml delete mode 100644 src/test/resources/elasticsearch-rest-template-test.xml delete mode 100644 src/test/resources/elasticsearch-template-test.xml delete mode 100644 src/test/resources/existing-index-repository-test.xml delete mode 100644 src/test/resources/field-dynamic-settings-test.xml delete mode 100644 src/test/resources/infrastructure.xml delete mode 100644 src/test/resources/integer-id-repository-test.xml delete mode 100644 src/test/resources/repository-test-nested-object-books.xml delete mode 100644 src/test/resources/repository-test-nested-object.xml delete mode 100644 src/test/resources/synonym-test.xml diff --git a/pom.xml b/pom.xml index 6333b1cda..4b990ec3e 100644 --- a/pom.xml +++ b/pom.xml @@ -289,7 +289,6 @@ test
- diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 806d52842..5f71bb590 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -13,8 +13,10 @@ import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; +import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; @@ -259,6 +261,8 @@ public boolean putMapping(IndexCoordinates index, Class clazz) { abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); + public abstract SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); + protected void setPersistentEntityId(Object entity, String id) { ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 5e9a37e7a..3afdbcc42 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -44,7 +44,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -66,7 +66,7 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class NestedObjectTests { - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations elasticsearchTemplate; @BeforeEach public void before() { @@ -123,7 +123,7 @@ public void shouldIndexInitialLevelNestedObject() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user"); + IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Person.class); @@ -144,14 +144,14 @@ public void shouldIndexMultipleLevelNestedObject() { // when elasticsearchTemplate.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); // then GetQuery getQuery = new GetQuery(); getQuery.setId("1"); PersonMultipleLevelNested personIndexed = elasticsearchTemplate.get(getQuery, PersonMultipleLevelNested.class, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); assertThat(personIndexed).isNotNull(); } @@ -163,7 +163,7 @@ public void shouldIndexMultipleLevelNestedObjectWithIncludeInParent() { // when elasticsearchTemplate.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user")); + IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); // then Map mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class); @@ -182,9 +182,8 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes( "user"); - elasticsearchTemplate.bulkIndex(indexQueries, - index); + IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user"); + elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); // then @@ -323,7 +322,7 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes( "user"); + IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Person.class); @@ -372,7 +371,7 @@ public void shouldIndexAndSearchMapAsNestedType() { indexQueries.add(indexQuery2); // when - IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes( "book"); + IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes("book"); elasticsearchTemplate.bulkIndex(indexQueries, index); elasticsearchTemplate.refresh(Book.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java index 9c7d0aa8f..1618e0732 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java @@ -17,8 +17,8 @@ import static org.assertj.core.api.Assertions.*; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.data.annotation.Id; @@ -27,7 +27,7 @@ import org.springframework.data.elasticsearch.client.TransportClientFactoryBean; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; /** * @author Rizwan Idrees @@ -36,7 +36,7 @@ * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration("namespace.xml") public class ElasticsearchNamespaceHandlerTests { diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index 41d45b138..348abe6e5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -39,7 +39,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -70,10 +70,10 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @Configuration @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.config.notnested" }) + @EnableElasticsearchRepositories static class Config {} - @Autowired ElasticsearchTemplate elasticsearchTemplate; + @Autowired ElasticsearchOperations operations; @Autowired private SampleElasticsearchRepository repository; @@ -83,7 +83,7 @@ interface SampleRepository extends Repository parents = elasticsearchTemplate.queryForList(new NativeSearchQuery(query), ParentEntity.class, IndexCoordinates.of(ParentEntity.INDEX)); - - // we're expecting only the first parent as result - assertThat(parents).hasSize(1); - assertThat(parents.get(0).getId()).isEqualTo(parent1.getId()); - } - - @Ignore(value = "DATAES-421") - @Test - public void shouldUpdateChild() throws Exception { - - // index parent and child - ParentEntity parent = index("parent", "Parent"); - ChildEntity child = index("child", parent.getId(), "Child"); - String newChildName = "New Child Name"; - - // update the child, not forgetting to set the parent id as routing parameter - UpdateRequest updateRequest = new UpdateRequest(ParentEntity.INDEX, ParentEntity.CHILD_TYPE, child.getId()); - updateRequest.routing(parent.getId()); - XContentBuilder builder; - builder = jsonBuilder().startObject().field("name", newChildName).endObject(); - updateRequest.doc(builder); - UpdateResponse response = update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); - - assertThat(response.getShardInfo().getSuccessful()).isEqualTo(1); - } - - @Ignore(value = "DATAES-421") - @Test(expected = RoutingMissingException.class) - public void shouldFailWithRoutingMissingExceptionOnUpdateChildIfNotRoutingSetOnUpdateRequest() throws Exception { - - // index parent and child - ParentEntity parent = index("parent", "Parent"); - ChildEntity child = index("child", parent.getId(), "Child"); - String newChildName = "New Child Name"; - - // update the child, forget routing parameter - UpdateRequest updateRequest = new UpdateRequest(ParentEntity.INDEX, ParentEntity.CHILD_TYPE, child.getId()); - XContentBuilder builder; - builder = jsonBuilder().startObject().field("name", newChildName).endObject(); - updateRequest.doc(builder); - update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); - } - - @Ignore(value = "DATAES-421") - @Test(expected = RoutingMissingException.class) - public void shouldFailWithRoutingMissingExceptionOnUpdateChildIfRoutingOnlySetOnRequestDoc() throws Exception { - - // index parent and child - ParentEntity parent = index("parent", "Parent"); - ChildEntity child = index("child", parent.getId(), "Child"); - String newChildName = "New Child Name"; - - // update the child - UpdateRequest updateRequest = new UpdateRequest(ParentEntity.INDEX, ParentEntity.CHILD_TYPE, child.getId()); - XContentBuilder builder; - builder = jsonBuilder().startObject().field("name", newChildName).endObject(); - updateRequest.doc(builder); - updateRequest.doc().routing(parent.getId()); - update(updateRequest, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); - } - - private ParentEntity index(String parentId, String name) { - - ParentEntity parent = new ParentEntity(parentId, name); - IndexQuery index = new IndexQuery(); - index.setId(parent.getId()); - index.setObject(parent); - elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.PARENT_TYPE)); - - return parent; - } - - private ChildEntity index(String childId, String parentId, String name) { - - ChildEntity child = new ChildEntity(childId, parentId, name); - IndexQuery index = new IndexQuery(); - index.setId(child.getId()); - index.setObject(child); - index.setParentId(child.getParentId()); - elasticsearchTemplate.index(index, IndexCoordinates.of(ParentEntity.INDEX).withTypes( ParentEntity.CHILD_TYPE)); - - return child; - } - - private UpdateResponse update(UpdateRequest updateRequest, IndexCoordinates index) { - - UpdateQuery update = new UpdateQuery(); - update.setId(updateRequest.id()); - update.setUpdateRequest(updateRequest); - return elasticsearchTemplate.update(update, index); - } - - /** - * @author Philipp Jardas - * @author Mohsin Husen - */ - @Document( - indexName = org.springframework.data.elasticsearch.core.ElasticsearchTemplateParentChildTests.ParentEntity.INDEX, - type = org.springframework.data.elasticsearch.core.ElasticsearchTemplateParentChildTests.ParentEntity.PARENT_TYPE, - shards = 1, replicas = 0, refreshInterval = "-1") - static class ParentEntity { - - public static final String INDEX = "parent-child"; - public static final String PARENT_TYPE = "parent-entity"; - public static final String CHILD_TYPE = "child-entity"; - - @Id private String id; - @Field(type = FieldType.Text, store = true) private String name; - - public ParentEntity() {} - - public ParentEntity(String id, String name) { - this.id = id; - this.name = name; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return new ToStringCreator(this).append("id", id).append("name", name).toString(); - } - - @Document(indexName = INDEX, type = CHILD_TYPE, shards = 1, replicas = 0, refreshInterval = "-1") - static class ChildEntity { - - @Id private String id; - @Field(type = FieldType.Text, store = true) @Parent(type = PARENT_TYPE) private String parentId; - @Field(type = FieldType.Text, store = true) private String name; - - public ChildEntity() {} - - public ChildEntity(String id, String parentId, String name) { - this.id = id; - this.parentId = parentId; - this.name = name; - } - - public String getId() { - return id; - } - - public String getParentId() { - return parentId; - } - - public String getName() { - return name; - } - - @Override - public String toString() { - return new ToStringCreator(this).append("id", id).append("parentId", parentId).append("name", name).toString(); - } - } - } - -} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index be4a527f6..46ddeec4d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -27,17 +27,19 @@ import java.util.Date; import java.util.List; -import org.elasticsearch.action.search.SearchPhaseExecutionException; +import org.elasticsearch.ElasticsearchException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -50,16 +52,20 @@ * @author Peter-Josef Meisch */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { LogEntityTests.Config.class }) public class LogEntityTests { - private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes( "test-log-type"); - @Autowired private ElasticsearchTemplate template; + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes("test-log-type"); + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() throws ParseException { - IndexInitializer.init(template, LogEntity.class); + IndexInitializer.init(operations, LogEntity.class); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); IndexQuery indexQuery1 = new LogEntityBuilder("1").action("update").date(dateFormatter.parse("2013-10-18 18:01")) @@ -74,8 +80,8 @@ public void before() throws ParseException { IndexQuery indexQuery4 = new LogEntityBuilder("4").action("update").date(dateFormatter.parse("2013-10-19 18:04")) .code(2).ip("10.10.10.4").buildIndex(); - template.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index); - template.refresh(LogEntity.class); + operations.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index); + operations.refresh(LogEntity.class); } @Test // DATAES-66 @@ -83,7 +89,7 @@ public void shouldIndexGivenLogEntityWithIPFieldType() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); - List entities = template.queryForList(searchQuery, LogEntity.class, index); + List entities = operations.queryForList(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(1); @@ -96,8 +102,8 @@ public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); assertThatThrownBy(() -> { - List entities = template.queryForList(searchQuery, LogEntity.class, index); - }).isInstanceOf(SearchPhaseExecutionException.class); + List entities = operations.queryForList(searchQuery, LogEntity.class, index); + }).isInstanceOf(ElasticsearchException.class); } @Test // DATAES-66 @@ -106,7 +112,7 @@ public void shouldReturnLogsForGivenIPRanges() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build(); - List entities = template.queryForList(searchQuery, LogEntity.class, index); + List entities = operations.queryForList(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(3); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java new file mode 100644 index 000000000..76e2e4d8c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java @@ -0,0 +1,31 @@ +/* + * Copyright 2019 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; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { LogEntityTransportTests.Config.class }) +public class LogEntityTransportTests extends LogEntityTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index 4f0a3dbdf..dc7150264 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -34,18 +34,20 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -58,9 +60,13 @@ * @author Peter-Josef Meisch */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchTemplateAggregationTests.Config.class }) public class ElasticsearchTemplateAggregationTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + static final String RIZWAN_IDREES = "Rizwan Idrees"; static final String MOHSIN_HUSEN = "Mohsin Husen"; static final String JONATHAN_YAN = "Jonathan Yan"; @@ -70,12 +76,12 @@ public class ElasticsearchTemplateAggregationTests { static final int YEAR_2000 = 2000; static final String INDEX_NAME = "test-index-articles-core-aggregation"; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, ArticleEntity.class); + IndexInitializer.init(operations, ArticleEntity.class); IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").subject("computing") .addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10) @@ -91,17 +97,17 @@ public void before() { .score(40).buildIndex(); IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes("article"); - elasticsearchTemplate.index(article1, index); - elasticsearchTemplate.index(article2, index); - elasticsearchTemplate.index(article3, index); - elasticsearchTemplate.index(article4, index); - elasticsearchTemplate.refresh(ArticleEntity.class); + operations.index(article1, index); + operations.index(article2, index); + operations.index(article3, index); + operations.index(article4, index); + operations.refresh(ArticleEntity.class); } @AfterEach public void after() { - elasticsearchTemplate.deleteIndex(ArticleEntity.class); + operations.deleteIndex(ArticleEntity.class); } @Test @@ -114,7 +120,7 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { .addAggregation(terms("subjects").field("subject")) // .build(); // when - Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor() { + Aggregations aggregations = operations.query(searchQuery, new ResultsExtractor() { @Override public Aggregations extract(SearchResponse response) { return response.getAggregations(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java new file mode 100644 index 000000000..b0f158f2d --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.aggregation; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ElasticsearchTemplateAggregationTransportTests.Config.class }) +public class ElasticsearchTemplateAggregationTransportTests extends ElasticsearchTemplateAggregationTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 5a554b07c..03cfd7b25 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -28,13 +28,16 @@ import org.elasticsearch.search.suggest.completion.CompletionSuggestion; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.CompletionField; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -48,14 +51,18 @@ * @author Peter-Josef Meisch */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchTemplateCompletionTests.Config.class }) public class ElasticsearchTemplateCompletionTests { - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + @Autowired private ElasticsearchOperations operations; private void loadCompletionObjectEntities() { - IndexInitializer.init(elasticsearchTemplate, CompletionEntity.class); + IndexInitializer.init(operations, CompletionEntity.class); List indexQueries = new ArrayList<>(); indexQueries.add( @@ -67,13 +74,13 @@ private void loadCompletionObjectEntities() { indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[] { "Artur", "Konczak" }) .buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); - elasticsearchTemplate.refresh(CompletionEntity.class); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); + operations.refresh(CompletionEntity.class); } private void loadAnnotatedCompletionObjectEntities() { - IndexInitializer.init(elasticsearchTemplate, AnnotatedCompletionEntity.class); + IndexInitializer.init(operations, AnnotatedCompletionEntity.class); NonDocumentEntity nonDocumentEntity = new NonDocumentEntity(); nonDocumentEntity.setSomeField1("foo"); @@ -89,14 +96,14 @@ private void loadAnnotatedCompletionObjectEntities() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); - elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class); + operations.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + operations.refresh(AnnotatedCompletionEntity.class); } private void loadAnnotatedCompletionObjectEntitiesWithWeights() { - IndexInitializer.init(elasticsearchTemplate, AnnotatedCompletionEntity.class); + IndexInitializer.init(operations, AnnotatedCompletionEntity.class); List indexQueries = new ArrayList<>(); indexQueries.add(new AnnotatedCompletionEntityBuilder("1").name("Mewes Kochheim1") @@ -108,9 +115,9 @@ private void loadAnnotatedCompletionObjectEntitiesWithWeights() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4") .suggest(new String[] { "Mewes Kochheim4" }, Integer.MAX_VALUE).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); - elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class); + operations.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + operations.refresh(AnnotatedCompletionEntity.class); } @Test @@ -118,10 +125,10 @@ public void shouldPutMappingForGivenEntity() throws Exception { // given Class entity = CompletionEntity.class; - elasticsearchTemplate.createIndex(entity); + operations.createIndex(entity); // when - assertThat(elasticsearchTemplate.putMapping(entity)).isTrue(); + assertThat(operations.putMapping(entity)).isTrue(); } @Test @@ -134,9 +141,9 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() { Fuzziness.AUTO); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); + IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -155,9 +162,9 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEn Fuzziness.AUTO); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-core-completion").withTypes( "completion-type")); + IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -176,9 +183,9 @@ public void shouldFindSuggestionsWithWeightsForGivenCriteriaQueryUsingAnnotatedC Fuzziness.AUTO); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-annotated-completion").withTypes( "annotated-completion-type")); + IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java new file mode 100644 index 000000000..239f19e24 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.completion; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ElasticsearchTemplateCompletionTransportTests.Config.class }) +public class ElasticsearchTemplateCompletionTransportTests extends ElasticsearchTemplateCompletionTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index b29564e77..75e2a0de2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -35,14 +35,17 @@ import org.elasticsearch.search.suggest.completion.context.ContextMapping; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.CompletionContext; import org.springframework.data.elasticsearch.annotations.CompletionField; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -52,14 +55,18 @@ * @author Peter-Josef Meisch */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchTemplateCompletionWithContextsTests.Config.class }) public class ElasticsearchTemplateCompletionWithContextsTests { - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + @Autowired private ElasticsearchOperations operations; private void loadContextCompletionObjectEntities() { - IndexInitializer.init(elasticsearchTemplate, ContextCompletionEntity.class); + IndexInitializer.init(operations, ContextCompletionEntity.class); NonDocumentEntity nonDocumentEntity = new NonDocumentEntity(); nonDocumentEntity.setSomeField1("foo"); @@ -87,9 +94,9 @@ private void loadContextCompletionObjectEntities() { indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }, context4).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); - elasticsearchTemplate.refresh(ContextCompletionEntity.class); + operations.bulkIndex(indexQueries, + IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); + operations.refresh(ContextCompletionEntity.class); } @Test @@ -97,10 +104,10 @@ public void shouldPutMappingForGivenEntity() throws Exception { // given Class entity = ContextCompletionEntity.class; - elasticsearchTemplate.createIndex(entity); + operations.createIndex(entity); // when - assertThat(elasticsearchTemplate.putMapping(entity)).isTrue(); + assertThat(operations.putMapping(entity)).isTrue(); } @Test // DATAES-536 @@ -123,9 +130,9 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti ((CompletionSuggestionBuilder) completionSuggestionFuzzyBuilder).contexts(contextMap); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); + IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -155,9 +162,9 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti ((CompletionSuggestionBuilder) completionSuggestionFuzzyBuilder).contexts(contextMap); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); + IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -187,9 +194,9 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti ((CompletionSuggestionBuilder) completionSuggestionFuzzyBuilder).contexts(contextMap); // when - SearchResponse suggestResponse = elasticsearchTemplate.suggest( + SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes( "context-completion-type")); + IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java new file mode 100644 index 000000000..8f88d1d56 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 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.completion; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ElasticsearchTemplateCompletionWithContextsTransportTests.Config.class }) +public class ElasticsearchTemplateCompletionWithContextsTransportTests + extends ElasticsearchTemplateCompletionWithContextsTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index 90200df56..39394a364 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -32,16 +32,18 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.data.geo.Point; @@ -59,21 +61,25 @@ * Latitude , max Longitude , max Latitude */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchTemplateGeoTests.Config.class }) public class ElasticsearchTemplateGeoTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + private final IndexCoordinates locationMarkerIndex = IndexCoordinates.of("test-index-location-marker-core-geo") .withTypes("geo-annotation-point-type"); private final IndexCoordinates authorMarkerIndex = IndexCoordinates.of("test-index-author-marker-core-geo") .withTypes("geo-class-point-type"); - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, AuthorMarkerEntity.class); - IndexInitializer.init(elasticsearchTemplate, LocationMarkerEntity.class); + IndexInitializer.init(operations, AuthorMarkerEntity.class); + IndexInitializer.init(operations, LocationMarkerEntity.class); } private void loadClassBaseEntities() { @@ -83,8 +89,8 @@ private void loadClassBaseEntities() { .add(new AuthorMarkerEntityBuilder("1").name("Franck Marchand").location(45.7806d, 3.0875d).buildIndex()); indexQueries.add(new AuthorMarkerEntityBuilder("2").name("Mohsin Husen").location(51.5171d, 0.1062d).buildIndex()); indexQueries.add(new AuthorMarkerEntityBuilder("3").name("Rizwan Idrees").location(51.5171d, 0.1062d).buildIndex()); - elasticsearchTemplate.bulkIndex(indexQueries, authorMarkerIndex); - elasticsearchTemplate.refresh(AuthorMarkerEntity.class); + operations.bulkIndex(indexQueries, authorMarkerIndex); + operations.refresh(AuthorMarkerEntity.class); } private void loadAnnotationBaseEntities() { @@ -115,8 +121,8 @@ private void loadAnnotationBaseEntities() { indexQueries.add(buildIndex(location2)); indexQueries.add(buildIndex(location3)); - elasticsearchTemplate.bulkIndex(indexQueries, locationMarkerIndex); - elasticsearchTemplate.refresh(LocationMarkerEntity.class); + operations.bulkIndex(indexQueries, locationMarkerIndex); + operations.refresh(LocationMarkerEntity.class); } @Test @@ -124,10 +130,10 @@ public void shouldPutMappingForGivenEntityWithGeoLocation() throws Exception { // given Class entity = AuthorMarkerEntity.class; - elasticsearchTemplate.createIndex(entity); + operations.createIndex(entity); // when - assertThat(elasticsearchTemplate.putMapping(entity)).isTrue(); + assertThat(operations.putMapping(entity)).isTrue(); } @Test @@ -139,7 +145,7 @@ public void shouldFindAuthorMarkersInRangeForGivenCriteriaQuery() { new Criteria("location").within(new GeoPoint(45.7806d, 3.0875d), "20km")); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, + List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -156,7 +162,7 @@ public void shouldFindSelectedAuthorMarkerInRangeForGivenCriteriaQuery() { new Criteria("name").is("Mohsin Husen").and("location").within(new GeoPoint(51.5171d, 0.1062d), "20km")); // when - List geoAuthorsForGeoCriteria2 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery2, + List geoAuthorsForGeoCriteria2 = operations.queryForList(geoLocationCriteriaQuery2, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -172,7 +178,7 @@ public void shouldFindStringAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery( new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km")); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, + List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -188,7 +194,7 @@ public void shouldFindDoubleAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { new Criteria("locationAsArray").within(new GeoPoint(51.001000, 0.10100), "1km")); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, + List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -203,7 +209,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery( new Criteria("locationAsArray").within("51.001000, 0.10100", "1km")); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, + List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -218,7 +224,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQueryUsingGeohas CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery(new Criteria("locationAsArray").within("u1044", "3km")); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery, + List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -234,7 +240,7 @@ public void shouldFindAllMarkersForNativeSearchQuery() { .withFilter(QueryBuilders.geoBoundingBoxQuery("locationAsArray").setCorners(52, -1, 50, 1)); // when - List geoAuthorsForGeoCriteria = elasticsearchTemplate.queryForList(queryBuilder.build(), + List geoAuthorsForGeoCriteria = operations.queryForList(queryBuilder.build(), LocationMarkerEntity.class, locationMarkerIndex); // then @@ -250,7 +256,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoBox() { new Criteria("location").boundedBy(new GeoBox(new GeoPoint(53.5171d, 0), new GeoPoint(49.5171d, 0.2062d)))); // when - List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, + List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -268,7 +274,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeohash() { new Criteria("location").boundedBy(Geohash.stringEncode(0, 53.5171d), Geohash.stringEncode(0.2062d, 49.5171d))); // when - List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, + List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -286,7 +292,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoPoints() { new Criteria("location").boundedBy(new GeoPoint(53.5171d, 0), new GeoPoint(49.5171d, 0.2062d))); // when - List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, + List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -304,7 +310,7 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingPoints() { new Criteria("location").boundedBy(new Point(53.5171d, 0), new Point(49.5171d, 0.2062d))); // when - List geoAuthorsForGeoCriteria3 = elasticsearchTemplate.queryForList(geoLocationCriteriaQuery3, + List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then @@ -332,18 +338,18 @@ public void shouldFindLocationWithGeoHashPrefix() { .withFilter(QueryBuilders.geoBoundingBoxQuery("locationAsGeoHash").setCorners("u10j46mkfek")); // when - List result1 = elasticsearchTemplate.queryForList(location1.build(), - LocationMarkerEntity.class, locationMarkerIndex); - List result2 = elasticsearchTemplate.queryForList(location2.build(), - LocationMarkerEntity.class, locationMarkerIndex); - List result3 = elasticsearchTemplate.queryForList(location3.build(), - LocationMarkerEntity.class, locationMarkerIndex); - List result4 = elasticsearchTemplate.queryForList(location4.build(), - LocationMarkerEntity.class, locationMarkerIndex); - List result5 = elasticsearchTemplate.queryForList(location5.build(), - LocationMarkerEntity.class, locationMarkerIndex); - List result11 = elasticsearchTemplate.queryForList(location11.build(), - LocationMarkerEntity.class, locationMarkerIndex); + List result1 = operations.queryForList(location1.build(), LocationMarkerEntity.class, + locationMarkerIndex); + List result2 = operations.queryForList(location2.build(), LocationMarkerEntity.class, + locationMarkerIndex); + List result3 = operations.queryForList(location3.build(), LocationMarkerEntity.class, + locationMarkerIndex); + List result4 = operations.queryForList(location4.build(), LocationMarkerEntity.class, + locationMarkerIndex); + List result5 = operations.queryForList(location5.build(), LocationMarkerEntity.class, + locationMarkerIndex); + List result11 = operations.queryForList(location11.build(), LocationMarkerEntity.class, + locationMarkerIndex); // then assertThat(result1).hasSize(3); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java new file mode 100644 index 000000000..b4067334c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.geo; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ElasticsearchTemplateGeoTransportTests.Config.class }) +public class ElasticsearchTemplateGeoTransportTests extends ElasticsearchTemplateGeoTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 1ae67095e..d99b31b45 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -33,15 +33,17 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; @@ -52,19 +54,24 @@ * @author James Bodkin */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { CriteriaQueryTests.Config.class }) public class CriteriaQueryTests { - private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes( "test-type"); - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes("test-type"); + + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - elasticsearchTemplate.deleteIndex(SampleEntity.class); - elasticsearchTemplate.createIndex(SampleEntity.class); - elasticsearchTemplate.putMapping(SampleEntity.class); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.deleteIndex(SampleEntity.class); + operations.createIndex(SampleEntity.class); + operations.putMapping(SampleEntity.class); + operations.refresh(SampleEntity.class); } @Test @@ -80,13 +87,13 @@ public void shouldPerformAndOperation() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("test").and("message").contains("some")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -123,13 +130,13 @@ public void shouldPerformOrOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").or("message").contains("test")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -154,13 +161,13 @@ public void shouldPerformAndOperationWithinCriteria() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -186,12 +193,12 @@ public void shouldPerformOrOperationWithinCriteria() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -215,12 +222,12 @@ public void shouldPerformIsOperation() { indexQuery.setObject(sampleEntity); indexQueries.add(indexQuery); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -257,12 +264,12 @@ public void shouldPerformMultipleIsOperations() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -299,13 +306,13 @@ public void shouldPerformEndsWithOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").endsWith("end"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -341,13 +348,13 @@ public void shouldPerformStartsWithOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").startsWith("start"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -383,12 +390,12 @@ public void shouldPerformContainsOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -424,12 +431,12 @@ public void shouldExecuteExpression() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -465,13 +472,13 @@ public void shouldExecuteCriteriaChain() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -507,12 +514,12 @@ public void shouldPerformIsNotOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().isNegating()).isTrue(); @@ -551,12 +558,12 @@ public void shouldPerformBetweenOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); // when - SampleEntity sampleEntity = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity).isNotNull(); @@ -593,12 +600,12 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -636,12 +643,12 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -679,12 +686,12 @@ public void shouldPerformLessThanEqualOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -722,12 +729,12 @@ public void shouldPerformGreaterThanEquals() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -765,12 +772,12 @@ public void shouldPerformBoostOperation() { indexQuery2.setObject(sampleEntity2); indexQueries.add(indexQuery2); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -786,14 +793,14 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + operations.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("a").or(new Criteria("message").contains("b"))); criteriaQuery.setMinScore(2.0F); - Page page = elasticsearchTemplate.queryForPage(criteriaQuery, SampleEntity.class, index); + Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); @@ -813,13 +820,13 @@ public void shouldEscapeValue() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + operations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java new file mode 100644 index 000000000..1a18d17ed --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.query; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { CriteriaQueryTestsTransport.Config.class }) +public class CriteriaQueryTestsTransport extends CriteriaQueryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index 59e904e1d..9031540c3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -31,11 +31,10 @@ import org.apache.webbeans.cditest.CdiTestContainer; import org.apache.webbeans.cditest.CdiTestContainerLoader; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; @@ -56,7 +55,7 @@ public class CdiRepositoryTests { private SamplePersonRepository personRepository; private QualifiedProductRepository qualifiedProductRepository; - @BeforeClass + @BeforeAll public static void init() throws Exception { cdiContainer = CdiTestContainerLoader.getCdiContainer(); @@ -64,14 +63,14 @@ public static void init() throws Exception { cdiContainer.bootContainer(); } - @AfterClass + @AfterAll public static void shutdown() throws Exception { cdiContainer.stopContexts(); cdiContainer.shutdownContainer(); } - @Before + @BeforeEach public void setUp() { CdiRepositoryClient client = cdiContainer.getInstance(CdiRepositoryClient.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index 3b7273a19..05ed308fd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -28,8 +28,8 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -45,19 +45,17 @@ public class ComplexCustomMethodRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories( - basePackages = { "org.springframework.data.elasticsearch.repositories.complex.custommethod.autowiring" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} @Autowired private ComplexElasticsearchRepository complexRepository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); + IndexInitializer.init(operations, SampleEntity.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java new file mode 100644 index 000000000..15885237f --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.complex.custommethod.autowiring; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ComplexCustomMethodRepositoryTransportTests.Config.class }) +public class ComplexCustomMethodRepositoryTransportTests extends ComplexCustomMethodRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryImpl.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryImpl.java index a60369260..74cb89462 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryImpl.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryImpl.java @@ -1,18 +1,18 @@ package org.springframework.data.elasticsearch.repositories.complex.custommethod.autowiring; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; /** * @author Artur Konczak */ public class ComplexElasticsearchRepositoryImpl implements ComplexElasticsearchRepositoryCustom { - @Autowired private ElasticsearchTemplate template; + @Autowired private ElasticsearchOperations operations; @Override public String doSomethingSpecial() { - assert (template.getElasticsearchConverter() != null); + assert (operations.getElasticsearchConverter() != null); return "2+2=4"; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java index d1546ec3a..ed1f3172b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java @@ -20,34 +20,41 @@ import lombok.Data; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Artur Konczak * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:complex-custom-method-repository-manual-wiring-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { ComplexCustomMethodRepositoryManualWiringTests.Config.class }) public class ComplexCustomMethodRepositoryManualWiringTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} + @Autowired private ComplexElasticsearchRepositoryManualWiring complexRepository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; - @Before + @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); + IndexInitializer.init(operations, SampleEntity.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java new file mode 100644 index 000000000..7236ed774 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 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.repositories.complex.custommethod.manualwiring; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ComplexCustomMethodRepositoryManualWiringTransportTests.Config.class }) +public class ComplexCustomMethodRepositoryManualWiringTransportTests + extends ComplexCustomMethodRepositoryManualWiringTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java index 8a327393c..825a7aa6d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java @@ -15,24 +15,25 @@ */ package org.springframework.data.elasticsearch.repositories.complex.custommethod.manualwiring; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.repositories.complex.custommethod.autowiring.ComplexElasticsearchRepositoryCustom; /** * @author Artur Konczak * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class ComplexElasticsearchRepositoryManualWiringImpl implements ComplexElasticsearchRepositoryCustom { - private ElasticsearchTemplate template; + private ElasticsearchOperations operations; + + public ComplexElasticsearchRepositoryManualWiringImpl(ElasticsearchOperations operations) { + this.operations = operations; + } @Override public String doSomethingSpecial() { - assert (template.getElasticsearchConverter() != null); + assert (operations.getElasticsearchConverter() != null); return "3+3=6"; } - - public void setTemplate(ElasticsearchTemplate template) { - this.template = template; - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java index 2a4eb13a4..4d91b80f1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -40,10 +40,10 @@ public class CustomMethodRepositoryTests extends CustomMethodRepositoryBaseTests considerNestedRepositories = true) static class Config {} - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); + IndexInitializer.init(operations, SampleEntity.class); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index bbd290b9e..fd55e5a71 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -21,19 +21,22 @@ import java.util.Optional; import org.apache.commons.lang.math.RandomUtils; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Rizwan Idrees @@ -42,23 +45,28 @@ * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:/double-id-repository-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { DoubleIDRepositoryTests.Config.class }) public class DoubleIDRepositoryTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} + @Autowired private DoubleIDRepository repository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; - @Before + @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, DoubleIDEntity.class); + IndexInitializer.init(operations, DoubleIDEntity.class); } - @After + @AfterEach public void after() { - elasticsearchTemplate.deleteIndex(DoubleIDEntity.class); + operations.deleteIndex(DoubleIDEntity.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java new file mode 100644 index 000000000..2e42afb0a --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.doubleid; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { DoubleIDRepositoryTransportTests.Config.class }) +public class DoubleIDRepositoryTransportTests extends DoubleIDRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index bebf707ff..44ccd10ad 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -17,20 +17,21 @@ import static org.assertj.core.api.Assertions.*; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ImportResource; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * DynamicIndexEntityTests @@ -39,33 +40,43 @@ * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = DynamicIndexEntityTests.TestConfig.class) +@SpringIntegrationTest +@ContextConfiguration(classes = { DynamicIndexEntityTests.Config.class }) public class DynamicIndexEntityTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config { + @Bean + public IndexNameProvider indexNameProvider() { + return new IndexNameProvider(); + } + } + @Autowired private DynamicIndexRepository repository; - @Autowired private ElasticsearchTemplate template; + @Autowired private ElasticsearchOperations operations; @Autowired private IndexNameProvider indexNameProvider; - @Before + @BeforeEach public void init() { deleteIndexes(); - template.createIndex("index1"); - template.createIndex("index2"); + operations.createIndex("index1"); + operations.createIndex("index2"); } - @After + @AfterEach public void teardown() { deleteIndexes(); } private void deleteIndexes() { - template.deleteIndex("index1"); - template.deleteIndex("index2"); + operations.deleteIndex("index1"); + operations.deleteIndex("index2"); } @Test // DATAES-456 @@ -82,16 +93,6 @@ public void indexNameIsDynamicallyProvided() { assertThat(repository.count()).isEqualTo(0L); } - @ImportResource(value = "classpath:/dynamic-index-repository-test.xml") - static class TestConfig { - - @Bean - public IndexNameProvider indexNameProvider() { - return new IndexNameProvider(); - } - - } - static class IndexNameProvider { private String indexName; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java similarity index 65% rename from src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java rename to src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java index 5f73e9e3e..7dadae7c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRestRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java @@ -13,26 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.elasticsearch.repository.query.keywords; +package org.springframework.data.elasticsearch.repositories.dynamicindex; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.test.context.ContextConfiguration; /** - * {@link QueryKeywordsTests} using a Repository backed by an ElasticsearchRestTemplate. - * * @author Peter-Josef Meisch */ -@ContextConfiguration(classes = { QueryKeywordsRestRepositoryTests.Config.class }) -public class QueryKeywordsRestRepositoryTests extends QueryKeywordsTests { +@ContextConfiguration(classes = { DynamicIndexEntityTransportTests.Config.class }) +public class DynamicIndexEntityTransportTests extends DynamicIndexEntityTests { @Configuration - @Import({ ElasticsearchRestTemplateConfiguration.class }) - @EnableElasticsearchRepositories( - basePackages = { "org.springframework.data.elasticsearch.repository.query.keywords" }, - considerNestedRepositories = true) + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 2ee6fe916..a2de6313e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -34,9 +34,9 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -57,18 +57,17 @@ public class SpringDataGeoRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.geo" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} - @Autowired ElasticsearchTemplate template; + @Autowired ElasticsearchOperations operations; @Autowired SpringDataGeoRepository repository; @BeforeEach public void init() { - IndexInitializer.init(template, GeoEntity.class); + IndexInitializer.init(operations, GeoEntity.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java new file mode 100644 index 000000000..81c3d3a3e --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.geo; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { SpringDataGeoRepositoryTransportTests.Config.class }) +public class SpringDataGeoRepositoryTransportTests extends SpringDataGeoRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index f99fafae9..680e4d374 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -21,18 +21,21 @@ import java.util.Optional; import org.apache.commons.lang.math.RandomUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Rizwan Idrees @@ -41,17 +44,22 @@ * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:/integer-id-repository-test.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { IntegerIDRepositoryTests.Config.class }) public class IntegerIDRepositoryTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} + @Autowired private IntegerIDRepository repository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; - @Before + @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, IntegerIDEntity.class); + IndexInitializer.init(operations, IntegerIDEntity.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java new file mode 100644 index 000000000..451ef33b9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.integer; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { IntegerIDRepositoryTransportTests.Config.class }) +public class IntegerIDRepositoryTransportTests extends IntegerIDRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index 698b7e3fe..4079afc3a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -29,38 +29,46 @@ import java.util.HashMap; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; 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.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Mohsin Husen * @author Christoph Strobl * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration("classpath:/repository-test-nested-object-books.xml") +@SpringIntegrationTest +@ContextConfiguration(classes = { InnerObjectTests.Config.class }) public class InnerObjectTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} + @Autowired private SampleElasticSearchBookRepository bookRepository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; - @Before + @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, Book.class); + IndexInitializer.init(operations, Book.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java new file mode 100644 index 000000000..62d5ff43e --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.nestedobject; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { InnerObjectTransportTests.Config.class }) +public class InnerObjectTransportTests extends InnerObjectTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 531b90751..45eb27605 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -31,11 +31,11 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -54,19 +54,17 @@ public class DynamicSettingAndMappingEntityRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories( - basePackages = { "org.springframework.data.elasticsearch.repositories.setting.dynamic" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} - @Autowired private DynamicSettingAndMappingEntityRepository repository; + @Autowired private ElasticsearchOperations operations; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private DynamicSettingAndMappingEntityRepository repository; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, DynamicSettingAndMappingEntity.class); + IndexInitializer.init(operations, DynamicSettingAndMappingEntity.class); } @Test // DATAES-64 @@ -76,8 +74,8 @@ public void shouldCreateGivenDynamicSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - assertThat(elasticsearchTemplate.indexExists(DynamicSettingAndMappingEntity.class)).isTrue(); - Map map = elasticsearchTemplate.getSetting(DynamicSettingAndMappingEntity.class); + assertThat(operations.indexExists(DynamicSettingAndMappingEntity.class)).isTrue(); + Map map = operations.getSetting(DynamicSettingAndMappingEntity.class); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); @@ -108,10 +106,10 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build(); - IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping").withTypes( "test-setting-type"); - long count = elasticsearchTemplate.count(searchQuery, DynamicSettingAndMappingEntity.class, - index); - List entityList = elasticsearchTemplate.queryForList(searchQuery, + IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping") + .withTypes("test-setting-type"); + long count = operations.count(searchQuery, DynamicSettingAndMappingEntity.class, index); + List entityList = operations.queryForList(searchQuery, DynamicSettingAndMappingEntity.class, index); // then @@ -127,7 +125,7 @@ public void shouldGetMappingForGivenIndexAndType() { // delete , create and apply mapping in before method // when - Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); // then Map properties = (Map) mapping.get("properties"); @@ -142,9 +140,9 @@ public void shouldGetMappingForGivenIndexAndType() { public void shouldCreateMappingWithSpecifiedMappings() { // given - elasticsearchTemplate.deleteIndex(DynamicSettingAndMappingEntity.class); - elasticsearchTemplate.createIndex(DynamicSettingAndMappingEntity.class); - elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class); + operations.deleteIndex(DynamicSettingAndMappingEntity.class); + operations.createIndex(DynamicSettingAndMappingEntity.class); + operations.refresh(DynamicSettingAndMappingEntity.class); // when String mappings = "{\n" + // @@ -154,11 +152,11 @@ public void shouldCreateMappingWithSpecifiedMappings() { " }\n" + // " }\n" + // "}"; - elasticsearchTemplate.putMapping(DynamicSettingAndMappingEntity.class, mappings); - elasticsearchTemplate.refresh(DynamicSettingAndMappingEntity.class); + operations.putMapping(DynamicSettingAndMappingEntity.class, mappings); + operations.refresh(DynamicSettingAndMappingEntity.class); // then - Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); @@ -173,7 +171,7 @@ public void shouldCreateMappingWithUsingMappingAnnotation() { // given // then - Map mapping = elasticsearchTemplate.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java new file mode 100644 index 000000000..c4e0c0b8c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 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.repositories.setting.dynamic; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { DynamicSettingAndMappingEntityRepositoryTransportTests.Config.class }) +public class DynamicSettingAndMappingEntityRepositoryTransportTests + extends DynamicSettingAndMappingEntityRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index 9693a4050..3ac5c7145 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -27,8 +27,8 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -46,19 +46,17 @@ public class FieldDynamicMappingEntityRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories( - basePackages = { "org.springframework.data.elasticsearch.repositories.setting.fielddynamic" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} @Autowired private FieldDynamicMappingEntityRepository repository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, FieldDynamicMappingEntity.class); + IndexInitializer.init(operations, FieldDynamicMappingEntity.class); } @Test // DATAES-209 @@ -67,7 +65,7 @@ public void shouldCreateMappingWithMappingAnnotationAtFieldLevel() { // given // then - Map mapping = elasticsearchTemplate.getMapping(FieldDynamicMappingEntity.class); + Map mapping = operations.getMapping(FieldDynamicMappingEntity.class); assertThat(mapping).isNotNull(); Map properties = (Map) mapping.get("properties"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java new file mode 100644 index 000000000..03a68bcf9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.setting.fielddynamic; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { FieldDynamicMappingEntityRepositoryTransportTests.Config.class }) +public class FieldDynamicMappingEntityRepositoryTransportTests extends FieldDynamicMappingEntityRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index fe7acedc8..56d8b9703 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -25,10 +25,10 @@ import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -45,18 +45,18 @@ @ContextConfiguration(classes = { SpELEntityTests.Config.class }) public class SpELEntityTests { - @Autowired private SpELRepository repository; - - @Autowired private ElasticsearchTemplate template; - @Configuration - @Import(ElasticsearchTemplateConfiguration.class) + @Import(ElasticsearchRestTemplateConfiguration.class) @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} + @Autowired private SpELRepository repository; + + @Autowired private ElasticsearchOperations operations; + @BeforeEach public void before() { - IndexInitializer.init(template, SpELEntity.class); + IndexInitializer.init(operations, SpELEntity.class); } @Test @@ -70,7 +70,7 @@ public void shouldDo() { // then NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); - long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); + long count = operations.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(2); } @@ -85,7 +85,7 @@ public void shouldSupportSpelInType() { // then NativeSearchQuery nativeSearchQuery = new NativeSearchQuery(QueryBuilders.matchAllQuery()); - long count = template.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); + long count = operations.count(nativeSearchQuery, IndexCoordinates.of("test-index-abz-entity")); assertThat(count).isEqualTo(1); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java new file mode 100644 index 000000000..3e4dd6c70 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.spel; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { SpELEntityTransportTests.Config.class }) +public class SpELEntityTransportTests extends SpELEntityTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index b2bb76daf..57c19799c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -31,10 +31,10 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -52,18 +52,17 @@ public class SynonymRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.synonym" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} @Autowired private SynonymRepository repository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, SynonymEntity.class); + IndexInitializer.init(operations, SynonymEntity.class); } @Test @@ -83,9 +82,9 @@ public void shouldDo() { // then assertThat(repository.count()).isEqualTo(2L); - List synonymEntities = elasticsearchTemplate.queryForList( + List synonymEntities = operations.queryForList( new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("text", "british")).build(), - SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes( "synonym-type")); + SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes("synonym-type")); assertThat(synonymEntities).hasSize(1); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java new file mode 100644 index 000000000..b0e52a913 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.synonym; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { SynonymRepositoryTransportTests.Config.class }) +public class SynonymRepositoryTransportTests extends SynonymRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 27a7608c2..4ad24d3c6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -44,11 +44,11 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -69,19 +69,18 @@ public class UUIDElasticsearchRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.repositories.uuidkeyed" }, - considerNestedRepositories = true) + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} @Autowired private SampleUUIDKeyedElasticsearchRepository repository; - @Autowired private ElasticsearchTemplate elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; @BeforeEach public void before() { - IndexInitializer.init(elasticsearchTemplate, SampleEntityUUIDKeyed.class); + IndexInitializer.init(operations, SampleEntityUUIDKeyed.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java new file mode 100644 index 000000000..abbc32a43 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.repositories.uuidkeyed; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { UUIDElasticsearchRepositoryTransportTests.Config.class }) +public class UUIDElasticsearchRepositoryTransportTests extends UUIDElasticsearchRepositoryTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java index c536cebcb..674ab6055 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java @@ -23,9 +23,7 @@ import lombok.NoArgsConstructor; import org.assertj.core.api.Assertions; -import org.junit.Test; -import org.junit.runner.RunWith; - +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; @@ -35,17 +33,16 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; /** * @author Christoph Strobl - * @currentRead Fool's Fate - Robin Hobb * @author Peter-Josef Meisch */ -@RunWith(SpringRunner.class) -@ContextConfiguration +@SpringIntegrationTest +@ContextConfiguration(classes = { ReactiveElasticsearchRepositoriesRegistrarTests.Config.class }) public class ReactiveElasticsearchRepositoriesRegistrarTests { @Configuration diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java index 9739f20b0..b3fa4de59 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java @@ -19,8 +19,7 @@ import java.util.Collection; -import org.junit.Test; - +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.core.env.Environment; @@ -37,7 +36,7 @@ /** * @author Christoph Strobl - * @currentRead Fool's Fate - Robin Hobb + * @author Peter-Josef Meisch */ public class ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java similarity index 80% rename from src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java rename to src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java index 034f9955c..59f31af29 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java @@ -26,13 +26,11 @@ * * @author Peter-Josef Meisch */ -@ContextConfiguration(classes = { QueryKeywordsRepositoryTests.Config.class}) -public class QueryKeywordsRepositoryTests extends QueryKeywordsTests { +@ContextConfiguration(classes = { QueryKeywordsRepositoryTransportTests.Config.class }) +public class QueryKeywordsRepositoryTransportTests extends QueryKeywordsTests { @Configuration @Import({ ElasticsearchTemplateConfiguration.class }) - @EnableElasticsearchRepositories( - basePackages = { "org.springframework.data.elasticsearch.repository.query.keywords" }, - considerNestedRepositories = true) + @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index a70d839c5..de43eed5d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -31,14 +31,19 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; 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.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.test.context.ContextConfiguration; /** * base class for query keyword tests. Implemented by subclasses using ElasticsearchClient and ElasticsearchRestClient @@ -49,7 +54,13 @@ * @author Peter-Josef Meisch */ @SpringIntegrationTest -abstract class QueryKeywordsTests { +@ContextConfiguration(classes = { QueryKeywordsTests.Config.class }) +class QueryKeywordsTests { + + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} @Autowired private ProductRepository repository; diff --git a/src/test/resources/complex-custom-method-repository-manual-wiring-test.xml b/src/test/resources/complex-custom-method-repository-manual-wiring-test.xml deleted file mode 100644 index 5fd597009..000000000 --- a/src/test/resources/complex-custom-method-repository-manual-wiring-test.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/test/resources/double-id-repository-test.xml b/src/test/resources/double-id-repository-test.xml deleted file mode 100644 index 44f5d70f7..000000000 --- a/src/test/resources/double-id-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/dynamic-index-repository-test.xml b/src/test/resources/dynamic-index-repository-test.xml deleted file mode 100644 index 05029c0bc..000000000 --- a/src/test/resources/dynamic-index-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/elasticsearch-rest-template-test.xml b/src/test/resources/elasticsearch-rest-template-test.xml deleted file mode 100644 index 8204543b8..000000000 --- a/src/test/resources/elasticsearch-rest-template-test.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/elasticsearch-template-test.xml b/src/test/resources/elasticsearch-template-test.xml deleted file mode 100644 index d9785793a..000000000 --- a/src/test/resources/elasticsearch-template-test.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/existing-index-repository-test.xml b/src/test/resources/existing-index-repository-test.xml deleted file mode 100644 index c9fe5eb79..000000000 --- a/src/test/resources/existing-index-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/field-dynamic-settings-test.xml b/src/test/resources/field-dynamic-settings-test.xml deleted file mode 100644 index ac9da11b7..000000000 --- a/src/test/resources/field-dynamic-settings-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/infrastructure.xml b/src/test/resources/infrastructure.xml deleted file mode 100644 index d53d9c4a0..000000000 --- a/src/test/resources/infrastructure.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/integer-id-repository-test.xml b/src/test/resources/integer-id-repository-test.xml deleted file mode 100644 index 1e4c354ef..000000000 --- a/src/test/resources/integer-id-repository-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/repository-non-document-entity.xml b/src/test/resources/repository-non-document-entity.xml index 64b7fb1a7..e1645c556 100644 --- a/src/test/resources/repository-non-document-entity.xml +++ b/src/test/resources/repository-non-document-entity.xml @@ -1,19 +1,21 @@ - + - - - + + + - + diff --git a/src/test/resources/repository-test-nested-object-books.xml b/src/test/resources/repository-test-nested-object-books.xml deleted file mode 100644 index d4b40ddb5..000000000 --- a/src/test/resources/repository-test-nested-object-books.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/repository-test-nested-object.xml b/src/test/resources/repository-test-nested-object.xml deleted file mode 100644 index 1aa3e21de..000000000 --- a/src/test/resources/repository-test-nested-object.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - diff --git a/src/test/resources/synonym-test.xml b/src/test/resources/synonym-test.xml deleted file mode 100644 index f36931f1f..000000000 --- a/src/test/resources/synonym-test.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - From aa4ae525f4798114e555ca27effd0956f2b71316 Mon Sep 17 00:00:00 2001 From: Sascha Woo Date: Tue, 3 Dec 2019 12:16:52 +0100 Subject: [PATCH 0011/1191] DATAES-702 - Travis CI builds currently broken. Original PR: #351 --- .travis.yml | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 82d2ab665..0b2b94275 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,8 @@ +dist: xenial + language: java jdk: - - oraclejdk8 - -before_install: - - curl -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-${ES_VERSION}.deb && sudo dpkg -i --force-confnew elasticsearch-${ES_VERSION}.deb && sudo service elasticsearch restart - - sleep 10 - -env: - global: - - ES_VERSION=6.5.1 - -addons: - apt: - packages: - - oracle-java8-set-default - - oracle-java8-installer - -sudo: true + - openjdk8 -script: "mvn clean dependency:list test -Dsort" +script: "mvn clean dependency:list test -Dsort -U -B" From e882dae3afa1406feef30f7ba7a851135bbc6948 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 4 Dec 2019 11:40:55 +0100 Subject: [PATCH 0012/1191] DATAES-691 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 4ede9e2f7..950c8c9a5 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.14.RELEASE (2019-12-04) +---------------------------------------------- +* DATAES-691 - Release 3.1.14 (Lovelace SR14). + + Changes in version 3.2.2.RELEASE (2019-11-18) --------------------------------------------- * DATAES-685 - Release 3.2.2 (Moore SR2). @@ -910,3 +915,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) * #8 - java.lang.NoSuchMethodError: org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty.isVersionProperty()Z * #7 - Missing core types in org.springframework.data.elasticsearch.annotations.FieldType * #6 - spirng-data-elasticsearch with elasticsearch-river-mongodb + From 9d4fe6d4afa6ae230af0e807f1a005eb948fc84c Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 4 Dec 2019 14:11:42 +0100 Subject: [PATCH 0013/1191] DATAES-692 - Updated changelog. --- src/main/resources/changelog.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 950c8c9a5..7488d2037 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,13 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.3.RELEASE (2019-12-04) +--------------------------------------------- +* DATAES-700 - Enable proxy support for RestClient. +* DATAES-699 - ElasticsearchRestTemplate.count(..) returns all documents instead of just total hits number. +* DATAES-692 - Release 3.2.3 (Moore SR3). + + Changes in version 3.1.14.RELEASE (2019-12-04) ---------------------------------------------- * DATAES-691 - Release 3.1.14 (Lovelace SR14). @@ -916,3 +923,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) * #7 - Missing core types in org.springframework.data.elasticsearch.annotations.FieldType * #6 - spirng-data-elasticsearch with elasticsearch-river-mongodb + From ff381c63b6d7633a7a17b3d8a63db36661763afe Mon Sep 17 00:00:00 2001 From: Sascha Woo Date: Fri, 6 Dec 2019 13:15:15 +0100 Subject: [PATCH 0014/1191] DATAES-187 - Use Pageable#getOffset to set from offset in SearchRequest. Original PR: #353 --- .../elasticsearch/core/RequestFactory.java | 9 ++--- .../core/ElasticsearchTemplateTests.java | 34 ++++++++++++++++--- .../ElasticsearchTransportTemplateTests.java | 34 +++++++++++++++++++ 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index e1b880015..04e036639 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -75,6 +75,7 @@ * Factory class to create Elasticsearch request instances from Spring Data Elasticsearch query objects. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ class RequestFactory { @@ -551,7 +552,6 @@ private SearchRequest prepareSearchRequest(Query query, Optional b Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); Assert.notNull(index.getTypeNames(), "No type defined for Query"); - int startRecord = 0; SearchRequest request = new SearchRequest(index.getIndexNames()); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); request.types(index.getTypeNames()); @@ -566,10 +566,9 @@ private SearchRequest prepareSearchRequest(Query query, Optional b } if (query.getPageable().isPaged()) { - startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); + sourceBuilder.from((int) query.getPageable().getOffset()); sourceBuilder.size(query.getPageable().getPageSize()); } - sourceBuilder.from(startRecord); if (!query.getFields().isEmpty()) { sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); @@ -618,7 +617,6 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); Assert.notNull(index.getTypeNames(), "No type defined for Query"); - int startRecord = 0; SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index.getIndexNames()) // .setSearchType(query.getSearchType()) // .setTypes(index.getTypeNames()) // @@ -631,10 +629,9 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli } if (query.getPageable().isPaged()) { - startRecord = query.getPageable().getPageNumber() * query.getPageable().getPageSize(); + searchRequestBuilder.setFrom((int) query.getPageable().getOffset()); searchRequestBuilder.setSize(query.getPageable().getPageSize()); } - searchRequestBuilder.setFrom(startRecord); if (!query.getFields().isEmpty()) { searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 67a8cf400..ee2718ae0 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -43,6 +43,7 @@ import org.assertj.core.util.Lists; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; @@ -61,6 +62,7 @@ import org.springframework.data.annotation.Version; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.ElasticsearchException; @@ -1443,8 +1445,7 @@ public void shouldUseUpsertOnUpdate() throws IOException { .withUpdateRequest(updateRequest).build(); // when - UpdateRequest request = ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory() - .updateRequest(updateQuery, IndexCoordinates.of("index")); + UpdateRequest request = getRequestFactory().updateRequest(updateQuery, IndexCoordinates.of("index")); // then assertThat(request).isNotNull(); @@ -1465,8 +1466,7 @@ public void shouldReturnSourceWhenRequested() throws IOException { .withUpdateRequest(updateRequest).build(); // when - UpdateRequest request = ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory() - .updateRequest(updateQuery, IndexCoordinates.of("index")); + UpdateRequest request = getRequestFactory().updateRequest(updateQuery, IndexCoordinates.of("index")); // then assertThat(request).isNotNull(); @@ -2794,6 +2794,32 @@ class ResultAggregator { } } + @Test // DATAES-187 + public void shouldUsePageableOffsetToSetFromInSearchRequest() { + + // given + Pageable pageable = new PageRequest(1, 10, Sort.unsorted()) { + @Override + public long getOffset() { + return 30; + } + }; + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withPageable(pageable) // + .build(); + + // when + SearchRequest searchRequest = getRequestFactory().searchRequest(query, null, IndexCoordinates.of("test")); + + // then + assertThat(searchRequest.source().from()).isEqualTo(30); + } + + protected RequestFactory getRequestFactory() { + return ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory(); + } + @Data @NoArgsConstructor @AllArgsConstructor diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index f5ffc790f..0fdde2b78 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -22,12 +22,20 @@ import lombok.Data; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.client.Client; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.engine.DocumentMissingException; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; @@ -36,11 +44,14 @@ /** * @author Peter-Josef Meisch + * @author Sascha Woo */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class ElasticsearchTransportTemplateTests extends ElasticsearchTemplateTests { + @Autowired private Client client; + @Test public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() { // when @@ -52,6 +63,29 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() }).isInstanceOf(DocumentMissingException.class); } + @Test // DATAES-187 + public void shouldUsePageableOffsetToSetFromInSearchRequest() { + + // given + Pageable pageable = new PageRequest(1, 10, Sort.unsorted()) { + @Override + public long getOffset() { + return 30; + } + }; + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withPageable(pageable) // + .build(); + + // when + SearchRequestBuilder searchRequestBuilder = getRequestFactory().searchRequestBuilder(client, query, null, + IndexCoordinates.of("test")); + + // then + assertThat(searchRequestBuilder.request().source().from()).isEqualTo(30); + } + @Data @Document(indexName = "test-index-sample-core-transport-template", type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") From 11a6430a90abf5d27909bbc8567acfdeb09959fa Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 10 Dec 2019 19:04:37 +0100 Subject: [PATCH 0015/1191] DATAES-634 - Rearrange methods in Template API. Original PR: #352 --- .../core/AbstractDefaultIndexOperations.java | 171 ++++ .../core/AbstractElasticsearchTemplate.java | 221 ++--- .../core/DefaultIndexOperations.java | 281 +++++++ .../core/DefaultTransportIndexOperations.java | 141 ++++ .../core/DocumentOperations.java | 136 +++ .../core/ElasticsearchOperations.java | 547 ++++-------- .../core/ElasticsearchRestTemplate.java | 429 ++-------- .../core/ElasticsearchTemplate.java | 262 ++---- .../elasticsearch/core/EntityOperations.java | 5 +- .../elasticsearch/core/IndexOperations.java | 216 +++++ .../core/ReactiveDocumentOperations.java | 186 +++++ .../core/ReactiveElasticsearchOperations.java | 271 +----- .../core/ReactiveElasticsearchTemplate.java | 529 ++++++------ .../core/ReactiveSearchOperations.java | 119 +++ .../elasticsearch/core/RequestFactory.java | 1 + .../elasticsearch/core/SearchOperations.java | 204 +++++ .../core/index/MappingBuilder.java | 13 +- .../ElasticsearchPersistentEntity.java | 4 +- .../core/{ => mapping}/IndexCoordinates.java | 2 +- .../SimpleElasticsearchPersistentEntity.java | 11 +- .../repository/ElasticsearchRepository.java | 3 +- ...tReactiveElasticsearchRepositoryQuery.java | 2 +- .../query/ElasticsearchPartQuery.java | 2 +- .../query/ElasticsearchStringQuery.java | 2 +- .../ReactiveElasticsearchQueryExecution.java | 2 +- .../SimpleElasticsearchEntityMetadata.java | 4 +- .../AbstractElasticsearchRepository.java | 83 +- .../ElasticsearchEntityInformation.java | 6 +- ...MappingElasticsearchEntityInformation.java | 21 +- ...eactiveElasticsearchRepositoryFactory.java | 5 +- ...SimpleReactiveElasticsearchRepository.java | 21 +- .../data/elasticsearch/NestedObjectTests.java | 2 +- .../core/ElasticsearchRestTemplateTests.java | 2 +- .../core/ElasticsearchTemplateTests.java | 785 +++++++++--------- .../ElasticsearchTransportTemplateTests.java | 3 +- .../core/IndexCoordinatesTest.java | 1 + .../elasticsearch/core/LogEntityTests.java | 1 + .../ReactiveElasticsearchTemplateTests.java | 1 + ...eactiveElasticsearchTemplateUnitTests.java | 1 + ...ElasticsearchTemplateAggregationTests.java | 2 +- .../ElasticsearchTemplateCompletionTests.java | 33 +- ...chTemplateCompletionWithContextsTests.java | 26 +- .../geo/ElasticsearchTemplateGeoTests.java | 22 +- .../core/index/MappingBuilderTests.java | 2 +- .../core/query/CriteriaQueryTests.java | 2 +- .../dynamicindex/DynamicIndexEntityTests.java | 12 +- .../nondocument/NonDocumentEntityTests.java | 78 -- ...ettingAndMappingEntityRepositoryTests.java | 2 +- .../repositories/spel/SpELEntityTests.java | 2 +- .../synonym/SynonymRepositoryTests.java | 2 +- .../elasticsearch/utils/IndexInitializer.java | 16 + .../repository-non-document-entity.xml | 21 - 52 files changed, 2740 insertions(+), 2176 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java rename src/main/java/org/springframework/data/elasticsearch/core/{ => mapping}/IndexCoordinates.java (97%) delete mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/nondocument/NonDocumentEntityTests.java delete mode 100644 src/test/resources/repository-non-document-entity.xml diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java new file mode 100644 index 000000000..1ea286d54 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -0,0 +1,171 @@ +/* + * Copyright 2019 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; + +import static org.springframework.util.StringUtils.*; + +import java.util.HashMap; +import java.util.Map; + +import org.elasticsearch.common.collect.MapBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.Setting; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.index.MappingBuilder; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.util.StringUtils; + +/** + * Base implementation of {@link IndexOperations} common to Transport and Rest based Implementations of IndexOperations. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +abstract class AbstractDefaultIndexOperations implements IndexOperations { + + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractDefaultIndexOperations.class); + + protected final ElasticsearchConverter elasticsearchConverter; + protected final RequestFactory requestFactory; + + public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter) { + this.elasticsearchConverter = elasticsearchConverter; + requestFactory = new RequestFactory(elasticsearchConverter); + } + + // region IndexOperations + @Override + public boolean createIndex(String indexName) { + return createIndex(indexName, null); + } + + @Override + public boolean createIndex(Class clazz) { + + String indexName = getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(); + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + + if (hasText(settingPath)) { + String settings = ResourceUtil.readFileFromClasspath(settingPath); + + if (hasText(settings)) { + return createIndex(indexName, settings); + } + } else { + LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); + } + } + return createIndex(indexName, getDefaultSettings(getRequiredPersistentEntity(clazz))); + } + + @Override + public boolean createIndex(Class clazz, Object settings) { + return createIndex(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(), settings); + } + + @Override + public boolean deleteIndex(Class clazz) { + return deleteIndex(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName()); + } + + @Override + public boolean indexExists(Class clazz) { + return indexExists(getIndexCoordinatesFor(clazz).getIndexName()); + } + + @Override + public Map getMapping(Class clazz) { + return getMapping(getIndexCoordinatesFor(clazz)); + } + + @Override + public boolean putMapping(Class clazz) { + return putMapping(clazz, buildMapping(clazz)); + } + + @Override + public boolean putMapping(Class clazz, Object mapping) { + return putMapping(getIndexCoordinatesFor(clazz), mapping); + } + + @Override + public boolean putMapping(IndexCoordinates index, Class clazz) { + return putMapping(index, buildMapping(clazz)); + } + + @Override + public Map getSetting(Class clazz) { + return getSetting(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName()); + } + + @Override + public void refresh(Class clazz) { + refresh(getIndexCoordinatesFor(clazz)); + } + + protected String buildMapping(Class clazz) { + + // load mapping specified in Mapping annotation if present + if (clazz.isAnnotationPresent(Mapping.class)) { + String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); + + if (!StringUtils.isEmpty(mappingPath)) { + String mappings = ResourceUtil.readFileFromClasspath(mappingPath); + + if (!StringUtils.isEmpty(mappings)) { + return mappings; + } + } else { + LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); + } + } + + // build mapping from field annotations + try { + return new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz); + } catch (Exception e) { + throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); + } + } + // endregion + + // region Helper functions + private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { + + if (persistentEntity.isUseServerConfiguration()) + return new HashMap(); + + return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) + .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) + .put("index.refresh_interval", persistentEntity.getRefreshInterval()) + .put("index.store.type", persistentEntity.getIndexStoreType()).map(); + } + + ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { + return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); + } + + public IndexCoordinates getIndexCoordinatesFor(Class clazz) { + return getRequiredPersistentEntity(clazz).getIndexCoordinates(); + } + // endregion + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 5f71bb590..8006dc996 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -1,7 +1,5 @@ package org.springframework.data.elasticsearch.core; -import static org.springframework.util.StringUtils.*; - import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -14,32 +12,28 @@ import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; +import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.suggest.SuggestBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.annotations.Mapping; -import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; -import org.springframework.data.elasticsearch.core.index.MappingBuilder; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.util.CloseableIterator; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * AbstractElasticsearchTemplate @@ -49,22 +43,18 @@ */ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class); - protected ElasticsearchConverter elasticsearchConverter; protected RequestFactory requestFactory; + protected IndexOperations indexOperations; - /** - * @since 4.0 - */ - public RequestFactory getRequestFactory() { - return requestFactory; - } + // region Initialization + protected void initialize(ElasticsearchConverter elasticsearchConverter, IndexOperations indexOperations) { - protected void initialize(ElasticsearchConverter elasticsearchConverter) { Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); + this.elasticsearchConverter = elasticsearchConverter; - this.requestFactory = new RequestFactory(elasticsearchConverter); + requestFactory = new RequestFactory(elasticsearchConverter); + this.indexOperations = indexOperations; } protected ElasticsearchConverter createElasticsearchConverter() { @@ -76,129 +66,54 @@ protected ElasticsearchConverter createElasticsearchConverter() { @Override public void setApplicationContext(ApplicationContext context) throws BeansException { + if (elasticsearchConverter instanceof ApplicationContextAware) { ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context); } } + // endregion - protected String buildMapping(Class clazz) { - - // load mapping specified in Mapping annotation if present - if (clazz.isAnnotationPresent(Mapping.class)) { - String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); - if (!StringUtils.isEmpty(mappingPath)) { - String mappings = ResourceUtil.readFileFromClasspath(mappingPath); - if (!StringUtils.isEmpty(mappings)) { - return mappings; - } - } else { - LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); - } - } - - // build mapping from field annotations - try { - MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter); - return mappingBuilder.buildPropertyMapping(clazz); - } catch (Exception e) { - throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); - } - } - - @Override - public boolean createIndex(String indexName) { - return createIndexIfNotCreated(indexName); - } - - private boolean createIndexIfNotCreated(String indexName) { - return indexExists(indexName) || createIndex(indexName, null); - } - - @Override - public boolean createIndex(Class clazz) { - return createIndexIfNotCreated(clazz); - } - - private boolean createIndexIfNotCreated(Class clazz) { - return indexExists(getPersistentEntityFor(clazz).getIndexName()) || createIndexWithSettings(clazz); - } - - private boolean createIndexWithSettings(Class clazz) { - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - if (hasText(settingPath)) { - String settings = ResourceUtil.readFileFromClasspath(settingPath); - if (hasText(settings)) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); - } - } else { - LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); - } - } - return createIndex(getPersistentEntityFor(clazz).getIndexName(), getDefaultSettings(getPersistentEntityFor(clazz))); - } - + // region getter/setter @Override - public boolean createIndex(Class clazz, Object settings) { - return createIndex(getPersistentEntityFor(clazz).getIndexName(), settings); + public IndexOperations getIndexOperations() { + return indexOperations; } + // endregion - @Override + // region DocumentOperations public void delete(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query, "Query must not be null."); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(searchRequest.source().query()); - delete(deleteQuery, index); - } - - @Override - public Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { - Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); - MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index); - return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); - } - protected static String[] toArray(List values) { - String[] valuesAsArray = new String[values.size()]; - return values.toArray(valuesAsArray); + delete(deleteQuery, index); } + // endregion + // region SearchOperations @Override - public ElasticsearchConverter getElasticsearchConverter() { - return elasticsearchConverter; + public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { + long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); + return StreamQueries.streamResults(startScroll(scrollTimeInMillis, query, clazz, index), + scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), this::clearScroll); } @Override - public ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz) { - Assert.isTrue(clazz.isAnnotationPresent(Document.class), "Unable to identify index name. " + clazz.getSimpleName() - + " is not a Document. Make sure the document class is annotated with @Document(indexName=\"foo\")"); - return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); - } + public Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { - private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { + Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); - if (persistentEntity.isUseServerConfiguration()) - return new HashMap(); + MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index); - return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) - .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) - .put("index.refresh_interval", persistentEntity.getRefreshInterval()) - .put("index.store.type", persistentEntity.getIndexStoreType()).map(); + return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); } - protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { - if (bulkResponse.hasFailures()) { - Map failedDocuments = new HashMap<>(); - for (BulkItemResponse item : bulkResponse.getItems()) { - if (item.isFailed()) - failedDocuments.put(item.getId(), item.getFailureMessage()); - } - throw new ElasticsearchException( - "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" - + failedDocuments + "]", - failedDocuments); - } + @Override + public List queryForList(Query query, Class clazz, IndexCoordinates index) { + return queryForPage(query, clazz, index).getContent(); } @Override @@ -244,34 +159,80 @@ private List> doMultiSearch(List queries, List return res; } - @Override - public boolean putMapping(Class clazz) { - return putMapping(clazz, buildMapping(clazz)); + abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); + + protected List extractIds(SearchResponse response) { + List ids = new ArrayList<>(); + for (SearchHit hit : response.getHits()) { + if (hit != null) { + ids.add(hit.getId()); + } + } + return ids; } + // endregion + + // region Helper methods @Override - public boolean putMapping(Class clazz, Object mapping) { - return putMapping(getIndexCoordinatesFor(clazz), mapping); + public ElasticsearchConverter getElasticsearchConverter() { + return elasticsearchConverter; } - @Override - public boolean putMapping(IndexCoordinates index, Class clazz) { - return putMapping(index, buildMapping(clazz)); + /** + * @since 4.0 + */ + public RequestFactory getRequestFactory() { + return requestFactory; } - abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); + protected static String[] toArray(List values) { + String[] valuesAsArray = new String[values.size()]; + return values.toArray(valuesAsArray); + } + @Override public abstract SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); + /** + * @param clazz + * @return the IndexCoordinates defined on the entity. + * @since 4.0 + */ + @Override + public IndexCoordinates getIndexCoordinatesFor(Class clazz) { + return getRequiredPersistentEntity(clazz).getIndexCoordinates(); + } + + protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { + + if (bulkResponse.hasFailures()) { + Map failedDocuments = new HashMap<>(); + for (BulkItemResponse item : bulkResponse.getItems()) { + + if (item.isFailed()) + failedDocuments.put(item.getId(), item.getFailureMessage()); + } + throw new ElasticsearchException( + "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + + failedDocuments + ']', + failedDocuments); + } + } + protected void setPersistentEntityId(Object entity, String id) { - ElasticsearchPersistentEntity persistentEntity = getPersistentEntityFor(entity.getClass()); + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); - // Only deal with text because ES generated Ids are strings ! - + // Only deal with text because ES generated Ids are strings! if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id); } } + + ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { + return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java new file mode 100644 index 000000000..6b4f1aa03 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -0,0 +1,281 @@ +/* + * Copyright 2019 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; + +import static org.elasticsearch.client.Requests.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.http.util.EntityUtils; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.Response; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.DeprecationHandler; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.common.xcontent.XContentType; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.core.client.support.AliasData; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.util.Assert; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * {@link IndexOperations} implementation using the RestClient. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +class DefaultIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { + + private RestHighLevelClient client; + + public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { + super(elasticsearchConverter); + this.client = client; + } + + @Override + public boolean createIndex(String indexName, Object settings) { + CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); + try { + return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException("Error for creating index: " + request.toString(), e); + } + } + + @Override + public boolean deleteIndex(String indexName) { + + Assert.notNull(indexName, "No index defined for delete operation"); + + if (indexExists(indexName)) { + DeleteIndexRequest request = new DeleteIndexRequest(indexName); + try { + return client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException("Error while deleting index request: " + request.toString(), e); + } + } + return false; + } + + @Override + public boolean indexExists(String indexName) { + GetIndexRequest request = new GetIndexRequest(indexName); + try { + return client.indices().exists(request, RequestOptions.DEFAULT); + } catch (IOException e) { + throw new ElasticsearchException("Error while for indexExists request: " + request.toString(), e); + } + } + + @Override + public boolean putMapping(IndexCoordinates index, Object mapping) { + + Assert.notNull(index, "No index defined for putMapping()"); + + PutMappingRequest request = requestFactory.putMappingRequest(index, mapping); + try { + return client.indices().putMapping(request, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException("Failed to put mapping for " + index.getIndexName(), e); + } + } + + @Override + public Map getMapping(IndexCoordinates index) { + + Assert.notNull(index, "No index defined for getMapping()"); + + RestClient restClient = client.getLowLevelClient(); + try { + Request request = new Request("GET", + '/' + index.getIndexName() + "/_mapping/" + index.getTypeName() + "?include_type_name=true"); + Response response = restClient.performRequest(request); + return convertMappingResponse(EntityUtils.toString(response.getEntity()), index.getTypeName()); + } catch (Exception e) { + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() + + " type : " + index.getTypeName() + ' ', e); + } + } + + @Override + public boolean addAlias(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); + try { + return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException("failed to update aliases with request: " + request, e); + } + } + + @Override + public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + + Assert.notNull(index, "No index defined for Alias"); + Assert.notNull(query.getAliasName(), "No alias defined"); + + IndicesAliasesRequest indicesAliasesRequest = requestFactory.indicesRemoveAliasesRequest(query, index); + try { + return client.indices().updateAliases(indicesAliasesRequest, RequestOptions.DEFAULT).isAcknowledged(); + } catch (IOException e) { + throw new ElasticsearchException( + "failed to update aliases with indicesRemoveAliasesRequest: " + indicesAliasesRequest, e); + } + } + + @Override + public List queryForAlias(String indexName) { + List aliases = null; + RestClient restClient = client.getLowLevelClient(); + Response response; + String aliasResponse; + + try { + response = restClient.performRequest(new Request("GET", '/' + indexName + "/_alias/*")); + aliasResponse = EntityUtils.toString(response.getEntity()); + } catch (Exception e) { + throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName, e); + } + + return convertAliasResponse(aliasResponse); + } + + @Override + public Map getSetting(String indexName) { + + Assert.notNull(indexName, "No index defined for getSettings"); + + ObjectMapper objMapper = new ObjectMapper(); + Map settings = null; + RestClient restClient = client.getLowLevelClient(); + try { + Response response = restClient.performRequest(new Request("GET", "/" + indexName + "/_settings")); + settings = convertSettingResponse(EntityUtils.toString(response.getEntity()), indexName); + + } catch (Exception e) { + throw new ElasticsearchException("Error while getting settings for indexName : " + indexName, e); + } + return settings; + } + + @Override + public void refresh(IndexCoordinates index) { + + Assert.notNull(index, "No index defined for refresh()"); + + try { + client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT); + } catch (IOException e) { + throw new ElasticsearchException("failed to refresh index: " + index, e); + } + } + + // region Helper methods + private Map convertMappingResponse(String mappingResponse, String type) { + ObjectMapper mapper = new ObjectMapper(); + + try { + Map result = null; + JsonNode node = mapper.readTree(mappingResponse); + + node = node.findValue("mappings").findValue(type); + result = mapper.readValue(mapper.writeValueAsString(node), HashMap.class); + + return result; + } catch (IOException e) { + throw new ElasticsearchException("Could not map alias response : " + mappingResponse, e); + } + } + + /** + * It takes two steps to create a List from the elasticsearch http response because the aliases field + * is actually a Map by alias name, but the alias name is on the AliasMetadata. + * + * @param aliasResponse + * @return + */ + private List convertAliasResponse(String aliasResponse) { + ObjectMapper mapper = new ObjectMapper(); + + try { + JsonNode node = mapper.readTree(aliasResponse); + node = node.findValue("aliases"); + + if (node == null) { + return Collections.emptyList(); + } + + Map aliasData = mapper.readValue(mapper.writeValueAsString(node), + new TypeReference>() {}); + + Iterable> aliasIter = aliasData.entrySet(); + List aliasMetaDataList = new ArrayList(); + + for (Map.Entry aliasentry : aliasIter) { + AliasData data = aliasentry.getValue(); + aliasMetaDataList.add(AliasMetaData.newAliasMetaDataBuilder(aliasentry.getKey()).filter(data.getFilter()) + .routing(data.getRouting()).searchRouting(data.getSearch_routing()).indexRouting(data.getIndex_routing()) + .build()); + } + return aliasMetaDataList; + } catch (IOException e) { + throw new ElasticsearchException("Could not map alias response : " + aliasResponse, e); + } + } + + private Map convertSettingResponse(String settingResponse, String indexName) { + ObjectMapper mapper = new ObjectMapper(); + + try { + Settings settings = Settings.fromXContent(XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, settingResponse)); + String prefix = indexName + ".settings."; + // Backwards compatibility. TODO Change to return Settings object. + Map result = new HashMap(); + Set keySet = settings.keySet(); + for (String key : keySet) { + result.put(key.substring(prefix.length()), settings.get(key)); + } + return result; + } catch (IOException e) { + throw new ElasticsearchException("Could not map alias response : " + settingResponse, e); + } + + } + // endregion +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java new file mode 100644 index 000000000..6dc69bd59 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -0,0 +1,141 @@ +/* + * Copyright 2019 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; + +import static org.elasticsearch.client.Requests.*; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.client.Client; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.settings.Settings; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.util.Assert; + +/** + * {@link IndexOperations} implementation using the TransportClient. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { + + private final Client client; + + public DefaultTransportIndexOperations(Client client, ElasticsearchConverter elasticsearchConverter) { + super(elasticsearchConverter); + this.client = client; + } + + @Override + public boolean createIndex(String indexName, Object settings) { + CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, indexName, + settings); + return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); + } + + @Override + public boolean deleteIndex(String indexName) { + + Assert.notNull(indexName, "No index defined for delete operation"); + + if (indexExists(indexName)) { + return client.admin().indices().delete(new DeleteIndexRequest(indexName)).actionGet().isAcknowledged(); + } + return false; + } + + @Override + public boolean indexExists(String indexName) { + return client.admin().indices().exists(indicesExistsRequest(indexName)).actionGet().isExists(); + } + + @Override + public boolean putMapping(IndexCoordinates index, Object mapping) { + + Assert.notNull(index, "No index defined for putMapping()"); + + PutMappingRequestBuilder requestBuilder = requestFactory.putMappingRequestBuilder(client, index, mapping); + return requestBuilder.execute().actionGet().isAcknowledged(); + } + + @Override + public Map getMapping(IndexCoordinates index) { + + Assert.notNull(index, "No index defined for putMapping()"); + + try { + return client.admin().indices() + .getMappings(new GetMappingsRequest().indices(index.getIndexNames()).types(index.getTypeNames())).actionGet() + .getMappings().get(index.getIndexName()).get(index.getTypeName()).getSourceAsMap(); + } catch (Exception e) { + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() + + " type : " + index.getTypeName() + ' ' + e.getMessage()); + } + } + + @Override + public boolean addAlias(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest.AliasActions aliasAction = requestFactory.aliasAction(query, index); + return client.admin().indices().prepareAliases().addAliasAction(aliasAction).execute().actionGet().isAcknowledged(); + } + + @Override + public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + + Assert.notNull(index, "No index defined for Alias"); + Assert.notNull(query.getAliasName(), "No alias defined"); + + return client.admin().indices().prepareAliases().removeAlias(index.getIndexName(), query.getAliasName()).execute() + .actionGet().isAcknowledged(); + } + + @Override + public List queryForAlias(String indexName) { + return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)).actionGet().getAliases() + .get(indexName); + } + + @Override + public Map getSetting(String indexName) { + + Assert.notNull(indexName, "No index defined for getSettings"); + + Settings settings = client.admin().indices().getSettings(new GetSettingsRequest()).actionGet().getIndexToSettings() + .get(indexName); + return settings.keySet().stream().collect(Collectors.toMap((key) -> key, (key) -> settings.get(key))); + } + + @Override + public void refresh(IndexCoordinates index) { + + Assert.notNull(index, "No index defined for refresh()"); + + client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet(); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java new file mode 100644 index 000000000..58b5ee836 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -0,0 +1,136 @@ +/* + * Copyright 2019 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; + +import java.util.List; + +import org.elasticsearch.action.update.UpdateResponse; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; + +/** + * The operations for the + * Elasticsearch Document APIs. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface DocumentOperations { + + /** + * Index an object. Will do save or update. + * + * @param query the query defining the object + * @param index the index from which the object is read. + * @return returns the document id + */ + String index(IndexQuery query, IndexCoordinates index); + + /** + * Retrieves an object from an index. + * + * @param query the query defining the id of the object to get + * @param clazz the type of the object to be returned + * @param index the index from which the object is read. + * @return the found object + */ + T get(GetQuery query, Class clazz, IndexCoordinates index); + + /** + * Execute a multiGet against elasticsearch for the given ids. + * + * @param query the query defining the ids of the objects to get + * @param clazz the type of the object to be returned + * @param index the index(es) from which the objects are read. + * @return list of objects + */ + List multiGet(Query query, Class clazz, IndexCoordinates index); + + /** + * Bulk index all objects. Will do save or update. + * + * @param queries the queries to execute in bulk + */ + default void bulkIndex(List queries, IndexCoordinates index) { + bulkIndex(queries, BulkOptions.defaultOptions(), index); + } + + /** + * Bulk index all objects. Will do save or update. + * + * @param queries the queries to execute in bulk + * @param bulkOptions options to be added to the bulk request + */ + void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); + + /** + * Bulk update all objects. Will do update. + * + * @param queries the queries to execute in bulk + */ + default void bulkUpdate(List queries, IndexCoordinates index) { + bulkUpdate(queries, BulkOptions.defaultOptions(), index); + } + + /** + * Bulk update all objects. Will do update. + * + * @param queries the queries to execute in bulk + * @param bulkOptions options to be added to the bulk request + */ + void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index); + + /** + * Delete the one object with provided id. + * + * @param id the document ot delete + * @param index the index from which to delete + * @return documentId of the document deleted + */ + String delete(String id, IndexCoordinates index); + + /** + * Delete all records matching the query. + * + * @param query query defining the objects + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @param index the index from which to delete + */ + void delete(Query query, Class clazz, IndexCoordinates index); + + /** + * Delete all records matching the query. + * + * @param query query defining the objects + * @param index the index where to delete the records + */ + void delete(DeleteQuery query, IndexCoordinates index); + + /** + * Partial update of the document. + * + * @param updateQuery query defining the update + * @param index the index where to update the records + * @return the update response + */ + UpdateResponse update(UpdateQuery updateQuery, IndexCoordinates index); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index ef467a408..f968f1e3c 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -17,27 +17,17 @@ import java.util.List; import java.util.Map; -import java.util.stream.Collectors; -import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.springframework.data.domain.Page; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; -import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.DeleteQuery; -import org.springframework.data.elasticsearch.core.query.GetQuery; -import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.UpdateQuery; -import org.springframework.data.util.CloseableIterator; -import org.springframework.lang.Nullable; /** - * ElasticsearchOperations + * ElasticsearchOperations. Since 4.0 this interface only contains common helper functions, the other methods have been + * moved to the different interfaces that are extended by ElasticsearchOperations. The interfaces now reflect the - * @return + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @deprecated since 4.0, use {@link IndexOperations#refresh(Class)} instead} */ - Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); - - ElasticsearchPersistentEntity getPersistentEntityFor(Class clazz); - - /** - * @return Converter in use - */ - ElasticsearchConverter getElasticsearchConverter(); - - /** - * @param clazz - * @return the IndexCoordinates defined on the entity. - * @since 4.0 - */ - default IndexCoordinates getIndexCoordinatesFor(Class clazz) { - ElasticsearchPersistentEntity entity = getPersistentEntityFor(clazz); - return IndexCoordinates.of(entity.getIndexName()).withTypes(entity.getIndexType()); + @Deprecated + default void refresh(Class clazz) { + getIndexOperations().refresh(clazz); } - + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 6b37bb967..275b49492 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -15,21 +15,9 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.client.Requests.*; - import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.http.util.EntityUtils; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; -import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; + import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; @@ -45,41 +33,29 @@ import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; -import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.client.indices.GetIndexRequest; -import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.DeprecationHandler; -import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.reindex.DeleteByQueryRequest; -import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.suggest.SuggestBuilder; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; -import org.springframework.data.elasticsearch.core.client.support.AliasData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.SearchHitsUtil; -import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * ElasticsearchRestTemplate * @@ -116,6 +92,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { private RestHighLevelClient client; + // region Initialization public ElasticsearchRestTemplate(RestHighLevelClient client) { initialize(client, createElasticsearchConverter()); } @@ -127,83 +104,25 @@ public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConver private void initialize(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { Assert.notNull(client, "Client must not be null!"); this.client = client; - initialize(elasticsearchConverter); - } - - @Override - public boolean addAlias(AliasQuery query, IndexCoordinates index) { - IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); - try { - return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("failed to update aliases with request: " + request, e); - } - } - - @Override - public boolean removeAlias(AliasQuery query, IndexCoordinates index) { - Assert.notNull(index, "No index defined for Alias"); - Assert.notNull(query.getAliasName(), "No alias defined"); - - IndicesAliasesRequest indicesAliasesRequest = requestFactory.indicesRemoveAliasesRequest(query, index); - try { - return client.indices().updateAliases(indicesAliasesRequest, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("failed to update aliases with indicesRemoveAliasesRequest: " + indicesAliasesRequest, e); - } + initialize(elasticsearchConverter, new DefaultIndexOperations(client, elasticsearchConverter)); } + // endregion + // region DocumentOperations @Override - public boolean createIndex(String indexName, Object settings) { - CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); - try { - return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Error for creating index: " + request.toString(), e); - } - } - - @Override - public boolean putMapping(IndexCoordinates index, Object mapping) { - Assert.notNull(index, "No index defined for putMapping()"); - PutMappingRequest request = requestFactory.putMappingRequest(index, mapping); - try { - return client.indices().putMapping(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Failed to put mapping for " + index.getIndexName(), e); - } - } - - @Override - public Map getMapping(IndexCoordinates index) { - Assert.notNull(index, "No index defined for getMapping()"); - RestClient restClient = client.getLowLevelClient(); - try { - Request request = new Request("GET", - '/' + index.getIndexName() + "/_mapping/" + index.getTypeName() + "?include_type_name=true"); - Response response = restClient.performRequest(request); - return convertMappingResponse(EntityUtils.toString(response.getEntity()), index.getTypeName()); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() - + " type : " + index.getTypeName() + ' ', e); - } - } - - private Map convertMappingResponse(String mappingResponse, String type) { - ObjectMapper mapper = new ObjectMapper(); - + public String index(IndexQuery query, IndexCoordinates index) { + IndexRequest request = requestFactory.indexRequest(query, index); try { - Map result = null; - JsonNode node = mapper.readTree(mappingResponse); - - node = node.findValue("mappings").findValue(type); - result = mapper.readValue(mapper.writeValueAsString(node), HashMap.class); + String documentId = client.index(request, RequestOptions.DEFAULT).getId(); - return result; + // We should call this because we are not going through a mapper. + if (query.getObject() != null) { + setPersistentEntityId(query.getObject(), documentId); + } + return documentId; } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + mappingResponse, e); + throw new ElasticsearchException("Error while index for request: " + request.toString(), e); } - } @Override @@ -217,115 +136,56 @@ public T get(GetQuery query, Class clazz, IndexCoordinates index) { } } - @Nullable - private T getObjectFromPage(Page page) { - int contentSize = page.getContent().size(); - Assert.isTrue(contentSize < 2, "Expected 1 but found " + contentSize + " results"); - return contentSize > 0 ? page.getContent().get(0) : null; - } - @Override - protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { - MultiSearchResponse response; - try { - response = client.multiSearch(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + request.toString(), e); - } - MultiSearchResponse.Item[] items = response.getResponses(); - Assert.isTrue(items.length == request.requests().size(), "Response should has same length with queries"); - return items; - } + public List multiGet(Query query, Class clazz, IndexCoordinates index) { - @Override - public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - SearchResponse response; - try { - response = client.search(searchRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); - } + Assert.notNull(index, "index must not be null"); + Assert.notEmpty(query.getIds(), "No Id define for Query"); - @Override - public T query(Query query, ResultsExtractor resultsExtractor, @Nullable Class clazz, IndexCoordinates index) { - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + MultiGetRequest request = requestFactory.multiGetRequest(query, index); try { - SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); - return resultsExtractor.extract(result); + MultiGetResponse result = client.mget(request, RequestOptions.DEFAULT); + return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); + throw new ElasticsearchException("Error while multiget for request: " + request.toString(), e); } } @Override - public List queryForList(Query query, Class clazz, IndexCoordinates index) { - return queryForPage(query, clazz, index).getContent(); - } - - @Override - public List queryForIds(Query query, Class clazz, IndexCoordinates index) { - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - try { - SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); - return extractIds(response); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } - } + public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - @Override - public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { - long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, index), clazz); - } + Assert.notNull(queries, "List of IndexQuery must not be null"); + Assert.notNull(bulkOptions, "BulkOptions must not be null"); - private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage page, Class clazz) { - return StreamQueries.streamResults(page, scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), - this::clearScroll); + doBulkOperation(queries, bulkOptions, index); } @Override - public long count(Query query, Class clazz, IndexCoordinates index) { - Assert.notNull(index, "index must not be null"); - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - searchRequest.source().size(0); + public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - try { - return SearchHitsUtil.getTotalCount(client.search(searchRequest, RequestOptions.DEFAULT).getHits()); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } + Assert.notNull(queries, "List of UpdateQuery must not be null"); + Assert.notNull(bulkOptions, "BulkOptions must not be null"); + + doBulkOperation(queries, bulkOptions, index); } @Override - public List multiGet(Query query, Class clazz, IndexCoordinates index) { - Assert.notNull(index, "index must not be null"); - Assert.notEmpty(query.getIds(), "No Id define for Query"); - MultiGetRequest request = requestFactory.multiGetRequest(query, index); + public String delete(String id, IndexCoordinates index) { + DeleteRequest request = new DeleteRequest(index.getIndexName(), id); try { - MultiGetResponse result = client.mget(request, RequestOptions.DEFAULT); - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); + return client.delete(request, RequestOptions.DEFAULT).getId(); } catch (IOException e) { - throw new ElasticsearchException("Error while multiget for request: " + request.toString(), e); + throw new ElasticsearchException("Error while deleting item request: " + request.toString(), e); } } @Override - public String index(IndexQuery query, IndexCoordinates index) { - IndexRequest request = requestFactory.indexRequest(query, index); + public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { + DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(deleteQuery, index); try { - String documentId = client.index(request, RequestOptions.DEFAULT).getId(); - - // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); - } - return documentId; + client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); } catch (IOException e) { - throw new ElasticsearchException("Error while index for request: " + request.toString(), e); + throw new ElasticsearchException("Error for delete request: " + deleteByQueryRequest.toString(), e); } } @@ -339,22 +199,6 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } } - @Override - public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - Assert.notNull(queries, "List of IndexQuery must not be null"); - Assert.notNull(bulkOptions, "BulkOptions must not be null"); - - doBulkOperation(queries, bulkOptions, index); - } - - @Override - public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - Assert.notNull(queries, "List of UpdateQuery must not be null"); - Assert.notNull(bulkOptions, "BulkOptions must not be null"); - - doBulkOperation(queries, bulkOptions, index); - } - private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); try { @@ -363,54 +207,64 @@ private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoor throw new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e); } } + // endregion + // region SearchOperations @Override - public boolean indexExists(String indexName) { - GetIndexRequest request = new GetIndexRequest(indexName); + public long count(Query query, Class clazz, IndexCoordinates index) { + + Assert.notNull(index, "index must not be null"); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + + searchRequest.source().size(0); + try { - return client.indices().exists(request, RequestOptions.DEFAULT); + return SearchHitsUtil.getTotalCount(client.search(searchRequest, RequestOptions.DEFAULT).getHits()); } catch (IOException e) { - throw new ElasticsearchException("Error while for indexExists request: " + request.toString(), e); + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } } @Override - public boolean deleteIndex(String indexName) { - Assert.notNull(indexName, "No index defined for delete operation"); - if (indexExists(indexName)) { - DeleteIndexRequest request = new DeleteIndexRequest(indexName); - try { - return client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Error while deleting index request: " + request.toString(), e); - } + public T query(Query query, ResultsExtractor resultsExtractor, @Nullable Class clazz, + IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + try { + SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); + return resultsExtractor.extract(result); + } catch (IOException e) { + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } - return false; } @Override - public String delete(String id, IndexCoordinates index) { - DeleteRequest request = new DeleteRequest(index.getIndexName(), index.getTypeName(), id); + public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + SearchResponse response; try { - return client.delete(request, RequestOptions.DEFAULT).getId(); + response = client.search(searchRequest, RequestOptions.DEFAULT); } catch (IOException e) { - throw new ElasticsearchException("Error while deleting item request: " + request.toString(), e); + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } + return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { - DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(deleteQuery, index); + public List queryForIds(Query query, Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); try { - client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); + SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); + return extractIds(response); } catch (IOException e) { - throw new ElasticsearchException("Error for delete request: " + deleteByQueryRequest.toString(), e); + throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } } @Override public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); + SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); searchRequest.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); @@ -422,7 +276,6 @@ public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Cla } } - @Override public ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { SearchScrollRequest request = new SearchScrollRequest(scrollId); request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); @@ -447,119 +300,6 @@ public void clearScroll(String scrollId) { } @Override - public Map getSetting(Class clazz) { - return getSetting(getPersistentEntityFor(clazz).getIndexName()); - } - - @Override // TODO change interface to return Settings. - public Map getSetting(String indexName) { - Assert.notNull(indexName, "No index defined for getSettings"); - ObjectMapper objMapper = new ObjectMapper(); - Map settings = null; - RestClient restClient = client.getLowLevelClient(); - try { - Response response = restClient.performRequest(new Request("GET", "/" + indexName + "/_settings")); - settings = convertSettingResponse(EntityUtils.toString(response.getEntity()), indexName); - - } catch (Exception e) { - throw new ElasticsearchException("Error while getting settings for indexName : " + indexName, e); - } - return settings; - } - - private Map convertSettingResponse(String settingResponse, String indexName) { - ObjectMapper mapper = new ObjectMapper(); - - try { - Settings settings = Settings.fromXContent(XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, settingResponse)); - String prefix = indexName + ".settings."; - // Backwards compatibility. TODO Change to return Settings object. - Map result = new HashMap(); - Set keySet = settings.keySet(); - for (String key : keySet) { - result.put(key.substring(prefix.length()), settings.get(key)); - } - return result; - } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + settingResponse, e); - } - - } - - @Override - public void refresh(IndexCoordinates index) { - Assert.notNull(index, "No index defined for refresh()"); - try { - client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("failed to refresh index: " + index, e); - } - } - - @Override - public List queryForAlias(String indexName) { - List aliases = null; - RestClient restClient = client.getLowLevelClient(); - Response response; - String aliasResponse; - - try { - response = restClient.performRequest(new Request("GET", '/' + indexName + "/_alias/*")); - aliasResponse = EntityUtils.toString(response.getEntity()); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName, e); - } - - return convertAliasResponse(aliasResponse); - } - - /** - * It takes two steps to create a List from the elasticsearch http response because the aliases field - * is actually a Map by alias name, but the alias name is on the AliasMetadata. - * - * @param aliasResponse - * @return - */ - private List convertAliasResponse(String aliasResponse) { - ObjectMapper mapper = new ObjectMapper(); - - try { - JsonNode node = mapper.readTree(aliasResponse); - node = node.findValue("aliases"); - - if (node == null) { - return Collections.emptyList(); - } - - Map aliasData = mapper.readValue(mapper.writeValueAsString(node), - new TypeReference>() {}); - - Iterable> aliasIter = aliasData.entrySet(); - List aliasMetaDataList = new ArrayList(); - - for (Map.Entry aliasentry : aliasIter) { - AliasData data = aliasentry.getValue(); - aliasMetaDataList.add(AliasMetaData.newAliasMetaDataBuilder(aliasentry.getKey()).filter(data.getFilter()) - .routing(data.getRouting()).searchRouting(data.getSearch_routing()).indexRouting(data.getIndex_routing()) - .build()); - } - return aliasMetaDataList; - } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + aliasResponse, e); - } - } - - private List extractIds(SearchResponse response) { - List ids = new ArrayList<>(); - for (SearchHit hit : response.getHits()) { - if (hit != null) { - ids.add(hit.getId()); - } - } - return ids; - } - public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { SearchRequest searchRequest = new SearchRequest(index.getIndexNames()); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); @@ -571,5 +311,20 @@ public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) } catch (IOException e) { throw new ElasticsearchException("Could not execute search request : " + searchRequest.toString(), e); } + + } + + @Override + protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { + MultiSearchResponse response; + try { + response = client.multiSearch(request, RequestOptions.DEFAULT); + } catch (IOException e) { + throw new ElasticsearchException("Error for search request: " + request.toString(), e); + } + MultiSearchResponse.Item[] items = response.getResponses(); + Assert.isTrue(items.length == request.requests().size(), "Response should has same length with queries"); + return items; } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 7a8ddade5..65a384cd8 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -15,21 +15,9 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.client.Requests.*; - -import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import org.elasticsearch.action.ActionFuture; -import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; -import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; -import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; -import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; @@ -42,23 +30,16 @@ import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; -import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; -import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.GetQuery; @@ -66,7 +47,6 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.SearchHitsUtil; -import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -100,13 +80,13 @@ */ @Deprecated public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { - private static final Logger QUERY_LOGGER = LoggerFactory .getLogger("org.springframework.data.elasticsearch.core.QUERY"); private Client client; private String searchTimeout; + // region Initialization public ElasticsearchTemplate(Client client) { initialize(client, createElasticsearchConverter()); } @@ -118,52 +98,30 @@ public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearch private void initialize(Client client, ElasticsearchConverter elasticsearchConverter) { Assert.notNull(client, "Client must not be null!"); this.client = client; - initialize(elasticsearchConverter); + initialize(elasticsearchConverter, new DefaultTransportIndexOperations(client, elasticsearchConverter)); } + // endregion - public void setSearchTimeout(String searchTimeout) { - this.searchTimeout = searchTimeout; + // region getter/setter + public String getSearchTimeout() { + return searchTimeout; } - @Override - public boolean addAlias(AliasQuery query, IndexCoordinates index) { - IndicesAliasesRequest.AliasActions aliasAction = requestFactory.aliasAction(query, index); - return client.admin().indices().prepareAliases().addAliasAction(aliasAction).execute().actionGet().isAcknowledged(); - } - - @Override - public boolean removeAlias(AliasQuery query, IndexCoordinates index) { - Assert.notNull(index, "No index defined for Alias"); - Assert.notNull(query.getAliasName(), "No alias defined"); - return client.admin().indices().prepareAliases().removeAlias(index.getIndexName(), query.getAliasName()).execute() - .actionGet().isAcknowledged(); - } - - @Override - public boolean createIndex(String indexName, Object settings) { - CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, indexName, - settings); - return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); - } - - @Override - public boolean putMapping(IndexCoordinates index, Object mapping) { - Assert.notNull(index, "No index defined for putMapping()"); - PutMappingRequestBuilder requestBuilder = requestFactory.putMappingRequestBuilder(client, index, mapping); - return requestBuilder.execute().actionGet().isAcknowledged(); + public void setSearchTimeout(String searchTimeout) { + this.searchTimeout = searchTimeout; } + // endregion + // region DocumentOperations @Override - public Map getMapping(IndexCoordinates index) { - Assert.notNull(index, "No index defined for putMapping()"); - try { - return client.admin().indices() - .getMappings(new GetMappingsRequest().indices(index.getIndexNames()).types(index.getTypeNames())).actionGet() - .getMappings().get(index.getIndexName()).get(index.getTypeName()).getSourceAsMap(); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() - + " type : " + index.getTypeName() + ' ' + e.getMessage()); + public String index(IndexQuery query, IndexCoordinates index) { + IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); + String documentId = indexRequestBuilder.execute().actionGet().getId(); + // We should call this because we are not going through a mapper. + if (query.getObject() != null) { + setPersistentEntityId(query.getObject(), documentId); } + return documentId; } @Override @@ -174,85 +132,43 @@ public T get(GetQuery query, Class clazz, IndexCoordinates index) { return entity; } - @Nullable - private T getObjectFromPage(Page page) { - int contentSize = page.getContent().size(); - Assert.isTrue(contentSize < 2, "Expected 1 but found " + contentSize + " results"); - return contentSize > 0 ? page.getContent().get(0) : null; - } - @Override - protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { - ActionFuture future = client.multiSearch(request); - MultiSearchResponse response = future.actionGet(); - MultiSearchResponse.Item[] items = response.getResponses(); - Assert.isTrue(items.length == request.requests().size(), "Response should have same length with queries"); - return items; - } + public List multiGet(Query query, Class clazz, IndexCoordinates index) { - @Override - public T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index) { - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return resultsExtractor.extract(response); - } + Assert.notNull(index, "index must not be null"); + Assert.notEmpty(query.getIds(), "No Id define for Query"); - @Override - public List queryForList(Query query, Class clazz, IndexCoordinates index) { - return queryForPage(query, clazz, index).getContent(); - } + MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); - @Override - public List queryForIds(Query query, Class clazz, IndexCoordinates index) { - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return extractIds(response); + return elasticsearchConverter.mapDocuments(DocumentAdapters.from(builder.execute().actionGet()), clazz); } @Override - public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); - } + public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - @Override - public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { - long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return doStream(scrollTimeInMillis, startScroll(scrollTimeInMillis, query, clazz, index), clazz); - } + Assert.notNull(queries, "List of IndexQuery must not be null"); + Assert.notNull(bulkOptions, "BulkOptions must not be null"); - private CloseableIterator doStream(long scrollTimeInMillis, ScrolledPage page, Class clazz) { - return StreamQueries.streamResults(page, scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), - this::clearScroll); + doBulkOperation(queries, bulkOptions, index); } @Override - public long count(Query query, @Nullable Class clazz, IndexCoordinates index) { - Assert.notNull(index, "index must not be null"); - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - searchRequestBuilder.setSize(0); + public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - return SearchHitsUtil.getTotalCount(getSearchResponse(searchRequestBuilder).getHits()); + Assert.notNull(queries, "List of UpdateQuery must not be null"); + Assert.notNull(bulkOptions, "BulkOptions must not be null"); + + doBulkOperation(queries, bulkOptions, index); } @Override - public List multiGet(Query query, Class clazz, IndexCoordinates index) { - Assert.notNull(index, "index must not be null"); - Assert.notEmpty(query.getIds(), "No Id define for Query"); - MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(builder.execute().actionGet()), clazz); + public String delete(String id, IndexCoordinates index) { + return client.prepareDelete(index.getIndexName(), index.getTypeName(), id).execute().actionGet().getId(); } @Override - public String index(IndexQuery query, IndexCoordinates index) { - IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); - String documentId = indexRequestBuilder.execute().actionGet().getId(); - // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); - } - return documentId; + public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { + requestFactory.deleteByQueryRequestBuilder(client, deleteQuery, index).get(); } @Override @@ -261,54 +177,49 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { return updateRequestBuilder.execute().actionGet(); } - @Override - public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - Assert.notNull(queries, "List of IndexQuery must not be null"); - Assert.notNull(bulkOptions, "BulkOptions must not be null"); - - doBulkOperation(queries, bulkOptions, index); - } - - @Override - public void bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - Assert.notNull(queries, "List of UpdateQuery must not be null"); - Assert.notNull(bulkOptions, "BulkOptions must not be null"); - - doBulkOperation(queries, bulkOptions, index); - } - private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); checkForBulkOperationFailure(bulkRequest.execute().actionGet()); } + // endregion + // region SearchOperations @Override - public boolean indexExists(String indexName) { - return client.admin().indices().exists(indicesExistsRequest(indexName)).actionGet().isExists(); + public long count(Query query, @Nullable Class clazz, IndexCoordinates index) { + + Assert.notNull(index, "index must not be null"); + + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + searchRequestBuilder.setSize(0); + + return SearchHitsUtil.getTotalCount(getSearchResponse(searchRequestBuilder).getHits()); } @Override - public boolean deleteIndex(String indexName) { - Assert.notNull(indexName, "No index defined for delete operation"); - if (indexExists(indexName)) { - return client.admin().indices().delete(new DeleteIndexRequest(indexName)).actionGet().isAcknowledged(); - } - return false; + public T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + SearchResponse response = getSearchResponse(searchRequestBuilder); + return resultsExtractor.extract(response); } @Override - public String delete(String id, IndexCoordinates index) { - return client.prepareDelete(index.getIndexName(), index.getTypeName(), id).execute().actionGet().getId(); + public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + SearchResponse response = getSearchResponse(searchRequestBuilder); + return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { - requestFactory.deleteByQueryRequestBuilder(client, deleteQuery, index).get(); + public List queryForIds(Query query, Class clazz, IndexCoordinates index) { + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + SearchResponse response = getSearchResponse(searchRequestBuilder); + return extractIds(response); } @Override public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); searchRequestBuilder.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)); SearchResponse response = getSearchResponse(searchRequestBuilder); @@ -327,55 +238,30 @@ public void clearScroll(String scrollId) { client.prepareClearScroll().addScrollId(scrollId).execute().actionGet(); } - private SearchResponse getSearchResponse(SearchRequestBuilder requestBuilder) { - - if (QUERY_LOGGER.isDebugEnabled()) { - QUERY_LOGGER.debug(requestBuilder.toString()); - } - return getSearchResponseWithTimeout(requestBuilder.execute()); - } - - private SearchResponse getSearchResponseWithTimeout(ActionFuture response) { - return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout); - } - @Override - public Map getSetting(Class clazz) { - return getSetting(getPersistentEntityFor(clazz).getIndexName()); - } - - @Override - public Map getSetting(String indexName) { - Assert.notNull(indexName, "No index defined for getSettings"); - Settings settings = client.admin().indices().getSettings(new GetSettingsRequest()).actionGet().getIndexToSettings() - .get(indexName); - return settings.keySet().stream().collect(Collectors.toMap((key) -> key, (key) -> settings.get(key))); + public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { + return client.prepareSearch(index.getIndexNames()).suggest(suggestion).get(); } @Override - public void refresh(IndexCoordinates index) { - Assert.notNull(index, "No index defined for refresh()"); - client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet(); + protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { + ActionFuture future = client.multiSearch(request); + MultiSearchResponse response = future.actionGet(); + MultiSearchResponse.Item[] items = response.getResponses(); + Assert.isTrue(items.length == request.requests().size(), "Response should have same length with queries"); + return items; } - @Override - public List queryForAlias(String indexName) { - return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)).actionGet().getAliases() - .get(indexName); - } + private SearchResponse getSearchResponse(SearchRequestBuilder requestBuilder) { - private List extractIds(SearchResponse response) { - List ids = new ArrayList<>(); - for (SearchHit hit : response.getHits()) { - if (hit != null) { - ids.add(hit.getId()); - } + if (QUERY_LOGGER.isDebugEnabled()) { + QUERY_LOGGER.debug(requestBuilder.toString()); } - return ids; + return getSearchResponseWithTimeout(requestBuilder.execute()); } - public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { - return client.prepareSearch(index.getIndexNames()).suggest(suggestion).get(); + private SearchResponse getSearchResponseWithTimeout(ActionFuture response) { + return searchTimeout == null ? response.actionGet() : response.actionGet(searchTimeout); } - + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index f1aebbfc2..f376ac270 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -24,6 +24,7 @@ import org.springframework.core.convert.ConversionService; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; @@ -127,7 +128,7 @@ private static String indexName(@Nullable ElasticsearchPersistentEntity entit if (StringUtils.isEmpty(index)) { Assert.notNull(entity, "Cannot determine index name"); - return entity.getIndexName(); + return entity.getIndexCoordinates().getIndexName(); } return index; @@ -137,7 +138,7 @@ private static String typeName(@Nullable ElasticsearchPersistentEntity entity if (StringUtils.isEmpty(type)) { Assert.notNull(entity, "Cannot determine index type"); - return entity.getIndexType(); + return entity.getIndexCoordinates().getTypeName(); } return type; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java new file mode 100644 index 000000000..52e195fae --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -0,0 +1,216 @@ +/* + * Copyright 2019 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; + +import java.util.List; +import java.util.Map; + +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.AliasQuery; + +/** + * The operations for the + * Elasticsearch Index APIs. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface IndexOperations { + + /** + * Create an index for given indexName. + * + * @param indexName the name of the index + * @return {@literal true} if the index was created + */ + boolean createIndex(String indexName); + + /** + * Create an index for given indexName and Settings. + * + * @param indexName the name of the index + * @param settings the index settings + * @return {@literal true} if the index was created + */ + boolean createIndex(String indexName, Object settings); + + /** + * Create an index for a class. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return {@literal true} if the index was created + */ + boolean createIndex(Class clazz); + + /** + * Create an index for given class and Settings. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @param settings the index settings + * @return {@literal true} if the index was created + */ + boolean createIndex(Class clazz, Object settings); + + /** + * Deletes an index for given entity. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return {@literal true} if the index was deleted + */ + boolean deleteIndex(Class clazz); + + /** + * Deletes an index. + * + * @param indexName the name of the index to delete + * @return {@literal true} if the index was deleted + */ + boolean deleteIndex(String indexName); + + /** + * check if index exists. + * + * @param indexName the name of the index + * @return {@literal true} if the index exists + */ + boolean indexExists(String indexName); + + /** + * check if index is exists. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return {@literal true} if the index exists + */ + boolean indexExists(Class clazz); + + /** + * Create mapping for a class and store it to the index. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return {@literal true} if the mapping could be stored + */ + boolean putMapping(Class clazz); + + /** + * Create mapping for the given class and put the mapping to the given index. + * + * @param index the index to store the mapping to + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return {@literal true} if the mapping could be stored + */ + boolean putMapping(IndexCoordinates index, Class clazz); + + /** + * Stores a mapping to an index. + * + * @param index the index to store the mapping to + * @param mappings can be a JSON String or a {@link Map} + * @return {@literal true} if the mapping could be stored + */ + boolean putMapping(IndexCoordinates index, Object mappings); + + /** + * Create mapping for a class Stores a mapping to an index. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @param mappings can be a JSON String or a {@link Map} + * @return {@literal true} if the mapping could be stored + */ + boolean putMapping(Class clazz, Object mappings); + + /** + * Get mapping for an index defined by a class. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document}. + * @return the mapping + */ + Map getMapping(Class clazz); + + /** + * Get mapping for a given index. + * + * @param index the index to read the mapping from + * @return the mapping + */ + Map getMapping(IndexCoordinates index); + + /** + * Add an alias. + * + * @param query query defining the alias + * @param index the index for which to add an alias + * @return true if the alias was created + */ + boolean addAlias(AliasQuery query, IndexCoordinates index); + + /** + * Remove an alias. + * + * @param query query defining the alias + * @param index the index for which to remove an alias + * @return true if the alias was removed + */ + boolean removeAlias(AliasQuery query, IndexCoordinates index); + + /** + * Get the alias informations for a specified index. + * + * @param indexName the name of the index + * @return alias information + */ + List queryForAlias(String indexName); + + /** + * Get settings for a given indexName. + * + * @param indexName the name of the index + * @return the settings + */ + Map getSetting(String indexName); + + /** + * Get settings for a given class. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return the settings + */ + Map getSetting(Class clazz); + + /** + * Refresh the index(es). + * + * @param index the index to refresh + */ + void refresh(IndexCoordinates index); + + /** + * Refresh the index. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + */ + void refresh(Class clazz); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java new file mode 100644 index 000000000..bba9582ea --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -0,0 +1,186 @@ +/* + * Copyright 2019 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; + +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.Query; +import reactor.core.publisher.Mono; + +import org.springframework.util.Assert; + +/** + * The reactive operations for the + * Elasticsearch Document APIs. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface ReactiveDocumentOperations { + /** + * Index the given entity, once available, extracting index and type from entity metadata. + * + * @param entityPublisher must not be {@literal null}. + * @param + * @return a {@link Mono} emitting the saved entity. + */ + default Mono save(Mono entityPublisher) { + + Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); + return entityPublisher.flatMap(this::save); + } + + /** + * Index the given entity extracting index and type from entity metadata. + * + * @param entity must not be {@literal null}. + * @param + * @return a {@link Mono} emitting the saved entity. + */ + Mono save(T entity); + + /** + * Index the entity, once available, under the given {@literal type} in the given {@literal index}. If the + * {@literal index} is {@literal null} or empty the index name provided via entity metadata is used. Same for the + * {@literal type}. + * + * @param entityPublisher must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Mono} emitting the saved entity. + */ + default Mono save(Mono entityPublisher, IndexCoordinates index) { + + Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); + return entityPublisher.flatMap(it -> save(it, index)); + } + + /** + * Index the entity under the given {@literal type} in the given {@literal index}. If the {@literal index} is + * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. + * + * @param entity must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Mono} emitting the saved entity. + */ + Mono save(T entity, IndexCoordinates index); + + /** + * Find the document with the given {@literal id} mapped onto the given {@literal entityType}. + * + * @param id the {@literal _id} of the document to fetch. + * @param entityType the domain type used for mapping the document. + * @param + * @return {@link Mono#empty()} if not found. + */ + Mono findById(String id, Class entityType); + + /** + * Fetch the entity with given {@literal id}. + * + * @param id must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return the {@link Mono} emitting the entity or signalling completion if none found. + */ + Mono findById(String id, Class entityType, IndexCoordinates index); + + /** + * Check if an entity with given {@literal id} exists. + * + * @param id the {@literal _id} of the document to look for. + * @param entityType the domain type used. + * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. + */ + Mono exists(String id, Class entityType); + + /** + * Check if an entity with given {@literal id} exists. + * + * @param id the {@literal _id} of the document to look for. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. + */ + Mono exists(String id, Class entityType, IndexCoordinates index); + + /** + * Delete the given entity extracting index and type from entity metadata. + * + * @param entity must not be {@literal null}. + * @return a {@link Mono} emitting the {@literal id} of the removed document. + */ + Mono delete(Object entity); + + /** + * Delete the given entity extracting index and type from entity metadata. + * + * @param entity must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting the {@literal id} of the removed document. + */ + Mono delete(Object entity, IndexCoordinates index); + + /** + * Delete the entity with given {@literal id}. + * + * @param id must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting the {@literal id} of the removed document. + */ + default Mono deleteById(String id, IndexCoordinates index) { + + Assert.notNull(index, "Index must not be null!"); + + return deleteById(id, Object.class, index); + } + + /** + * Delete the entity with given {@literal id} extracting index and type from entity metadata. + * + * @param id must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @return a {@link Mono} emitting the {@literal id} of the removed document. + */ + Mono deleteById(String id, Class entityType); + + /** + * Delete the entity with given {@literal id} extracting index and type from entity metadata. + * + * @param id must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting the {@literal id} of the removed document. + */ + Mono deleteById(String id, Class entityType, IndexCoordinates index); + /** + * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @return a {@link Mono} emitting the number of the removed documents. + */ + Mono deleteBy(Query query, Class entityType); + + /** + * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting the number of the removed documents. + */ + Mono deleteBy(Query query, Class entityType, IndexCoordinates index); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java index 947458f49..880a6d133 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java @@ -15,19 +15,12 @@ */ package org.springframework.data.elasticsearch.core; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.elasticsearch.index.query.QueryBuilders; import org.reactivestreams.Publisher; -import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; /** * Interface that specifies a basic set of Elasticsearch operations executed in a reactive way. @@ -41,7 +34,7 @@ * @author Peter-Josef Meisch * @since 3.2 */ -public interface ReactiveElasticsearchOperations { +public interface ReactiveElasticsearchOperations extends ReactiveDocumentOperations, ReactiveSearchOperations { /** * Execute within a {@link ClientCallback} managing resources and translating errors. @@ -52,261 +45,6 @@ public interface ReactiveElasticsearchOperations { */ Publisher execute(ClientCallback> callback); - /** - * Index the given entity, once available, extracting index and type from entity metadata. - * - * @param entityPublisher must not be {@literal null}. - * @param - * @return a {@link Mono} emitting the saved entity. - */ - default Mono save(Mono entityPublisher) { - - Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); - return entityPublisher.flatMap(this::save); - } - - /** - * Index the given entity extracting index and type from entity metadata. - * - * @param entity must not be {@literal null}. - * @param - * @return a {@link Mono} emitting the saved entity. - */ - default Mono save(T entity) { - return save(entity, getIndexCoordinatesFor(entity.getClass())); - } - - /** - * Index the entity, once available, under the given {@literal type} in the given {@literal index}. If the - * {@literal index} is {@literal null} or empty the index name provided via entity metadata is used. Same for the - * {@literal type}. - * - * @param entityPublisher must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @param - * @return a {@link Mono} emitting the saved entity. - */ - default Mono save(Mono entityPublisher, IndexCoordinates index) { - - Assert.notNull(entityPublisher, "EntityPublisher must not be null!"); - return entityPublisher.flatMap(it -> save(it, index)); - } - - /** - * Index the entity under the given {@literal type} in the given {@literal index}. If the {@literal index} is - * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. - * - * @param entity must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @param - * @return a {@link Mono} emitting the saved entity. - */ - Mono save(T entity, IndexCoordinates index); - - /** - * Find the document with the given {@literal id} mapped onto the given {@literal entityType}. - * - * @param id the {@literal _id} of the document to fetch. - * @param entityType the domain type used for mapping the document. - * @param - * @return {@link Mono#empty()} if not found. - */ - default Mono findById(String id, Class entityType) { - return findById(id, entityType, getIndexCoordinatesFor(entityType)); - } - - /** - * Fetch the entity with given {@literal id}. - * - * @param id must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @param - * @return the {@link Mono} emitting the entity or signalling completion if none found. - */ - Mono findById(String id, Class entityType, IndexCoordinates index); - - /** - * Check if an entity with given {@literal id} exists. - * - * @param id the {@literal _id} of the document to look for. - * @param entityType the domain type used. - * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. - */ - default Mono exists(String id, Class entityType) { - return exists(id, entityType, getIndexCoordinatesFor(entityType)); - } - - /** - * Check if an entity with given {@literal id} exists. - * - * @param id the {@literal _id} of the document to look for. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. - */ - Mono exists(String id, Class entityType, IndexCoordinates index); - - /** - * Search the index for entities matching the given {@link Query query}.
- * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either - * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) - * size}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param - * @return a {@link Flux} emitting matching entities one by one. - */ - default Flux find(Query query, Class entityType) { - return find(query, entityType, entityType); - } - - /** - * Search the index for entities matching the given {@link Query query}.
- * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either * - * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) * - * size}. - * - * @param query must not be {@literal null}. - * @param entityType The entity type for mapping the query. Must not be {@literal null}. - * @param returnType The mapping target type. Must not be {@literal null}. Th - * @param - * @return a {@link Flux} emitting matching entities one by one. - */ - default Flux find(Query query, Class entityType, Class returnType) { - return find(query, entityType, returnType, getIndexCoordinatesFor(entityType)); - } - - /** - * Search the index for entities matching the given {@link Query query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @param - * @returnm a {@link Flux} emitting matching entities one by one. - */ - default Flux find(Query query, Class entityType, IndexCoordinates index) { - return find(query, entityType, entityType, index); - } - - /** - * Search the index for entities matching the given {@link Query query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param resultType the projection result type. - * @param index the target index, must not be {@literal null} - * @param - * @return a {@link Flux} emitting matching entities one by one. - */ - Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index); - - /** - * Count the number of documents matching the given {@link Query}. - * - * @param entityType must not be {@literal null}. - * @return a {@link Mono} emitting the nr of matching documents. - */ - default Mono count(Class entityType) { - return count(new StringQuery(QueryBuilders.matchAllQuery().toString()), entityType); - } - - /** - * Count the number of documents matching the given {@link Query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @return a {@link Mono} emitting the nr of matching documents. - */ - default Mono count(Query query, Class entityType) { - return count(query, entityType, getIndexCoordinatesFor(entityType)); - } - - /** - * Count the number of documents matching the given {@link Query}. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting the nr of matching documents. - */ - Mono count(Query query, Class entityType, IndexCoordinates index); - - /** - * Delete the given entity extracting index and type from entity metadata. - * - * @param entity must not be {@literal null}. - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - default Mono delete(Object entity) { - return delete(entity, getIndexCoordinatesFor(entity.getClass())); - } - - /** - * Delete the given entity extracting index and type from entity metadata. - * - * @param entity must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - Mono delete(Object entity, IndexCoordinates index); - - /** - * Delete the entity with given {@literal id}. - * - * @param id must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - default Mono deleteById(String id, IndexCoordinates index) { - - Assert.notNull(index, "Index must not be null!"); - - return deleteById(id, Object.class, index); - } - - /** - * Delete the entity with given {@literal id} extracting index and type from entity metadata. - * - * @param id must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - default Mono deleteById(String id, Class entityType) { - return deleteById(id, entityType, getIndexCoordinatesFor(entityType)); - } - - /** - * Delete the entity with given {@literal id} extracting index and type from entity metadata. - * - * @param id must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting the {@literal id} of the removed document. - */ - Mono deleteById(String id, Class entityType, IndexCoordinates index); - - /** - * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @return a {@link Mono} emitting the number of the removed documents. - */ - default Mono deleteBy(Query query, Class entityType) { - return deleteBy(query, entityType, getIndexCoordinatesFor(entityType)); - } - - /** - * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. - * - * @param query must not be {@literal null}. - * @param entityType must not be {@literal null}. - * @param index the target index, must not be {@literal null} - * @return a {@link Mono} emitting the number of the removed documents. - */ - Mono deleteBy(Query query, Class entityType, IndexCoordinates index); - /** * Get the {@link ElasticsearchConverter} used. * @@ -322,10 +60,7 @@ default Mono deleteBy(Query query, Class entityType) { * @return the IndexCoordinates defined on the entity. * @since 4.0 */ - default IndexCoordinates getIndexCoordinatesFor(Class clazz) { - ElasticsearchPersistentEntity entity = getPersistentEntityFor(clazz); - return IndexCoordinates.of(entity.getIndexName()).withTypes(entity.getIndexType()); - } + IndexCoordinates getIndexCoordinatesFor(Class clazz); /** * Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 92ced2299..8c308d43c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -17,6 +17,7 @@ import static org.elasticsearch.index.VersionType.*; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -48,7 +49,6 @@ import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.NoSuchIndexException; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; @@ -93,6 +93,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera private @Nullable RefreshPolicy refreshPolicy = RefreshPolicy.IMMEDIATE; private @Nullable IndicesOptions indicesOptions = IndicesOptions.strictExpandOpenAndForbidClosedIgnoreThrottled(); + // region Initialization public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client) { this(client, new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext())); } @@ -109,19 +110,12 @@ public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client, Elastic this.operations = new EntityOperations(this.mappingContext); this.requestFactory = new RequestFactory(converter); } + // endregion + // region DocumentOperations /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exctute(ClientCallback) - */ - @Override - public Publisher execute(ClientCallback> callback) { - return Flux.defer(() -> callback.doWithClient(getClient())).onErrorMap(this::translateException); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#index(Object, IndexCoordinates) + * @see org.springframework.data.elasticsearch.core.ReactiveDElasticsearchOperations#index(Object, IndexCoordinates) */ @Override public Mono save(T entity, IndexCoordinates index) { @@ -136,6 +130,51 @@ public Mono save(T entity, IndexCoordinates index) { }); } + @Override + public Mono save(T entity) { + return save(entity, getIndexCoordinatesFor(entity.getClass())); + } + + /** + * Customization hook on the actual execution result {@link Publisher}.
+ * You know what you're doing here? Well fair enough, go ahead on your own risk. + * + * @param request the already prepared {@link IndexRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. + */ + protected Mono doIndex(IndexRequest request) { + return Mono.from(execute(client -> client.index(request))); + } + + /** + * Customization hook on the actual execution result {@link Publisher}.
+ * + * @param request the already prepared {@link GetRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. + */ + protected Mono doFindById(GetRequest request) { + + return Mono.from(execute(client -> client.get(request))) // + .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); + } + + @Override + public Mono exists(String id, Class entityType) { + return exists(id, entityType, getIndexCoordinatesFor(entityType)); + } + + /** + * Customization hook on the actual execution result {@link Publisher}.
+ * + * @param request the already prepared {@link GetRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. + */ + protected Mono doExists(GetRequest request) { + + return Mono.from(execute(client -> client.exists(request))) // + .onErrorReturn(NoSuchIndexException.class, false); + } + private Mono doIndex(Object value, AdaptibleEntity entity, IndexCoordinates index) { return Mono.defer(() -> { @@ -162,6 +201,11 @@ private Mono doIndex(Object value, AdaptibleEntity entity, Ind }); } + @Override + public Mono findById(String id, Class entityType) { + return findById(id, entityType, getIndexCoordinatesFor(entityType)); + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#findById(String, Class, IndexCoordinates) @@ -200,85 +244,6 @@ private Mono doExists(String id, ElasticsearchPersistentEntity entit return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), index.getTypeName(), id))); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#find(Query, Class, Class, IndexCoordinates) - */ - @Override - public Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index) { - - return doFind(query, entityType, index).map(it -> converter.mapDocument(DocumentAdapters.from(it), resultType)); - } - - private Flux doFind(Query query, Class clazz, IndexCoordinates index) { - - return Flux.defer(() -> { - SearchRequest request = requestFactory.searchRequest(query, clazz, index); - - if (indicesOptions != null) { - request.indicesOptions(indicesOptions); - } - - if (query.getPageable().isPaged() || query.isLimiting()) { - return doFind(request); - } else { - return doScroll(request); - } - }); - } - - @Override - public Mono count(Query query, Class entityType, IndexCoordinates index) { - return doCount(query, getPersistentEntityFor(entityType), index); - } - - private Mono doCount(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - return Mono.defer(() -> { - - CountRequest countRequest = buildCountRequest(query, entity, index); - CountRequest request = prepareCountRequest(countRequest); - return doCount(request); - }); - - } - - private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - - CountRequest request = new CountRequest(index.getIndexNames()); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - searchSourceBuilder.query(mappedQuery(query, entity)); - searchSourceBuilder.trackScores(query.getTrackScores()); - - QueryBuilder postFilterQuery = mappedFilterQuery(query, entity); - if (postFilterQuery != null) { - searchSourceBuilder.postFilter(postFilterQuery); - } - - if (query.getSourceFilter() != null) { - searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); - } - - if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { - searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); - } - - sort(query, entity).forEach(searchSourceBuilder::sort); - - if (query.getMinScore() > 0) { - searchSourceBuilder.minScore(query.getMinScore()); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); - } - - if (query.getPreference() != null) { - request.preference(query.getPreference()); - } - request.source(searchSourceBuilder); - return request; - } - /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(Object, String, String) @@ -305,6 +270,16 @@ public Mono deleteById(String id, Class entityType, IndexCoordinates } + @Override + public Mono delete(Object entity) { + return delete(entity, getIndexCoordinatesFor(entity.getClass())); + } + + @Override + public Mono deleteById(String id, Class entityType) { + return deleteById(id, entityType, getIndexCoordinatesFor(entityType)); + } + private Mono doDeleteById(@Nullable Object source, String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { @@ -327,6 +302,11 @@ public Mono deleteBy(Query query, Class entityType, IndexCoordinates in .publishNext(); } + @Override + public Mono deleteBy(Query query, Class entityType) { + return deleteBy(query, entityType, getIndexCoordinatesFor(entityType)); + } + private Flux doDeleteBy(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { @@ -339,61 +319,70 @@ private Flux doDeleteBy(Query query, ElasticsearchPersiste }); } - // Property Setters / Getters - /** - * Set the default {@link RefreshPolicy} to apply when writing to Elasticsearch. + * Customization hook on the actual execution result {@link Publisher}.
* - * @param refreshPolicy can be {@literal null}. + * @param request the already prepared {@link DeleteRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. */ - public void setRefreshPolicy(@Nullable RefreshPolicy refreshPolicy) { - this.refreshPolicy = refreshPolicy; + protected Mono doDelete(DeleteRequest request) { + + return Mono.from(execute(client -> client.delete(request))) // + + .flatMap(it -> { + + if (HttpStatus.valueOf(it.status().getStatus()).equals(HttpStatus.NOT_FOUND)) { + return Mono.empty(); + } + + return Mono.just(it.getId()); + }) // + .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } /** - * Set the default {@link IndicesOptions} for {@link SearchRequest search requests}. + * Customization hook on the actual execution result {@link Publisher}.
* - * @param indicesOptions can be {@literal null}. + * @param request the already prepared {@link DeleteByQueryRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. */ - public void setIndicesOptions(@Nullable IndicesOptions indicesOptions) { - this.indicesOptions = indicesOptions; - } + protected Mono doDeleteBy(DeleteByQueryRequest request) { - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#getElasticsearchConverter() - */ - @Override - public ElasticsearchConverter getElasticsearchConverter() { - return converter; + return Mono.from(execute(client -> client.deleteBy(request))) // + .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } - // Customization Hooks - /** - * Obtain the {@link ReactiveElasticsearchClient} to operate upon. + * Customization hook to modify a generated {@link DeleteRequest} prior to its execution. Eg. by setting the + * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. * + * @param source the source object the {@link DeleteRequest} was derived from. My be {@literal null} if using the + * {@literal id} directly. + * @param request the generated {@link DeleteRequest}. * @return never {@literal null}. */ - protected ReactiveElasticsearchClient getClient() { - return this.client; + protected DeleteRequest prepareDeleteRequest(@Nullable Object source, DeleteRequest request) { + return prepareWriteRequest(request); } /** - * Pre process the write request before it is sent to the server, eg. by setting the + * Customization hook to modify a generated {@link DeleteByQueryRequest} prior to its execution. Eg. by setting the * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. * - * @param request must not be {@literal null}. - * @param - * @return the processed {@link WriteRequest}. + * @param request the generated {@link DeleteByQueryRequest}. + * @return never {@literal null}. */ - protected > R prepareWriteRequest(R request) { + protected DeleteByQueryRequest prepareDeleteByRequest(DeleteByQueryRequest request) { - if (refreshPolicy == null) { - return request; + if (refreshPolicy != null && !RefreshPolicy.NONE.equals(refreshPolicy)) { + request = request.setRefresh(true); } - return request.setRefreshPolicy(refreshPolicy); + if (indicesOptions != null) { + request = request.setIndicesOptions(indicesOptions); + } + + return request; } /** @@ -409,103 +398,112 @@ protected IndexRequest prepareIndexRequest(Object source, IndexRequest request) } /** - * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the - * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. + * Pre process the write request before it is sent to the server, eg. by setting the + * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. * - * @param request the generated {@link CountRequest}. - * @return never {@literal null}. + * @param request must not be {@literal null}. + * @param + * @return the processed {@link WriteRequest}. */ - protected CountRequest prepareCountRequest(CountRequest request) { + protected > R prepareWriteRequest(R request) { - if (indicesOptions == null) { + if (refreshPolicy == null) { return request; } - return request.indicesOptions(indicesOptions); + return request.setRefreshPolicy(refreshPolicy); } - /** - * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the - * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. - * - * @param request the generated {@link SearchRequest}. - * @return never {@literal null}. - */ - protected SearchRequest prepareSearchRequest(SearchRequest request) { + // endregion - if (indicesOptions == null) { - return request; - } + // region SearchOperations + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#find(Query, Class, Class, IndexCoordinates) + */ + @Override + public Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index) { - return request.indicesOptions(indicesOptions); + return doFind(query, entityType, index).map(it -> converter.mapDocument(DocumentAdapters.from(it), resultType)); } - /** - * Customization hook to modify a generated {@link DeleteRequest} prior to its execution. Eg. by setting the - * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. - * - * @param source the source object the {@link DeleteRequest} was derived from. My be {@literal null} if using the - * {@literal id} directly. - * @param request the generated {@link DeleteRequest}. - * @return never {@literal null}. - */ - protected DeleteRequest prepareDeleteRequest(@Nullable Object source, DeleteRequest request) { - return prepareWriteRequest(request); + @Override + public Flux find(Query query, Class entityType, Class returnType) { + return find(query, entityType, returnType, getIndexCoordinatesFor(entityType)); } - /** - * Customization hook to modify a generated {@link DeleteByQueryRequest} prior to its execution. Eg. by setting the - * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. - * - * @param request the generated {@link DeleteByQueryRequest}. - * @return never {@literal null}. - */ - protected DeleteByQueryRequest prepareDeleteByRequest(DeleteByQueryRequest request) { + private Flux doFind(Query query, Class clazz, IndexCoordinates index) { - if (refreshPolicy != null && !RefreshPolicy.NONE.equals(refreshPolicy)) { - request = request.setRefresh(true); - } + return Flux.defer(() -> { + SearchRequest request = requestFactory.searchRequest(query, clazz, index); - if (indicesOptions != null) { - request = request.setIndicesOptions(indicesOptions); - } + if (indicesOptions != null) { + request.indicesOptions(indicesOptions); + } - return request; + if (query.getPageable().isPaged() || query.isLimiting()) { + return doFind(request); + } else { + return doScroll(request); + } + }); } - /** - * Customization hook on the actual execution result {@link Publisher}.
- * You know what you're doing here? Well fair enough, go ahead on your own risk. - * - * @param request the already prepared {@link IndexRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doIndex(IndexRequest request) { - return Mono.from(execute(client -> client.index(request))); + @Override + public Mono count(Query query, Class entityType) { + return count(query, entityType, getIndexCoordinatesFor(entityType)); } - /** - * Customization hook on the actual execution result {@link Publisher}.
- * - * @param request the already prepared {@link GetRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doFindById(GetRequest request) { + @Override + public Mono count(Query query, Class entityType, IndexCoordinates index) { + return doCount(query, getPersistentEntityFor(entityType), index); + } + + private Mono doCount(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { + return Mono.defer(() -> { + + CountRequest countRequest = buildCountRequest(query, entity, index); + CountRequest request = prepareCountRequest(countRequest); + return doCount(request); + }); - return Mono.from(execute(client -> client.get(request))) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } - /** - * Customization hook on the actual execution result {@link Publisher}.
- * - * @param request the already prepared {@link GetRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doExists(GetRequest request) { + private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - return Mono.from(execute(client -> client.exists(request))) // - .onErrorReturn(NoSuchIndexException.class, false); + CountRequest request = new CountRequest(index.getIndexNames()); + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); + searchSourceBuilder.query(mappedQuery(query, entity)); + searchSourceBuilder.trackScores(query.getTrackScores()); + + QueryBuilder postFilterQuery = mappedFilterQuery(query, entity); + if (postFilterQuery != null) { + searchSourceBuilder.postFilter(postFilterQuery); + } + + if (query.getSourceFilter() != null) { + searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); + } + + if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { + searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); + } + + sort(query, entity).forEach(searchSourceBuilder::sort); + + if (query.getMinScore() > 0) { + searchSourceBuilder.minScore(query.getMinScore()); + } + + if (query.getIndicesOptions() != null) { + request.indicesOptions(query.getIndicesOptions()); + } + + if (query.getPreference() != null) { + request.preference(query.getPreference()); + } + request.source(searchSourceBuilder); + return request; } /** @@ -556,40 +554,34 @@ protected Flux doScroll(SearchRequest request) { .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } - /** - * Customization hook on the actual execution result {@link Publisher}.
- * - * @param request the already prepared {@link DeleteRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doDelete(DeleteRequest request) { + @Nullable + private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntity entity) { - return Mono.from(execute(client -> client.delete(request))) // + if (query instanceof NativeSearchQuery) { + return ((NativeSearchQuery) query).getFilter(); + } - .flatMap(it -> { + return null; + } - if (HttpStatus.valueOf(it.status().getStatus()).equals(HttpStatus.NOT_FOUND)) { - return Mono.empty(); - } + private QueryBuilder mappedQuery(Query query, ElasticsearchPersistentEntity entity) { - return Mono.just(it.getId()); - }) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); - } + // TODO: we need to actually map the fields to the according field names! - /** - * Customization hook on the actual execution result {@link Publisher}.
- * - * @param request the already prepared {@link DeleteByQueryRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doDeleteBy(DeleteByQueryRequest request) { + QueryBuilder elasticsearchQuery = null; - return Mono.from(execute(client -> client.deleteBy(request))) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); - } + if (query instanceof CriteriaQuery) { + elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(((CriteriaQuery) query).getCriteria()); + } else if (query instanceof StringQuery) { + elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource()); + } else if (query instanceof NativeSearchQuery) { + elasticsearchQuery = ((NativeSearchQuery) query).getQuery(); + } else { + throw new IllegalArgumentException(String.format("Unknown query type '%s'.", query.getClass())); + } - // private helpers + return elasticsearchQuery != null ? elasticsearchQuery : QueryBuilders.matchAllQuery(); + } private static List sort(Query query, ElasticsearchPersistentEntity entity) { @@ -618,33 +610,82 @@ private static List sort(Query query, ElasticsearchPersistentE return mappedSort; } - private QueryBuilder mappedQuery(Query query, ElasticsearchPersistentEntity entity) { + /** + * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the + * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. + * + * @param request the generated {@link CountRequest}. + * @return never {@literal null}. + */ + protected CountRequest prepareCountRequest(CountRequest request) { - // TODO: we need to actually map the fields to the according field names! + if (indicesOptions == null) { + return request; + } - QueryBuilder elasticsearchQuery = null; + return request.indicesOptions(indicesOptions); + } - if (query instanceof CriteriaQuery) { - elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(((CriteriaQuery) query).getCriteria()); - } else if (query instanceof StringQuery) { - elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource()); - } else if (query instanceof NativeSearchQuery) { - elasticsearchQuery = ((NativeSearchQuery) query).getQuery(); - } else { - throw new IllegalArgumentException(String.format("Unknown query type '%s'.", query.getClass())); + /** + * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the + * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. + * + * @param request the generated {@link SearchRequest}. + * @return never {@literal null}. + */ + protected SearchRequest prepareSearchRequest(SearchRequest request) { + + if (indicesOptions == null) { + return request; } - return elasticsearchQuery != null ? elasticsearchQuery : QueryBuilders.matchAllQuery(); + return request.indicesOptions(indicesOptions); } - @Nullable - private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntity entity) { + // endregion - if (query instanceof NativeSearchQuery) { - return ((NativeSearchQuery) query).getFilter(); - } + // region Helper methods + // Property Setters / Getters - return null; + /** + * Set the default {@link RefreshPolicy} to apply when writing to Elasticsearch. + * + * @param refreshPolicy can be {@literal null}. + */ + public void setRefreshPolicy(@Nullable RefreshPolicy refreshPolicy) { + this.refreshPolicy = refreshPolicy; + } + + /** + * Set the default {@link IndicesOptions} for {@link SearchRequest search requests}. + * + * @param indicesOptions can be {@literal null}. + */ + public void setIndicesOptions(@Nullable IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exctute(ClientCallback) + */ + @Override + public Publisher execute(ClientCallback> callback) { + return Flux.defer(() -> callback.doWithClient(getClient())).onErrorMap(this::translateException); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#getElasticsearchConverter() + */ + @Override + public ElasticsearchConverter getElasticsearchConverter() { + return converter; + } + + @Override + public IndexCoordinates getIndexCoordinatesFor(Class clazz) { + return getPersistentEntityFor(clazz).getIndexCoordinates(); } @Override @@ -661,4 +702,16 @@ private Throwable translateException(Throwable throwable) { return potentiallyTranslatedException != null ? potentiallyTranslatedException : throwable; } + + /** + * Obtain the {@link ReactiveElasticsearchClient} to operate upon. + * + * @return never {@literal null}. + */ + protected ReactiveElasticsearchClient getClient() { + return this.client; + } + + // endregion + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java new file mode 100644 index 000000000..dabc23097 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -0,0 +1,119 @@ +/* + * Copyright 2019 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; + +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import org.elasticsearch.index.query.QueryBuilders; +import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.StringQuery; + +/** + * The reactive operations for the + * Elasticsearch Document + * APIs. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface ReactiveSearchOperations { + /** + * Search the index for entities matching the given {@link Query query}.
+ * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either + * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) + * size}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param + * @return a {@link Flux} emitting matching entities one by one. + */ + default Flux find(Query query, Class entityType) { + return find(query, entityType, entityType); + } + + /** + * Search the index for entities matching the given {@link Query query}.
+ * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either * + * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) * + * size}. + * + * @param query must not be {@literal null}. + * @param entityType The entity type for mapping the query. Must not be {@literal null}. + * @param returnType The mapping target type. Must not be {@literal null}. Th + * @param + * @return a {@link Flux} emitting matching entities one by one. + */ + Flux find(Query query, Class entityType, Class returnType); + + /** + * Search the index for entities matching the given {@link Query query}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @returnm a {@link Flux} emitting matching entities one by one. + */ + default Flux find(Query query, Class entityType, IndexCoordinates index) { + return find(query, entityType, entityType, index); + } + + /** + * Search the index for entities matching the given {@link Query query}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param resultType the projection result type. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Flux} emitting matching entities one by one. + */ + Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index); + + /** + * Count the number of documents matching the given {@link Query}. + * + * @param entityType must not be {@literal null}. + * @return a {@link Mono} emitting the nr of matching documents. + */ + default Mono count(Class entityType) { + return count(new StringQuery(QueryBuilders.matchAllQuery().toString()), entityType); + } + + /** + * Count the number of documents matching the given {@link Query}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @return a {@link Mono} emitting the nr of matching documents. + */ + Mono count(Query query, Class entityType); + + /** + * Count the number of documents matching the given {@link Query}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting the nr of matching documents. + */ + Mono count(Query query, Class entityType, IndexCoordinates index); + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 04e036639..de5fb02d2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -66,6 +66,7 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.lang.Nullable; import org.springframework.util.Assert; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java new file mode 100644 index 000000000..14a4d18d6 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -0,0 +1,204 @@ +/* + * Copyright 2019 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; + +import java.util.List; +import java.util.stream.Collectors; + +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.search.suggest.SuggestBuilder; +import org.springframework.data.domain.Page; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; + +/** + * The operations for the + * Elasticsearch Document + * APIs. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface SearchOperations { + /** + * Return number of elements found by given query. + * + * @param query the query to execute + * @param index the index to run the query against + * @return count + */ + default long count(Query query, IndexCoordinates index) { + return count(query, null, index); + } + + /** + * return number of elements found by given query + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return count + */ + long count(Query query, @Nullable Class clazz, IndexCoordinates index); + + T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index); + + /** + * Execute the query against elasticsearch and return the first returned object. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return the first matching object + */ + default T queryForObject(Query query, Class clazz, IndexCoordinates index) { + List content = queryForPage(query, clazz, index).getContent(); + return content.isEmpty() ? null : content.get(0); + } + + /** + * Execute the query against elasticsearch and return result as {@link Page}. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return a page with aggregations + */ + AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index); + + /** + * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} + * + * @param queries the queries + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return list of pages with the results + */ + List> queryForPage(List queries, Class clazz, IndexCoordinates index); + + /** + * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} + * + * @param queries the queries + * @param classes the entity classes used for the queries + * @param index the index to run the query against + * @return list of pages with the results + */ + List> queryForPage(List queries, List> classes, IndexCoordinates index); + + /** + * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. + *

+ * + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * + * error. + */ + CloseableIterator stream(Query query, Class clazz, IndexCoordinates index); + + /** + * Execute the criteria query against elasticsearch and return result as {@link List} + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @param element return type + * @return list of found objects + */ + List queryForList(Query query, Class clazz, IndexCoordinates index); + + /** + * Execute the multi search query against elasticsearch and return result as {@link List} + * + * @param queries the queries to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @param element return type + * @return list of found objects + */ + default List> queryForList(List queries, Class clazz, IndexCoordinates index) { + return queryForPage(queries, clazz, index).stream().map(Page::getContent).collect(Collectors.toList()); + } + + /** + * Execute the multi search query against elasticsearch and return result as {@link List} + * + * @param queries the queries to execute + * @param classes the entity classes used for property mapping + * @param index the index to run the query against + * @return list of list of found objects + */ + default List> queryForList(List queries, List> classes, IndexCoordinates index) { + return queryForPage(queries, classes, index).stream().map(Page::getContent).collect(Collectors.toList()); + } + + /** + * Execute the query against elasticsearch and return ids + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return list of found object ids + */ + List queryForIds(Query query, Class clazz, IndexCoordinates index); + + /** + * Returns scrolled page for given query + * + * @param scrollTimeInMillis duration of the scroll time + * @param query The search query. + * @param clazz The class of entity to retrieve. + * @param index the index to run the query against + * @return scrolled page result + */ + ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index); + + ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz); + + /** + * Clears the search contexts associated with specified scroll ids. + * + * @param scrollId the scroll id + */ + void clearScroll(String scrollId); + + /** + * more like this query to search for documents that are "like" a specific document. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @param element return type + * @return page with the results + */ + Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); + + /** + * Does a suggest query + * + * @param suggestion the query + * @param index the index to run the query against + * @return the suggest response + */ + SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 7355a9511..b12ef55cb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -31,16 +31,7 @@ import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.data.annotation.Transient; -import org.springframework.data.elasticsearch.annotations.CompletionContext; -import org.springframework.data.elasticsearch.annotations.CompletionField; -import org.springframework.data.elasticsearch.annotations.DynamicMapping; -import org.springframework.data.elasticsearch.annotations.DynamicTemplates; -import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.annotations.FieldType; -import org.springframework.data.elasticsearch.annotations.GeoPointField; -import org.springframework.data.elasticsearch.annotations.InnerField; -import org.springframework.data.elasticsearch.annotations.Mapping; -import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.completion.Completion; @@ -111,7 +102,7 @@ public String buildPropertyMapping(Class clazz) throws IOException { ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() .getRequiredPersistentEntity(clazz); - XContentBuilder builder = jsonBuilder().startObject().startObject(entity.getIndexType()); + XContentBuilder builder = jsonBuilder().startObject().startObject(entity.getIndexCoordinates().getTypeName()); // Dynamic templates addDynamicTemplatesMapping(builder, entity); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index e1be3d558..759d38745 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -32,9 +32,7 @@ */ public interface ElasticsearchPersistentEntity extends PersistentEntity { - String getIndexName(); - - String getIndexType(); + IndexCoordinates getIndexCoordinates(); short getShards(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java similarity index 97% rename from src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java rename to src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java index 0cf73c76e..eb1757544 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexCoordinates.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.elasticsearch.core; +package org.springframework.data.elasticsearch.core.mapping; import java.util.Arrays; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 93b4e4611..d0dd1705d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -102,8 +102,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws context.setRootObject(applicationContext); } - @Override - public String getIndexName() { + private String getIndexName() { if (indexName != null) { Expression expression = parser.parseExpression(indexName, ParserContext.TEMPLATE_EXPRESSION); @@ -113,8 +112,7 @@ public String getIndexName() { return getTypeInformation().getType().getSimpleName(); } - @Override - public String getIndexType() { + private String getIndexType() { if (indexType != null) { Expression expression = parser.parseExpression(indexType, ParserContext.TEMPLATE_EXPRESSION); @@ -124,6 +122,11 @@ public String getIndexType() { return ""; } + @Override + public IndexCoordinates getIndexCoordinates() { + return IndexCoordinates.of(getIndexName()).withTypes(getIndexType()); + } + @Override public String getIndexStoreType() { return indexStoreType; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index 3a7dcd53d..c04043df3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -19,6 +19,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.NoRepositoryBean; /** @@ -46,7 +47,7 @@ public interface ElasticsearchRepository extends ElasticsearchCrudReposit Page search(QueryBuilder query, Pageable pageable); - Page search(NativeSearchQuery searchQuery); + Page search(Query searchQuery); Page searchSimilar(T entity, String[] fields, Pageable pageable); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index 397794ff4..f9303515f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -20,7 +20,7 @@ import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 5ee079d33..b0453adc4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -17,7 +17,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 49166c0b9..ebbe03010 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -20,7 +20,7 @@ import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.convert.DateTimeConverters; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.repository.query.ParametersParameterAccessor; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java index af02d8080..7ef44c08e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java @@ -16,7 +16,7 @@ package org.springframework.data.elasticsearch.repository.query; import org.springframework.core.convert.converter.Converter; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.query.ResultProcessor; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java index 857bb8b7b..d900f89ac 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java @@ -38,12 +38,12 @@ public SimpleElasticsearchEntityMetadata(Class type, ElasticsearchPersistentE @Override public String getIndexName() { - return entity.getIndexName(); + return entity.getIndexCoordinates().getIndexName(); } @Override public String getIndexTypeName() { - return entity.getIndexType(); + return entity.getIndexCoordinates().getTypeName(); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 8edc1f135..b2f3a7184 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -35,14 +35,19 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.core.DocumentOperations; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.SearchOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.util.Streamable; import org.springframework.util.Assert; @@ -66,21 +71,23 @@ public abstract class AbstractElasticsearchRepository implements Elastics static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchRepository.class); - protected ElasticsearchOperations elasticsearchOperations; + protected ElasticsearchOperations operations; + protected IndexOperations indexOperations; + protected Class entityClass; protected ElasticsearchEntityInformation entityInformation; public AbstractElasticsearchRepository() {} - public AbstractElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) { - Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!"); - - this.setElasticsearchOperations(elasticsearchOperations); + public AbstractElasticsearchRepository(ElasticsearchOperations operations) { + Assert.notNull(operations, "ElasticsearchOperations must not be null."); + this.operations = operations; + this.indexOperations = operations.getIndexOperations(); } public AbstractElasticsearchRepository(ElasticsearchEntityInformation metadata, - ElasticsearchOperations elasticsearchOperations) { - this(elasticsearchOperations); + ElasticsearchOperations operations) { + this(operations); Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); @@ -97,22 +104,25 @@ public AbstractElasticsearchRepository(ElasticsearchEntityInformation met } private void createIndex() { - elasticsearchOperations.createIndex(getEntityClass()); + indexOperations.createIndex(getEntityClass()); } private void putMapping() { - elasticsearchOperations.putMapping(getEntityClass()); + indexOperations.putMapping(getEntityClass()); } private boolean createIndexAndMapping() { - return elasticsearchOperations.getPersistentEntityFor(getEntityClass()).isCreateIndexAndMapping(); + + final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter() + .getMappingContext().getRequiredPersistentEntity(getEntityClass()); + return entity.isCreateIndexAndMapping(); } @Override public Optional findById(ID id) { GetQuery query = new GetQuery(); query.setId(stringIdRepresentation(id)); - return Optional.ofNullable(elasticsearchOperations.get(query, getEntityClass(), getIndexCoordinates())); + return Optional.ofNullable(operations.get(query, getEntityClass(), getIndexCoordinates())); } @Override @@ -128,7 +138,7 @@ public Iterable findAll() { @Override public Page findAll(Pageable pageable) { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); - return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override @@ -140,27 +150,27 @@ public Iterable findAll(Sort sort) { } NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); - return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override public Iterable findAllById(Iterable ids) { Assert.notNull(ids, "ids can't be null."); NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); - return elasticsearchOperations.multiGet(query, getEntityClass(), getIndexCoordinates()); + return operations.multiGet(query, getEntityClass(), getIndexCoordinates()); } @Override public long count() { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - return elasticsearchOperations.count(query, getEntityClass(), getIndexCoordinates()); + return operations.count(query, getEntityClass(), getIndexCoordinates()); } @Override public S save(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); - elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates()); - elasticsearchOperations.refresh(getIndexCoordinates()); + operations.index(createIndexQuery(entity), getIndexCoordinates()); + indexOperations.refresh(getIndexCoordinates()); return entity; } @@ -177,7 +187,7 @@ public S index(S entity) { @Override public S indexWithoutRefresh(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); - elasticsearchOperations.index(createIndexQuery(entity), getIndexCoordinates()); + operations.index(createIndexQuery(entity), getIndexCoordinates()); return entity; } @@ -188,8 +198,8 @@ public Iterable saveAll(Iterable entities) { .collect(Collectors.toList()); if (!queries.isEmpty()) { - elasticsearchOperations.bulkIndex(queries, getIndexCoordinates()); - elasticsearchOperations.refresh(getIndexCoordinates()); + operations.bulkIndex(queries, getIndexCoordinates()); + indexOperations.refresh(getIndexCoordinates()); } return entities; @@ -203,24 +213,24 @@ public boolean existsById(ID id) { @Override public Iterable search(QueryBuilder query) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); - int count = (int) elasticsearchOperations.count(searchQuery, getEntityClass(), getIndexCoordinates()); + int count = (int) operations.count(searchQuery, getEntityClass(), getIndexCoordinates()); if (count == 0) { return new PageImpl<>(Collections. emptyList()); } searchQuery.setPageable(PageRequest.of(0, count)); - return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + return operations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); } @Override public Page search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); - return elasticsearchOperations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + return operations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); } @Override - public Page search(NativeSearchQuery query) { - return elasticsearchOperations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + public Page search(Query query) { + return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); } @Override @@ -235,22 +245,22 @@ public Page searchSimilar(T entity, String[] fields, Pageable pageable) { query.addFields(fields); } - return elasticsearchOperations.moreLikeThis(query, getEntityClass(), getIndexCoordinates()); + return operations.moreLikeThis(query, getEntityClass(), getIndexCoordinates()); } @Override public void deleteById(ID id) { Assert.notNull(id, "Cannot delete entity with id 'null'."); IndexCoordinates indexCoordinates = getIndexCoordinates(); - elasticsearchOperations.delete(stringIdRepresentation(id), indexCoordinates); - elasticsearchOperations.refresh(indexCoordinates); + operations.delete(stringIdRepresentation(id), indexCoordinates); + indexOperations.refresh(indexCoordinates); } @Override public void delete(T entity) { Assert.notNull(entity, "Cannot delete 'null' entity."); deleteById(extractIdFromBean(entity)); - elasticsearchOperations.refresh(getIndexCoordinates()); + indexOperations.refresh(getIndexCoordinates()); } @Override @@ -266,13 +276,13 @@ public void deleteAll() { DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(matchAllQuery()); IndexCoordinates indexCoordinates = getIndexCoordinates(); - elasticsearchOperations.delete(deleteQuery, indexCoordinates); - elasticsearchOperations.refresh(indexCoordinates); + operations.delete(deleteQuery, indexCoordinates); + indexOperations.refresh(indexCoordinates); } @Override public void refresh() { - elasticsearchOperations.refresh(getEntityClass()); + indexOperations.refresh(getEntityClass()); } private IndexQuery createIndexQuery(T entity) { @@ -326,11 +336,6 @@ public final void setEntityClass(Class entityClass) { this.entityClass = entityClass; } - public final void setElasticsearchOperations(ElasticsearchOperations elasticsearchOperations) { - Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null."); - this.elasticsearchOperations = elasticsearchOperations; - } - protected ID extractIdFromBean(T entity) { return entityInformation.getId(entity); } @@ -356,6 +361,6 @@ private String extractParentIdFromBean(T entity) { } private IndexCoordinates getIndexCoordinates() { - return elasticsearchOperations.getIndexCoordinatesFor(getEntityClass()); + return operations.getIndexCoordinatesFor(getEntityClass()); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java index 7383708a0..83bd22fdd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.repository.support; import org.elasticsearch.index.VersionType; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.core.EntityInformation; /** @@ -25,14 +26,13 @@ * @author Mohsin Husen * @author Christoph Strobl * @author Ivan Greene + * @author Peter-Josef Meisch */ public interface ElasticsearchEntityInformation extends EntityInformation { String getIdAttribute(); - String getIndexName(); - - String getType(); + IndexCoordinates getIndexCoordinates(); Long getVersion(T entity); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java index 5a8da2f3c..69b8983ac 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.repository.support; import org.elasticsearch.index.VersionType; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.repository.core.support.PersistentEntityInformation; @@ -39,21 +40,19 @@ public class MappingElasticsearchEntityInformation extends PersistentEnti implements ElasticsearchEntityInformation { private final ElasticsearchPersistentEntity entityMetadata; - private final String indexName; - private final String type; + private final IndexCoordinates indexCoordinates; private final VersionType versionType; public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity entity) { - this(entity, entity.getIndexName(), entity.getIndexType(), entity.getVersionType()); + this(entity, entity.getIndexCoordinates(), entity.getVersionType()); } - public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity entity, String indexName, String type, - VersionType versionType) { + public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity entity, + IndexCoordinates indexCoordinates, VersionType versionType) { super(entity); this.entityMetadata = entity; - this.indexName = indexName; - this.type = type; + this.indexCoordinates = indexCoordinates; this.versionType = versionType; } @@ -62,14 +61,10 @@ public String getIdAttribute() { return entityMetadata.getRequiredIdProperty().getFieldName(); } - @Override - public String getIndexName() { - return indexName != null ? indexName : entityMetadata.getIndexName(); - } @Override - public String getType() { - return type != null ? type : entityMetadata.getIndexType(); + public IndexCoordinates getIndexCoordinates() { + return indexCoordinates; } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java index 8281226de..0ecb9024e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java @@ -115,9 +115,8 @@ private ElasticsearchEntityInformation getEntityInformation(Class @Nullable RepositoryInformation information) { ElasticsearchPersistentEntity entity = mappingContext.getRequiredPersistentEntity(domainClass); - - return new MappingElasticsearchEntityInformation<>((ElasticsearchPersistentEntity) entity, entity.getIndexName(), - entity.getIndexType(), entity.getVersionType()); + return new MappingElasticsearchEntityInformation<>((ElasticsearchPersistentEntity) entity, + entity.getIndexCoordinates(), entity.getVersionType()); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index de2e74a47..3d87f54ce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -20,7 +20,6 @@ import org.reactivestreams.Publisher; import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.core.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; @@ -35,7 +34,6 @@ public class SimpleReactiveElasticsearchRepository implements ReactiveEla private final ElasticsearchEntityInformation entityInformation; private final ReactiveElasticsearchOperations elasticsearchOperations; - private final IndexCoordinates index; public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation entityInformation, ReactiveElasticsearchOperations elasticsearchOperations) { @@ -45,20 +43,19 @@ public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation findAll(Sort sort) { - return elasticsearchOperations.find(Query.findAll().addSort(sort), entityInformation.getJavaType(), index); + return elasticsearchOperations.find(Query.findAll().addSort(sort), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override public Mono save(S entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.save(entity, index); + return elasticsearchOperations.save(entity, entityInformation.getIndexCoordinates()); } @Override @@ -79,7 +76,7 @@ public Flux saveAll(Publisher entityStream) { public Mono findById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), index); + return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override @@ -93,7 +90,7 @@ public Mono findById(Publisher id) { public Mono existsById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), index); + return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override @@ -106,7 +103,7 @@ public Mono existsById(Publisher id) { @Override public Flux findAll() { - return elasticsearchOperations.find(Query.findAll(), entityInformation.getJavaType(), index); + return elasticsearchOperations.find(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override @@ -127,14 +124,14 @@ public Flux findAllById(Publisher idStream) { @Override public Mono count() { - return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), index); + return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override public Mono deleteById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.deleteById(convertId(id), entityInformation.getJavaType(), index) // + return elasticsearchOperations.deleteById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // .then(); } @@ -149,7 +146,7 @@ public Mono deleteById(Publisher id) { public Mono delete(T entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.delete(entity, index) // + return elasticsearchOperations.delete(entity, entityInformation.getIndexCoordinates()) // .then(); } @@ -170,7 +167,7 @@ public Mono deleteAll(Publisher entityStream) { @Override public Mono deleteAll() { - return elasticsearchOperations.deleteBy(Query.findAll(), entityInformation.getJavaType(), index) // + return elasticsearchOperations.deleteBy(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // .then(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 3afdbcc42..07350522c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -45,7 +45,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 407e0efee..83a286cb3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -61,7 +61,7 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() indexRequest.source("{}", XContentType.JSON); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); assertThatThrownBy(() -> { - elasticsearchTemplate.update(updateQuery, index); + operations.update(updateQuery, index); }).isInstanceOf(ElasticsearchStatusException.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index ee2718ae0..6aba00fab 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -75,6 +75,7 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.CloseableIterator; @@ -111,18 +112,22 @@ public abstract class ElasticsearchTemplateTests { protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME); - @Autowired protected ElasticsearchOperations elasticsearchTemplate; + @Autowired protected ElasticsearchOperations operations; + + private IndexOperations indexOperations; @BeforeEach public void before() { + indexOperations = operations.getIndexOperations(); + deleteIndices(); - elasticsearchTemplate.createIndex(SampleEntity.class); - elasticsearchTemplate.putMapping(SampleEntity.class); + indexOperations.createIndex(SampleEntity.class); + indexOperations.putMapping(SampleEntity.class); - elasticsearchTemplate.createIndex(SampleEntityUUIDKeyed.class); - elasticsearchTemplate.putMapping(SampleEntityUUIDKeyed.class); + indexOperations.createIndex(SampleEntityUUIDKeyed.class); + indexOperations.putMapping(SampleEntityUUIDKeyed.class); } @AfterEach @@ -133,14 +138,14 @@ public void after() { private void deleteIndices() { - elasticsearchTemplate.deleteIndex(SampleEntity.class); - elasticsearchTemplate.deleteIndex(SampleEntityUUIDKeyed.class); - elasticsearchTemplate.deleteIndex(UseServerConfigurationEntity.class); - elasticsearchTemplate.deleteIndex(SampleMappingEntity.class); - elasticsearchTemplate.deleteIndex(Book.class); - elasticsearchTemplate.deleteIndex(INDEX_1_NAME); - elasticsearchTemplate.deleteIndex(INDEX_2_NAME); - elasticsearchTemplate.deleteIndex(INDEX_3_NAME); + indexOperations.deleteIndex(SampleEntity.class); + indexOperations.deleteIndex(SampleEntityUUIDKeyed.class); + indexOperations.deleteIndex(UseServerConfigurationEntity.class); + indexOperations.deleteIndex(SampleMappingEntity.class); + indexOperations.deleteIndex(Book.class); + indexOperations.deleteIndex(INDEX_1_NAME); + indexOperations.deleteIndex(INDEX_2_NAME); + indexOperations.deleteIndex(INDEX_3_NAME); } @Test // DATAES-106 @@ -152,13 +157,13 @@ public void shouldReturnCountForGivenCriteriaQuery() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class, index); + long count = operations.count(criteriaQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -173,13 +178,13 @@ public void shouldReturnCountForGivenSearchQuery() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class, index); + long count = operations.count(searchQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); } @@ -192,12 +197,12 @@ public void shouldReturnObjectForGivenId() { SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); + operations.index(indexQuery, index); // when GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity sampleEntity1 = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.get(getQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -220,12 +225,12 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); - List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, index); + List sampleEntities = operations.multiGet(query, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(2); @@ -249,13 +254,13 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)) .withFields("message", "type").build(); - List sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, index); + List sampleEntities = operations.multiGet(query, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(2); @@ -271,13 +276,13 @@ public void shouldReturnPageForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -294,15 +299,15 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQueryWithValidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_local").build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQueryWithValidPreference, - SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQueryWithValidPreference, SampleEntity.class, + index); // then assertThat(sampleEntities).isNotNull(); @@ -319,15 +324,15 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQueryWithInvalidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_only_nodes:oops").build(); // when assertThatThrownBy(() -> { - elasticsearchTemplate.queryForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); + operations.queryForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); }).isInstanceOf(Exception.class); } @@ -341,13 +346,13 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - Page entities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, + Page entities = operations.queryForPage(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then @@ -374,12 +379,12 @@ public void shouldDoBulkIndex() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); // when - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -396,8 +401,8 @@ public void shouldDoBulkUpdate() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", messageAfterUpdate); @@ -407,12 +412,12 @@ public void shouldDoBulkUpdate() { queries.add(updateQuery); // when - elasticsearchTemplate.bulkUpdate(queries, index); + operations.bulkUpdate(queries, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); + SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -426,15 +431,15 @@ public void shouldDeleteDocumentForGivenId() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); + operations.index(indexQuery, index); // when - elasticsearchTemplate.delete(documentId, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(documentId, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -448,15 +453,15 @@ public void shouldDeleteEntityForGivenId() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); + operations.index(indexQuery, index); // when - elasticsearchTemplate.delete(documentId, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(documentId, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -470,18 +475,18 @@ public void shouldDeleteDocumentForGivenQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("id", documentId)); - elasticsearchTemplate.delete(deleteQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(deleteQuery, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -496,27 +501,27 @@ public void shouldDeleteAcrossIndex() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(typeQuery(TYPE_NAME)); - elasticsearchTemplate.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + operations.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")).build(); - assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME))).isEqualTo(0); + assertThat(operations.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME))).isEqualTo(0); } @Test // DATAES-547 @@ -530,27 +535,27 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - elasticsearchTemplate.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("message", "negative")); - elasticsearchTemplate.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + operations.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")).build(); - assertThat(elasticsearchTemplate.count(searchQuery, IndexCoordinates.of("test-index-*"))).isEqualTo(2); + assertThat(operations.count(searchQuery, IndexCoordinates.of("test-index-*"))).isEqualTo(2); } @Test @@ -562,14 +567,14 @@ public void shouldFilterSearchResultsForGivenFilter() { .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -597,14 +602,14 @@ public void shouldSortResultsGivenSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -633,15 +638,15 @@ public void shouldSortResultsGivenMultipleSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").order(SortOrder.ASC)).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -672,14 +677,14 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -710,14 +715,14 @@ public void shouldSortResultsGivenNullLastSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); @@ -734,8 +739,8 @@ public void shouldSortResultsByScore() { SampleEntity.builder().id("2").message("yellow green").build(), // SampleEntity.builder().id("3").message("blue").build()); - elasticsearchTemplate.bulkIndex(getIndexQueries(entities), index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(getIndexQueries(entities), index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(matchQuery("message", "green")) // @@ -743,7 +748,7 @@ public void shouldSortResultsByScore() { .build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(2); @@ -761,13 +766,13 @@ public void shouldExecuteStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -788,8 +793,8 @@ public void shouldUseScriptedFields() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); Map params = new HashMap<>(); params.put("factor", 2); @@ -798,7 +803,7 @@ public void shouldUseScriptedFields() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( new ScriptField("scriptedRate", new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params))) .build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -815,13 +820,13 @@ public void shouldReturnPageableResultsGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10)); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -841,14 +846,14 @@ public void shouldReturnSortedPageableResultsGivenStringQuery() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10), Sort.by(Order.asc("message"))); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -864,13 +869,13 @@ public void shouldReturnObjectMatchingGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(termQuery("id", documentId).toString()); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(stringQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.queryForObject(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -881,12 +886,10 @@ public void shouldReturnObjectMatchingGivenStringQuery() { public void shouldCreateIndexGivenEntityClass() { // when - boolean created = elasticsearchTemplate.createIndex(SampleEntity.class); - elasticsearchTemplate.putMapping(SampleEntity.class); - Map setting = elasticsearchTemplate.getSetting(SampleEntity.class); + // creation is done in setup method + Map setting = indexOperations.getSetting(SampleEntity.class); // then - assertThat(created).isTrue(); assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); assertThat(setting.get("index.number_of_replicas")).isEqualTo("0"); } @@ -901,12 +904,12 @@ public void shouldExecuteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when - SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(criteriaQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -922,17 +925,17 @@ public void shouldDeleteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when - elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(criteriaQuery, SampleEntity.class, index); + indexOperations.refresh(SampleEntity.class); // then StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class, index); + List sampleEntities = operations.queryForList(stringQuery, SampleEntity.class, index); assertThat(sampleEntities).isEmpty(); } @@ -949,13 +952,13 @@ public void shouldReturnSpecifiedFields() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -977,8 +980,8 @@ public void shouldReturnFieldsBasedOnSourceFilter() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); FetchSourceFilterBuilder sourceFilter = new FetchSourceFilterBuilder(); sourceFilter.withIncludes("message"); @@ -987,7 +990,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { .withSourceFilter(sourceFilter.build()).build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -1011,15 +1014,15 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); + operations.index(indexQuery, index); String documentId2 = randomNumeric(5); - elasticsearchTemplate.index( + operations.index( getIndexQuery( SampleEntity.builder().id(documentId2).message(sampleMessage).version(System.currentTimeMillis()).build()), index); - elasticsearchTemplate.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); MoreLikeThisQuery moreLikeThisQuery = new MoreLikeThisQuery(); moreLikeThisQuery.setId(documentId2); @@ -1027,8 +1030,7 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { moreLikeThisQuery.setMinDocFreq(1); // when - Page sampleEntities = elasticsearchTemplate.moreLikeThis(moreLikeThisQuery, SampleEntity.class, - index); + Page sampleEntities = operations.moreLikeThis(moreLikeThisQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -1042,21 +1044,20 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scroll.getScrollId()); + operations.clearScroll(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1067,21 +1068,21 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scroll.getScrollId()); + operations.clearScroll(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1092,24 +1093,23 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1120,22 +1120,22 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .withQuery(matchAllQuery()).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1146,23 +1146,22 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1173,22 +1172,22 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1199,23 +1198,22 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1226,22 +1224,22 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scrollId); + operations.clearScroll(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1252,14 +1250,14 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - CloseableIterator stream = elasticsearchTemplate.stream(criteriaQuery, SampleEntity.class, index); + CloseableIterator stream = operations.stream(criteriaQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (stream.hasNext()) { sampleEntities.add(stream.next()); @@ -1307,16 +1305,16 @@ public void shouldReturnListForGivenCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); // when - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery singleCriteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); CriteriaQuery multipleCriteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").and("message").contains("message")); - List sampleEntitiesForSingleCriteria = elasticsearchTemplate.queryForList(singleCriteriaQuery, - SampleEntity.class, index); - List sampleEntitiesForAndCriteria = elasticsearchTemplate.queryForList(multipleCriteriaQuery, + List sampleEntitiesForSingleCriteria = operations.queryForList(singleCriteriaQuery, SampleEntity.class, index); + List sampleEntitiesForAndCriteria = operations.queryForList(multipleCriteriaQuery, SampleEntity.class, + index); // then assertThat(sampleEntitiesForSingleCriteria).hasSize(2); assertThat(sampleEntitiesForAndCriteria).hasSize(1); @@ -1344,11 +1342,11 @@ public void shouldReturnListForGivenStringQuery() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); // when - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = elasticsearchTemplate.queryForList(stringQuery, SampleEntity.class, index); + List sampleEntities = operations.queryForList(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(3); @@ -1359,13 +1357,13 @@ public void shouldPutMappingForGivenEntity() throws Exception { // given Class entity = SampleMappingEntity.class; - elasticsearchTemplate.deleteIndex(entity); - elasticsearchTemplate.createIndex(entity); + indexOperations.deleteIndex(entity); + indexOperations.createIndex(entity); // when // then - assertThat(elasticsearchTemplate.putMapping(entity)).isTrue(); + assertThat(indexOperations.putMapping(entity)).isTrue(); } @Test // DATAES-305 @@ -1373,15 +1371,14 @@ public void shouldPutMappingWithCustomIndexName() throws Exception { // given Class entity = SampleEntity.class; - elasticsearchTemplate.deleteIndex(INDEX_1_NAME); - elasticsearchTemplate.createIndex(INDEX_1_NAME); + indexOperations.deleteIndex(INDEX_1_NAME); + indexOperations.createIndex(INDEX_1_NAME); // when - elasticsearchTemplate.putMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME), entity); + indexOperations.putMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME), entity); // then - Map mapping = elasticsearchTemplate - .getMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME)); + Map mapping = indexOperations.getMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME)); assertThat(mapping.get("properties")).isNotNull(); } @@ -1392,10 +1389,10 @@ public void shouldDeleteIndexForGivenEntity() { Class clazz = SampleEntity.class; // when - elasticsearchTemplate.deleteIndex(clazz); + indexOperations.deleteIndex(clazz); // then - assertThat(elasticsearchTemplate.indexExists(clazz)).isFalse(); + assertThat(indexOperations.indexExists(clazz)).isFalse(); } @Test @@ -1411,20 +1408,20 @@ public void shouldDoPartialUpdateForExistingDocument() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", messageAfterUpdate); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withIndexRequest(indexRequest).build(); // when - elasticsearchTemplate.update(updateQuery, index); + operations.update(updateQuery, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); + SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -1485,12 +1482,12 @@ public void shouldDoUpsertIfDocumentDoesNotExist() { .withIndexRequest(indexRequest).build(); // when - elasticsearchTemplate.update(updateQuery, index); + operations.update(updateQuery, index); // then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity indexedEntity = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); + SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(message); } @@ -1506,8 +1503,8 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); IndexCoordinates index = IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type"); - elasticsearchTemplate.index(idxQuery, index); - elasticsearchTemplate.refresh(index); + operations.index(idxQuery, index); + indexOperations.refresh(index); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -1515,13 +1512,13 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { List entities = new ArrayList<>(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery, - SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(scrollTimeInMillis, searchQuery, SampleEntity.class, + index); entities.addAll(scroll.getContent()); while (scroll.hasContent()) { - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); entities.addAll(scroll.getContent()); } @@ -1541,8 +1538,8 @@ public void shouldReturnSameEntityForMultiSearch() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when List queries = new ArrayList<>(); @@ -1552,7 +1549,7 @@ public void shouldReturnSameEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ac")).build()); // then - List> sampleEntities = elasticsearchTemplate.queryForPage(queries, SampleEntity.class, index); + List> sampleEntities = operations.queryForPage(queries, SampleEntity.class, index); for (Page sampleEntity : sampleEntities) { assertThat(sampleEntity.getTotalElements()).isEqualTo(1); } @@ -1563,24 +1560,24 @@ public void shouldReturnDifferentEntityForMultiSearch() { // given Class clazz = Book.class; - elasticsearchTemplate.deleteIndex(clazz); - elasticsearchTemplate.createIndex(clazz); - elasticsearchTemplate.putMapping(clazz); - elasticsearchTemplate.refresh(clazz); + indexOperations.deleteIndex(clazz); + indexOperations.createIndex(clazz); + indexOperations.putMapping(clazz); + indexOperations.refresh(clazz); IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template").withTypes("book"); - elasticsearchTemplate.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()), index); - elasticsearchTemplate.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex); - elasticsearchTemplate.refresh(SampleEntity.class); - elasticsearchTemplate.refresh(clazz); + operations.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()), index); + operations.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex); + indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(clazz); // when List queries = new ArrayList<>(); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("description", "bc")).build()); - List> pages = elasticsearchTemplate.queryForPage(queries, Lists.newArrayList(SampleEntity.class, clazz), + List> pages = operations.queryForPage(queries, Lists.newArrayList(SampleEntity.class, clazz), IndexCoordinates.of(index.getIndexName(), bookIndex.getIndexName())); // then @@ -1602,18 +1599,18 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("id", documentId)); - elasticsearchTemplate.delete(deleteQuery, index); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.delete(deleteQuery, index); + indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -1627,13 +1624,13 @@ public void shouldIndexDocumentForSpecifiedSource() { indexQuery.setSource(documentSource); // when - elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) .build(); // then - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(page).isNotNull(); assertThat(page.getContent()).hasSize(1); assertThat(page.getContent().get(0).getId()).isEqualTo(indexQuery.getId()); @@ -1647,8 +1644,9 @@ public void shouldThrowElasticsearchExceptionWhenNoDocumentSpecified() { indexQuery.setId("2333343434"); // when - assertThatThrownBy(() -> elasticsearchTemplate.index(indexQuery, - IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME))).isInstanceOf(ElasticsearchException.class); + assertThatThrownBy( + () -> operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME))) + .isInstanceOf(ElasticsearchException.class); } @Test @@ -1656,12 +1654,12 @@ public void shouldReturnIds() { // given List entities = createSampleEntitiesWithMessage("Test message", 30); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) .withPageable(PageRequest.of(0, 100)).build(); // then - List ids = elasticsearchTemplate.queryForIds(searchQuery, SampleEntity.class, index); + List ids = operations.queryForIds(searchQuery, SampleEntity.class, index); assertThat(ids).hasSize(30); } @@ -1674,15 +1672,15 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) .withMinScore(2.0F).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); @@ -1699,14 +1697,14 @@ public void shouldReturnScores() { indexQueries.add(buildIndex(SampleEntity.builder().id("2").message("bc").build())); indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac xz hi").build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) .withSort(SortBuilders.fieldSort("message")).withTrackScores(true).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isInstanceOf(AggregatedPage.class); @@ -1727,14 +1725,14 @@ public void shouldDoIndexWithoutId() { indexQuery.setObject(sampleEntity); // when - String documentId = elasticsearchTemplate.index(indexQuery, index); + String documentId = operations.index(indexQuery, index); // then assertThat(sampleEntity.getId()).isEqualTo(documentId); GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); - SampleEntity result = elasticsearchTemplate.get(getQuery, SampleEntity.class, index); + SampleEntity result = operations.get(getQuery, SampleEntity.class, index); assertThat(result.getId()).isEqualTo(documentId); } @@ -1762,12 +1760,12 @@ public void shouldDoBulkIndexWithoutId() { indexQueries.add(indexQuery2); // when - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); List content = sampleEntities.getContent(); @@ -1806,12 +1804,12 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { indexQueries.add(indexQuery2); // when - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(index); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(index); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, Map.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, Map.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); List content = sampleEntities.getContent(); @@ -1830,23 +1828,23 @@ public void shouldIndexGteEntityWithVersionType() { IndexQueryBuilder indexQueryBuilder = new IndexQueryBuilder().withId(documentId).withVersion(entity.getVersion()) .withObject(entity); - elasticsearchTemplate.index(indexQueryBuilder.build(), index); - elasticsearchTemplate.refresh(index); + operations.index(indexQueryBuilder.build(), index); + indexOperations.refresh(index); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page entities = elasticsearchTemplate.queryForPage(searchQuery, GTEVersionEntity.class, index); + Page entities = operations.queryForPage(searchQuery, GTEVersionEntity.class, index); // then assertThat(entities).isNotNull(); assertThat(entities.getTotalElements()).isGreaterThanOrEqualTo(1); // reindex with same version - elasticsearchTemplate.index(indexQueryBuilder.build(), index); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.index(indexQueryBuilder.build(), index); + indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // reindex with version one below assertThatThrownBy(() -> { - elasticsearchTemplate.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index); + operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index); }).hasMessageContaining("version").hasMessageContaining("conflict"); } @@ -1860,13 +1858,13 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { IndexQuery indexQuery = new IndexQueryBuilder().withId(documentId).withObject(sampleEntity).build(); - elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -1882,12 +1880,12 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQue .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class, index); + long count = operations.count(criteriaQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -1902,12 +1900,12 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class, index); + long count = operations.count(searchQuery, SampleEntity.class, index); // then assertThat(count).isEqualTo(1); @@ -1922,12 +1920,12 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, index); + long count = operations.count(criteriaQuery, index); // then assertThat(count).isEqualTo(1); @@ -1942,12 +1940,12 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearch .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, index); + long count = operations.count(searchQuery, index); // then assertThat(count).isEqualTo(1); @@ -1970,15 +1968,15 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); + long count = operations.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(count).isEqualTo(2); @@ -2001,53 +1999,54 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); + long count = operations.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then assertThat(count).isEqualTo(2); } private void cleanUpIndices() { - elasticsearchTemplate.deleteIndex(INDEX_1_NAME); - elasticsearchTemplate.deleteIndex(INDEX_2_NAME); - elasticsearchTemplate.createIndex(INDEX_1_NAME); - elasticsearchTemplate.createIndex(INDEX_2_NAME); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); + indexOperations.deleteIndex(INDEX_1_NAME); + indexOperations.deleteIndex(INDEX_2_NAME); + indexOperations.createIndex(INDEX_1_NAME); + indexOperations.createIndex(INDEX_2_NAME); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); } @Test // DATAES-71 public void shouldCreatedIndexWithSpecifiedIndexName() { // given - elasticsearchTemplate.deleteIndex(INDEX_3_NAME); + indexOperations.deleteIndex(INDEX_3_NAME); // when - elasticsearchTemplate.createIndex(INDEX_3_NAME); + indexOperations.createIndex(INDEX_3_NAME); // then - assertThat(elasticsearchTemplate.indexExists(INDEX_3_NAME)).isTrue(); + assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue(); } @Test // DATAES-72 public void shouldDeleteIndexForSpecifiedIndexName() { // given - elasticsearchTemplate.createIndex(SampleEntity.class); - elasticsearchTemplate.refresh(SampleEntity.class); + String indexName = "some-random-index"; + indexOperations.createIndex(indexName); + indexOperations.refresh(IndexCoordinates.of(indexName)); // when - elasticsearchTemplate.deleteIndex(INDEX_3_NAME); + indexOperations.deleteIndex(indexName); // then - assertThat(elasticsearchTemplate.indexExists(INDEX_3_NAME)).isFalse(); + assertThat(indexOperations.indexExists(indexName)).isFalse(); } @Test // DATAES-106 @@ -2067,15 +2066,15 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - long count = elasticsearchTemplate.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME)); + long count = operations.count(criteriaQuery, IndexCoordinates.of(INDEX_1_NAME)); // then assertThat(count).isEqualTo(1); @@ -2098,15 +2097,15 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - long count = elasticsearchTemplate.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME)); + long count = operations.count(searchQuery, IndexCoordinates.of(INDEX_1_NAME)); // then assertThat(count).isEqualTo(1); @@ -2121,13 +2120,13 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when assertThatThrownBy(() -> { - elasticsearchTemplate.count(criteriaQuery, (IndexCoordinates) null); + operations.count(criteriaQuery, (IndexCoordinates) null); }).isInstanceOf(IllegalArgumentException.class); } @@ -2140,13 +2139,13 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); - elasticsearchTemplate.index(indexQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.index(indexQuery, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when assertThatThrownBy(() -> { - elasticsearchTemplate.count(searchQuery, (IndexCoordinates) null); + operations.count(searchQuery, (IndexCoordinates) null); }).isInstanceOf(IllegalArgumentException.class); } @@ -2161,14 +2160,14 @@ public void shouldCreateIndexWithGivenSettings() { + " \"tokenizer\": \"uax_url_email\"\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}"; - elasticsearchTemplate.deleteIndex(INDEX_3_NAME); + indexOperations.deleteIndex(INDEX_3_NAME); // when - elasticsearchTemplate.createIndex(INDEX_3_NAME, settings); + indexOperations.createIndex(INDEX_3_NAME, settings); // then - Map map = elasticsearchTemplate.getSetting(INDEX_3_NAME); - assertThat(elasticsearchTemplate.indexExists(INDEX_3_NAME)).isTrue(); + Map map = indexOperations.getSetting(INDEX_3_NAME); + assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); assertThat(map.get("index.analysis.analyzer.emailAnalyzer.tokenizer")).isEqualTo("uax_url_email"); } @@ -2180,8 +2179,8 @@ public void shouldCreateGivenSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - Map map = elasticsearchTemplate.getSetting(SampleEntity.class); - assertThat(elasticsearchTemplate.indexExists(SampleEntity.class)).isTrue(); + Map map = indexOperations.getSetting(SampleEntity.class); + assertThat(indexOperations.indexExists(SampleEntity.class)).isTrue(); assertThat(map.containsKey("index.refresh_interval")).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); @@ -2204,14 +2203,14 @@ public void shouldCreateIndexWithGivenClassAndSettings() { + " }\n" + " }\n" + " }\n" + "}"; // when - elasticsearchTemplate.deleteIndex(SampleEntity.class); - elasticsearchTemplate.createIndex(SampleEntity.class, settings); - elasticsearchTemplate.putMapping(SampleEntity.class); - elasticsearchTemplate.refresh(SampleEntity.class); + indexOperations.deleteIndex(SampleEntity.class); + indexOperations.createIndex(SampleEntity.class, settings); + indexOperations.putMapping(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); // then - Map map = elasticsearchTemplate.getSetting(SampleEntity.class); - assertThat(elasticsearchTemplate.indexExists(INDEX_NAME_SAMPLE_ENTITY)).isTrue(); + Map map = indexOperations.getSetting(SampleEntity.class); + assertThat(indexOperations.indexExists(INDEX_NAME_SAMPLE_ENTITY)).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); assertThat((String) map.get("index.number_of_replicas")).isEqualTo("0"); @@ -2234,15 +2233,15 @@ public void shouldTestResultsAcrossMultipleIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - List sampleEntities = elasticsearchTemplate.queryForList(searchQuery, SampleEntity.class, + List sampleEntities = operations.queryForList(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then @@ -2262,14 +2261,14 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { IndexQuery indexQuery1 = new IndexQueryBuilder().withId(entity1.getId()).withObject(entity1).build(); IndexQuery indexQuery2 = new IndexQueryBuilder().withId(entity2.getId()).withObject(entity2).build(); - elasticsearchTemplate.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("hetro")); - elasticsearchTemplate.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("hetro")); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_1_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("hetro")); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("hetro")); + indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page page = elasticsearchTemplate.queryForPage(searchQuery, ResultAggregator.class, + Page page = operations.queryForPage(searchQuery, ResultAggregator.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); assertThat(page.getTotalElements()).isEqualTo(2); @@ -2281,11 +2280,11 @@ public void shouldCreateIndexUsingServerDefaultConfiguration() { // given // when - boolean created = elasticsearchTemplate.createIndex(UseServerConfigurationEntity.class); + boolean created = indexOperations.createIndex(UseServerConfigurationEntity.class); // then assertThat(created).isTrue(); - Map setting = elasticsearchTemplate.getSetting(UseServerConfigurationEntity.class); + Map setting = indexOperations.getSetting(UseServerConfigurationEntity.class); assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); assertThat(setting.get("index.number_of_replicas")).isEqualTo("1"); } @@ -2296,12 +2295,9 @@ public void shouldReturnMappingForGivenEntityClass() { // given // when - boolean created = elasticsearchTemplate.createIndex(SampleEntity.class); - elasticsearchTemplate.putMapping(SampleEntity.class); - Map mapping = elasticsearchTemplate.getMapping(SampleEntity.class); + Map mapping = indexOperations.getMapping(SampleEntity.class); // then - assertThat(created).isTrue(); assertThat(mapping).isNotNull(); assertThat(((Map) ((Map) mapping.get("properties")).get("message")).get("type")) .isEqualTo("text"); @@ -2321,19 +2317,19 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(idsQuery().addIds(documentIdToDelete)); - elasticsearchTemplate.delete(deleteQuery, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(deleteQuery, index); + indexOperations.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2353,18 +2349,18 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("id").is(documentIdToDelete)); - elasticsearchTemplate.delete(criteriaQuery, SampleEntity.class, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(criteriaQuery, SampleEntity.class, index); + indexOperations.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2383,17 +2379,17 @@ public void shouldDeleteDocumentForGivenIdOnly() { String remainingDocumentId = UUID.randomUUID().toString(); indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when - elasticsearchTemplate.delete(documentIdToDelete, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.delete(documentIdToDelete, index); + indexOperations.refresh(SampleEntity.class); // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); } @@ -2412,21 +2408,20 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(UUID.randomUUID().toString()).message(notFindableMessage) .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("message")); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scroll.getScrollId()); + operations.clearScroll(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); @@ -2448,20 +2443,20 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(UUID.randomUUID().toString()).message(notFindableMessage) .version(System.currentTimeMillis()).build())); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scroll.getScrollId()); + operations.clearScroll(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); @@ -2476,8 +2471,8 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { List entities = createSampleEntitiesWithMessage("Test message", 3); // when - elasticsearchTemplate.bulkIndex(entities, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(entities, index); + indexOperations.refresh(SampleEntity.class); // then SourceFilter sourceFilter = new FetchSourceFilter(new String[] { "id" }, new String[] {}); @@ -2485,13 +2480,13 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build(); - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } - elasticsearchTemplate.clearScroll(scroll.getScrollId()); + operations.clearScroll(scroll.getScrollId()); assertThat(sampleEntities).hasSize(3); assertThat(sampleEntities.stream().map(SampleEntity::getId).collect(Collectors.toList())) .doesNotContain((String) null); @@ -2521,19 +2516,19 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); // when - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } // then @@ -2567,8 +2562,8 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable( @@ -2576,11 +2571,11 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { .build(); // when - ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); } // then @@ -2605,14 +2600,14 @@ public void shouldReturnDocumentWithCollapsedField() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity, sampleEntity2, sampleEntity3)); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(SampleEntity.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(SampleEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withCollapseField("rate") .build(); // when - Page page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class, index); + Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -2645,10 +2640,10 @@ public void shouldAddAlias() { .build(); // when - elasticsearchTemplate.addAlias(aliasQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + indexOperations.addAlias(aliasQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // then - List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); } @@ -2672,8 +2667,8 @@ public void shouldAddAliasForVariousRoutingValues() { // when IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); - elasticsearchTemplate.addAlias(aliasQuery1, index); - elasticsearchTemplate.addAlias(aliasQuery2, index); + indexOperations.addAlias(aliasQuery1, index); + indexOperations.addAlias(aliasQuery2, index); String documentId = randomNumeric(5); SampleEntity entity = SampleEntity.builder() // @@ -2687,10 +2682,10 @@ public void shouldAddAliasForVariousRoutingValues() { .withObject(entity) // .build(); - elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(alias1).withTypes(TYPE_NAME)); + operations.index(indexQuery, IndexCoordinates.of(alias1).withTypes(TYPE_NAME)); // then - List aliasMetaData = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliasMetaData = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliasMetaData).isNotEmpty(); AliasMetaData aliasMetaData1 = aliasMetaData.get(0); @@ -2704,8 +2699,8 @@ public void shouldAddAliasForVariousRoutingValues() { assertThat(aliasMetaData2.searchRouting()).isEqualTo("1"); // cleanup - elasticsearchTemplate.removeAlias(aliasQuery1, index); - elasticsearchTemplate.removeAlias(aliasQuery2, index); + indexOperations.removeAlias(aliasQuery1, index); + indexOperations.removeAlias(aliasQuery2, index); } @Test // DATAES-70 @@ -2721,7 +2716,7 @@ public void shouldAddAliasWithGivenRoutingValue() { .build(); // when - elasticsearchTemplate.addAlias(aliasQuery, index); + indexOperations.addAlias(aliasQuery, index); String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder() // @@ -2735,17 +2730,17 @@ public void shouldAddAliasWithGivenRoutingValue() { .withObject(sampleEntity) // .build(); - elasticsearchTemplate.index(indexQuery, IndexCoordinates.of(alias).withTypes(TYPE_NAME)); - elasticsearchTemplate.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.index(indexQuery, IndexCoordinates.of(alias).withTypes(TYPE_NAME)); + indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // .build(); - long count = elasticsearchTemplate.count(query, IndexCoordinates.of(alias)); + long count = operations.count(query, IndexCoordinates.of(alias)); // then - List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isNotNull(); AliasMetaData aliasMetaData = aliases.get(0); assertThat(aliasMetaData.alias()).isEqualTo(alias); @@ -2754,7 +2749,7 @@ public void shouldAddAliasWithGivenRoutingValue() { assertThat(count).isEqualTo(1); // cleanup - elasticsearchTemplate.removeAlias(aliasQuery, index); + indexOperations.removeAlias(aliasQuery, index); } @Test // DATAES-541 @@ -2769,14 +2764,14 @@ public void shouldRemoveAlias() { .build(); // when - elasticsearchTemplate.addAlias(aliasQuery, index); - List aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + indexOperations.addAlias(aliasQuery, index); + List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); // then - elasticsearchTemplate.removeAlias(aliasQuery, index); - aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + indexOperations.removeAlias(aliasQuery, index); + aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); assertThat(aliases).isEmpty(); } @@ -2817,7 +2812,7 @@ public long getOffset() { } protected RequestFactory getRequestFactory() { - return ((AbstractElasticsearchTemplate) elasticsearchTemplate).getRequestFactory(); + return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 0fdde2b78..e9e150b21 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -34,6 +34,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; @@ -59,7 +60,7 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() indexRequest.source("{}", XContentType.JSON); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); assertThatThrownBy(() -> { - elasticsearchTemplate.update(updateQuery, index); + operations.update(updateQuery, index); }).isInstanceOf(DocumentMissingException.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java index 1d7650622..12bc66bce 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import org.junit.jupiter.api.Test; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; /** * @author Peter-Josef Meisch diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 46ddeec4d..f3369d4a2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -36,6 +36,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 3b3193ffd..8abfa0d60 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -24,6 +24,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index d4c4b7b43..5bd97580b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -24,6 +24,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index dc7150264..f05a43000 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -42,7 +42,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 03cfd7b25..acb204390 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -26,6 +26,7 @@ import org.elasticsearch.search.suggest.SuggestBuilders; import org.elasticsearch.search.suggest.SuggestionBuilder; import org.elasticsearch.search.suggest.completion.CompletionSuggestion; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -35,7 +36,8 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -60,9 +62,17 @@ static class Config {} @Autowired private ElasticsearchOperations operations; - private void loadCompletionObjectEntities() { + IndexOperations indexOperations; + + @BeforeEach + private void setup() { + indexOperations = operations.getIndexOperations(); + + IndexInitializer.init(indexOperations, CompletionEntity.class); + IndexInitializer.init(indexOperations, AnnotatedCompletionEntity.class); + } - IndexInitializer.init(operations, CompletionEntity.class); + private void loadCompletionObjectEntities() { List indexQueries = new ArrayList<>(); indexQueries.add( @@ -80,8 +90,6 @@ private void loadCompletionObjectEntities() { private void loadAnnotatedCompletionObjectEntities() { - IndexInitializer.init(operations, AnnotatedCompletionEntity.class); - NonDocumentEntity nonDocumentEntity = new NonDocumentEntity(); nonDocumentEntity.setSomeField1("foo"); nonDocumentEntity.setSomeField2("bar"); @@ -103,8 +111,6 @@ private void loadAnnotatedCompletionObjectEntities() { private void loadAnnotatedCompletionObjectEntitiesWithWeights() { - IndexInitializer.init(operations, AnnotatedCompletionEntity.class); - List indexQueries = new ArrayList<>(); indexQueries.add(new AnnotatedCompletionEntityBuilder("1").name("Mewes Kochheim1") .suggest(new String[] { "Mewes Kochheim1" }, 4).buildIndex()); @@ -120,17 +126,6 @@ private void loadAnnotatedCompletionObjectEntitiesWithWeights() { operations.refresh(AnnotatedCompletionEntity.class); } - @Test - public void shouldPutMappingForGivenEntity() throws Exception { - - // given - Class entity = CompletionEntity.class; - operations.createIndex(entity); - - // when - assertThat(operations.putMapping(entity)).isTrue(); - } - @Test public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() { @@ -164,7 +159,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEn // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); + IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index 75e2a0de2..71864d076 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -33,6 +33,7 @@ import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.completion.context.CategoryQueryContext; import org.elasticsearch.search.suggest.completion.context.ContextMapping; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -43,7 +44,8 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -64,9 +66,18 @@ static class Config {} @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; + + @BeforeEach + void setup() { + indexOperations = operations.getIndexOperations(); + + indexOperations.deleteIndex(ContextCompletionEntity.class); + } + private void loadContextCompletionObjectEntities() { - IndexInitializer.init(operations, ContextCompletionEntity.class); + IndexInitializer.init(indexOperations, ContextCompletionEntity.class); NonDocumentEntity nonDocumentEntity = new NonDocumentEntity(); nonDocumentEntity.setSomeField1("foo"); @@ -99,17 +110,6 @@ private void loadContextCompletionObjectEntities() { operations.refresh(ContextCompletionEntity.class); } - @Test - public void shouldPutMappingForGivenEntity() throws Exception { - - // given - Class entity = ContextCompletionEntity.class; - operations.createIndex(entity); - - // when - assertThat(operations.putMapping(entity)).isTrue(); - } - @Test // DATAES-536 public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEntityOfMongo() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index 39394a364..dab4f30cb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -38,7 +38,8 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +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.IndexQuery; @@ -75,11 +76,15 @@ static class Config {} @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; + @BeforeEach public void before() { - IndexInitializer.init(operations, AuthorMarkerEntity.class); - IndexInitializer.init(operations, LocationMarkerEntity.class); + indexOperations = operations.getIndexOperations(); + + IndexInitializer.init(indexOperations, AuthorMarkerEntity.class); + IndexInitializer.init(indexOperations, LocationMarkerEntity.class); } private void loadClassBaseEntities() { @@ -125,17 +130,6 @@ private void loadAnnotationBaseEntities() { operations.refresh(LocationMarkerEntity.class); } - @Test - public void shouldPutMappingForGivenEntityWithGeoLocation() throws Exception { - - // given - Class entity = AuthorMarkerEntity.class; - operations.createIndex(entity); - - // when - assertThat(operations.putMapping(entity)).isTrue(); - } - @Test public void shouldFindAuthorMarkersInRangeForGivenCriteriaQuery() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index e9f6167cd..33de2b84f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -51,7 +51,7 @@ import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.IndexQuery; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index d99b31b45..83643152b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -42,7 +42,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 44ccd10ad..09e080041 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -27,6 +27,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -57,15 +58,18 @@ public IndexNameProvider indexNameProvider() { @Autowired private DynamicIndexRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired private IndexNameProvider indexNameProvider; @BeforeEach public void init() { + indexOperations = operations.getIndexOperations(); + deleteIndexes(); - operations.createIndex("index1"); - operations.createIndex("index2"); + indexOperations.createIndex("index1"); + indexOperations.createIndex("index2"); } @AfterEach @@ -75,8 +79,8 @@ public void teardown() { private void deleteIndexes() { - operations.deleteIndex("index1"); - operations.deleteIndex("index2"); + indexOperations.deleteIndex("index1"); + indexOperations.deleteIndex("index2"); } @Test // DATAES-456 diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nondocument/NonDocumentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nondocument/NonDocumentEntityTests.java deleted file mode 100644 index 588439f35..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nondocument/NonDocumentEntityTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2013-2019 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.repositories.nondocument; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.BeanCreationException; -import org.springframework.context.annotation.Lazy; -import org.springframework.context.support.ClassPathXmlApplicationContext; -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; - -/** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Peter-Josef Meisch - */ -public class NonDocumentEntityTests { - - @Test - public void shouldNotInitialiseRepositoryWithNonDocument() { - // when - ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/repository-non-document-entity.xml"); - assertThatThrownBy(() -> { - ctx.getBean(NonDocumentEntityRepository.class); - }).isInstanceOf(BeanCreationException.class); - } - - /** - * @author Rizwan Idrees - * @author Mohsin Husen - */ - static class NonDocumentEntity { - - @Id private String someId; - private String someField1; - private String someField2; - - public String getSomeField1() { - return someField1; - } - - public void setSomeField1(String someField1) { - this.someField1 = someField1; - } - - public String getSomeField2() { - return someField2; - } - - public void setSomeField2(String someField2) { - this.someField2 = someField2; - } - } - - /** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Oliver Gierke - */ - @Lazy - interface NonDocumentEntityRepository extends ElasticsearchRepository {} - -} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 45eb27605..5bb26bd00 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -32,7 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 56d8b9703..1eef7734f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -26,7 +26,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 57c19799c..469341a8b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -32,7 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java index 6924f092c..58a1b2d69 100644 --- a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.utils; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; /** * Utility to initialize indexes. @@ -31,9 +32,24 @@ private IndexInitializer() {} * * @param operations * @param clazz + * @deprecated since 4.0, use {@link IndexInitializer#init(IndexOperations, Class)} */ public static void init(ElasticsearchOperations operations, Class clazz) { + operations.getIndexOperations().deleteIndex(clazz); + operations.getIndexOperations().createIndex(clazz); + operations.getIndexOperations().putMapping(clazz); + operations.getIndexOperations().refresh(clazz); + } + + /** + * Initialize a fresh index with mappings for {@link Class}. Drops the index if it exists before creation. + * + * @param operations + * @param clazz + */ + public static void init(IndexOperations operations, Class clazz) { + operations.deleteIndex(clazz); operations.createIndex(clazz); operations.putMapping(clazz); diff --git a/src/test/resources/repository-non-document-entity.xml b/src/test/resources/repository-non-document-entity.xml deleted file mode 100644 index e1645c556..000000000 --- a/src/test/resources/repository-non-document-entity.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - From dec5231a05c4bec9e8a5595384f709f25b1fc01e Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 11 Dec 2019 22:09:02 +0100 Subject: [PATCH 0016/1191] DATAES-239 - Query for null values. Original PR: #355 --- .../core/CriteriaQueryProcessor.java | 17 ++- .../elasticsearch/core/query/Criteria.java | 115 +++++++++++------- .../parser/ElasticsearchQueryCreator.java | 11 +- .../query/keywords/QueryKeywordsTests.java | 58 +++++---- 4 files changed, 123 insertions(+), 78 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java index f11de8802..4683fd7b6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java @@ -41,6 +41,7 @@ * @author Artur Konczak * @author Rasmus Faber-Espensen * @author James Bodkin + * @author Peter-Josef Meisch */ class CriteriaQueryProcessor { @@ -134,17 +135,23 @@ private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) { return query; } - private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, - /* OperationKey key, Object value,*/ String fieldName) { + private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String fieldName) { + OperationKey key = entry.getKey(); Object value = entry.getValue(); + if (value == null) { - return null; + + if (key == OperationKey.EXISTS) { + return existsQuery(fieldName); + } else { + return null; + } } - OperationKey key = entry.getKey(); - QueryBuilder query = null; String searchText = QueryParserUtil.escape(value.toString()); + QueryBuilder query = null; + switch (key) { case EQUALS: query = queryStringQuery(searchText).field(fieldName).defaultOperator(AND); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index ffb2ecb63..83ae04429 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -15,10 +15,14 @@ */ package org.springframework.data.elasticsearch.core.query; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; @@ -26,6 +30,8 @@ import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; /** * Criteria is the central class when constructing queries. It follows more or less a fluent API style, which allows to @@ -34,18 +40,15 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Franck Marchand + * @author Peter-Josef Meisch */ public class Criteria { @Override public String toString() { - return "Criteria{" + - "field=" + field.getName() + - ", boost=" + boost + - ", negating=" + negating + - ", queryCriteria=" + ObjectUtils.nullSafeToString(queryCriteria) + - ", filterCriteria=" + ObjectUtils.nullSafeToString(filterCriteria) + - '}'; + return "Criteria{" + "field=" + field.getName() + ", boost=" + boost + ", negating=" + negating + ", queryCriteria=" + + ObjectUtils.nullSafeToString(queryCriteria) + ", filterCriteria=" + + ObjectUtils.nullSafeToString(filterCriteria) + '}'; } public static final String WILDCARD = "*"; @@ -64,8 +67,7 @@ public String toString() { private Set filterCriteria = new LinkedHashSet<>(); - public Criteria() { - } + public Criteria() {} /** * Creates a new Criteria with provided field name @@ -209,6 +211,17 @@ public Criteria is(Object o) { return this; } + /** + * Creates a new CriteriaEntry for existence check. + * + * @return this object + * @since 4.0 + */ + public Criteria exists() { + queryCriteria.add(new CriteriaEntry(OperationKey.EXISTS, null)); + return this; + } + /** * Crates new CriteriaEntry with leading and trailing wildcards
* NOTE: mind your schema as leading wildcards may not be supported and/or execution might be slow. @@ -305,7 +318,7 @@ public Criteria between(Object lowerBound, Object upperBound) { throw new InvalidDataAccessApiUsageException("Range [* TO *] is not allowed"); } - queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[]{lowerBound, upperBound})); + queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound })); return this; } @@ -377,9 +390,9 @@ public Criteria in(Iterable values) { private List toCollection(Object... values) { if (values.length == 0 || (values.length > 1 && values[1] instanceof Collection)) { - throw new InvalidDataAccessApiUsageException("At least one element " - + (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "") - + " has to be present."); + throw new InvalidDataAccessApiUsageException( + "At least one element " + (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "") + + " has to be present."); } return Arrays.asList(values); } @@ -398,15 +411,14 @@ public Criteria notIn(Iterable values) { * Creates new CriteriaEntry for {@code location WITHIN distance} * * @param location {@link org.springframework.data.elasticsearch.core.geo.GeoPoint} center coordinates - * @param distance {@link String} radius as a string (e.g. : '100km'). - * Distance unit : - * either mi/miles or km can be set + * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be + * set * @return Criteria the chaind criteria with the new 'within' criteria included. */ public Criteria within(GeoPoint location, String distance) { Assert.notNull(location, "Location value for near criteria must not be null"); Assert.notNull(location, "Distance value for near criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{location, distance})); + filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); return this; } @@ -414,56 +426,54 @@ public Criteria within(GeoPoint location, String distance) { * Creates new CriteriaEntry for {@code location WITHIN distance} * * @param location {@link org.springframework.data.geo.Point} center coordinates - * @param distance {@link org.springframework.data.geo.Distance} radius - * . + * @param distance {@link org.springframework.data.geo.Distance} radius . * @return Criteria the chaind criteria with the new 'within' criteria included. */ public Criteria within(Point location, Distance distance) { Assert.notNull(location, "Location value for near criteria must not be null"); Assert.notNull(location, "Distance value for near criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{location, distance})); + filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); return this; } /** * Creates new CriteriaEntry for {@code geoLocation WITHIN distance} * - * @param geoLocation {@link String} center point - * supported formats: - * lat on = > "41.2,45.1", - * geohash = > "asd9as0d" - * @param distance {@link String} radius as a string (e.g. : '100km'). - * Distance unit : - * either mi/miles or km can be set + * @param geoLocation {@link String} center point supported formats: lat on = > "41.2,45.1", geohash = > "asd9as0d" + * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be + * set * @return */ public Criteria within(String geoLocation, String distance) { Assert.isTrue(!StringUtils.isEmpty(geoLocation), "geoLocation value must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[]{geoLocation, distance})); + filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance })); return this; } /** * Creates new CriteriaEntry for {@code location GeoBox bounding box} * - * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner) + * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + + * right bottom corner) * @return Criteria the chaind criteria with the new 'boundingBox' criteria included. */ public Criteria boundedBy(GeoBox boundingBox) { Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox})); + filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox })); return this; } /** * Creates new CriteriaEntry for {@code location Box bounding box} * - * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + right bottom corner) + * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + + * right bottom corner) * @return Criteria the chaind criteria with the new 'boundingBox' criteria included. */ public Criteria boundedBy(Box boundingBox) { Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{boundingBox.getFirst(), boundingBox.getSecond()})); + filterCriteria + .add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() })); return this; } @@ -477,7 +487,7 @@ public Criteria boundedBy(Box boundingBox) { public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) { Assert.isTrue(!StringUtils.isEmpty(topLeftGeohash), "topLeftGeohash must not be empty"); Assert.isTrue(!StringUtils.isEmpty(bottomRightGeohash), "bottomRightGeohash must not be empty"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftGeohash, bottomRightGeohash})); + filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash })); return this; } @@ -491,14 +501,15 @@ public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) { public Criteria boundedBy(GeoPoint topLeftPoint, GeoPoint bottomRightPoint) { Assert.notNull(topLeftPoint, "topLeftPoint must not be null"); Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{topLeftPoint, bottomRightPoint})); + filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint })); return this; } public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) { Assert.notNull(topLeftPoint, "topLeftPoint must not be null"); Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[]{GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint)})); + filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, + new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) })); return this; } @@ -587,8 +598,27 @@ public String getConjunctionOperator() { } } - public enum OperationKey { - EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH, EXPRESSION, BETWEEN, FUZZY, IN, NOT_IN, WITHIN, BBOX, NEAR, LESS, LESS_EQUAL, GREATER, GREATER_EQUAL; + public enum OperationKey { // + EQUALS, // + CONTAINS, // + STARTS_WITH, // + ENDS_WITH, // + EXPRESSION, // + BETWEEN, // + FUZZY, // + IN, // + NOT_IN, // + WITHIN, // + BBOX, // + NEAR, // + LESS, // + LESS_EQUAL, // + GREATER, // + GREATER_EQUAL, // + /** + * @since 4.0 + */ + EXISTS; } public static class CriteriaEntry { @@ -611,10 +641,7 @@ public Object getValue() { @Override public String toString() { - return "CriteriaEntry{" + - "key=" + key + - ", value=" + value + - '}'; + return "CriteriaEntry{" + "key=" + key + ", value=" + value + '}'; } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java index ab5490224..f7f327efd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java @@ -138,9 +138,14 @@ private Criteria from(Part part, Criteria instance, Iterator parameters) { Object firstParameter = parameters.next(); Object secondParameter = null; if (type == Part.Type.SIMPLE_PROPERTY) { - if (part.getProperty().getType() != GeoPoint.class) - return criteria.is(firstParameter); - else { + if (part.getProperty().getType() != GeoPoint.class) { + if (firstParameter != null) { + return criteria.is(firstParameter); + } else { + // searching for null is a must_not (exists) + return criteria.exists().not(); + } + } else { // it means it's a simple find with exact geopoint matching (e.g. findByLocation) // and because Elasticsearch does not have any kind of query with just a geopoint // as argument we use a "geo distance" query with a distance of one meter. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index de43eed5d..a5679e89f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -24,7 +24,6 @@ import lombok.Setter; import java.util.Arrays; -import java.util.Date; import java.util.List; import java.util.stream.Collectors; @@ -43,6 +42,7 @@ import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -81,10 +81,10 @@ public void before() { .sortName("sort2").build(); Product product5 = Product.builder().id("5").name("Salt").text("Sea salt").price(2.1f).available(false) .sortName("sort1").build(); + Product product6 = Product.builder().id("6").name(null).text("no name").price(3.4f).available(false) + .sortName("sort0").build(); - repository.saveAll(Arrays.asList(product1, product2, product3, product4, product5)); - - elasticsearchTemplate.refresh(Product.class); + repository.saveAll(Arrays.asList(product1, product2, product3, product4, product5, product6)); } @Test @@ -120,7 +120,7 @@ public void shouldSupportTrueAndFalse() { // then assertThat(repository.findByAvailableTrue()).hasSize(3); - assertThat(repository.findByAvailableFalse()).hasSize(2); + assertThat(repository.findByAvailableFalse()).hasSize(3); } @Test @@ -132,8 +132,8 @@ public void shouldSupportInAndNotInAndNot() { // then assertThat(repository.findByPriceIn(Arrays.asList(1.2f, 1.1f))).hasSize(2); - assertThat(repository.findByPriceNotIn(Arrays.asList(1.2f, 1.1f))).hasSize(3); - assertThat(repository.findByPriceNot(1.2f)).hasSize(4); + assertThat(repository.findByPriceNotIn(Arrays.asList(1.2f, 1.1f))).hasSize(4); + assertThat(repository.findByPriceNot(1.2f)).hasSize(5); } @Test // DATAES-171 @@ -144,7 +144,7 @@ public void shouldWorkWithNotIn() { // when // then - assertThat(repository.findByIdNotIn(Arrays.asList("2", "3"))).hasSize(3); + assertThat(repository.findByIdNotIn(Arrays.asList("2", "3"))).hasSize(4); } @Test @@ -169,8 +169,8 @@ public void shouldSupportLessThanAndGreaterThan() { assertThat(repository.findByPriceLessThan(1.1f)).hasSize(1); assertThat(repository.findByPriceLessThanEqual(1.1f)).hasSize(2); - assertThat(repository.findByPriceGreaterThan(1.9f)).hasSize(1); - assertThat(repository.findByPriceGreaterThanEqual(1.9f)).hasSize(2); + assertThat(repository.findByPriceGreaterThan(1.9f)).hasSize(2); + assertThat(repository.findByPriceGreaterThanEqual(1.9f)).hasSize(3); } @Test // DATAES-615 @@ -195,7 +195,7 @@ public void shouldSupportSortOnStandardFieldWithoutCriteria() { List sortedIds = repository.findAllByOrderByText().stream() // .map(it -> it.text).collect(Collectors.toList()); - assertThat(sortedIds).containsExactly("Beet sugar", "Cane sugar", "Cane sugar", "Rock salt", "Sea salt"); + assertThat(sortedIds).containsExactly("Beet sugar", "Cane sugar", "Cane sugar", "Rock salt", "Sea salt", "no name"); } @Test // DATAES-615 @@ -204,7 +204,7 @@ public void shouldSupportSortOnFieldWithCustomFieldNameWithoutCriteria() { List sortedIds = repository.findAllByOrderBySortName().stream() // .map(it -> it.id).collect(Collectors.toList()); - assertThat(sortedIds).containsExactly("5", "4", "3", "2", "1"); + assertThat(sortedIds).containsExactly("6", "5", "4", "3", "2", "1"); } @Test // DATAES-178 @@ -241,6 +241,22 @@ public void shouldReturnTwoWithFindTop2() { products.forEach(product -> assertThat(product.name).isEqualTo("Sugar")); } + @Test + void shouldSearchForNullValues() { + final List products = repository.findByName(null); + + assertThat(products).hasSize(1); + assertThat(products.get(0).getId()).isEqualTo("6"); + } + + @Test + void shouldDeleteWithNullValues() { + repository.deleteByName(null); + + long count = repository.count(); + assertThat(count).isEqualTo(5); + } + /** * @author Mohsin Husen * @author Artur Konczak @@ -256,28 +272,14 @@ static class Product { @Id private String id; - private List title; - private String name; - private String description; - @Field(type = FieldType.Keyword) private String text; - private List categories; - - private Float weight; - @Field(type = FieldType.Float) private Float price; - private Integer popularity; - private boolean available; - private String location; - - private Date lastModified; - @Field(name = "sort-name", type = FieldType.Keyword) private String sortName; } @@ -286,6 +288,8 @@ static class Product { */ interface ProductRepository extends ElasticsearchRepository { + List findByName(@Nullable String name); + List findByNameAndText(String name, String text); List findByNameAndPrice(String name, Float price); @@ -331,6 +335,8 @@ interface ProductRepository extends ElasticsearchRepository { List findFirst2ByName(String name); List findTop2ByName(String name); + + void deleteByName(@Nullable String name); } } From 47d0104295339e2e364265d41acb3954955eb49f Mon Sep 17 00:00:00 2001 From: Sascha Woo Date: Sun, 15 Dec 2019 09:44:37 +0100 Subject: [PATCH 0017/1191] DATAES-709 - Add parameter to include defaults on get settings. Original PR: #357 --- .../core/AbstractDefaultIndexOperations.java | 33 +++++++++++- .../core/DefaultIndexOperations.java | 51 +++++++------------ .../core/DefaultTransportIndexOperations.java | 25 ++++++--- .../core/ElasticsearchOperations.java | 8 +-- .../elasticsearch/core/IndexOperations.java | 24 ++++++++- .../core/ElasticsearchTemplateTests.java | 32 ++++++++++-- 6 files changed, 121 insertions(+), 52 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 1ea286d54..cc49fb7cb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -20,7 +20,9 @@ import java.util.HashMap; import java.util.Map; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.common.collect.MapBuilder; +import org.elasticsearch.common.settings.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.elasticsearch.ElasticsearchException; @@ -36,6 +38,7 @@ * Base implementation of {@link IndexOperations} common to Transport and Rest based Implementations of IndexOperations. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ abstract class AbstractDefaultIndexOperations implements IndexOperations { @@ -112,8 +115,13 @@ public boolean putMapping(IndexCoordinates index, Class clazz) { } @Override - public Map getSetting(Class clazz) { - return getSetting(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName()); + public Map getSettings(Class clazz) { + return getSettings(clazz, false); + } + + @Override + public Map getSettings(Class clazz, boolean includeDefaults) { + return getSettings(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(), includeDefaults); } @Override @@ -166,6 +174,27 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { public IndexCoordinates getIndexCoordinatesFor(Class clazz) { return getRequiredPersistentEntity(clazz).getIndexCoordinates(); } + + protected Map convertSettingsResponseToMap(GetSettingsResponse response, String indexName) { + + Map settings = new HashMap<>(); + + if (!response.getIndexToDefaultSettings().isEmpty()) { + Settings defaultSettings = response.getIndexToDefaultSettings().get(indexName); + for (String key : defaultSettings.keySet()) { + settings.put(key, defaultSettings.get(key)); + } + } + + if (!response.getIndexToSettings().isEmpty()) { + Settings customSettings = response.getIndexToSettings().get(indexName); + for (String key : customSettings.keySet()) { + settings.put(key, customSettings.get(key)); + } + } + + return settings; + } // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 6b4f1aa03..0da7173fb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -23,13 +23,14 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.http.util.EntityUtils; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; @@ -37,10 +38,6 @@ import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.xcontent.DeprecationHandler; -import org.elasticsearch.common.xcontent.NamedXContentRegistry; -import org.elasticsearch.common.xcontent.XContentType; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.client.support.AliasData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -56,6 +53,7 @@ * {@link IndexOperations} implementation using the RestClient. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { @@ -176,21 +174,27 @@ public List queryForAlias(String indexName) { } @Override - public Map getSetting(String indexName) { + public Map getSettings(String indexName) { + return getSettings(indexName, false); + } + + @Override + public Map getSettings(String indexName, boolean includeDefaults) { Assert.notNull(indexName, "No index defined for getSettings"); - ObjectMapper objMapper = new ObjectMapper(); - Map settings = null; - RestClient restClient = client.getLowLevelClient(); + GetSettingsRequest request = new GetSettingsRequest() // + .indices(indexName) // + .includeDefaults(includeDefaults); + try { - Response response = restClient.performRequest(new Request("GET", "/" + indexName + "/_settings")); - settings = convertSettingResponse(EntityUtils.toString(response.getEntity()), indexName); + GetSettingsResponse response = client.indices() // + .getSettings(request, RequestOptions.DEFAULT); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting settings for indexName : " + indexName, e); + return convertSettingsResponseToMap(response, indexName); + } catch (IOException e) { + throw new ElasticsearchException("failed to get settings for index: " + indexName, e); } - return settings; } @Override @@ -258,24 +262,5 @@ private List convertAliasResponse(String aliasResponse) { } } - private Map convertSettingResponse(String settingResponse, String indexName) { - ObjectMapper mapper = new ObjectMapper(); - - try { - Settings settings = Settings.fromXContent(XContentType.JSON.xContent().createParser(NamedXContentRegistry.EMPTY, - DeprecationHandler.THROW_UNSUPPORTED_OPERATION, settingResponse)); - String prefix = indexName + ".settings."; - // Backwards compatibility. TODO Change to return Settings object. - Map result = new HashMap(); - Set keySet = settings.keySet(); - for (String key : keySet) { - result.put(key.substring(prefix.length()), settings.get(key)); - } - return result; - } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + settingResponse, e); - } - - } // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 6dc69bd59..2c34c2e9f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; @@ -28,9 +27,9 @@ import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.settings.Settings; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -41,6 +40,7 @@ * {@link IndexOperations} implementation using the TransportClient. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { @@ -122,13 +122,25 @@ public List queryForAlias(String indexName) { } @Override - public Map getSetting(String indexName) { + public Map getSettings(String indexName) { + return getSettings(indexName, false); + } + + @Override + public Map getSettings(String indexName, boolean includeDefaults) { Assert.notNull(indexName, "No index defined for getSettings"); - Settings settings = client.admin().indices().getSettings(new GetSettingsRequest()).actionGet().getIndexToSettings() - .get(indexName); - return settings.keySet().stream().collect(Collectors.toMap((key) -> key, (key) -> settings.get(key))); + GetSettingsRequest request = new GetSettingsRequest() // + .indices(indexName) // + .includeDefaults(includeDefaults); + + GetSettingsResponse response = client.admin() // + .indices() // + .getSettings(request) // + .actionGet(); + + return convertSettingsResponseToMap(response, indexName); } @Override @@ -138,4 +150,5 @@ public void refresh(IndexCoordinates index) { client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet(); } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index f968f1e3c..715d166e3 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -269,11 +269,11 @@ default List queryForAlias(String indexName) { * * @param indexName the name of the index * @return the settings - * @deprecated since 4.0, use {@link IndexOperations#getSetting(String)} )} instead} + * @deprecated since 4.0, use {@link IndexOperations#getSettings(String)} )} instead} */ @Deprecated default Map getSetting(String indexName) { - return getIndexOperations().getSetting(indexName); + return getIndexOperations().getSettings(indexName); } /** @@ -282,11 +282,11 @@ default Map getSetting(String indexName) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return the settings - * @deprecated since 4.0, use {@link IndexOperations#getSetting(Class)} instead} + * @deprecated since 4.0, use {@link IndexOperations#getSettings(Class)} instead} */ @Deprecated default Map getSetting(Class clazz) { - return getIndexOperations().getSetting(clazz); + return getIndexOperations().getSettings(clazz); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 52e195fae..1fba70566 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -27,6 +27,7 @@ * Elasticsearch Index APIs. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ public interface IndexOperations { @@ -188,16 +189,35 @@ public interface IndexOperations { * @param indexName the name of the index * @return the settings */ - Map getSetting(String indexName); + Map getSettings(String indexName); + + /** + * Get settings for a given indexName. + * + * @param indexName the name of the index + * @param includeDefaults whether or not to include all the default settings + * @return the settings + */ + Map getSettings(String indexName, boolean includeDefaults); + + /** + * Get settings for a given class. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @return the settings + */ + Map getSettings(Class clazz); /** * Get settings for a given class. * * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} + * @param includeDefaults whether or not to include all the default settings * @return the settings */ - Map getSetting(Class clazz); + Map getSettings(Class clazz, boolean includeDefaults); /** * Refresh the index(es). diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 6aba00fab..4ff17b4c7 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -887,7 +887,7 @@ public void shouldCreateIndexGivenEntityClass() { // when // creation is done in setup method - Map setting = indexOperations.getSetting(SampleEntity.class); + Map setting = indexOperations.getSettings(SampleEntity.class); // then assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); @@ -2166,7 +2166,7 @@ public void shouldCreateIndexWithGivenSettings() { indexOperations.createIndex(INDEX_3_NAME, settings); // then - Map map = indexOperations.getSetting(INDEX_3_NAME); + Map map = indexOperations.getSettings(INDEX_3_NAME); assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); assertThat(map.get("index.analysis.analyzer.emailAnalyzer.tokenizer")).isEqualTo("uax_url_email"); @@ -2179,7 +2179,7 @@ public void shouldCreateGivenSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - Map map = indexOperations.getSetting(SampleEntity.class); + Map map = indexOperations.getSettings(SampleEntity.class); assertThat(indexOperations.indexExists(SampleEntity.class)).isTrue(); assertThat(map.containsKey("index.refresh_interval")).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); @@ -2209,7 +2209,7 @@ public void shouldCreateIndexWithGivenClassAndSettings() { indexOperations.refresh(SampleEntity.class); // then - Map map = indexOperations.getSetting(SampleEntity.class); + Map map = indexOperations.getSettings(SampleEntity.class); assertThat(indexOperations.indexExists(INDEX_NAME_SAMPLE_ENTITY)).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); @@ -2284,7 +2284,7 @@ public void shouldCreateIndexUsingServerDefaultConfiguration() { // then assertThat(created).isTrue(); - Map setting = indexOperations.getSetting(UseServerConfigurationEntity.class); + Map setting = indexOperations.getSettings(UseServerConfigurationEntity.class); assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); assertThat(setting.get("index.number_of_replicas")).isEqualTo("1"); } @@ -2811,6 +2811,28 @@ public long getOffset() { assertThat(searchRequest.source().from()).isEqualTo(30); } + @Test // DATAES-709 + public void shouldNotIncludeDefaultsGetIndexSettings() { + + // given + // when + Map map = indexOperations.getSettings(SampleEntity.class); + + // then + assertThat(map).doesNotContainKey("index.max_result_window"); + } + + @Test // DATAES-709 + public void shouldIncludeDefaultsOnGetIndexSettings() { + + // given + // when + Map map = indexOperations.getSettings(SampleEntity.class, true); + + // then + assertThat(map).containsKey("index.max_result_window"); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } From 2bb3fdfa8b42490af1b2ca2b8a489c423d5c8752 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 15 Dec 2019 15:53:52 +0100 Subject: [PATCH 0018/1191] DATAES-314 - NodeClientFactoryBean doesn't shutdown ES on destroy life-cycle. Original PR: #360 --- .../elasticsearch/client/NodeClientFactoryBean.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java index ef6e463d6..465d60e8e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java @@ -57,7 +57,7 @@ public class NodeClientFactoryBean implements FactoryBean, InitializingB public static class TestNode extends Node { - private static final String DEFAULT_NODE_NAME = "spring-data-elasticsearch-test-node"; + private static final String DEFAULT_NODE_NAME = "spring-data-elasticsearch-nodeclientfactorybean-test"; public TestNode(Settings preparedSettings, Collection> classpathPlugins) { @@ -151,13 +151,12 @@ public void setPathConfiguration(String configuration) { public void destroy() throws Exception { try { // NodeClient.close() is a noop, no need to call it here + nodeClient = null; logger.info("Closing elasticSearch node"); - // closing the Node causes tests to fail in the pipeline build and on some - // "mvn test" runs, there seem still to be tests relying on a running instance that - // is not properly set up. -// if (node != null) { -// node.close(); -// } + if (node != null) { + node.close(); + node = null; + } } catch (final Exception e) { logger.error("Error closing ElasticSearch client: ", e); } From e55bae725e4779f31b38328cb24ca45693c4725a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 22 Dec 2019 12:15:46 +0100 Subject: [PATCH 0019/1191] DATAES-672 - Introduce SearchHit and SearchHits types to enrich search results. Original PR: #359 --- .../core/AbstractElasticsearchTemplate.java | 51 ++- .../core/ElasticsearchRestTemplate.java | 22 +- .../core/ElasticsearchTemplate.java | 17 +- .../core/ReactiveElasticsearchTemplate.java | 30 +- .../core/ReactiveSearchOperations.java | 81 ++++- .../data/elasticsearch/core/SearchHit.java | 66 ++++ .../elasticsearch/core/SearchHitSupport.java | 84 +++++ .../data/elasticsearch/core/SearchHits.java | 92 +++++ .../elasticsearch/core/SearchOperations.java | 232 ++++++++++++- .../aggregation/impl/AggregatedPageImpl.java | 10 +- .../core/convert/ElasticsearchConverter.java | 22 +- .../MappingElasticsearchConverter.java | 37 +- .../core/convert/package-info.java | 2 + .../core/document/SearchDocument.java | 2 +- ...tReactiveElasticsearchRepositoryQuery.java | 11 +- .../query/ElasticsearchPartQuery.java | 35 +- .../query/ElasticsearchStringQuery.java | 15 +- .../AbstractElasticsearchRepository.java | 33 +- ...SimpleReactiveElasticsearchRepository.java | 24 +- .../data/elasticsearch/NestedObjectTests.java | 15 +- .../core/ElasticsearchTemplateTests.java | 323 ++++++++++-------- .../elasticsearch/core/LogEntityTests.java | 7 +- .../ReactiveElasticsearchTemplateTests.java | 41 ++- ...eactiveElasticsearchTemplateUnitTests.java | 16 +- .../geo/ElasticsearchTemplateGeoTests.java | 48 +-- .../core/index/MappingBuilderTests.java | 92 ++--- .../core/query/CriteriaQueryTests.java | 45 +-- .../CustomMethodRepositoryBaseTests.java | 14 + ...ettingAndMappingEntityRepositoryTests.java | 7 +- .../synonym/SynonymRepositoryTests.java | 8 +- 30 files changed, 1037 insertions(+), 445 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 8006dc996..84c81a703 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -14,13 +14,12 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; -import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; -import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -98,26 +97,29 @@ public void delete(Query query, Class clazz, IndexCoordinates index) { public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); return StreamQueries.streamResults(startScroll(scrollTimeInMillis, query, clazz, index), - scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), this::clearScroll); + scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), this::searchScrollClear); } @Override - public Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { + public CloseableIterator> searchForStream(Query query, Class clazz, IndexCoordinates index) { + long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); + return StreamQueries.streamResults(searchScrollStart(scrollTimeInMillis, query, clazz, index), + scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz), this::searchScrollClear); + } + + @Override + public AggregatedPage> search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index); - return queryForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); - } - - @Override - public List queryForList(Query query, Class clazz, IndexCoordinates index) { - return queryForPage(query, clazz, index).getContent(); + return searchForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); } @Override - public List> queryForPage(List queries, Class clazz, IndexCoordinates index) { + public List>> multiSearchForPage(List queries, Class clazz, + IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); for (Query query : queries) { request.add(requestFactory.searchRequest(query, clazz, index)); @@ -126,7 +128,8 @@ public List> queryForPage(List queries, Class cl } @Override - public List> queryForPage(List queries, List> classes, IndexCoordinates index) { + public List>> multiSearchForPage(List queries, + List> classes, IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); Iterator> it = classes.iterator(); for (Query query : queries) { @@ -135,9 +138,10 @@ public List> queryForPage(List queries, List> return doMultiSearch(queries, classes, request); } - private List> doMultiSearch(List queries, Class clazz, MultiSearchRequest request) { + private List>> doMultiSearch(List queries, Class clazz, + MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); + List>> res = new ArrayList<>(queries.size()); int c = 0; for (Query query : queries) { res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, @@ -146,10 +150,10 @@ private List> doMultiSearch(List queries, Class return res; } - private List> doMultiSearch(List queries, List> classes, - MultiSearchRequest request) { + private List>> doMultiSearch(List queries, + List> classes, MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List> res = new ArrayList<>(queries.size()); + List>> res = new ArrayList<>(queries.size()); int c = 0; Iterator> it = classes.iterator(); for (Query query : queries) { @@ -160,17 +164,6 @@ private List> doMultiSearch(List queries, List } abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); - - protected List extractIds(SearchResponse response) { - List ids = new ArrayList<>(); - for (SearchHit hit : response.getHits()) { - if (hit != null) { - ids.add(hit.getId()); - } - } - return ids; - } - // endregion // region Helper methods @@ -195,7 +188,7 @@ protected static String[] toArray(List values) { public abstract SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); /** - * @param clazz + * @param clazz the entity class * @return the IndexCoordinates defined on the entity. * @since 4.0 */ diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 275b49492..29c51ba63 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -238,7 +238,7 @@ public T query(Query query, ResultsExtractor resultsExtractor, @Nullable } @Override - public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + public AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index) { SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); SearchResponse response; try { @@ -250,18 +250,8 @@ public AggregatedPage queryForPage(Query query, Class clazz, IndexCoor } @Override - public List queryForIds(Query query, Class clazz, IndexCoordinates index) { - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - try { - SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); - return extractIds(response); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } - } - - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { + public ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, + IndexCoordinates index) { Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); @@ -276,7 +266,9 @@ public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Cla } } - public ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + @Override + public ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, + Class clazz) { SearchScrollRequest request = new SearchScrollRequest(scrollId); request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); SearchResponse response; @@ -289,7 +281,7 @@ public ScrolledPage continueScroll(@Nullable String scrollId, long scroll } @Override - public void clearScroll(String scrollId) { + public void searchScrollClear(String scrollId) { ClearScrollRequest request = new ClearScrollRequest(); request.addScrollId(scrollId); try { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 65a384cd8..03499348f 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -203,21 +203,15 @@ public T query(Query query, ResultsExtractor resultsExtractor, Class c } @Override - public AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + public AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index) { SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); SearchResponse response = getSearchResponse(searchRequestBuilder); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); } @Override - public List queryForIds(Query query, Class clazz, IndexCoordinates index) { - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return extractIds(response); - } - - @Override - public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { + public ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, + IndexCoordinates index) { Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); @@ -227,14 +221,15 @@ public ScrolledPage startScroll(long scrollTimeInMillis, Query query, Cla } @Override - public ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + public ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, + Class clazz) { SearchResponse response = getSearchResponseWithTimeout( client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, Pageable.unpaged()); } @Override - public void clearScroll(String scrollId) { + public void searchScrollClear(String scrollId) { client.prepareClearScroll().addScrollId(scrollId).execute().actionGet(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8c308d43c..8c234a8ee 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -17,7 +17,6 @@ import static org.elasticsearch.index.VersionType.*; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -41,7 +40,6 @@ import org.elasticsearch.index.query.WrapperQueryBuilder; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; -import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; @@ -57,8 +55,10 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; +import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -417,22 +417,18 @@ protected > R prepareWriteRequest(R request) { // endregion // region SearchOperations - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#find(Query, Class, Class, IndexCoordinates) - */ @Override - public Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index) { + public Flux> search(Query query, Class entityType, Class resultType, IndexCoordinates index) { - return doFind(query, entityType, index).map(it -> converter.mapDocument(DocumentAdapters.from(it), resultType)); + return doFind(query, entityType, index).map(searchDocument -> converter.read(resultType, searchDocument)); } @Override - public Flux find(Query query, Class entityType, Class returnType) { - return find(query, entityType, returnType, getIndexCoordinatesFor(entityType)); + public Flux> search(Query query, Class entityType, Class returnType) { + return search(query, entityType, returnType, getIndexCoordinatesFor(entityType)); } - private Flux doFind(Query query, Class clazz, IndexCoordinates index) { + private Flux doFind(Query query, Class clazz, IndexCoordinates index) { return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, clazz, index); @@ -510,15 +506,15 @@ private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntit * Customization hook on the actual execution result {@link Publisher}.
* * @param request the already prepared {@link SearchRequest} ready to be executed. - * @return a {@link Flux} emitting the result of the operation. + * @return a {@link Flux} emitting the result of the operation converted to {@link SearchDocument}s. */ - protected Flux doFind(SearchRequest request) { + protected Flux doFind(SearchRequest request) { if (QUERY_LOGGER.isDebugEnabled()) { QUERY_LOGGER.debug("Executing doFind: {}", request); } - return Flux.from(execute(client -> client.search(request))) // + return Flux.from(execute(client -> client.search(request))).map(DocumentAdapters::from) // .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } @@ -542,16 +538,16 @@ protected Mono doCount(CountRequest request) { * Customization hook on the actual execution result {@link Publisher}.
* * @param request the already prepared {@link SearchRequest} ready to be executed. - * @return a {@link Flux} emitting the result of the operation. + * @return a {@link Flux} emitting the result of the operation converted to {@link SearchDocument}s. */ - protected Flux doScroll(SearchRequest request) { + protected Flux doScroll(SearchRequest request) { if (QUERY_LOGGER.isDebugEnabled()) { QUERY_LOGGER.debug("Executing doScroll: {}", request); } return Flux.from(execute(client -> client.scroll(request))) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); + .map(DocumentAdapters::from).onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java index dabc23097..2177ae8c9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -15,12 +15,12 @@ */ package org.springframework.data.elasticsearch.core; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.elasticsearch.index.query.QueryBuilders; import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.StringQuery; @@ -42,8 +42,10 @@ public interface ReactiveSearchOperations { * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. * @param - * @return a {@link Flux} emitting matching entities one by one. + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + * @deprecated since 4.0, use {@link #search(Query, Class)}. */ + @Deprecated default Flux find(Query query, Class entityType) { return find(query, entityType, entityType); } @@ -58,9 +60,13 @@ default Flux find(Query query, Class entityType) { * @param entityType The entity type for mapping the query. Must not be {@literal null}. * @param returnType The mapping target type. Must not be {@literal null}. Th * @param - * @return a {@link Flux} emitting matching entities one by one. + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + * @deprecated since 4.0, use {@link #search(Query, Class, Class)}. */ - Flux find(Query query, Class entityType, Class returnType); + @Deprecated + default Flux find(Query query, Class entityType, Class returnType) { + return search(query, entityType, returnType).map(SearchHit::getContent); + } /** * Search the index for entities matching the given {@link Query query}. @@ -69,8 +75,10 @@ default Flux find(Query query, Class entityType) { * @param entityType must not be {@literal null}. * @param index the target index, must not be {@literal null} * @param - * @returnm a {@link Flux} emitting matching entities one by one. + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + * @deprecated since 4.0, use {@link #search(Query, Class, IndexCoordinates)} */ + @Deprecated default Flux find(Query query, Class entityType, IndexCoordinates index) { return find(query, entityType, entityType, index); } @@ -78,14 +86,19 @@ default Flux find(Query query, Class entityType, IndexCoordinates inde /** * Search the index for entities matching the given {@link Query query}. * + * @param * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. * @param resultType the projection result type. * @param index the target index, must not be {@literal null} * @param - * @return a {@link Flux} emitting matching entities one by one. + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + * @deprecated since 4.0, use {@link #search(Query, Class, Class, IndexCoordinates)}. */ - Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index); + @Deprecated + default Flux find(Query query, Class entityType, Class resultType, IndexCoordinates index) { + return search(query, entityType, resultType, index).map(SearchHit::getContent); + } /** * Count the number of documents matching the given {@link Query}. @@ -116,4 +129,58 @@ default Mono count(Class entityType) { */ Mono count(Query query, Class entityType, IndexCoordinates index); + /** + * Search the index for entities matching the given {@link Query query}.
+ * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either * + * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) * + * size}. + * + * @param query must not be {@literal null}. + * @param entityType The entity type for mapping the query. Must not be {@literal null}. + * @param returnType The mapping target type. Must not be {@literal null}. Th + * @param + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + */ + Flux> search(Query query, Class entityType, Class returnType); + + /** + * Search the index for entities matching the given {@link Query query}.
+ * {@link Pageable#isUnpaged() Unpaged} queries may overrule elasticsearch server defaults for page size by either + * delegating to the scroll API or using a max {@link org.elasticsearch.search.builder.SearchSourceBuilder#size(int) + * size}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + */ + default Flux> search(Query query, Class entityType) { + return search(query, entityType, entityType); + } + + /** + * Search the index for entities matching the given {@link Query query}. + * + * @param + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param resultType the projection result type. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + */ + Flux> search(Query query, Class entityType, Class resultType, IndexCoordinates index); + + /** + * Search the index for entities matching the given {@link Query query}. + * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Flux} emitting matching entities one by one wrapped in a {@link SearchHit}. + */ + default Flux> search(Query query, Class entityType, IndexCoordinates index) { + return search(query, entityType, entityType, index); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java new file mode 100644 index 000000000..b84b5843f --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019 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; + +import org.springframework.lang.Nullable; + +/** + * Encapsulates the found data with additional information from the search. + * + * @param the result data class. + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class SearchHit { + + private final String id; + private final float score; + private final T content; + + public SearchHit(@Nullable String id, float score, T content) { + this.id = id; + this.score = score; + this.content = content; + } + + @Nullable + public String getId() { + return id; + } + + /** + * @return the score for the hit. + */ + public float getScore() { + return score; + } + + /** + * @return the object data from the search. + */ + public T getContent() { + return content; + } + + @Override + public String toString() { + return "SearchHit{" + + "id='" + id + '\'' + + ", score=" + score + + ", content=" + content + + '}'; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java new file mode 100644 index 000000000..44854e460 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -0,0 +1,84 @@ +/* + * Copyright 2019 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; + +import reactor.core.publisher.Flux; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; +import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; + +/** + * Utility class with helper methods for working with {@link SearchHit}. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public final class SearchHitSupport { + + private SearchHitSupport() {} + + /** + * unwraps the data contained in a SearchHit for different types containing SearchHits if possible + * + * @param result the object, list, page or whatever containing SearchHit objects + * @return a corresponding object where the SearchHits are replaced by their content if possible, otherwise the + * original object + */ + public static Object unwrapSearchHits(Object result) { + + if (result == null) { + return result; + } + + if (result instanceof SearchHit) { + return ((SearchHit) result).getContent(); + } + + if (result instanceof List) { + return ((List) result).stream() // + .map(SearchHitSupport::unwrapSearchHits) // + .collect(Collectors.toList()); + } + + if (result instanceof AggregatedPage) { + AggregatedPage page = (AggregatedPage) result; + List list = page.getContent().stream().map(o -> unwrapSearchHits(o)).collect(Collectors.toList()); + return new AggregatedPageImpl<>(list, null, page.getTotalElements(), page.getAggregations(), page.getScrollId(), + page.getMaxScore()); + + } + + if (result instanceof Stream) { + return ((Stream) result).map(SearchHitSupport::unwrapSearchHits); + } + + if (result instanceof SearchHits) { + SearchHits searchHits = (SearchHits) result; + return unwrapSearchHits(searchHits.getSearchHits()); + } + + if (result instanceof Flux) { + Flux flux = (Flux) result; + return flux.map(SearchHitSupport::unwrapSearchHits); + } + + return result; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java new file mode 100644 index 000000000..ec36780af --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -0,0 +1,92 @@ +/* + * Copyright 2019 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; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Stream; + +import org.springframework.data.util.Streamable; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Encapsulates a list of {@link SearchHit}s with additional information from the search. + * + * @param the result data class. + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class SearchHits implements Streamable> { + + private final List> searchHits; + private final long totalHits; + private final float maxScore; + + /** + * @param searchHits must not be {@literal null} + * @param totalHits + * @param maxScore + */ + public SearchHits(List> searchHits, long totalHits, float maxScore) { + this.totalHits = totalHits; + this.maxScore = maxScore; + + Assert.notNull(searchHits, "searchHits must not be null"); + + this.searchHits = searchHits; + } + + @Override + public Iterator> iterator() { + return (Iterator>) searchHits.iterator(); + } + + // region getter + /** + * @return the contained {@link SearchHit}s. + */ + public List> getSearchHits() { + return Collections.unmodifiableList(searchHits); + } + + public long getTotalHits() { + return totalHits; + } + + public float getMaxScore() { + return maxScore; + } + // endregion + + // region SearchHit access + /** + * @param index position in List. + * @return the {@link SearchHit} at position {index} + * @throws IndexOutOfBoundsException on invalid index + */ + public SearchHit getSearchHit(int index) { + return searchHits.get(index); + } + // endregion + + @Override + public String toString() { + return "SearchHits{" + "totalHits=" + totalHits + ", maxScore=" + maxScore + ", searchHits=" + + StringUtils.collectionToCommaDelimitedString(searchHits) + '}'; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 14a4d18d6..e47981111 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -67,10 +68,11 @@ default long count(Query query, IndexCoordinates index) { * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return the first matching object + * @deprecated since 4.0, use {@link #searchOne(Query, Class, IndexCoordinates)}. */ + @Deprecated default T queryForObject(Query query, Class clazz, IndexCoordinates index) { - List content = queryForPage(query, clazz, index).getContent(); - return content.isEmpty() ? null : content.get(0); + return (T) SearchHitSupport.unwrapSearchHits(searchOne(query, clazz, index)); } /** @@ -80,8 +82,12 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return a page with aggregations + * @deprecated since 4.0, use {@link #searchForPage(Query, Class, IndexCoordinates)}. */ - AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index); + @Deprecated + default AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { + return (AggregatedPage) SearchHitSupport.unwrapSearchHits(searchForPage(query, clazz, index)); + } /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} @@ -90,8 +96,14 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return list of pages with the results + * @deprecated since 4.0, use {@link #multiSearchForPage(List, Class, IndexCoordinates)}. */ - List> queryForPage(List queries, Class clazz, IndexCoordinates index); + @Deprecated + default List> queryForPage(List queries, Class clazz, IndexCoordinates index) { + return multiSearchForPage(queries, clazz, index).stream() // + .map(page -> (Page) SearchHitSupport.unwrapSearchHits(page)) // + .collect(Collectors.toList()); + } /** * Execute the multi-search against elasticsearch and return result as {@link List} of {@link Page} @@ -100,8 +112,15 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param classes the entity classes used for the queries * @param index the index to run the query against * @return list of pages with the results + * @deprecated since 4.0, use {@link #multiSearchForPage(List, List, IndexCoordinates)}. */ - List> queryForPage(List queries, List> classes, IndexCoordinates index); + @Deprecated + default List> queryForPage(List queries, List> classes, + IndexCoordinates index) { + return multiSearchForPage(queries, classes, index).stream() // + .map(page -> (AggregatedPage) SearchHitSupport.unwrapSearchHits(page)) // + .collect(Collectors.toList()); + } /** * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. @@ -113,19 +132,25 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param index the index to run the query against * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * * error. + * @deprecated since 4.0, use {@link #searchForStream(Query, Class, IndexCoordinates)}. */ + @Deprecated CloseableIterator stream(Query query, Class clazz, IndexCoordinates index); /** * Execute the criteria query against elasticsearch and return result as {@link List} * + * @param element return type * @param query the query to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against - * @param element return type * @return list of found objects + * @deprecated since 4.0, use {@link #search(Query, Class, IndexCoordinates)}. */ - List queryForList(Query query, Class clazz, IndexCoordinates index); + @Deprecated + default List queryForList(Query query, Class clazz, IndexCoordinates index) { + return (List) SearchHitSupport.unwrapSearchHits(search(query, clazz, index)); + } /** * Execute the multi search query against elasticsearch and return result as {@link List} @@ -135,7 +160,9 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param index the index to run the query against * @param element return type * @return list of found objects + * @deprecated since 4.0, use {@link #multiSearch(List, Class, IndexCoordinates)}. */ + @Deprecated default List> queryForList(List queries, Class clazz, IndexCoordinates index) { return queryForPage(queries, clazz, index).stream().map(Page::getContent).collect(Collectors.toList()); } @@ -147,7 +174,9 @@ default List> queryForList(List queries, Class clazz, Inde * @param classes the entity classes used for property mapping * @param index the index to run the query against * @return list of list of found objects + * @deprecated since 4.0, use {@link #multiSearch(List, List, IndexCoordinates)}. */ + @Deprecated default List> queryForList(List queries, List> classes, IndexCoordinates index) { return queryForPage(queries, classes, index).stream().map(Page::getContent).collect(Collectors.toList()); } @@ -159,8 +188,12 @@ default List> queryForList(List queries, List> classes, * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return list of found object ids + * @deprecated since 4.0 use {@link #search(Query, Class, IndexCoordinates)} and map the results. */ - List queryForIds(Query query, Class clazz, IndexCoordinates index); + @Deprecated + default List queryForIds(Query query, Class clazz, IndexCoordinates index) { + return search(query, clazz, index).map(SearchHit::getId).toList(); + } /** * Returns scrolled page for given query @@ -170,32 +203,205 @@ default List> queryForList(List queries, List> classes, * @param clazz The class of entity to retrieve. * @param index the index to run the query against * @return scrolled page result + * @deprecated since 4.0, use {@link #searchScrollStart(long, Query, Class, IndexCoordinates)}. */ - ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index); + @Deprecated + default ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, + IndexCoordinates index) { + return (ScrolledPage) SearchHitSupport + .unwrapSearchHits(searchScrollStart(scrollTimeInMillis, query, clazz, index)); + } - ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz); + /** + * Returns next scrolled page. + * + * @param scrollId the scroll id + * @param scrollTimeInMillis duration of the scroll time + * @param clazz The class of entity to retrieve. + * @return scrolled page result + * @deprecated since 4.0, use {@link #searchScrollStart(long, Query, Class, IndexCoordinates)}. + */ + @Deprecated + default ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + return (ScrolledPage) SearchHitSupport + .unwrapSearchHits(searchScrollContinue(scrollId, scrollTimeInMillis, clazz)); + } /** * Clears the search contexts associated with specified scroll ids. * * @param scrollId the scroll id + * @deprecated since 4.0, use {@link #searchScrollClear(String)}. */ - void clearScroll(String scrollId); + @Deprecated + default void clearScroll(String scrollId) { + searchScrollClear(scrollId); + } /** * more like this query to search for documents that are "like" a specific document. * + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return page with the results + * @deprecated since 4.0, use {@link #search(MoreLikeThisQuery, Class, IndexCoordinates)}. + */ + @Deprecated + default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { + return (AggregatedPage) SearchHitSupport.unwrapSearchHits(search(query, clazz, index)); + } + + /** + * Execute the query against elasticsearch and return the first returned object. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return the first found object + */ + @Nullable + default SearchHit searchOne(Query query, Class clazz, IndexCoordinates index) { + List> content = searchForPage(query, clazz, index).getContent(); + return content.isEmpty() ? null : content.get(0); + } + + /** + * Execute the query against elasticsearch and return result as {@link AggregatedPage}. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return a page with aggregations + */ + AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index); + + /** + * Execute the multi-search against elasticsearch and return result as {@link List} of {@link AggregatedPage} + * + * @param queries the queries + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return list of pages with the results + */ + List>> multiSearchForPage(List queries, Class clazz, + IndexCoordinates index); + + /** + * Execute the multi-search against elasticsearch and return result as {@link List} of {@link AggregatedPage} + * + * @param queries the queries + * @param classes the entity classes used for the queries + * @param index the index to run the query against + * @return list of pages with the results + */ + List>> multiSearchForPage(List queries, List> classes, + IndexCoordinates index); + + /** + * Execute the criteria query against elasticsearch and return result as {@link SearchHits} + * + * @param element return type * @param query the query to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against + * @return SearchHits containing the list of found objects + */ + default SearchHits search(Query query, Class clazz, IndexCoordinates index) { + AggregatedPage> aggregatedPage = searchForPage(query, clazz, index); + return new SearchHits<>(aggregatedPage.getContent(), aggregatedPage.getTotalElements(), + aggregatedPage.getMaxScore()); + } + + /** + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. + * + * @param queries the queries to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @param element return type + * @return list of SearchHits + */ + default List> multiSearch(List queries, Class clazz, IndexCoordinates index) { + return multiSearchForPage(queries, clazz, index).stream() + .map(page -> new SearchHits(page.getContent(), page.getTotalElements(), page.getMaxScore())) + .collect(Collectors.toList()); + } + + /** + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. + * + * @param queries the queries to execute + * @param classes the entity classes used for property mapping + * @param index the index to run the query against + * @return list of SearchHits + */ + default List> multiSearch(List queries, List> classes, IndexCoordinates index) { + List> searchHitsList = new ArrayList<>(); + multiSearchForPage(queries, classes, index).forEach(page -> { + searchHitsList.add(new SearchHits(page.getContent(), page.getTotalElements(), page.getMaxScore())); + }); + return searchHitsList; + } + + /** + * more like this query to search for documents that are "like" a specific document. + * * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against * @return page with the results */ - Page moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); + AggregatedPage> search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); + + /** + * Returns scrolled page for given query + * + * @param scrollTimeInMillis duration of the scroll time + * @param query The search query. + * @param clazz The class of entity to retrieve. + * @param index the index to run the query against + * @return scrolled page result + */ + ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, + IndexCoordinates index); + + /** + * Returns next scrolled page + * + * @param scrollId the scroll id + * @param scrollTimeInMillis duration of the scroll time + * @param clazz The class of entity to retrieve. + * @return scrolled page result + */ + ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, + Class clazz); + + /** + * Clears the search contexts associated with specified scroll ids. + * + * @param scrollId the scroll id + */ + void searchScrollClear(String scrollId); + + /** + * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. + *

+ * + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * + * error. + */ + CloseableIterator> searchForStream(Query query, Class clazz, IndexCoordinates index); /** * Does a suggest query - * + * * @param suggestion the query * @param index the index to run the query against * @return the suggest response diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java index 5250bdc1d..01da64509 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java @@ -87,25 +87,25 @@ public AggregatedPageImpl(List content, Pageable pageable, long total, Aggreg } public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, float maxScore) { - this(content, pageable, total, aggregations); + this(content, pageableOrUnpaged(pageable), total, aggregations); this.maxScore = maxScore; } public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, String scrollId) { - this(content, pageable, total, aggregations); + this(content, pageableOrUnpaged(pageable), total, aggregations); this.scrollId = scrollId; } public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, String scrollId, float maxScore) { - this(content, pageable, total, aggregations, scrollId); + this(content, pageableOrUnpaged(pageable), total, aggregations, scrollId); this.maxScore = maxScore; } public AggregatedPageImpl(List content, Pageable pageable, SearchDocumentResponse response) { - this(content, pageable, response.getTotalHits(), response.getAggregations(), response.getScrollId(), - response.getMaxScore()); + this(content, pageableOrUnpaged(pageable), response.getTotalHits(), response.getAggregations(), + response.getScrollId(), response.getMaxScore()); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index 9d2074e6a..216e376fe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -19,8 +19,10 @@ import org.springframework.data.convert.EntityConverter; import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; 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.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; @@ -57,7 +59,8 @@ default String convertId(Object idValue) { return getConversionService().convert(idValue, String.class); } - AggregatedPage mapResults(SearchDocumentResponse response, Class clazz, Pageable pageable); + AggregatedPage> mapResults(SearchDocumentResponse response, Class clazz, + @Nullable Pageable pageable); /** * Get the configured {@link ProjectionFactory}.
@@ -72,14 +75,25 @@ default ProjectionFactory getProjectionFactory() { /** * Map a single {@link Document} to an instance of the given type. * - * @param document must not be {@literal null}. + * @param document the document to map * @param type must not be {@literal null}. * @param - * @return can be {@literal null} if the {@link Document#isEmpty()} is true. + * @return can be {@literal null} if the document is null or {@link Document#isEmpty()} is true. * @since 4.0 */ @Nullable - T mapDocument(Document document, Class type); + T mapDocument(@Nullable Document document, Class type); + + /** + * builds a {@link SearchHit} from a {@link SearchDocument}. + * + * @param searchDocument must not be {@literal null} + * @param the clazz of the type, must not be {@literal null}. + * @param type the type of the returned data, must not be {@literal null}. + * @return SearchHit with all available information filled in + * @since 4.0 + */ + SearchHit read(Class type, SearchDocument searchDocument); /** * Map a list of {@link Document}s to alist of instance of the given type. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 715f59d52..180034ba0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -17,17 +17,8 @@ import lombok.RequiredArgsConstructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; import org.springframework.beans.BeansException; @@ -44,6 +35,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.elasticsearch.core.document.Document; @@ -588,7 +580,11 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert @Override @Nullable - public T mapDocument(Document document, Class type) { + public T mapDocument(@Nullable Document document, Class type) { + + if (document == null) { + return null; + } Object mappedResult = read(type, document); @@ -601,6 +597,15 @@ public T mapDocument(Document document, Class type) { : type.cast(mappedResult); } + @Override + public SearchHit read(Class type, SearchDocument searchDocument) { + String id = searchDocument.hasId() ? searchDocument.getId() : null; + float score = searchDocument.getScore(); + T content = mapDocument(searchDocument, type); + + return new SearchHit(id, score, content); + } + @Override public List mapDocuments(List documents, Class type) { return documents.stream().map(it -> mapDocument(it, type)).collect(Collectors.toList()); @@ -697,12 +702,14 @@ private boolean isSimpleType(Class type) { } @Override - public AggregatedPage mapResults(SearchDocumentResponse response, Class type, Pageable pageable) { + public AggregatedPage> mapResults(SearchDocumentResponse response, Class type, + Pageable pageable) { - List results = response.getSearchDocuments().stream() // - .map(searchDocument -> mapDocument(searchDocument, type)).collect(Collectors.toList()); + List> results = response.getSearchDocuments().stream() // + .map(searchDocument -> read(type, searchDocument)) // + .collect(Collectors.toList()); - return new AggregatedPageImpl(results, pageable, response); + return new AggregatedPageImpl<>(results, pageable, response); } private void populateScriptFields(T result, SearchDocument searchDocument) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java new file mode 100644 index 000000000..baa01ef51 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java @@ -0,0 +1,2 @@ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.core.convert; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java index c5fc6928f..8195015af 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java @@ -19,7 +19,7 @@ import java.util.Map; /** - * Extension to {@link Document} exposing a search {@link #getScore() score}. + * Extension to {@link Document} exposing a search response related data. * * @author Mark Paluch * @author Peter-Josef Meisch diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index f9303515f..d361d5708 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -20,10 +20,11 @@ import org.reactivestreams.Publisher; import org.springframework.core.convert.converter.Converter; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchQueryExecution.ResultProcessingConverter; import org.springframework.data.elasticsearch.repository.query.ReactiveElasticsearchQueryExecution.ResultProcessingExecution; @@ -56,10 +57,12 @@ abstract class AbstractReactiveElasticsearchRepositoryQuery implements Repositor * (non-Javadoc) * @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[]) */ + @Override public Object execute(Object[] parameters) { - return queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parameters) + Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parameters) : execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parameters)); + return SearchHitSupport.unwrapSearchHits(result); } private Object executeDeferred(Object[] parameters) { @@ -116,10 +119,10 @@ private ReactiveElasticsearchQueryExecution getExecutionToWrap(ElasticsearchPara return (query, type, targetType, indexCoordinates) -> operations.count(query, type, indexCoordinates) .map(count -> count > 0); } else if (queryMethod.isCollectionQuery()) { - return (query, type, targetType, indexCoordinates) -> operations.find(query.setPageable(accessor.getPageable()), + return (query, type, targetType, indexCoordinates) -> operations.search(query.setPageable(accessor.getPageable()), type, targetType, indexCoordinates); } else { - return (query, type, targetType, indexCoordinates) -> operations.find(query, type, targetType, indexCoordinates); + return (query, type, targetType, indexCoordinates) -> operations.search(query, type, targetType, indexCoordinates); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index b0453adc4..a750e022d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -17,14 +17,14 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.repository.query.parser.ElasticsearchQueryCreator; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; -import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.StreamUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -54,24 +54,24 @@ public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOper @Override public Object execute(Object[] parameters) { - ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); CriteriaQuery query = createQuery(accessor); Assert.notNull(query, "unsupported query"); Class clazz = queryMethod.getEntityInformation().getJavaType(); IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); + Object result = null; + if (tree.isLimiting()) { query.setMaxResults(tree.getMaxResults()); } if (tree.isDelete()) { - Object result = countOrGetDocumentsForDelete(query, accessor); + result = countOrGetDocumentsForDelete(query, accessor); elasticsearchOperations.delete(query, clazz, index); - return result; } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); - return elasticsearchOperations.queryForPage(query, clazz, index); + result = elasticsearchOperations.searchForPage(query, clazz, index); } else if (queryMethod.isStreamQuery()) { Class entityType = clazz; if (accessor.getPageable().isUnpaged()) { @@ -79,44 +79,41 @@ public Object execute(Object[] parameters) { } else { query.setPageable(accessor.getPageable()); } - return StreamUtils - .createStreamFromIterator((CloseableIterator) elasticsearchOperations.stream(query, entityType, index)); + result = StreamUtils.createStreamFromIterator(elasticsearchOperations.stream(query, entityType, index)); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { - - int itemCount = (int) elasticsearchOperations.count(query, clazz, - index); + int itemCount = (int) elasticsearchOperations.count(query, clazz, index); query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); } else { query.setPageable(accessor.getPageable()); } - return elasticsearchOperations.queryForList(query, clazz, index); + result = elasticsearchOperations.search(query, clazz, index); } else if (tree.isCountProjection()) { - return elasticsearchOperations.count(query, clazz, index); + result = elasticsearchOperations.count(query, clazz, index); + } else { + result = elasticsearchOperations.searchOne(query, clazz, index); } - return elasticsearchOperations.queryForObject(query, clazz, index); + return SearchHitSupport.unwrapSearchHits(result); } private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) { Object result = null; Class clazz = queryMethod.getEntityInformation().getJavaType(); - IndexCoordinates index = elasticsearchOperations - .getIndexCoordinatesFor(clazz); + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { - int itemCount = (int) elasticsearchOperations.count(query, clazz, - index); + int itemCount = (int) elasticsearchOperations.count(query, clazz, index); query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); } else { query.setPageable(accessor.getPageable()); } - result = elasticsearchOperations.queryForList(query, clazz, index); + result = elasticsearchOperations.search(query, clazz, index); } if (ClassUtils.isAssignable(Number.class, queryMethod.getReturnedObjectType())) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index ebbe03010..48a79e93d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -20,8 +20,9 @@ import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.convert.DateTimeConverters; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.util.Assert; @@ -71,17 +72,23 @@ public Object execute(Object[] parameters) { StringQuery stringQuery = createQuery(accessor); Class clazz = queryMethod.getEntityInformation().getJavaType(); IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); + + Object result = null; + if (queryMethod.isPageQuery()) { stringQuery.setPageable(accessor.getPageable()); - return elasticsearchOperations.queryForPage(stringQuery, clazz, index); + result = elasticsearchOperations.searchForPage(stringQuery, clazz, index); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isPaged()) { stringQuery.setPageable(accessor.getPageable()); } - return elasticsearchOperations.queryForList(stringQuery, clazz, index); + result = elasticsearchOperations.search(stringQuery, clazz, index); + } else { + result = elasticsearchOperations.searchOne(stringQuery, clazz, index); } - return elasticsearchOperations.queryForObject(stringQuery, clazz, index); + return SearchHitSupport.unwrapSearchHits(result); + } protected StringQuery createQuery(ParametersParameterAccessor parameterAccessor) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index b2f3a7184..f4f156cb8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -35,12 +35,13 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.core.DocumentOperations; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; -import org.springframework.data.elasticsearch.core.SearchOperations; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHitSupport; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.DeleteQuery; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -113,8 +114,8 @@ private void putMapping() { private boolean createIndexAndMapping() { - final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter() - .getMappingContext().getRequiredPersistentEntity(getEntityClass()); + final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter().getMappingContext() + .getRequiredPersistentEntity(getEntityClass()); return entity.isCreateIndexAndMapping(); } @@ -138,7 +139,8 @@ public Iterable findAll() { @Override public Page findAll(Pageable pageable) { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); - return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); } @Override @@ -150,7 +152,12 @@ public Iterable findAll(Sort sort) { } NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); - return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); + } + + private Page unwrapSearchHits(AggregatedPage> page) { + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override @@ -219,18 +226,21 @@ public Iterable search(QueryBuilder query) { return new PageImpl<>(Collections. emptyList()); } searchQuery.setPageable(PageRequest.of(0, count)); - return operations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.searchForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); } @Override public Page search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); - return operations.queryForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.searchForPage(searchQuery, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); } @Override public Page search(Query query) { - return operations.queryForPage(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); } @Override @@ -245,7 +255,8 @@ public Page searchSimilar(T entity, String[] fields, Pageable pageable) { query.addFields(fields); } - return operations.moreLikeThis(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = operations.search(query, getEntityClass(), getIndexCoordinates()); + return unwrapSearchHits(page); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index 3d87f54ce..2d7b1ef11 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -21,6 +21,7 @@ import org.reactivestreams.Publisher; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.util.Assert; @@ -48,7 +49,9 @@ public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation findAll(Sort sort) { - return elasticsearchOperations.find(Query.findAll().addSort(sort), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations + .search(Query.findAll().addSort(sort), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) + .map(SearchHit::getContent); } @Override @@ -76,7 +79,8 @@ public Flux saveAll(Publisher entityStream) { public Mono findById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), + entityInformation.getIndexCoordinates()); } @Override @@ -90,7 +94,8 @@ public Mono findById(Publisher id) { public Mono existsById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), + entityInformation.getIndexCoordinates()); } @Override @@ -103,7 +108,9 @@ public Mono existsById(Publisher id) { @Override public Flux findAll() { - return elasticsearchOperations.find(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations + .search(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) + .map(SearchHit::getContent); } @Override @@ -124,14 +131,16 @@ public Flux findAllById(Publisher idStream) { @Override public Mono count() { - return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), + entityInformation.getIndexCoordinates()); } @Override public Mono deleteById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.deleteById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // + return elasticsearchOperations + .deleteById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // .then(); } @@ -167,7 +176,8 @@ public Mono deleteAll(Publisher entityStream) { @Override public Mono deleteAll() { - return elasticsearchOperations.deleteBy(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // + return elasticsearchOperations + .deleteBy(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // .then(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 07350522c..566ac5055 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -45,6 +45,9 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -131,7 +134,7 @@ public void shouldIndexInitialLevelNestedObject() { boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index); + SearchHits persons = elasticsearchTemplate.search(searchQuery, Person.class, index); assertThat(persons).hasSize(1); } @@ -193,11 +196,11 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - Page personIndexed = elasticsearchTemplate.queryForPage(searchQuery, + Page> personIndexed = elasticsearchTemplate.searchForPage(searchQuery, PersonMultipleLevelNested.class, index); assertThat(personIndexed).isNotNull(); assertThat(personIndexed.getTotalElements()).isEqualTo(1); - assertThat(personIndexed.getContent().get(0).getId()).isEqualTo("1"); + assertThat(personIndexed.getContent().get(0).getContent().getId()).isEqualTo("1"); } private List createPerson() { @@ -330,7 +333,7 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - List persons = elasticsearchTemplate.queryForList(searchQuery, Person.class, index); + SearchHits persons = elasticsearchTemplate.search(searchQuery, Person.class, index); // then assertThat(persons).hasSize(1); @@ -378,10 +381,10 @@ public void shouldIndexAndSearchMapAsNestedType() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); - Page books = elasticsearchTemplate.queryForPage(searchQuery, Book.class, index); + AggregatedPage> books = elasticsearchTemplate.searchForPage(searchQuery, Book.class, index); assertThat(books.getContent()).hasSize(1); - assertThat(books.getContent().get(0).getId()).isEqualTo(book2.getId()); + assertThat(books.getContent().get(0).getContent().getId()).isEqualTo(book2.getId()); } @Setter diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 4ff17b4c7..437808c91 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -282,7 +282,7 @@ public void shouldReturnPageForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -306,8 +306,8 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { .withPreference("_local").build(); // when - Page sampleEntities = operations.queryForPage(searchQueryWithValidPreference, SampleEntity.class, - index); + Page> sampleEntities = operations.searchForPage(searchQueryWithValidPreference, + SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -332,7 +332,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { // when assertThatThrownBy(() -> { - operations.queryForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); + operations.searchForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); }).isInstanceOf(Exception.class); } @@ -352,7 +352,7 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - Page entities = operations.queryForPage(searchQuery, SampleEntity.class, + Page> entities = operations.searchForPage(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then @@ -384,7 +384,7 @@ public void shouldDoBulkIndex() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); } @@ -439,7 +439,7 @@ public void shouldDeleteDocumentForGivenId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -461,7 +461,7 @@ public void shouldDeleteEntityForGivenId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -486,7 +486,7 @@ public void shouldDeleteDocumentForGivenQuery() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -574,7 +574,7 @@ public void shouldFilterSearchResultsForGivenFilter() { .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -609,11 +609,11 @@ public void shouldSortResultsGivenSortCriteria() { .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); } @Test @@ -646,12 +646,12 @@ public void shouldSortResultsGivenMultipleSortCriteria() { .withSort(new FieldSortBuilder("message").order(SortOrder.ASC)).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getRate()).isEqualTo(sampleEntity2.getRate()); - assertThat(sampleEntities.getContent().get(1).getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-312 @@ -684,12 +684,12 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getRate()).isEqualTo(sampleEntity3.getRate()); - assertThat(sampleEntities.getContent().get(1).getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity3.getRate()); + assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-312 @@ -722,12 +722,12 @@ public void shouldSortResultsGivenNullLastSortCriteria() { .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getRate()).isEqualTo(sampleEntity1.getRate()); - assertThat(sampleEntities.getContent().get(1).getMessage()).isEqualTo(sampleEntity2.getMessage()); + assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity1.getRate()); + assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity2.getMessage()); } @Test // DATAES-467, DATAES-657 @@ -748,12 +748,12 @@ public void shouldSortResultsByScore() { .build(); // when - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(2); - assertThat(page.getContent().get(0).getId()).isEqualTo("2"); - assertThat(page.getContent().get(1).getId()).isEqualTo("1"); + assertThat(page.getContent().get(0).getContent().getId()).isEqualTo("2"); + assertThat(page.getContent().get(1).getContent().getId()).isEqualTo("1"); } @Test @@ -772,7 +772,7 @@ public void shouldExecuteStringQuery() { StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); // when - Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); @@ -803,11 +803,11 @@ public void shouldUseScriptedFields() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( new ScriptField("scriptedRate", new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params))) .build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getScriptedRate()).isEqualTo(4.0); + assertThat(sampleEntities.getContent().get(0).getContent().getScriptedRate()).isEqualTo(4.0); } @Test @@ -826,7 +826,7 @@ public void shouldReturnPageableResultsGivenStringQuery() { StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10)); // when - Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -853,7 +853,7 @@ public void shouldReturnSortedPageableResultsGivenStringQuery() { Sort.by(Order.asc("message"))); // when - Page sampleEntities = operations.queryForPage(stringQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -875,11 +875,11 @@ public void shouldReturnObjectMatchingGivenStringQuery() { StringQuery stringQuery = new StringQuery(termQuery("id", documentId).toString()); // when - SampleEntity sampleEntity1 = operations.queryForObject(stringQuery, SampleEntity.class, index); + SearchHit sampleEntity1 = operations.searchOne(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); - assertThat(sampleEntity1.getId()).isEqualTo(documentId); + assertThat(sampleEntity1.getContent().getId()).isEqualTo(documentId); } @Test @@ -909,7 +909,7 @@ public void shouldExecuteGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when - SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity1 = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -935,7 +935,7 @@ public void shouldDeleteGivenCriteriaQuery() { // then StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = operations.queryForList(stringQuery, SampleEntity.class, index); + SearchHits sampleEntities = operations.search(stringQuery, SampleEntity.class, index); assertThat(sampleEntities).isEmpty(); } @@ -958,12 +958,12 @@ public void shouldReturnSpecifiedFields() { .build(); // when - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); assertThat(page.getTotalElements()).isEqualTo(1); - final SampleEntity actual = page.getContent().get(0); + final SampleEntity actual = page.getContent().get(0).getContent(); assertThat(actual.message).isEqualTo(message); assertThat(actual.getType()).isNull(); assertThat(actual.getLocation()).isNull(); @@ -990,12 +990,12 @@ public void shouldReturnFieldsBasedOnSourceFilter() { .withSourceFilter(sourceFilter.build()).build(); // when - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getMessage()).isEqualTo(message); + assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo(message); } @Test @@ -1030,11 +1030,13 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { moreLikeThisQuery.setMinDocFreq(1); // when - Page sampleEntities = operations.moreLikeThis(moreLikeThisQuery, SampleEntity.class, index); + Page> sampleEntities = operations.search(moreLikeThisQuery, SampleEntity.class, index); // then assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent()).contains(sampleEntity); + List content = sampleEntities.getContent().stream().map(SearchHit::getContent) + .collect(Collectors.toList()); + assertThat(content).contains(sampleEntity); } @Test // DATAES-167 @@ -1051,13 +1053,14 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } - operations.clearScroll(scroll.getScrollId()); + operations.searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1076,13 +1079,14 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } - operations.clearScroll(scroll.getScrollId()); + operations.searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1101,15 +1105,16 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1127,15 +1132,16 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .withQuery(matchAllQuery()).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1153,15 +1159,16 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1179,15 +1186,16 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1205,15 +1213,16 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1231,15 +1240,16 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); String scrollId = scroll.getScrollId(); - List sampleEntities = new ArrayList<>(); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.clearScroll(scrollId); + operations.searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1257,8 +1267,9 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - CloseableIterator stream = operations.stream(criteriaQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + CloseableIterator> stream = operations.searchForStream(criteriaQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (stream.hasNext()) { sampleEntities.add(stream.next()); } @@ -1311,9 +1322,9 @@ public void shouldReturnListForGivenCriteria() { CriteriaQuery singleCriteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); CriteriaQuery multipleCriteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").and("message").contains("message")); - List sampleEntitiesForSingleCriteria = operations.queryForList(singleCriteriaQuery, + SearchHits sampleEntitiesForSingleCriteria = operations.search(singleCriteriaQuery, SampleEntity.class, index); - List sampleEntitiesForAndCriteria = operations.queryForList(multipleCriteriaQuery, SampleEntity.class, + SearchHits sampleEntitiesForAndCriteria = operations.search(multipleCriteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntitiesForSingleCriteria).hasSize(2); @@ -1346,17 +1357,17 @@ public void shouldReturnListForGivenStringQuery() { indexOperations.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); - List sampleEntities = operations.queryForList(stringQuery, SampleEntity.class, index); + SearchHits sampleEntities = operations.search(stringQuery, SampleEntity.class, index); // then assertThat(sampleEntities).hasSize(3); } @Test - public void shouldPutMappingForGivenEntity() throws Exception { + public void shouldPutMappingForGivenEntity() { // given - Class entity = SampleMappingEntity.class; + Class entity = SampleEntity.class; indexOperations.deleteIndex(entity); indexOperations.createIndex(entity); @@ -1367,7 +1378,7 @@ public void shouldPutMappingForGivenEntity() throws Exception { } @Test // DATAES-305 - public void shouldPutMappingWithCustomIndexName() throws Exception { + public void shouldPutMappingWithCustomIndexName() { // given Class entity = SampleEntity.class; @@ -1510,15 +1521,15 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - List entities = new ArrayList<>(); + List> entities = new ArrayList<>(); - ScrolledPage scroll = operations.startScroll(scrollTimeInMillis, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = operations.searchScrollStart(scrollTimeInMillis, searchQuery, + SampleEntity.class, index); entities.addAll(scroll.getContent()); while (scroll.hasContent()) { - scroll = operations.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); entities.addAll(scroll.getContent()); } @@ -1549,8 +1560,9 @@ public void shouldReturnSameEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ac")).build()); // then - List> sampleEntities = operations.queryForPage(queries, SampleEntity.class, index); - for (Page sampleEntity : sampleEntities) { + List>> sampleEntities = operations.multiSearchForPage(queries, + SampleEntity.class, index); + for (Page> sampleEntity : sampleEntities) { assertThat(sampleEntity.getTotalElements()).isEqualTo(1); } } @@ -1577,16 +1589,19 @@ public void shouldReturnDifferentEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("description", "bc")).build()); - List> pages = operations.queryForPage(queries, Lists.newArrayList(SampleEntity.class, clazz), + List>> pages = operations.multiSearchForPage(queries, + Lists.newArrayList(SampleEntity.class, clazz), IndexCoordinates.of(index.getIndexName(), bookIndex.getIndexName())); // then Page page0 = pages.get(0); assertThat(page0.getTotalElements()).isEqualTo(1L); - assertThat(page0.getContent().get(0).getClass()).isEqualTo(SampleEntity.class); + SearchHit searchHit0 = (SearchHit) page0.getContent().get(0); + assertThat(searchHit0.getContent().getClass()).isEqualTo(SampleEntity.class); Page page1 = pages.get(1); assertThat(page1.getTotalElements()).isEqualTo(1L); - assertThat(page1.getContent().get(0).getClass()).isEqualTo(clazz); + SearchHit searchHit1 = (SearchHit) page1.getContent().get(0); + assertThat(searchHit1.getContent().getClass()).isEqualTo(clazz); } @Test @@ -1610,7 +1625,7 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(0); } @@ -1630,10 +1645,10 @@ public void shouldIndexDocumentForSpecifiedSource() { .build(); // then - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(page).isNotNull(); assertThat(page.getContent()).hasSize(1); - assertThat(page.getContent().get(0).getId()).isEqualTo(indexQuery.getId()); + assertThat(page.getContent().get(0).getContent().getId()).isEqualTo(indexQuery.getId()); } @Test @@ -1680,11 +1695,11 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) .withMinScore(2.0F).build(); - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getMessage()).isEqualTo("ab"); + assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("ab"); } @Test // DATAES-462 @@ -1704,7 +1719,7 @@ public void shouldReturnScores() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) .withSort(SortBuilders.fieldSort("message")).withTrackScores(true).build(); - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isInstanceOf(AggregatedPage.class); @@ -1765,12 +1780,12 @@ public void shouldDoBulkIndexWithoutId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); - List content = sampleEntities.getContent(); - assertThat(content.get(0).getId()).isNotNull(); - assertThat(content.get(1).getId()).isNotNull(); + List> content = sampleEntities.getContent(); + assertThat(content.get(0).getContent().getId()).isNotNull(); + assertThat(content.get(1).getContent().getId()).isNotNull(); } @Test @@ -1809,12 +1824,12 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, Map.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, Map.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(2); - List content = sampleEntities.getContent(); - assertThat(content.get(0).get("userId")).isEqualTo(person1.get("userId")); - assertThat(content.get(1).get("userId")).isEqualTo(person2.get("userId")); + List> content = sampleEntities.getContent(); + assertThat(content.get(0).getContent().get("userId")).isEqualTo(person1.get("userId")); + assertThat(content.get(1).getContent().get("userId")).isEqualTo(person2.get("userId")); } @Test // DATAES-523 @@ -1833,7 +1848,7 @@ public void shouldIndexGteEntityWithVersionType() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page entities = operations.queryForPage(searchQuery, GTEVersionEntity.class, index); + Page> entities = operations.searchForPage(searchQuery, GTEVersionEntity.class, index); // then assertThat(entities).isNotNull(); assertThat(entities.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -1864,7 +1879,7 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(sampleEntities).isNotNull(); @@ -2241,7 +2256,7 @@ public void shouldTestResultsAcrossMultipleIndices() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - List sampleEntities = operations.queryForList(searchQuery, SampleEntity.class, + SearchHits sampleEntities = operations.search(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then @@ -2268,7 +2283,7 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page page = operations.queryForPage(searchQuery, ResultAggregator.class, + Page> page = operations.searchForPage(searchQuery, ResultAggregator.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); assertThat(page.getTotalElements()).isEqualTo(2); @@ -2329,9 +2344,9 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); + assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2360,9 +2375,9 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); + assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2389,9 +2404,9 @@ public void shouldDeleteDocumentForGivenIdOnly() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page sampleEntities = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); - assertThat(sampleEntities.getContent().get(0).getId()).isEqualTo(remainingDocumentId); + assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2415,18 +2430,20 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("message")); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage scroll = operations.startScroll(1000, criteriaQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } - operations.clearScroll(scroll.getScrollId()); + operations.searchScrollClear(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); - assertThat(sampleEntities.stream().map(SampleEntity::getMessage).collect(Collectors.toList())) - .doesNotContain(notFindableMessage); + assertThat( + sampleEntities.stream().map(SearchHit::getContent).map(SampleEntity::getMessage).collect(Collectors.toList())) + .doesNotContain(notFindableMessage); } @Test // DATAES-525 @@ -2450,18 +2467,20 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } - operations.clearScroll(scroll.getScrollId()); + operations.searchScrollClear(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); - assertThat(sampleEntities.stream().map(SampleEntity::getMessage).collect(Collectors.toList())) - .doesNotContain(notFindableMessage); + assertThat( + sampleEntities.stream().map(SearchHit::getContent).map(SampleEntity::getMessage).collect(Collectors.toList())) + .doesNotContain(notFindableMessage); } @Test // DATAES-565 @@ -2480,18 +2499,20 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build(); - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } - operations.clearScroll(scroll.getScrollId()); + operations.searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(3); - assertThat(sampleEntities.stream().map(SampleEntity::getId).collect(Collectors.toList())) + assertThat(sampleEntities.stream().map(SearchHit::getContent).map(SampleEntity::getId).collect(Collectors.toList())) .doesNotContain((String) null); - assertThat(sampleEntities.stream().map(SampleEntity::getMessage).collect(Collectors.toList())) - .containsOnly((String) null); + assertThat( + sampleEntities.stream().map(SearchHit::getContent).map(SampleEntity::getMessage).collect(Collectors.toList())) + .containsOnly((String) null); } @Test // DATAES-457 @@ -2524,20 +2545,21 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); // when - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } // then assertThat(sampleEntities).hasSize(3); - assertThat(sampleEntities.get(0).getRate()).isEqualTo(sampleEntity2.getRate()); - assertThat(sampleEntities.get(1).getRate()).isEqualTo(sampleEntity3.getRate()); - assertThat(sampleEntities.get(1).getMessage()).isEqualTo(sampleEntity3.getMessage()); - assertThat(sampleEntities.get(2).getRate()).isEqualTo(sampleEntity1.getRate()); - assertThat(sampleEntities.get(2).getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(sampleEntities.get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(sampleEntities.get(1).getContent().getRate()).isEqualTo(sampleEntity3.getRate()); + assertThat(sampleEntities.get(1).getContent().getMessage()).isEqualTo(sampleEntity3.getMessage()); + assertThat(sampleEntities.get(2).getContent().getRate()).isEqualTo(sampleEntity1.getRate()); + assertThat(sampleEntities.get(2).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-457 @@ -2571,20 +2593,21 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { .build(); // when - ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); - List sampleEntities = new ArrayList<>(); + ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, + index); + List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.continueScroll(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } // then assertThat(sampleEntities).hasSize(3); - assertThat(sampleEntities.get(0).getRate()).isEqualTo(sampleEntity2.getRate()); - assertThat(sampleEntities.get(1).getRate()).isEqualTo(sampleEntity3.getRate()); - assertThat(sampleEntities.get(1).getMessage()).isEqualTo(sampleEntity3.getMessage()); - assertThat(sampleEntities.get(2).getRate()).isEqualTo(sampleEntity1.getRate()); - assertThat(sampleEntities.get(2).getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(sampleEntities.get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(sampleEntities.get(1).getContent().getRate()).isEqualTo(sampleEntity3.getRate()); + assertThat(sampleEntities.get(1).getContent().getMessage()).isEqualTo(sampleEntity3.getMessage()); + assertThat(sampleEntities.get(2).getContent().getRate()).isEqualTo(sampleEntity1.getRate()); + assertThat(sampleEntities.get(2).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-593 @@ -2607,14 +2630,14 @@ public void shouldReturnDocumentWithCollapsedField() { .build(); // when - Page page = operations.queryForPage(searchQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); assertThat(page.getTotalElements()).isEqualTo(3); assertThat(page.getContent()).hasSize(2); - assertThat(page.getContent().get(0).getMessage()).isEqualTo("message 1"); - assertThat(page.getContent().get(1).getMessage()).isEqualTo("message 2"); + assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("message 1"); + assertThat(page.getContent().get(1).getContent().getMessage()).isEqualTo("message 2"); } private IndexQuery getIndexQuery(SampleEntity sampleEntity) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index f3369d4a2..633a497c4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -25,7 +25,6 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; -import java.util.List; import org.elasticsearch.ElasticsearchException; import org.junit.jupiter.api.BeforeEach; @@ -90,7 +89,7 @@ public void shouldIndexGivenLogEntityWithIPFieldType() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10.1")).build(); - List entities = operations.queryForList(searchQuery, LogEntity.class, index); + SearchHits entities = operations.search(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(1); @@ -103,7 +102,7 @@ public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("ip", "10.10.10")).build(); assertThatThrownBy(() -> { - List entities = operations.queryForList(searchQuery, LogEntity.class, index); + SearchHits entities = operations.search(searchQuery, LogEntity.class, index); }).isInstanceOf(ElasticsearchException.class); } @@ -113,7 +112,7 @@ public void shouldReturnLogsForGivenIPRanges() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(rangeQuery("ip").from("10.10.10.1").to("10.10.10.3")).build(); - List entities = operations.queryForList(searchQuery, LogEntity.class, index); + SearchHits entities = operations.search(searchQuery, LogEntity.class, index); // then assertThat(entities).isNotNull().hasSize(3); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 8abfa0d60..41c04d0d3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -24,7 +24,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -54,6 +53,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; +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.IndexQuery; @@ -137,7 +137,7 @@ public void insertWithIdShouldWork() { restTemplate.refresh(SampleEntity.class); - List result = restTemplate.queryForList( + SearchHits result = restTemplate.search( new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)); assertThat(result).hasSize(1); @@ -311,38 +311,39 @@ public void existsShouldReturnFalseWhenNotFound() { } @Test // DATAES-519 - public void findShouldCompleteWhenIndexDoesNotExist() { + public void searchShouldCompleteWhenIndexDoesNotExist() { template - .find(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + .search(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .verifyComplete(); } @Test // DATAES-504 - public void findShouldApplyCriteria() { + public void searchShouldApplyCriteria() { SampleEntity sampleEntity = randomEntity("some message"); index(sampleEntity); CriteriaQuery criteriaQuery = new CriteriaQuery(Criteria.where("message").is("some message")); - template.find(criteriaQuery, SampleEntity.class) // + template.search(criteriaQuery, SampleEntity.class) // + .map(SearchHit::getContent) // .as(StepVerifier::create) // .expectNext(sampleEntity) // .verifyComplete(); } @Test // DATAES-504 - public void findShouldReturnEmptyFluxIfNothingFound() { + public void searchShouldReturnEmptyFluxIfNothingFound() { SampleEntity sampleEntity = randomEntity("some message"); index(sampleEntity); CriteriaQuery criteriaQuery = new CriteriaQuery(Criteria.where("message").is("foo")); - template.find(criteriaQuery, SampleEntity.class) // + template.search(criteriaQuery, SampleEntity.class) // .as(StepVerifier::create) // .verifyComplete(); } @@ -352,7 +353,7 @@ public void shouldAllowStringBasedQuery() { index(randomEntity("test message"), randomEntity("test test"), randomEntity("some message")); - template.find(new StringQuery(matchAllQuery().toString()), SampleEntity.class) // + template.search(new StringQuery(matchAllQuery().toString()), SampleEntity.class) // .as(StepVerifier::create) // .expectNextCount(3) // .verifyComplete(); @@ -367,7 +368,8 @@ public void shouldExecuteGivenCriteriaQuery() { CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test")); - template.find(query, SampleEntity.class) // + template.search(query, SampleEntity.class) // + .map(SearchHit::getContent) // .as(StepVerifier::create) // .expectNext(shouldMatch) // .verifyComplete(); @@ -385,7 +387,8 @@ public void shouldReturnListForGivenCriteria() { CriteriaQuery query = new CriteriaQuery( new Criteria("message").contains("some").and("message").contains("message")); - template.find(query, SampleEntity.class) // + template.search(query, SampleEntity.class) // + .map(SearchHit::getContent) // .as(StepVerifier::create) // .expectNext(sampleEntity3) // .verifyComplete(); @@ -404,7 +407,8 @@ public void shouldReturnListUsingLocalPreferenceForGivenCriteria() { new Criteria("message").contains("some").and("message").contains("message")); queryWithValidPreference.setPreference("_local"); - template.find(queryWithValidPreference, SampleEntity.class) // + template.search(queryWithValidPreference, SampleEntity.class) // + .map(SearchHit::getContent) // .as(StepVerifier::create) // .expectNext(sampleEntity3) // .verifyComplete(); @@ -423,7 +427,7 @@ public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGiven new Criteria("message").contains("some").and("message").contains("message")); queryWithInvalidPreference.setPreference("_only_nodes:oops"); - template.find(queryWithInvalidPreference, SampleEntity.class) // + template.search(queryWithInvalidPreference, SampleEntity.class) // .as(StepVerifier::create) // .expectError(ElasticsearchStatusException.class).verify(); } @@ -440,14 +444,15 @@ public void shouldReturnProjectedTargetEntity() { CriteriaQuery query = new CriteriaQuery( new Criteria("message").contains("some").and("message").contains("message")); - template.find(query, SampleEntity.class, Message.class) // + template.search(query, SampleEntity.class, Message.class) // + .map(SearchHit::getContent) // .as(StepVerifier::create) // .expectNext(new Message(sampleEntity3.getMessage())) // .verifyComplete(); } @Test // DATAES-518 - public void findShouldApplyPagingCorrectly() { + public void searchShouldApplyPagingCorrectly() { List source = IntStream.range(0, 100).mapToObj(it -> randomEntity("entity - " + it)) .collect(Collectors.toList()); @@ -458,7 +463,7 @@ public void findShouldApplyPagingCorrectly() { .addSort(Sort.by("message"))// .setPageable(PageRequest.of(0, 20)); - template.find(query, SampleEntity.class).as(StepVerifier::create) // + template.search(query, SampleEntity.class).as(StepVerifier::create) // .expectNextCount(20) // .verifyComplete(); } @@ -475,7 +480,7 @@ public void findWithoutPagingShouldReadAll() { .addSort(Sort.by("message"))// .setPageable(Pageable.unpaged()); - template.find(query, SampleEntity.class).as(StepVerifier::create) // + template.search(query, SampleEntity.class).as(StepVerifier::create) // .expectNextCount(100) // .verifyComplete(); } @@ -682,7 +687,7 @@ public void shouldReturnDocumentWithCollapsedField() { .withPageable(PageRequest.of(0, 25)) // .build(); - template.find(query, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + template.search(query, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // .as(StepVerifier::create) // .expectNextCount(2) // .verifyComplete(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index 5bd97580b..ce95568c9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -108,12 +108,12 @@ public void insertShouldApplyRefreshPolicy() { } @Test // DATAES-504, DATAES-518 - public void findShouldFallBackToDefaultIndexOptionsIfNotSet() { + public void searchShouldFallBackToDefaultIndexOptionsIfNotSet() { ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); when(client.search(captor.capture())).thenReturn(Flux.empty()); - template.find(new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(0, 10)), SampleEntity.class) // + template.search(new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(0, 10)), SampleEntity.class) // .as(StepVerifier::create) // .verifyComplete(); @@ -121,7 +121,7 @@ public void findShouldFallBackToDefaultIndexOptionsIfNotSet() { } @Test // DATAES-504, DATAES-518 - public void findShouldApplyIndexOptionsIfSet() { + public void searchShouldApplyIndexOptionsIfSet() { ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); when(client.search(captor.capture())).thenReturn(Flux.empty()); @@ -129,7 +129,7 @@ public void findShouldApplyIndexOptionsIfSet() { template.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); Query query = new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(0, 10)); - template.find(query, SampleEntity.class, index) // + template.search(query, SampleEntity.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -137,13 +137,13 @@ public void findShouldApplyIndexOptionsIfSet() { } @Test // DATAES-504 - public void findShouldApplyPaginationIfSet() { + public void searchShouldApplyPaginationIfSet() { ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); when(client.search(captor.capture())).thenReturn(Flux.empty()); Query query = new CriteriaQuery(new Criteria("*")).setPageable(PageRequest.of(2, 50)); - template.find(query, SampleEntity.class, index) // + template.search(query, SampleEntity.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -152,12 +152,12 @@ public void findShouldApplyPaginationIfSet() { } @Test // DATAES-504, DATAES-518 - public void findShouldUseScrollIfPaginationNotSet() { + public void searchShouldUseScrollIfPaginationNotSet() { ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); when(client.scroll(captor.capture())).thenReturn(Flux.empty()); - template.find(new CriteriaQuery(new Criteria("*")).setPageable(Pageable.unpaged()), SampleEntity.class) // + template.search(new CriteriaQuery(new Criteria("*")).setPageable(Pageable.unpaged()), SampleEntity.class) // .as(StepVerifier::create) // .verifyComplete(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index dab4f30cb..3469d2d14 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -39,6 +39,8 @@ import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; @@ -139,12 +141,12 @@ public void shouldFindAuthorMarkersInRangeForGivenCriteriaQuery() { new Criteria("location").within(new GeoPoint(45.7806d, 3.0875d), "20km")); // when - List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, + SearchHits geoAuthorsForGeoCriteria = operations.search(geoLocationCriteriaQuery, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria).hasSize(1); - assertThat(geoAuthorsForGeoCriteria.get(0).getName()).isEqualTo("Franck Marchand"); + assertThat(geoAuthorsForGeoCriteria.getSearchHit(0).getContent().getName()).isEqualTo("Franck Marchand"); } @Test @@ -156,12 +158,12 @@ public void shouldFindSelectedAuthorMarkerInRangeForGivenCriteriaQuery() { new Criteria("name").is("Mohsin Husen").and("location").within(new GeoPoint(51.5171d, 0.1062d), "20km")); // when - List geoAuthorsForGeoCriteria2 = operations.queryForList(geoLocationCriteriaQuery2, + SearchHits geoAuthorsForGeoCriteria2 = operations.search(geoLocationCriteriaQuery2, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria2).hasSize(1); - assertThat(geoAuthorsForGeoCriteria2.get(0).getName()).isEqualTo("Mohsin Husen"); + assertThat(geoAuthorsForGeoCriteria2.getSearchHit(0).getContent().getName()).isEqualTo("Mohsin Husen"); } @Test @@ -172,7 +174,7 @@ public void shouldFindStringAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery( new Criteria("locationAsString").within(new GeoPoint(51.000000, 0.100000), "1km")); // when - List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, + SearchHits geoAuthorsForGeoCriteria = operations.search(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -188,7 +190,7 @@ public void shouldFindDoubleAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { new Criteria("locationAsArray").within(new GeoPoint(51.001000, 0.10100), "1km")); // when - List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, + SearchHits geoAuthorsForGeoCriteria = operations.search(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -203,7 +205,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQuery() { CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery( new Criteria("locationAsArray").within("51.001000, 0.10100", "1km")); // when - List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, + SearchHits geoAuthorsForGeoCriteria = operations.search(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -218,7 +220,7 @@ public void shouldFindAnnotatedGeoMarkersInRangeForGivenCriteriaQueryUsingGeohas CriteriaQuery geoLocationCriteriaQuery = new CriteriaQuery(new Criteria("locationAsArray").within("u1044", "3km")); // when - List geoAuthorsForGeoCriteria = operations.queryForList(geoLocationCriteriaQuery, + SearchHits geoAuthorsForGeoCriteria = operations.search(geoLocationCriteriaQuery, LocationMarkerEntity.class, locationMarkerIndex); // then @@ -234,7 +236,7 @@ public void shouldFindAllMarkersForNativeSearchQuery() { .withFilter(QueryBuilders.geoBoundingBoxQuery("locationAsArray").setCorners(52, -1, 50, 1)); // when - List geoAuthorsForGeoCriteria = operations.queryForList(queryBuilder.build(), + SearchHits geoAuthorsForGeoCriteria = operations.search(queryBuilder.build(), LocationMarkerEntity.class, locationMarkerIndex); // then @@ -250,12 +252,12 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoBox() { new Criteria("location").boundedBy(new GeoBox(new GeoPoint(53.5171d, 0), new GeoPoint(49.5171d, 0.2062d)))); // when - List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, + SearchHits geoAuthorsForGeoCriteria3 = operations.search(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); - assertThat(geoAuthorsForGeoCriteria3.stream().map(AuthorMarkerEntity::getName)) + assertThat(geoAuthorsForGeoCriteria3.stream().map(SearchHit::getContent).map(AuthorMarkerEntity::getName)) .containsExactlyInAnyOrder("Mohsin Husen", "Rizwan Idrees"); } @@ -268,12 +270,12 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeohash() { new Criteria("location").boundedBy(Geohash.stringEncode(0, 53.5171d), Geohash.stringEncode(0.2062d, 49.5171d))); // when - List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, + SearchHits geoAuthorsForGeoCriteria3 = operations.search(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); - assertThat(geoAuthorsForGeoCriteria3.stream().map(AuthorMarkerEntity::getName)) + assertThat(geoAuthorsForGeoCriteria3.stream().map(SearchHit::getContent).map(AuthorMarkerEntity::getName)) .containsExactlyInAnyOrder("Mohsin Husen", "Rizwan Idrees"); } @@ -286,12 +288,12 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingGeoPoints() { new Criteria("location").boundedBy(new GeoPoint(53.5171d, 0), new GeoPoint(49.5171d, 0.2062d))); // when - List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, + SearchHits geoAuthorsForGeoCriteria3 = operations.search(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); - assertThat(geoAuthorsForGeoCriteria3.stream().map(AuthorMarkerEntity::getName)) + assertThat(geoAuthorsForGeoCriteria3.stream().map(SearchHit::getContent).map(AuthorMarkerEntity::getName)) .containsExactlyInAnyOrder("Mohsin Husen", "Rizwan Idrees"); } @@ -304,12 +306,12 @@ public void shouldFindAuthorMarkersInBoxForGivenCriteriaQueryUsingPoints() { new Criteria("location").boundedBy(new Point(53.5171d, 0), new Point(49.5171d, 0.2062d))); // when - List geoAuthorsForGeoCriteria3 = operations.queryForList(geoLocationCriteriaQuery3, + SearchHits geoAuthorsForGeoCriteria3 = operations.search(geoLocationCriteriaQuery3, AuthorMarkerEntity.class, authorMarkerIndex); // then assertThat(geoAuthorsForGeoCriteria3).hasSize(2); - assertThat(geoAuthorsForGeoCriteria3.stream().map(AuthorMarkerEntity::getName)) + assertThat(geoAuthorsForGeoCriteria3.stream().map(SearchHit::getContent).map(AuthorMarkerEntity::getName)) .containsExactlyInAnyOrder("Mohsin Husen", "Rizwan Idrees"); } @@ -332,17 +334,17 @@ public void shouldFindLocationWithGeoHashPrefix() { .withFilter(QueryBuilders.geoBoundingBoxQuery("locationAsGeoHash").setCorners("u10j46mkfek")); // when - List result1 = operations.queryForList(location1.build(), LocationMarkerEntity.class, + SearchHits result1 = operations.search(location1.build(), LocationMarkerEntity.class, locationMarkerIndex); - List result2 = operations.queryForList(location2.build(), LocationMarkerEntity.class, + SearchHits result2 = operations.search(location2.build(), LocationMarkerEntity.class, locationMarkerIndex); - List result3 = operations.queryForList(location3.build(), LocationMarkerEntity.class, + SearchHits result3 = operations.search(location3.build(), LocationMarkerEntity.class, locationMarkerIndex); - List result4 = operations.queryForList(location4.build(), LocationMarkerEntity.class, + SearchHits result4 = operations.search(location4.build(), LocationMarkerEntity.class, locationMarkerIndex); - List result5 = operations.queryForList(location5.build(), LocationMarkerEntity.class, + SearchHits result5 = operations.search(location5.build(), LocationMarkerEntity.class, locationMarkerIndex); - List result11 = operations.queryForList(location11.build(), LocationMarkerEntity.class, + SearchHits result11 = operations.search(location11.build(), LocationMarkerEntity.class, locationMarkerIndex); // then diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 33de2b84f..6cc8d75d1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -51,9 +51,11 @@ import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -80,28 +82,31 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class MappingBuilderTests extends MappingContextBaseTests { - @Autowired private ElasticsearchOperations elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - elasticsearchTemplate.deleteIndex(StockPrice.class); - elasticsearchTemplate.deleteIndex(SimpleRecursiveEntity.class); - elasticsearchTemplate.deleteIndex(StockPrice.class); - elasticsearchTemplate.deleteIndex(SampleInheritedEntity.class); - elasticsearchTemplate.deleteIndex(User.class); - elasticsearchTemplate.deleteIndex(Group.class); - elasticsearchTemplate.deleteIndex(Book.class); - elasticsearchTemplate.deleteIndex(NormalizerEntity.class); - elasticsearchTemplate.deleteIndex(CopyToEntity.class); + indexOperations = operations.getIndexOperations(); + + indexOperations.deleteIndex(StockPrice.class); + indexOperations.deleteIndex(SimpleRecursiveEntity.class); + indexOperations.deleteIndex(StockPrice.class); + indexOperations.deleteIndex(SampleInheritedEntity.class); + indexOperations.deleteIndex(User.class); + indexOperations.deleteIndex(Group.class); + indexOperations.deleteIndex(Book.class); + indexOperations.deleteIndex(NormalizerEntity.class); + indexOperations.deleteIndex(CopyToEntity.class); } @Test public void shouldNotFailOnCircularReference() { - elasticsearchTemplate.createIndex(SimpleRecursiveEntity.class); - elasticsearchTemplate.putMapping(SimpleRecursiveEntity.class); - elasticsearchTemplate.refresh(SimpleRecursiveEntity.class); + indexOperations.createIndex(SimpleRecursiveEntity.class); + indexOperations.putMapping(SimpleRecursiveEntity.class); + indexOperations.refresh(SimpleRecursiveEntity.class); } @Test // DATAES-568 @@ -134,26 +139,26 @@ public void shouldAddStockPriceDocumentToIndex() { // Given // When - elasticsearchTemplate.createIndex(StockPrice.class); - elasticsearchTemplate.putMapping(StockPrice.class); + indexOperations.createIndex(StockPrice.class); + indexOperations.putMapping(StockPrice.class); String symbol = "AU"; double price = 2.34; String id = "abc"; - IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes( "price"); - elasticsearchTemplate.index(buildIndex(StockPrice.builder() // + IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes("price"); + operations.index(buildIndex(StockPrice.builder() // .id(id) // .symbol(symbol) // .price(BigDecimal.valueOf(price)) // .build()), index); - elasticsearchTemplate.refresh(StockPrice.class); + indexOperations.refresh(StockPrice.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - List result = elasticsearchTemplate.queryForList(searchQuery, StockPrice.class, index); + SearchHits result = operations.search(searchQuery, StockPrice.class, index); // Then assertThat(result).hasSize(1); - StockPrice entry = result.get(0); + StockPrice entry = result.getSearchHit(0).getContent(); assertThat(entry.getSymbol()).isEqualTo(symbol); assertThat(entry.getPrice()).isCloseTo(BigDecimal.valueOf(price), Percentage.withPercentage(0.01)); } @@ -186,24 +191,23 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() { // given // when - elasticsearchTemplate.createIndex(SampleInheritedEntity.class); - elasticsearchTemplate.putMapping(SampleInheritedEntity.class); + indexOperations.createIndex(SampleInheritedEntity.class); + indexOperations.putMapping(SampleInheritedEntity.class); Date createdDate = new Date(); String message = "msg"; String id = "abc"; - IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes( "mapping"); - elasticsearchTemplate.index( - new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(), + IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes("mapping"); + operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(), index); - elasticsearchTemplate.refresh(SampleInheritedEntity.class); + operations.refresh(SampleInheritedEntity.class); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - List result = elasticsearchTemplate.queryForList(searchQuery, SampleInheritedEntity.class, index); + SearchHits result = operations.search(searchQuery, SampleInheritedEntity.class, index); // then assertThat(result).hasSize(1); - SampleInheritedEntity entry = result.get(0); + SampleInheritedEntity entry = result.getSearchHit(0).getContent(); assertThat(entry.getCreatedDate()).isEqualTo(createdDate); assertThat(entry.getMessage()).isEqualTo(message); } @@ -228,10 +232,10 @@ public void shouldBuildMappingsForGeoPoint() throws IOException, JSONException { public void shouldHandleReverseRelationship() { // given - elasticsearchTemplate.createIndex(User.class); - elasticsearchTemplate.putMapping(User.class); - elasticsearchTemplate.createIndex(Group.class); - elasticsearchTemplate.putMapping(Group.class); + indexOperations.createIndex(User.class); + indexOperations.putMapping(User.class); + indexOperations.createIndex(Group.class); + indexOperations.putMapping(Group.class); // when @@ -242,8 +246,8 @@ public void shouldHandleReverseRelationship() { public void shouldMapBooks() { // given - elasticsearchTemplate.createIndex(Book.class); - elasticsearchTemplate.putMapping(Book.class); + indexOperations.createIndex(Book.class); + indexOperations.putMapping(Book.class); // when @@ -254,11 +258,11 @@ public void shouldMapBooks() { public void shouldUseBothAnalyzer() { // given - elasticsearchTemplate.createIndex(Book.class); - elasticsearchTemplate.putMapping(Book.class); + indexOperations.createIndex(Book.class); + indexOperations.putMapping(Book.class); // when - Map mapping = elasticsearchTemplate.getMapping(Book.class); + Map mapping = operations.getMapping(Book.class); Map descriptionMapping = (Map) ((Map) mapping.get("properties")).get("description"); Map prefixDescription = (Map) ((Map) descriptionMapping.get("fields")).get("prefix"); @@ -275,11 +279,11 @@ public void shouldUseBothAnalyzer() { public void shouldUseKeywordNormalizer() { // given - elasticsearchTemplate.createIndex(NormalizerEntity.class); - elasticsearchTemplate.putMapping(NormalizerEntity.class); + operations.createIndex(NormalizerEntity.class); + operations.putMapping(NormalizerEntity.class); // when - Map mapping = elasticsearchTemplate.getMapping(NormalizerEntity.class); + Map mapping = operations.getMapping(NormalizerEntity.class); Map properties = (Map) mapping.get("properties"); Map fieldName = (Map) properties.get("name"); Map fieldDescriptionLowerCase = (Map) ((Map) ((Map) properties.get("description")).get("fields")).get("lower_case"); @@ -295,11 +299,11 @@ public void shouldUseKeywordNormalizer() { public void shouldUseCopyTo() { // given - elasticsearchTemplate.createIndex(CopyToEntity.class); - elasticsearchTemplate.putMapping(CopyToEntity.class); + operations.createIndex(CopyToEntity.class); + operations.putMapping(CopyToEntity.class); // when - Map mapping = elasticsearchTemplate.getMapping(CopyToEntity.class); + Map mapping = operations.getMapping(CopyToEntity.class); Map properties = (Map) mapping.get("properties"); Map fieldFirstName = (Map) properties.get("firstName"); Map fieldLastName = (Map) properties.get("lastName"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 83643152b..ade03dcb9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -42,6 +42,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -93,7 +94,7 @@ public void shouldPerformAndOperation() { new Criteria("message").contains("test").and("message").contains("some")); // when - SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity1 = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); @@ -136,7 +137,7 @@ public void shouldPerformOrOperation() { new Criteria("message").contains("some").or("message").contains("test")); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -167,7 +168,7 @@ public void shouldPerformAndOperationWithinCriteria() { // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -198,7 +199,7 @@ public void shouldPerformOrOperationWithinCriteria() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -227,7 +228,7 @@ public void shouldPerformIsOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -269,7 +270,7 @@ public void shouldPerformMultipleIsOperations() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -312,7 +313,7 @@ public void shouldPerformEndsWithOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -354,7 +355,7 @@ public void shouldPerformStartsWithOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -395,7 +396,7 @@ public void shouldPerformContainsOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -436,7 +437,7 @@ public void shouldExecuteExpression() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -478,7 +479,7 @@ public void shouldExecuteCriteriaChain() { new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); @@ -519,12 +520,12 @@ public void shouldPerformIsNotOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().isNegating()).isTrue(); assertThat(page).isNotNull(); - assertThat(page.iterator().next().getMessage()).doesNotContain("foo"); + assertThat(page.iterator().next().getContent().getMessage()).doesNotContain("foo"); } @Test @@ -563,7 +564,7 @@ public void shouldPerformBetweenOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); // when - SampleEntity sampleEntity = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity).isNotNull(); @@ -605,7 +606,7 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -648,7 +649,7 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -691,7 +692,7 @@ public void shouldPerformLessThanEqualOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -734,7 +735,7 @@ public void shouldPerformGreaterThanEquals() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page).isNotNull(); @@ -777,7 +778,7 @@ public void shouldPerformBoostOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); @@ -800,11 +801,11 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("a").or(new Criteria("message").contains("b"))); criteriaQuery.setMinScore(2.0F); - Page page = operations.queryForPage(criteriaQuery, SampleEntity.class, index); + Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); // then assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getMessage()).isEqualTo("ab"); + assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("ab"); } @Test // DATAES-213 @@ -826,7 +827,7 @@ public void shouldEscapeValue() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); // when - SampleEntity sampleEntity1 = operations.queryForObject(criteriaQuery, SampleEntity.class, index); + SearchHit sampleEntity1 = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then assertThat(sampleEntity1).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 7374bfcf2..da38a6e57 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -1333,6 +1333,20 @@ public void streamMethodsCanHandlePageable() { assertThat(stream.count()).isEqualTo(10L); } + @Test // DATAES-672 + void streamMethodShouldNotReturnSearchHits() { + // given + List entities = createSampleEntities("abc", 2); + repository.saveAll(entities); + + // when + Stream stream = streamingRepository.findByType("abc"); + + // then + assertThat(stream).isNotNull(); + stream.forEach(o -> assertThat(o).isInstanceOf(SampleEntity.class)); + } + private List createSampleEntities(String type, int numberOfEntities) { List entities = new ArrayList<>(); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 5bb26bd00..1b9d9e26b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -17,7 +17,6 @@ import static org.assertj.core.api.Assertions.*; -import java.util.List; import java.util.Map; import org.apache.commons.lang.RandomStringUtils; @@ -32,6 +31,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -109,13 +109,14 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping") .withTypes("test-setting-type"); long count = operations.count(searchQuery, DynamicSettingAndMappingEntity.class, index); - List entityList = operations.queryForList(searchQuery, + SearchHits entityList = operations.search(searchQuery, DynamicSettingAndMappingEntity.class, index); // then assertThat(count).isEqualTo(1L); assertThat(entityList).isNotNull().hasSize(1); - assertThat(entityList.get(0).getEmail()).isEqualTo(dynamicSettingAndMappingEntity1.getEmail()); + assertThat(entityList.getSearchHit(0).getContent().getEmail()) + .isEqualTo(dynamicSettingAndMappingEntity1.getEmail()); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 469341a8b..54a2db4bf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -19,8 +19,6 @@ import lombok.Data; -import java.util.List; - import org.elasticsearch.index.query.QueryBuilders; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -32,6 +30,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -77,12 +76,11 @@ public void shouldDo() { repository.save(entry1); repository.save(entry2); - // when - + // whe // then assertThat(repository.count()).isEqualTo(2L); - List synonymEntities = operations.queryForList( + SearchHits synonymEntities = operations.search( new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("text", "british")).build(), SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes("synonym-type")); assertThat(synonymEntities).hasSize(1); From d19e699b326e04845a6627191093a2f2ca673806 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 22 Dec 2019 14:25:43 +0100 Subject: [PATCH 0020/1191] DATAES-714 - Sort results should be returned in the SearchHits. Original PR: #361 --- .../data/elasticsearch/core/SearchHit.java | 23 ++++++--- .../MappingElasticsearchConverter.java | 3 +- .../core/document/DocumentAdapters.java | 17 +++++-- .../core/document/SearchDocument.java | 11 +++++ .../core/ElasticsearchTemplateTests.java | 49 +++++++++++++++++++ .../ReactiveElasticsearchTemplateTests.java | 23 +++++++++ 6 files changed, 116 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index b84b5843f..a4188bf0c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -15,6 +15,11 @@ */ package org.springframework.data.elasticsearch.core; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import org.springframework.lang.Nullable; /** @@ -28,11 +33,13 @@ public class SearchHit { private final String id; private final float score; + private final List sortValues; private final T content; - public SearchHit(@Nullable String id, float score, T content) { + public SearchHit(@Nullable String id, float score, Object[] sortValues, T content) { this.id = id; this.score = score; + this.sortValues = (sortValues != null) ? Arrays.asList(sortValues) : new ArrayList<>(); this.content = content; } @@ -55,12 +62,16 @@ public T getContent() { return content; } + /** + * @return the sort values if the query had a sort criterion. + */ + public List getSortValues() { + return Collections.unmodifiableList(sortValues); + } + @Override public String toString() { - return "SearchHit{" + - "id='" + id + '\'' + - ", score=" + score + - ", content=" + content + - '}'; + return "SearchHit{" + "id='" + id + '\'' + ", score=" + score + ", sortValues=" + sortValues + ", content=" + + content + '}'; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 180034ba0..d209077dc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -601,9 +601,10 @@ public T mapDocument(@Nullable Document document, Class type) { public SearchHit read(Class type, SearchDocument searchDocument) { String id = searchDocument.hasId() ? searchDocument.getId() : null; float score = searchDocument.getScore(); + Object[] sortValues = searchDocument.getSortValues(); T content = mapDocument(searchDocument, type); - return new SearchHit(id, score, content); + return new SearchHit(id, score, sortValues, content); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index bb2799c7b..28dd733d9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -142,7 +142,7 @@ public static SearchDocument from(SearchHit source) { BytesReference sourceRef = source.getSourceRef(); if (sourceRef == null || sourceRef.length() == 0) { - return new SearchDocumentAdapter(source.getScore(), source.getFields(), + return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), fromDocumentFields(source, source.getId(), source.getVersion())); } @@ -153,7 +153,7 @@ public static SearchDocument from(SearchHit source) { document.setVersion(source.getVersion()); } - return new SearchDocumentAdapter(source.getScore(), source.getFields(), document); + return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), document); } /** @@ -438,11 +438,13 @@ private static Object getValue(DocumentField documentField) { static class SearchDocumentAdapter implements SearchDocument { private final float score; + private final Object[] sortValues; private final Map> fields = new HashMap<>(); private final Document delegate; - SearchDocumentAdapter(float score, Map fields, Document delegate) { + SearchDocumentAdapter(float score, Object[] sortValues, Map fields, Document delegate) { this.score = score; + this.sortValues = sortValues; this.delegate = delegate; fields.forEach((name, documentField) -> this.fields.put(name, documentField.getValues())); } @@ -476,6 +478,15 @@ public Map> getFields() { return fields; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getSortValues() + */ + @Override + public Object[] getSortValues() { + return sortValues; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.document.Document#hasId() diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java index 8195015af..ec66da0a2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java @@ -18,6 +18,8 @@ import java.util.List; import java.util.Map; +import org.springframework.lang.Nullable; + /** * Extension to {@link Document} exposing a search response related data. * @@ -45,6 +47,7 @@ public interface SearchDocument extends Document { * * @param name the field name */ + @Nullable default V getFieldValue(final String name) { List values = getFields().get(name); if (values == null || values.isEmpty()) { @@ -52,4 +55,12 @@ default V getFieldValue(final String name) { } return (V) values.get(0); } + + /** + * @return the sort values for the search hit + */ + @Nullable + default Object[] getSortValues() { + return null; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 437808c91..aab98f596 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -128,6 +128,9 @@ public void before() { indexOperations.createIndex(SampleEntityUUIDKeyed.class); indexOperations.putMapping(SampleEntityUUIDKeyed.class); + + indexOperations.createIndex(SearchHitsEntity.class); + indexOperations.putMapping(SearchHitsEntity.class); } @AfterEach @@ -146,6 +149,7 @@ private void deleteIndices() { indexOperations.deleteIndex(INDEX_1_NAME); indexOperations.deleteIndex(INDEX_2_NAME); indexOperations.deleteIndex(INDEX_3_NAME); + indexOperations.deleteIndex(SearchHitsEntity.class); } @Test // DATAES-106 @@ -2856,6 +2860,41 @@ public void shouldIncludeDefaultsOnGetIndexSettings() { assertThat(map).containsKey("index.max_result_window"); } + @Test // DATAES-714 + void shouldReturnSortFieldsInSearchHits() { + IndexCoordinates index = IndexCoordinates.of("test-index-searchhits-entity-template"); + SearchHitsEntity entity = SearchHitsEntity.builder().id("1").number(1000L).keyword("thousands").build(); + IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build(); + operations.index(indexQuery, index); + indexOperations.refresh(index); + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withQuery(matchAllQuery()) // + .withSort(new FieldSortBuilder("keyword").order(SortOrder.ASC)) + .withSort(new FieldSortBuilder("number").order(SortOrder.DESC)).build(); + + SearchHits searchHits = operations.search(query, SearchHitsEntity.class, index); + + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getSearchHits()).hasSize(1); + + SearchHit searchHit = searchHits.getSearchHit(0); + List sortValues = searchHit.getSortValues(); + assertThat(sortValues).hasSize(2); + assertThat(sortValues.get(0)).isInstanceOf(String.class).isEqualTo("thousands"); + // transport client returns Long, rest client Integer + java.lang.Object o = sortValues.get(1); + if (o instanceof Integer) { + Integer i = (Integer) o; + assertThat(o).isInstanceOf(Integer.class).isEqualTo(1000); + } else if (o instanceof Long) { + Long l = (Long) o; + assertThat(o).isInstanceOf(Long.class).isEqualTo(1000L); + } else { + fail("unexpected object type " + o); + } + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @@ -3007,4 +3046,14 @@ public void setSomeField(String someField) { } } + @Data + @AllArgsConstructor + @Builder + @Document(indexName = "test-index-searchhits-entity-template") + static class SearchHitsEntity { + @Id private String id; + @Field(type = FieldType.Long) Long number; + @Field(type = FieldType.Keyword) String keyword; + } + } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 41c04d0d3..d85e25e4b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -40,6 +40,8 @@ import java.util.stream.IntStream; import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.search.sort.FieldSortBuilder; +import org.elasticsearch.search.sort.SortOrder; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -693,6 +695,27 @@ public void shouldReturnDocumentWithCollapsedField() { .verifyComplete(); } + @Test + void shouldReturnSortFields() { + SampleEntity entity = randomEntity("test message"); + entity.rate = 42; + index(entity); + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withQuery(matchAllQuery()) // + .withSort(new FieldSortBuilder("rate").order(SortOrder.DESC)) // + .build(); + + template.search(query, SampleEntity.class) // + .as(StepVerifier::create) // + .consumeNextWith(it -> { + List sortValues = it.getSortValues(); + assertThat(sortValues).hasSize(1); + assertThat(sortValues.get(0)).isEqualTo(42); + }) // + .verifyComplete(); + } + @Data @Document(indexName = "marvel", type = "characters") static class Person { From 6dfeee3ba953ce6465ed974c968d639d507056e4 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 24 Dec 2019 09:23:23 +0100 Subject: [PATCH 0021/1191] DATAES-676 - Fix documentation to reflect the changes in API restructuring. Original PR: #362 --- README.adoc | 75 +++++++++-------- src/main/asciidoc/preface.adoc | 13 +-- .../reference/elasticsearch-clients.adoc | 82 ++++++++++--------- .../reference/elasticsearch-misc.adoc | 23 ++++-- .../asciidoc/reference/elasticsearch-new.adoc | 12 +++ .../elasticsearch-object-mapping.adoc | 71 +++------------- .../reference/elasticsearch-operations.adoc | 61 ++++++++------ .../core/ElasticsearchOperations.java | 4 +- 8 files changed, 161 insertions(+), 180 deletions(-) diff --git a/README.adoc b/README.adoc index ad4814fa7..8a6ccee65 100644 --- a/README.adoc +++ b/README.adoc @@ -13,8 +13,8 @@ This project is lead and maintained by the community. * Spring configuration support using Java based `@Configuration` classes or an XML namespace for a ES clients instances. * `ElasticsearchRestTemplate` helper class that increases productivity performing common ES operations. Includes integrated object mapping between documents and POJOs. * Feature Rich Object Mapping integrated with Spring’s Conversion Service -* Annotation based mapping metadata but extensible to support other metadata formats -* Automatic implementation of `Repository` interfaces including support for custom finder methods. +* Annotation based mapping metadata +* Automatic implementation of `Repository` interfaces including support for custom search methods. * CDI support for repositories == Code of Conduct @@ -53,57 +53,56 @@ public class MyService { repository.save(person); List lastNameResults = repository.findByLastname("Gierke"); - List firstNameResults = repository.findByFirstnameLike("Oli*"); + List firstNameResults = repository.findByFirstnameLike("Oli"); } } ---- -Using Node Client +=== Using Transport Client -NOTE: Usage of the Node Client is deprecated as of version 4.0, use RestClient instead. +NOTE: Usage of the TransportClient is deprecated as of version 4.0, use RestClient instead. -[source,xml] +[source,java] ---- - - - - - - - - - - +@Configuration +public class TransportClientConfig extends ElasticsearchConfigurationSupport { + + @Bean + public Client elasticsearchClient() throws UnknownHostException { + Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build(); + TransportClient client = new PreBuiltTransportClient(settings); + client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); + return client; + } + + @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) + public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException { + return new ElasticsearchTemplate(elasticsearchClient()); + } +} ---- -Using Transport Client +=== Using the RestClient -NOTE: Usage of the Transport Client is deprecated as of version 4.0, use RestClient instead. +Provide a configuration like this: - -[source,xml] +[source,java] ---- - - +@Configuration +public class RestClientConfig extends AbstractElasticsearchConfiguration { - + @Override + @Bean + public RestHighLevelClient elasticsearchClient() { - + final ClientConfiguration clientConfiguration = ClientConfiguration.builder() + .connectedTo("localhost:9200") + .build(); - - - - - + return RestClients.create(clientConfiguration).rest(); + } +} ---- === Maven configuration @@ -196,7 +195,7 @@ You also need JDK 1.8. If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.5.0 or above]. -_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please sign the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before your first non-trivial change._ +_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please sign the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before submitting your first pull request._ === Building reference documentation diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 68260801b..1cec65a97 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -3,7 +3,7 @@ The Spring Data Elasticsearch project applies core Spring concepts to the development of solutions using the Elasticsearch Search Engine. It provides: -* _Templates_ as a high-level abstraction for storing, querying, sorting and faceting documents. +* _Templates_ as a high-level abstraction for storing, searching, sorting documents and building aggregations. * _Repositories_ which for example enable the user to express queries by defining interfaces having customized method names (for basic information about repositories see <>). You will notice similarities to the Spring data solr and mongodb support in the Spring Framework. @@ -34,11 +34,12 @@ Requires an installation of https://www.elastic.co/products/elasticsearch[Elasti The following table shows the Elasticsearch versions that are used by Spring Data release trains and version of Spring Data Elasticsearch included in that, as well as the Spring Boot versions refering to that particular Spring Data release train: [cols="^,^,^,^",options="header"] |=== -|Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -|Moorefootnote:cdv[Currently in development] |3.2.xfootnote:cdv[]|6.8.1 |2.2.0footnote:cdv[] -|Lovelace |3.1.x |6.2.2|2.1.x -|Kayfootnote:oom[Out of maintenance]|3.0.xfootnote:oom[] |5.5.0 |2.0.xfootnote:oom[] -|Ingallsfootnote:oom[]|2.1.xfootnote:oom[] |2.4.0 |1.5.xfootnote:oom[] +| Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot +| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.4.1 |2.3.xfootnote:cdv[] +| Moore | 3.2.x |6.8.4 | 2.2.x +| Lovelace | 3.1.x | 6.2.2 |2.1.x +| Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] +| Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] |=== Support for upcoming versions of Elasticsearch is being tracked and general compatibility should be given assuming the usage of the <>. diff --git a/src/main/asciidoc/reference/elasticsearch-clients.adoc b/src/main/asciidoc/reference/elasticsearch-clients.adoc index 1d1b8d813..1afe45f1c 100644 --- a/src/main/asciidoc/reference/elasticsearch-clients.adoc +++ b/src/main/asciidoc/reference/elasticsearch-clients.adoc @@ -3,13 +3,13 @@ This chapter illustrates configuration and usage of supported Elasticsearch client implementations. -Spring data Elasticsearch operates upon an Elasticsearch client that is connected to a single Elasticsearch node or a cluster. Although the Elasticsearch Client can be used to work with the cluster, applications using Spring Data Elasticsearch normally use the higher level abstractions of <> and <>. +Spring Data Elasticsearch operates upon an Elasticsearch client that is connected to a single Elasticsearch node or a cluster. Although the Elasticsearch Client can be used to work with the cluster, applications using Spring Data Elasticsearch normally use the higher level abstractions of <> and <>. [[elasticsearch.clients.transport]] == Transport Client WARNING: The well known `TransportClient` is deprecated as of Elasticsearch 7 and will be removed in Elasticsearch 8. (https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/transport-client.html[see the Elasticsearch documentation]). Spring Data Elasticsearch will support the `TransportClient` as long as it is available in the used -Elasticsearch <>. +Elasticsearch <> but has deprecated the classes using it since version 4.0. We strongly recommend to use the <> instead of the `TransportClient`. @@ -17,18 +17,21 @@ We strongly recommend to use the <> instead of the ` ==== [source,java] ---- -static class Config { - - @Bean - Client client() { - Settings settings = Settings.builder() - .put("cluster.name", "elasticsearch") <1> - .build(); - TransportClient client = new PreBuiltTransportClient(settings); - client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1") - , 9300)); <2> - return client; - } +@Configuration +public class TransportClientConfig extends ElasticsearchConfigurationSupport { + + @Bean + public Client elasticsearchClient() throws UnknownHostException { + Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build(); <1> + TransportClient client = new PreBuiltTransportClient(settings); + client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300)); <2> + return client; + } + + @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) + public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException { + return new ElasticsearchTemplate(elasticsearchClient()); + } } // ... @@ -46,7 +49,7 @@ IndexResponse response = client.index(request); [[elasticsearch.clients.rest]] == High Level REST Client -The Java High Level REST Client now is the default client of Elasticsearch, it provides a straight forward replacement for the `TransportClient` as it accepts and returns +The Java High Level REST Client is the default client of Elasticsearch, it provides a straight forward replacement for the `TransportClient` as it accepts and returns the very same request/response objects and therefore depends on the Elasticsearch core project. Asynchronous calls are operated upon a client managed thread pool and require a callback to be notified when the request is done. @@ -54,18 +57,19 @@ Asynchronous calls are operated upon a client managed thread pool and require a ==== [source,java] ---- -import org.springframework.beans.factory.annotation.Autowired;@Configuration -static class Config { +@Configuration +public class RestClientConfig extends AbstractElasticsearchConfiguration { - @Bean - RestHighLevelClient client() { + @Override + @Bean + public RestHighLevelClient elasticsearchClient() { - ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1> - .connectedTo("localhost:9200", "localhost:9201") - .build(); + final ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1> + .connectedTo("localhost:9200") + .build(); - return RestClients.create(clientConfiguration).rest(); <2> - } + return RestClients.create(clientConfiguration).rest(); <2> + } } // ... @@ -73,7 +77,7 @@ static class Config { @Autowired RestHighLevelClient highLevelClient; - RestClient lowLevelClient = highLevelClient.lowLevelClient(); <3> + RestClient lowLevelClient = highLevelClient.lowLevelClient(); <3> // ... @@ -138,27 +142,31 @@ Client behaviour can be changed via the `ClientConfiguration` that allows to set [source,java] ---- // optional if Basic Auhtentication is needed -HttpHeaders defaultHeaders = new HttpHeaders(); -defaultHeaders.setBasicAuth(USER_NAME, USER_PASS); <1> +HttpHeaders httpHeaders = new HttpHeaders(); +httpHeaders.add("es-security-runas-user", "some-user") <1> ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200", "localhost:9291") <2> - .withConnectTimeout(Duration.ofSeconds(5)) <3> - .withSocketTimeout(Duration.ofSeconds(3)) <4> - .useSsl() <5> - .withDefaultHeaders(defaultHeaders) <6> - .withBasicAuth(username, password) <7> + .withProxy("localhost:8888") <3> + .withPathPrefix("ela") <4> + .withConnectTimeout(Duration.ofSeconds(5)) <5> + .withSocketTimeout(Duration.ofSeconds(3)) <6> + .useSsl() <7> + .withDefaultHeaders(defaultHeaders) <8> + .withBasicAuth(username, password) <9> . // ... other options .build(); ---- <1> Define default headers, if they need to be customized <2> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL. -<3> Set the connection timeout. Default is 10 sec. -<4> Set the socket timeout. Default is 5 sec. -<5> Optionally enable SSL. -<6> Optionally set headers. -<7> Add basic authentication. +<3> Optionally set a proxy footnote:notreactive[not yet implemented for the reactive client]. +<4> Optionally set a path prefix, mostly used when different clusters a behind some reverse proxy. +<5> Set the connection timeout. Default is 10 sec. +<6> Set the socket timeout. Default is 5 sec. +<7> Optionally enable SSL. +<8> Optionally set headers. +<9> Add basic authentication. ==== [[elasticsearch.clients.logging]] diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index 2f0c48e4d..d35522f75 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -11,27 +11,30 @@ Filter Builder improves query speed. ==== [source,java] ---- -private ElasticsearchTemplate elasticsearchTemplate; +private ElasticsearchOperations operations; + +IndexCoordinates index = IndexCoordinates.of("sample-index"); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withFilter(boolFilter().must(termFilter("id", documentId))) .build(); -Page sampleEntities = - elasticsearchTemplate.queryForPage(searchQuery,SampleEntity.class); +Page sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); ---- ==== [[elasticsearch.scroll]] == Using Scroll For Big Result Set -Elasticsearch has a scroll API for getting big result set in chunks. `ElasticsearchTemplate` has startScroll and continueScroll methods that can be used as below. +Elasticsearch has a scroll API for getting big result set in chunks. `ElasticsearchOperations` has startScroll and continueScroll methods that can be used as below. .Using startScroll and continueScroll ==== [source,java] ---- +IndexCoordinates index = IndexCoordinates.of("sample-index"); + SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withIndices(INDEX_NAME) @@ -40,25 +43,27 @@ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withPageable(PageRequest.of(0, 10)) .build(); -ScrolledPage scroll = elasticsearchTemplate.startScroll(1000, searchQuery, SampleEntity.class); +ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = elasticsearchTemplate.continueScroll(scrollId, 1000, SampleEntity.class); + scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); } -elasticsearchTemplate.clearScroll(scrollId); +operations.clearScroll(scrollId); ---- ==== -`ElasticsearchTemplate` additionally has the stream method which wraps the scan and scroll operations into a CloseableIterator. +`ElasticsearchOperations` additionally has the stream method which wraps the scan and scroll operations into a CloseableIterator. .Using stream ==== [source,java] ---- +IndexCoordinates index = IndexCoordinates.of("sample-index"); + SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withIndices(INDEX_NAME) @@ -67,7 +72,7 @@ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withPageable(PageRequest.of(0, 10)) .build(); -CloseableIterator stream = elasticsearchTemplate.stream(searchQuery, SampleEntity.class); +CloseableIterator stream = elasticsearchTemplate.stream(searchQuery, SampleEntity.class, index); List sampleEntities = new ArrayList<>(); while (stream.hasNext()) { diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 26dc34d5d..fc8449a08 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -1,6 +1,18 @@ [[new-features]] = What's new +[[new-features.4-0-0]] +== New in Spring Data Elasticsearch 4.0 + +* Uses Spring 5.2. +* Upgrade to Elasticsearch 7.4.1. +* Deprecation of `TransportClient` usage. +* Implements most of the mapping-types available for the index mappings. +* Removal of the Jackson `ObjectMapper`, now using the <> +* Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules. +* Introduction of `SearchHit` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_). +* Introduction of the `SearchHits` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_). + [[new-features.3-2-0]] == New in Spring Data Elasticsearch 3.2 diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index 07c619c5d..8ca8ba16a 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -1,36 +1,15 @@ [[elasticsearch.mapping]] = Elasticsearch Object Mapping -Spring Data Elasticsearch allows to choose between two mapping implementations abstracted via the `EntityMapper` interface: +Spring Data Elasticsearch Object Mapping is the process that maps a Java object - the domain entity - into the JSON representation that is stored in Elasticsearch and back. -* <> -* <> +Earlier versions of Spring Data Elasticsearch used a Jackson based conversion, Spring Data Elasticsearch 3.2.x introduced the <>. As of version 4.0 only the Meta Object Mapping is used, the Jackson based mapper is not available anymore. -[[elasticsearch.mapping.jackson2]] -== Jackson Object Mapping +The main reasons for the removal of the Jackson based mapper are: -The Jackson2 based approach (used by default) utilizes a customized `ObjectMapper` instance with spring data specific modules. -Extensions to the actual mapping need to be customized via Jackson annotations like `@JsonInclude`. +* Custom mappings of fields needed to be done with annotations like `@JsonFormat` or `@JsonInclude`. This often caused problems when the same object was used in different JSON based datastores or sent over a JSON based API. +* Custom field types and formats also need to be stored into the Elasticsearch index mappings. The Jackson based annotations did not fully provide all the information that is necessary to represent the types of Elasticsearch. -.Jackson2 Object Mapping Configuration -==== -[source,java] ----- -@Configuration -public class Config extends AbstractElasticsearchConfiguration { <1> - - @Override - public RestHighLevelClient elasticsearchClient() { - return RestClients.create(ClientConfiguration.create("localhost:9200")).rest(); - } -} ----- -<1> `AbstractElasticsearchConfiguration` already defines a Jackson2 based `entityMapper` via `ElasticsearchConfigurationSupport`. -==== - -[WARNING] -`CustomConversions`, `@ReadingConverter` & `@WritingConverter` cannot be applied when using the Jackson based `EntityMapper`. + -Setting the name of a mapped field with `@Field(name="custom-name")` also cannot be used with this Mapper. [[elasticsearch.mapping.meta-model]] == Meta Model Object Mapping @@ -38,43 +17,13 @@ Setting the name of a mapped field with `@Field(name="custom-name")` also cannot The Metamodel based approach uses domain type information for reading/writing from/to Elasticsearch. This allows to register `Converter` instances for specific domain type mapping. -.Meta Model Object Mapping Configuration -==== -[source,java] ----- -@Configuration -public class Config extends AbstractElasticsearchConfiguration { - - @Override - public RestHighLevelClient elasticsearchClient() { - return RestClients.create(ClientConfiguration.create("localhost:9200")).rest() - } - - @Bean - @Override - public EntityMapper entityMapper() { <1> - - ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper( - elasticsearchMappingContext(), new DefaultConversionService() <2> - ); - entityMapper.setConversions(elasticsearchCustomConversions()); <3> - - return entityMapper; - } -} ----- -<1> Overwrite the default `EntityMapper` from `ElasticsearchConfigurationSupport` and expose it as bean. -<2> Use the provided `SimpleElasticsearchMappingContext` to avoid inconsistencies and provide a `GenericConversionService` -for `Converter` registration. -<3> Optionally set `CustomConversions` if applicable. -==== - [[elasticsearch.mapping.meta-model.annotations]] === Mapping Annotation Overview -The `ElasticsearchEntityMapper` can use metadata to drive the mapping of objects to documents. The following annotations are available: +The `ElasticsearchEntityMapper` can use metadata to drive the mapping of objects to documents. The metadata is taken from the entities properties which can be annotated. + +The following annotations are available: -* `@Id`: Applied at the field level to mark the field used for identity purpose. * `@Document`: Applied at the class level to indicate this class is a candidate for mapping to the database. The most important attributes are: ** `indexName`: the name of the index to store this entity in ** `type`: the mapping type. If not set, the lowercased simple name of the class is used. @@ -84,18 +33,18 @@ The `ElasticsearchEntityMapper` can use metadata to drive the mapping of objects ** `indexStoreType`: Index storage type for the index. Used for index creation. Default value is _"fs"_. ** `createIndex`: Configuration whether to create an index on repository bootstrapping. Default value is _true_. ** `versionType`: Configuration of version management. Default value is _EXTERNAL_. +* `@Id`: Applied at the field level to mark the field used for identity purpose. * `@Transient`: By default all private fields are mapped to the document, this annotation excludes the field where it is applied from being stored in the database * `@PersistenceConstructor`: Marks a given constructor - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved Document. * `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions: ** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used. -** `type`: the field type, can be one of _Text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, Keyword_. +** `type`: the field type, can be one of _Text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, Keyword_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types] ** `format` and `pattern` custom definitions for the _Date_ type. ** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_. ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. ** `copy_to`: the target field to copy multiple document fields to. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. - The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic. [[elasticsearch.mapping.meta-model.rules]] diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index ada458e32..7b1cc3ef1 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -1,10 +1,18 @@ [[elasticsearch.operations]] = Elasticsearch Operations -Spring Data Elasticsearch uses two interfaces to define the operations that can be called against an Elasticsearch index. These are `ElasticsearchOperations` and `ReactiveElasticsearchOperations`. Whereas the first is used with the classic synchronous implementations, the second one uses reactive infrastructure. +Spring Data Elasticsearch uses several interfaces to define the operations that can be called against an Elasticsearch index (for a description of the reactive interfaces see <>). + +* `IndexOperations` defines actions on index level like creating or deleting an index. +* `DocumentOperations` defines actions to store, update and retrieve entities based on their id. +* `SearchOperations` define the actions to search for multiple entities using queries +* `ElasticsearchOperations` combines the `DocumentOperations` and `SearchOperations` interfaces. + +These interfaces correspond to the structuring of the https://www.elastic.co/guide/en/elasticsearch/reference/current/rest-apis.html[Elasticsearch API]. The default implementations of the interfaces offer: +* index management functionality. * Read/Write mapping support for domain types. * A rich query and criteria api. * Resource management and Exception translation. @@ -35,21 +43,10 @@ public class TransportClientConfig extends ElasticsearchConfigurationSupport { public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException { <2> return new ElasticsearchTemplate(elasticsearchClient(), entityMapper()); } - - // use the ElasticsearchEntityMapper - @Bean - @Override - public EntityMapper entityMapper() { <3> - ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(), - new DefaultConversionService()); - entityMapper.setConversions(elasticsearchCustomConversions()); - return entityMapper; - } } ---- -<1> Setting up the <>. Deprecatedas of version 4.0. +<1> Setting up the <>. Deprecated as of version 4.0. <2> Creating the `ElasticsearchTemplate` bean, offering both names, _elasticsearchOperations_ and _elasticsearchTemplate_. -<3> Using the <> ElasticsearchMapper. ==== [[elasticsearch.operations.resttemplate]] @@ -69,29 +66,16 @@ public class RestClientConfig extends AbstractElasticsearchConfiguration { } // no special bean creation needed <2> - - // use the ElasticsearchEntityMapper - @Bean - @Override - public EntityMapper entityMapper() { <3> - ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(), - new DefaultConversionService()); - entityMapper.setConversions(elasticsearchCustomConversions()); - - return entityMapper; - } } ---- <1> Setting up the <>. <2> The base class `AbstractElasticsearchConfiguration` already provides the `elasticsearchTemplate` bean. -<3> Using the <> ElasticsearchMapper. ==== [[elasticsearch.operations.usage]] == Usage examples -As both `ElasticsearchTemplate` and `ElasticsearchRestTemplate` implement the `ElasticsearchOperations` interface, the code to use them is not different. The example shows how to use an injected `ElasticsearchOperations` instance in a Spring REST controller. The decision, if this is using the `TransportClient` or the `RestClient` is made by providing the - corresponding Bean with one of the configurations shown above. +As both `ElasticsearchTemplate` and `ElasticsearchRestTemplate` implement the `ElasticsearchOperations` interface, the code to use them is not different. The example shows how to use an injected `ElasticsearchOperations` instance in a Spring REST controller. The decision, if this is using the `TransportClient` or the `RestClient` is made by providing the corresponding Bean with one of the configurations shown above. .ElasticsearchOperations usage ==== @@ -135,3 +119,26 @@ public class TestController { To see the full possibilities of `ElasticsearchOperations` please refer to the API documentation. include::reactive-elasticsearch-operations.adoc[leveloffset=+1] + +[[elasticsearch.operations.searchresulttypes]] +== Search Result Types + +When a document is retrieved with the methods of the `DocumentOperations` interface, just the found entity will be returned. When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity. + +In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information. These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search ike the _maxScore_ or requested aggregations. + +.SearchHit +Contains the following information: + +* Id +* Score +* Sort Values +* the retrieved entity of type + +.SearchHits +Contains the following information: + +* Number of total hits +* Maximum score +* A list of `SearchHit` objects + diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 715d166e3..66d0ae503 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -25,8 +25,8 @@ /** * ElasticsearchOperations. Since 4.0 this interface only contains common helper functions, the other methods have been - * moved to the different interfaces that are extended by ElasticsearchOperations. The interfaces now reflect the REST API structure of * Elasticsearch. * * @author Rizwan Idrees From f7a14c1135189a62675a3345d70ccb1a6ec16af4 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 25 Dec 2019 08:35:48 +0100 Subject: [PATCH 0022/1191] DATAES-719 - Add customization hook for reactive WebClient. Original PR: #363 --- .../reference/elasticsearch-clients.adoc | 10 ++- .../client/ClientConfiguration.java | 19 ++++- .../client/ClientConfigurationBuilder.java | 15 +++- .../client/DefaultClientConfiguration.java | 48 +++-------- .../DefaultReactiveElasticsearchClient.java | 4 +- .../reactive/DefaultWebClientProvider.java | 83 ++++++++----------- .../client/reactive/WebClientProvider.java | 10 +++ .../client/ClientConfigurationUnitTests.java | 22 +++++ .../DefaultWebClientProviderUnitTests.java | 17 ++++ .../ReactiveMockClientTestsUtils.java | 6 ++ 10 files changed, 144 insertions(+), 90 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-clients.adoc b/src/main/asciidoc/reference/elasticsearch-clients.adoc index 1afe45f1c..a9f7d7ea2 100644 --- a/src/main/asciidoc/reference/elasticsearch-clients.adoc +++ b/src/main/asciidoc/reference/elasticsearch-clients.adoc @@ -108,8 +108,15 @@ static class Config { @Bean ReactiveElasticsearchClient client() { - ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1> + ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1> .connectedTo("localhost:9200", "localhost:9291") + .withWebClientConfigurer(webClient -> { <2> + ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() + .codecs(configurer -> configurer.defaultCodecs() + .maxInMemorySize(-1)) + .build(); + return webClient.mutate().exchangeStrategies(exchangeStrategies).build(); + }) .build(); return ReactiveRestClients.create(clientConfiguration); @@ -128,6 +135,7 @@ Mono response = client.index(request -> ); ---- <1> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL. +<2> when configuring a reactive client, the `withWebClientConfigurer` hook can be used to customize the WebClient. ==== NOTE: The ReactiveClient response, especially for search operations, is bound to the `from` (offset) & `size` (limit) options of the request. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index 5e57c2af5..6b3fe8dc1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -20,11 +20,13 @@ import java.time.Duration; import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; /** * Configuration interface exposing common client configuration properties for Elasticsearch clients. @@ -161,6 +163,11 @@ static ClientConfiguration create(InetSocketAddress socketAddress) { */ Optional getProxy(); + /** + * @return the function for configuring a WebClient. + */ + Function getWebClientConfigurer(); + /** * @author Christoph Strobl */ @@ -314,9 +321,17 @@ default TerminalClientConfigurationBuilder withSocketTimeout(long millis) { /** * @param proxy a proxy formatted as String {@literal host:port}. - * @return the {@link MaybeSecureClientConfigurationBuilder}. + * @return the {@link TerminalClientConfigurationBuilder}. + */ + TerminalClientConfigurationBuilder withProxy(String proxy); + + /** + * set customization hook in case of a reactive configuration + * + * @param webClientConfigurer function to configure the WebClient + * @return the {@link TerminalClientConfigurationBuilder}. */ - MaybeSecureClientConfigurationBuilder withProxy(String proxy); + TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer); /** * Build the {@link ClientConfiguration} object. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index 5d5907b38..fa1b49a4a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.function.Function; import java.util.stream.Collectors; import javax.net.ssl.HostnameVerifier; @@ -31,6 +32,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.web.reactive.function.client.WebClient; /** * Default builder implementation for {@link ClientConfiguration}. @@ -56,6 +58,7 @@ class ClientConfigurationBuilder private String password; private String pathPrefix; private String proxy; + private Function webClientConfigurer; /* * (non-Javadoc) @@ -187,12 +190,20 @@ public TerminalClientConfigurationBuilder withBasicAuth(String username, String @Override public TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix) { - this.pathPrefix = pathPrefix; return this; } + @Override + public TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer) { + + Assert.notNull(webClientConfigurer, "webClientConfigurer must not be null"); + + this.webClientConfigurer = webClientConfigurer; + return this; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build() @@ -208,7 +219,7 @@ public ClientConfiguration build() { } return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix, - hostnameVerifier, proxy); + hostnameVerifier, proxy, webClientConfigurer); } private static InetSocketAddress parse(String hostAndPort) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index b8b2a3991..72dbdfaa0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -21,12 +21,14 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.function.Function; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; +import org.springframework.web.reactive.function.client.WebClient; /** * Default {@link ClientConfiguration} implementation. @@ -34,6 +36,7 @@ * @author Mark Paluch * @author Christoph Strobl * @author Huw Ayling-Miller + * @author Peter-Josef Meisch * @since 3.2 */ class DefaultClientConfiguration implements ClientConfiguration { @@ -47,10 +50,11 @@ class DefaultClientConfiguration implements ClientConfiguration { private final String pathPrefix; private final @Nullable HostnameVerifier hostnameVerifier; private final String proxy; + private final Function webClientConfigurer; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, - @Nullable HostnameVerifier hostnameVerifier, String proxy) { + @Nullable HostnameVerifier hostnameVerifier, String proxy, Function webClientConfigurer) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -61,86 +65,56 @@ class DefaultClientConfiguration implements ClientConfiguration { this.pathPrefix = pathPrefix; this.hostnameVerifier = hostnameVerifier; this.proxy = proxy; + this.webClientConfigurer = webClientConfigurer; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getEndpoints() - */ @Override public List getEndpoints() { return this.hosts; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getDefaultHeaders() - */ @Override public HttpHeaders getDefaultHeaders() { return this.headers; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#useSsl() - */ @Override public boolean useSsl() { return this.useSsl; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSslContext() - */ @Override public Optional getSslContext() { return Optional.ofNullable(this.sslContext); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getHostNameVerifier() - */ @Override public Optional getHostNameVerifier() { return Optional.ofNullable(this.hostnameVerifier); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getConnectTimeout() - */ @Override public Duration getConnectTimeout() { return this.connectTimeout; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSocketTimeout() - */ @Override public Duration getSocketTimeout() { return this.soTimeout; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getPathPrefix() - */ @Override public String getPathPrefix() { return this.pathPrefix; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.ClientConfiguration#getProxy() - */ @Override public Optional getProxy() { return Optional.ofNullable(proxy); } + + @Override + public Function getWebClientConfigurer() { + return webClientConfigurer != null ? webClientConfigurer : Function.identity(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 4c4891321..c59d27707 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -226,7 +226,9 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client provider = provider.withPathPrefix(clientConfiguration.getPathPrefix()); } - return provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()); + provider = provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()) // + .withWebClientConfigurer(clientConfiguration.getWebClientConfigurer()); + return provider; } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java index bc72c086b..188a7c51f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java @@ -19,6 +19,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; +import java.util.function.Function; import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; @@ -33,6 +34,7 @@ * @author Mark Paluch * @author Christoph Strobl * @author Huw Ayling-Miller + * @author Peter-Josef Meisch * @since 3.2 */ class DefaultWebClientProvider implements WebClientProvider { @@ -44,6 +46,7 @@ class DefaultWebClientProvider implements WebClientProvider { private final Consumer errorListener; private final HttpHeaders headers; private final String pathPrefix; + private final Function webClientConfigurer; /** * Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}. @@ -52,24 +55,28 @@ class DefaultWebClientProvider implements WebClientProvider { * @param connector can be {@literal null}. */ DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector) { - this(scheme, connector, e -> {}, HttpHeaders.EMPTY, null); + this(scheme, connector, e -> {}, HttpHeaders.EMPTY, null, Function.identity()); } /** * Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}. * + * @param pathPrefixcan be {@literal null} * @param scheme must not be {@literal null}. * @param connector can be {@literal null}. * @param errorListener must not be {@literal null}. * @param headers must not be {@literal null}. - * @param pathPrefixcan be {@literal null} + * @param webClientConfigurer must not be {@literal null}. */ private DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector, - Consumer errorListener, HttpHeaders headers, @Nullable String pathPrefix) { + Consumer errorListener, HttpHeaders headers, @Nullable String pathPrefix, + Function webClientConfigurer) { Assert.notNull(scheme, "Scheme must not be null! A common scheme would be 'http'."); - Assert.notNull(errorListener, "ErrorListener must not be null! You may want use a no-op one 'e -> {}' instead."); + Assert.notNull(errorListener, "errorListener must not be null! You may want use a no-op one 'e -> {}' instead."); Assert.notNull(headers, "headers must not be null! Think about using 'HttpHeaders.EMPTY' as an alternative."); + Assert.notNull(webClientConfigurer, + "webClientConfigurer must not be null! You may want use a no-op one 'Function.identity()' instead."); this.cachedClients = new ConcurrentHashMap<>(); this.scheme = scheme; @@ -77,12 +84,9 @@ private DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector co this.errorListener = errorListener; this.headers = headers; this.pathPrefix = pathPrefix; + this.webClientConfigurer = webClientConfigurer; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#get(java.net.InetSocketAddress) - */ @Override public WebClient get(InetSocketAddress endpoint) { @@ -91,19 +95,21 @@ public WebClient get(InetSocketAddress endpoint) { return this.cachedClients.computeIfAbsent(endpoint, this::createWebClientForSocketAddress); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getDefaultHeaders() - */ @Override public HttpHeaders getDefaultHeaders() { return headers; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withDefaultHeaders(org.springframework.http.HttpHeaders) - */ + @Override + public Consumer getErrorListener() { + return this.errorListener; + } + + @Override + public String getPathPrefix() { + return pathPrefix; + } + @Override public WebClientProvider withDefaultHeaders(HttpHeaders headers) { @@ -113,51 +119,33 @@ public WebClientProvider withDefaultHeaders(HttpHeaders headers) { merged.addAll(this.headers); merged.addAll(headers); - return new DefaultWebClientProvider(this.scheme, this.connector, errorListener, merged, this.pathPrefix); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getErrorListener() - */ - @Override - public Consumer getErrorListener() { - return this.errorListener; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getPathPrefix() - */ - @Override - public String getPathPrefix() { - return pathPrefix; + return new DefaultWebClientProvider(scheme, connector, errorListener, merged, pathPrefix, webClientConfigurer); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withErrorListener(java.util.function.Consumer) - */ @Override public WebClientProvider withErrorListener(Consumer errorListener) { Assert.notNull(errorListener, "Error listener must not be null."); Consumer listener = this.errorListener.andThen(errorListener); - return new DefaultWebClientProvider(this.scheme, this.connector, listener, this.headers, this.pathPrefix); + return new DefaultWebClientProvider(scheme, this.connector, listener, headers, pathPrefix, webClientConfigurer); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withPathPrefix(java.lang.String) - */ @Override public WebClientProvider withPathPrefix(String pathPrefix) { Assert.notNull(pathPrefix, "pathPrefix must not be null."); - return new DefaultWebClientProvider(this.scheme, this.connector, this.errorListener, this.headers, pathPrefix); + return new DefaultWebClientProvider(this.scheme, this.connector, this.errorListener, this.headers, pathPrefix, + webClientConfigurer); + } + + @Override + public WebClientProvider withWebClientConfigurer(Function webClientConfigurer) { + return new DefaultWebClientProvider(scheme, connector, errorListener, headers, pathPrefix, webClientConfigurer); + } + protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddress) { Builder builder = WebClient.builder().defaultHeaders(it -> it.addAll(getDefaultHeaders())); @@ -167,7 +155,8 @@ protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddr } String baseUrl = String.format("%s://%s:%d%s", this.scheme, socketAddress.getHostString(), socketAddress.getPort(), - pathPrefix == null ? "" : "/" + pathPrefix); - return builder.baseUrl(baseUrl).filter((request, next) -> next.exchange(request).doOnError(errorListener)).build(); + pathPrefix == null ? "" : '/' + pathPrefix); + WebClient webClient = builder.baseUrl(baseUrl).filter((request, next) -> next.exchange(request).doOnError(errorListener)).build(); + return webClientConfigurer.apply(webClient); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java index 5c325f7f5..a6c3a6d6b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java @@ -17,6 +17,7 @@ import java.net.InetSocketAddress; import java.util.function.Consumer; +import java.util.function.Function; import org.springframework.http.HttpHeaders; import org.springframework.http.client.reactive.ClientHttpConnector; @@ -35,6 +36,7 @@ * @author Christoph Strobl * @author Mark Paluch * @author Huw Ayling-Miller + * @author Peter-Josef Meisch * @since 3.2 */ public interface WebClientProvider { @@ -129,4 +131,12 @@ static WebClientProvider create(String scheme, @Nullable ClientHttpConnector con * @since 4.0 */ WebClientProvider withPathPrefix(String pathPrefix); + + /** + * Create a new instance of {@link WebClientProvider} calling the given {@link Function} to configure the {@link WebClient}. + * @param webClientConfigurer configuration function + * @return new instance of {@link WebClientProvider} + * @since 4.0 + */ + WebClientProvider withWebClientConfigurer(Function webClientConfigurer); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java index 301bcf32f..96cb70f32 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java @@ -20,12 +20,14 @@ import java.net.InetSocketAddress; import java.time.Duration; +import java.util.function.Function; import javax.net.ssl.SSLContext; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.junit.jupiter.api.Test; import org.springframework.http.HttpHeaders; +import org.springframework.web.reactive.function.client.WebClient; /** * Unit tests for {@link ClientConfiguration}. @@ -143,6 +145,26 @@ public void shouldCreateSslConfigurationWithHostnameVerifier() { assertThat(clientConfiguration.getHostNameVerifier()).contains(NoopHostnameVerifier.INSTANCE); } + @Test // DATAES-719 + void shouldHaveDefaultWebClientConfigurer() { + ClientConfiguration clientConfiguration = ClientConfiguration.builder() // + .connectedTo("foo", "bar") // + .build(); + + assertThat(clientConfiguration.getWebClientConfigurer()).isEqualTo(Function.identity()); + } + + @Test // DATAES-719 + void shouldUseConfiguredWebClientConfigurer() { + Function webClientConfigurer = webClient -> webClient; + ClientConfiguration clientConfiguration = ClientConfiguration.builder() // + .connectedTo("foo", "bar") // + .withWebClientConfigurer(webClientConfigurer) // + .build(); + + assertThat(clientConfiguration.getWebClientConfigurer()).isEqualTo(webClientConfigurer); + } + private static String buildBasicAuth(String username, String password) { HttpHeaders headers = new HttpHeaders(); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java index 09e8970f3..64836ccba 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java @@ -18,12 +18,15 @@ import static org.assertj.core.api.Assertions.*; import java.net.InetSocketAddress; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Function; import org.junit.jupiter.api.Test; import org.springframework.web.reactive.function.client.WebClient; /** * @author Christoph Strobl + * @author Peter-Josef Meisch */ public class DefaultWebClientProviderUnitTests { @@ -40,4 +43,18 @@ public void shouldCacheClients() { assertThat(shouldBeCachedInstanceOfClient1).isSameAs(client1); assertThat(notClient1ButAnotherInstance).isNotSameAs(client1); } + + @Test // DATAES-719 + void shouldCallWebClientConfigurer() { + AtomicReference configurerCalled = new AtomicReference<>(false); + Function configurer = webClient -> { + configurerCalled.set(true); + return webClient; + }; + WebClientProvider provider = new DefaultWebClientProvider("http", null).withWebClientConfigurer(configurer); + + provider.get(InetSocketAddress.createUnresolved("localhost", 9200)); + + assertThat(configurerCalled).hasValue(true); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index aabc8282f..49063946b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -61,6 +61,7 @@ * @author Christoph Strobl * @author Huw Ayling-Miller * @author Henrique Amaral + * @author Peter-Josef Meisch */ public class ReactiveMockClientTestsUtils { @@ -276,6 +277,11 @@ public WebClientProvider withPathPrefix(String pathPrefix) { throw new UnsupportedOperationException(); } + @Override + public WebClientProvider withWebClientConfigurer(Function webClientConfigurer) { + throw new UnsupportedOperationException("not implemented"); + } + public Send when(String host) { InetSocketAddress inetSocketAddress = getInetSocketAddress(host); return new CallbackImpl(get(host), headersUriSpecMap.get(inetSocketAddress), From b634f318abe771b98d01bc38a3885ffb20e5368f Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 25 Dec 2019 10:40:10 +0100 Subject: [PATCH 0023/1191] DATAES-720 - SimpleReactiveElasticsearchRepository findAll() returns only 10 elements. Original PR: #364 --- ...SimpleReactiveElasticsearchRepository.java | 21 +++++++++---------- ...eReactiveElasticsearchRepositoryTests.java | 16 ++++++++++++++ 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index 2d7b1ef11..66919a460 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -19,6 +19,7 @@ import reactor.core.publisher.Mono; import org.reactivestreams.Publisher; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; @@ -46,14 +47,6 @@ public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation findAll(Sort sort) { - - return elasticsearchOperations - .search(Query.findAll().addSort(sort), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) - .map(SearchHit::getContent); - } - @Override public Mono save(S entity) { @@ -108,9 +101,15 @@ public Mono existsById(Publisher id) { @Override public Flux findAll() { - return elasticsearchOperations - .search(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) - .map(SearchHit::getContent); + return elasticsearchOperations.search(Query.findAll().setPageable(Pageable.unpaged()), + entityInformation.getJavaType(), entityInformation.getIndexCoordinates()).map(SearchHit::getContent); + } + + @Override + public Flux findAll(Sort sort) { + + return elasticsearchOperations.search(Query.findAll().addSort(sort).setPageable(Pageable.unpaged()), + entityInformation.getJavaType(), entityInformation.getIndexCoordinates()).map(SearchHit::getContent); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index 6cb28095e..f35c20444 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -17,6 +17,7 @@ import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.core.query.Query.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -33,6 +34,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.UUID; +import java.util.stream.IntStream; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.index.IndexRequest; @@ -154,6 +156,20 @@ public void findByIdShouldCompleteIfNothingFound() { .verifyComplete(); } + @Test // DATAES-720 + public void findAllShouldReturnAllElements() { + // make sure to be above the default page size of the Query interface + int count = DEFAULT_PAGE_SIZE * 2; + bulkIndex(IntStream.range(1, count + 1) // + .mapToObj(it -> SampleEntity.builder().id(String.valueOf(it)).build()) // + .toArray(SampleEntity[]::new)); + + repository.findAll() // + .as(StepVerifier::create) // + .expectNextCount(count) // + .verifyComplete(); + } + @Test // DATAES-519 public void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() { repository.findAllById(Arrays.asList("id-two", "id-two")).as(StepVerifier::create).verifyComplete(); From d2b7df87f4b1317ae6f3c8f157f0798889c0ac04 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 26 Dec 2019 20:14:04 +0100 Subject: [PATCH 0024/1191] DATAES-713 - Add returned aggregations from the AggregatedPage to the SearchHits. Original PR: #365 --- .../core/AbstractElasticsearchTemplate.java | 45 ++-- .../core/ElasticsearchRestTemplate.java | 16 +- .../core/ElasticsearchTemplate.java | 11 +- .../data/elasticsearch/core/ScoredPage.java | 2 + .../elasticsearch/core/SearchHitSupport.java | 13 + .../data/elasticsearch/core/SearchHits.java | 72 ++++- .../elasticsearch/core/SearchOperations.java | 123 ++++----- .../core/aggregation/AggregatedPage.java | 2 + .../core/convert/ElasticsearchConverter.java | 17 +- .../MappingElasticsearchConverter.java | 38 ++- .../query/ElasticsearchPartQuery.java | 4 +- .../query/ElasticsearchStringQuery.java | 4 +- .../AbstractElasticsearchRepository.java | 35 +-- .../data/elasticsearch/NestedObjectTests.java | 15 +- .../core/ElasticsearchTemplateTests.java | 248 +++++++++--------- ...ElasticsearchTemplateAggregationTests.java | 10 +- .../core/query/CriteriaQueryTests.java | 69 +++-- 17 files changed, 381 insertions(+), 343 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 84c81a703..3adf37130 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -19,7 +19,6 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -108,57 +107,47 @@ public CloseableIterator> searchForStream(Query query, Class } @Override - public AggregatedPage> search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { + public SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { Assert.notNull(query.getId(), "No document id defined for MoreLikeThisQuery"); MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = requestFactory.moreLikeThisQueryBuilder(query, index); - - return searchForPage(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); + return search(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); } @Override - public List>> multiSearchForPage(List queries, Class clazz, - IndexCoordinates index) { + public List> multiSearch(List queries, Class clazz, IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); for (Query query : queries) { request.add(requestFactory.searchRequest(query, clazz, index)); } - return doMultiSearch(queries, clazz, request); + + MultiSearchResponse.Item[] items = getMultiSearchResult(request); + + List> res = new ArrayList<>(queries.size()); + int c = 0; + for (Query query : queries) { + res.add(elasticsearchConverter.read(clazz, SearchDocumentResponse.from(items[c++].getResponse()))); + } + return res; } @Override - public List>> multiSearchForPage(List queries, - List> classes, IndexCoordinates index) { + public List> multiSearch(List queries, List> classes, + IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); Iterator> it = classes.iterator(); for (Query query : queries) { request.add(requestFactory.searchRequest(query, it.next(), index)); } - return doMultiSearch(queries, classes, request); - } - private List>> doMultiSearch(List queries, Class clazz, - MultiSearchRequest request) { MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List>> res = new ArrayList<>(queries.size()); - int c = 0; - for (Query query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), clazz, - query.getPageable())); - } - return res; - } - private List>> doMultiSearch(List queries, - List> classes, MultiSearchRequest request) { - MultiSearchResponse.Item[] items = getMultiSearchResult(request); - List>> res = new ArrayList<>(queries.size()); + List> res = new ArrayList<>(queries.size()); int c = 0; - Iterator> it = classes.iterator(); + Iterator> it1 = classes.iterator(); for (Query query : queries) { - res.add(elasticsearchConverter.mapResults(SearchDocumentResponse.from(items[c++].getResponse()), it.next(), - query.getPageable())); + res.add(elasticsearchConverter.read(it1.next(), SearchDocumentResponse.from(items[c++].getResponse()))); } return res; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 29c51ba63..bbe47971b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -226,19 +226,7 @@ public long count(Query query, Class clazz, IndexCoordinates index) { } @Override - public T query(Query query, ResultsExtractor resultsExtractor, @Nullable Class clazz, - IndexCoordinates index) { - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - try { - SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); - return resultsExtractor.extract(result); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } - } - - @Override - public AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index) { + public SearchHits search(Query query, Class clazz, IndexCoordinates index) { SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); SearchResponse response; try { @@ -246,7 +234,7 @@ public AggregatedPage> searchForPage(Query query, Class claz } catch (IOException e) { throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); } - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); + return elasticsearchConverter.read(clazz, SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 03499348f..c282b1197 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -196,17 +196,10 @@ public long count(Query query, @Nullable Class clazz, IndexCoordinates index) } @Override - public T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index) { + public SearchHits search(Query query, Class clazz, IndexCoordinates index) { SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); SearchResponse response = getSearchResponse(searchRequestBuilder); - return resultsExtractor.extract(response); - } - - @Override - public AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index) { - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, query.getPageable()); + return elasticsearchConverter.read(clazz, SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java b/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java index 49402140a..a444f2d6c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java @@ -22,7 +22,9 @@ * * @param * @author Sascha Woo + * @deprecated since 4.0, use {@link org.springframework.data.elasticsearch.core.SearchHits} to return values. */ +@Deprecated public interface ScoredPage extends Page { float getMaxScore(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 44854e460..6dda54ba5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -21,6 +21,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; @@ -81,4 +82,16 @@ public static Object unwrapSearchHits(Object result) { return result; } + + /** + * Builds an {@link AggregatedPage} with the {@link SearchHit} objects from a {@link SearchHits} object. + * + * @param searchHits, must not be {@literal null}. + * @param pageable, must not be {@literal null}. + * @return the created Page + */ + public static AggregatedPage> page(SearchHits searchHits, Pageable pageable) { + return new AggregatedPageImpl<>(searchHits.getSearchHits(), pageable, searchHits.getTotalHits(), + searchHits.getAggregations(), searchHits.getScrollId(), searchHits.getMaxScore()); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java index ec36780af..3591078b3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -18,9 +18,10 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.stream.Stream; +import org.elasticsearch.search.aggregations.Aggregations; import org.springframework.data.util.Streamable; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -33,22 +34,28 @@ */ public class SearchHits implements Streamable> { - private final List> searchHits; private final long totalHits; private final float maxScore; + private final String scrollId; + private final List> searchHits; + private final Aggregations aggregations; /** - * @param searchHits must not be {@literal null} * @param totalHits * @param maxScore + * @param searchHits must not be {@literal null} + * @param aggregations */ - public SearchHits(List> searchHits, long totalHits, float maxScore) { - this.totalHits = totalHits; - this.maxScore = maxScore; + public SearchHits(long totalHits, float maxScore, @Nullable String scrollId, List> searchHits, + @Nullable Aggregations aggregations) { Assert.notNull(searchHits, "searchHits must not be null"); + this.totalHits = totalHits; + this.maxScore = maxScore; + this.scrollId = scrollId; this.searchHits = searchHits; + this.aggregations = aggregations; } @Override @@ -56,21 +63,35 @@ public Iterator> iterator() { return (Iterator>) searchHits.iterator(); } - // region getter /** - * @return the contained {@link SearchHit}s. + * @return the number of total hits. */ - public List> getSearchHits() { - return Collections.unmodifiableList(searchHits); - } - + // region getter public long getTotalHits() { return totalHits; } + /** + * @return the maximum score + */ public float getMaxScore() { return maxScore; } + + /** + * @return the scroll id + */ + @Nullable + public String getScrollId() { + return scrollId; + } + + /** + * @return the contained {@link SearchHit}s. + */ + public List> getSearchHits() { + return Collections.unmodifiableList(searchHits); + } // endregion // region SearchHit access @@ -86,7 +107,30 @@ public SearchHit getSearchHit(int index) { @Override public String toString() { - return "SearchHits{" + "totalHits=" + totalHits + ", maxScore=" + maxScore + ", searchHits=" - + StringUtils.collectionToCommaDelimitedString(searchHits) + '}'; + return "SearchHits{" + + "totalHits=" + totalHits + + ", maxScore=" + maxScore + + ", scrollId='" + scrollId + '\'' + + ", searchHits=" + StringUtils.collectionToCommaDelimitedString(searchHits) + + ", aggregations=" + aggregations + + '}'; } + + /** + * @return true if aggregations are available + */ + // region aggregations + public boolean hasAggregations() { + return aggregations != null; + } + + /** + * @return the aggregations. + */ + @Nullable + public Aggregations getAggregations() { + return aggregations; + } + // endregion + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index e47981111..0165c04af 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; @@ -59,8 +60,7 @@ default long count(Query query, IndexCoordinates index) { */ long count(Query query, @Nullable Class clazz, IndexCoordinates index); - T query(Query query, ResultsExtractor resultsExtractor, Class clazz, IndexCoordinates index); - + // region deprecated /** * Execute the query against elasticsearch and return the first returned object. * @@ -82,11 +82,13 @@ default T queryForObject(Query query, Class clazz, IndexCoordinates index * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return a page with aggregations - * @deprecated since 4.0, use {@link #searchForPage(Query, Class, IndexCoordinates)}. + * @deprecated since 4.0, use {@link #search(Query, Class, IndexCoordinates)}. */ @Deprecated default AggregatedPage queryForPage(Query query, Class clazz, IndexCoordinates index) { - return (AggregatedPage) SearchHitSupport.unwrapSearchHits(searchForPage(query, clazz, index)); + SearchHits searchHits = search(query, clazz, index); + AggregatedPage> aggregatedPage = SearchHitSupport.page(searchHits, query.getPageable()); + return (AggregatedPage) SearchHitSupport.unwrapSearchHits(aggregatedPage); } /** @@ -96,13 +98,19 @@ default AggregatedPage queryForPage(Query query, Class clazz, IndexCoo * @param clazz the entity clazz used for property mapping * @param index the index to run the query against * @return list of pages with the results - * @deprecated since 4.0, use {@link #multiSearchForPage(List, Class, IndexCoordinates)}. + * @deprecated since 4.0, use {@link #multiSearch(List, Class, IndexCoordinates)}. */ @Deprecated default List> queryForPage(List queries, Class clazz, IndexCoordinates index) { - return multiSearchForPage(queries, clazz, index).stream() // - .map(page -> (Page) SearchHitSupport.unwrapSearchHits(page)) // - .collect(Collectors.toList()); + List> pageList = new ArrayList<>(); + List> searchHitsList = multiSearch(queries, clazz, index); + Iterator qit = queries.iterator(); + searchHitsList.forEach(searchHits -> { + AggregatedPage> aggregatedPage = SearchHitSupport.page(searchHits, qit.next().getPageable()); + Page page = (Page) SearchHitSupport.unwrapSearchHits(aggregatedPage); + pageList.add(page); + }); + return pageList; } /** @@ -112,14 +120,22 @@ default List> queryForPage(List queries, Class c * @param classes the entity classes used for the queries * @param index the index to run the query against * @return list of pages with the results - * @deprecated since 4.0, use {@link #multiSearchForPage(List, List, IndexCoordinates)}. + * @deprecated since 4.0, use {@link #multiSearch(List, List, IndexCoordinates)}. */ @Deprecated default List> queryForPage(List queries, List> classes, IndexCoordinates index) { - return multiSearchForPage(queries, classes, index).stream() // - .map(page -> (AggregatedPage) SearchHitSupport.unwrapSearchHits(page)) // - .collect(Collectors.toList()); + List> pageList = new ArrayList<>(); + List> searchHitsList = multiSearch(queries, classes, index); + Iterator qit = queries.iterator(); + searchHitsList.forEach(searchHits -> { + AggregatedPage> aggregatedPage = SearchHitSupport.page(searchHits, + qit.next().getPageable()); + AggregatedPage page = (AggregatedPage) SearchHitSupport.unwrapSearchHits(aggregatedPage); + pageList.add(page); + }); + + return pageList; } /** @@ -219,7 +235,7 @@ default ScrolledPage startScroll(long scrollTimeInMillis, Query query, Cl * @param scrollTimeInMillis duration of the scroll time * @param clazz The class of entity to retrieve. * @return scrolled page result - * @deprecated since 4.0, use {@link #searchScrollStart(long, Query, Class, IndexCoordinates)}. + * @deprecated since 4.0, use {@link #searchScrollContinue(String, long, Class)}. */ @Deprecated default ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { @@ -250,8 +266,11 @@ default void clearScroll(String scrollId) { */ @Deprecated default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { - return (AggregatedPage) SearchHitSupport.unwrapSearchHits(search(query, clazz, index)); + SearchHits searchHits = search(query, clazz, index); + AggregatedPage> aggregatedPage = SearchHitSupport.page(searchHits, query.getPageable()); + return (AggregatedPage) SearchHitSupport.unwrapSearchHits(aggregatedPage); } + // endregion /** * Execute the query against elasticsearch and return the first returned object. @@ -263,41 +282,30 @@ default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class cla */ @Nullable default SearchHit searchOne(Query query, Class clazz, IndexCoordinates index) { - List> content = searchForPage(query, clazz, index).getContent(); + List> content = search(query, clazz, index).getSearchHits(); return content.isEmpty() ? null : content.get(0); } /** - * Execute the query against elasticsearch and return result as {@link AggregatedPage}. - * - * @param query the query to execute - * @param clazz the entity clazz used for property mapping - * @param index the index to run the query against - * @return a page with aggregations - */ - AggregatedPage> searchForPage(Query query, Class clazz, IndexCoordinates index); - - /** - * Execute the multi-search against elasticsearch and return result as {@link List} of {@link AggregatedPage} + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. * - * @param queries the queries + * @param queries the queries to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against - * @return list of pages with the results + * @param element return type + * @return list of SearchHits */ - List>> multiSearchForPage(List queries, Class clazz, - IndexCoordinates index); + List> multiSearch(List queries, Class clazz, IndexCoordinates index); /** - * Execute the multi-search against elasticsearch and return result as {@link List} of {@link AggregatedPage} + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. * - * @param queries the queries - * @param classes the entity classes used for the queries + * @param queries the queries to execute + * @param classes the entity classes used for property mapping * @param index the index to run the query against - * @return list of pages with the results + * @return list of SearchHits */ - List>> multiSearchForPage(List queries, List> classes, - IndexCoordinates index); + List> multiSearch(List queries, List> classes, IndexCoordinates index); /** * Execute the criteria query against elasticsearch and return result as {@link SearchHits} @@ -308,42 +316,7 @@ List>> multiSearchForPage(List SearchHits search(Query query, Class clazz, IndexCoordinates index) { - AggregatedPage> aggregatedPage = searchForPage(query, clazz, index); - return new SearchHits<>(aggregatedPage.getContent(), aggregatedPage.getTotalElements(), - aggregatedPage.getMaxScore()); - } - - /** - * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. - * - * @param queries the queries to execute - * @param clazz the entity clazz used for property mapping - * @param index the index to run the query against - * @param element return type - * @return list of SearchHits - */ - default List> multiSearch(List queries, Class clazz, IndexCoordinates index) { - return multiSearchForPage(queries, clazz, index).stream() - .map(page -> new SearchHits(page.getContent(), page.getTotalElements(), page.getMaxScore())) - .collect(Collectors.toList()); - } - - /** - * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. - * - * @param queries the queries to execute - * @param classes the entity classes used for property mapping - * @param index the index to run the query against - * @return list of SearchHits - */ - default List> multiSearch(List queries, List> classes, IndexCoordinates index) { - List> searchHitsList = new ArrayList<>(); - multiSearchForPage(queries, classes, index).forEach(page -> { - searchHitsList.add(new SearchHits(page.getContent(), page.getTotalElements(), page.getMaxScore())); - }); - return searchHitsList; - } + SearchHits search(Query query, Class clazz, IndexCoordinates index); /** * more like this query to search for documents that are "like" a specific document. @@ -352,9 +325,9 @@ default List> multiSearch(List queries, List> clas * @param query the query to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against - * @return page with the results + * @return SearchHits containing the list of found objects */ - AggregatedPage> search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); + SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); /** * Returns scrolled page for given query @@ -377,7 +350,7 @@ ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query * @return scrolled page result */ ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz); + Class clazz); /** * Clears the search contexts associated with specified scroll ids. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java index 617b0ddb3..086845c92 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java @@ -9,7 +9,9 @@ * @author Petar Tahchiev * @author Sascha Woo * @author Peter-Josef Meisch + * @deprecated since 4.0, use {@link org.springframework.data.elasticsearch.core.SearchHits} to return values. */ +@Deprecated public interface AggregatedPage extends ScrolledPage, ScoredPage { boolean hasAggregations(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index 216e376fe..e377d8962 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -20,6 +20,7 @@ import org.springframework.data.convert.EntityConverter; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; @@ -84,12 +85,22 @@ default ProjectionFactory getProjectionFactory() { @Nullable T mapDocument(@Nullable Document document, Class type); + /** + * builds a {@link SearchHits} from a {@link SearchDocumentResponse}. + * @param the clazz of the type, must not be {@literal null}. + * @param type the type of the returned data, must not be {@literal null}. + * @param searchDocumentResponse the response to read from, must not be {@literal null}. + * @return a SearchHits object + * @since 4.0 + */ + SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse); + /** * builds a {@link SearchHit} from a {@link SearchDocument}. - * - * @param searchDocument must not be {@literal null} + * * @param the clazz of the type, must not be {@literal null}. * @param type the type of the returned data, must not be {@literal null}. + * @param searchDocument must not be {@literal null} * @return SearchHit with all available information filled in * @since 4.0 */ @@ -108,7 +119,7 @@ default ProjectionFactory getProjectionFactory() { /** * Map an object to a {@link Document}. - * + * * @param source * @return will not be {@literal null}. */ diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index d209077dc..2a7243d47 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -17,10 +17,20 @@ import lombok.RequiredArgsConstructor; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; +import org.elasticsearch.search.aggregations.Aggregations; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -36,6 +46,7 @@ import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.elasticsearch.core.document.Document; @@ -152,11 +163,6 @@ public R read(Class type, Document source) { @SuppressWarnings("unchecked") @Nullable protected R doRead(Document source, TypeInformation typeHint) { - - if (source == null) { - return null; - } - typeHint = (TypeInformation) typeMapper.readType(source, typeHint); if (conversions.hasCustomReadTarget(Map.class, typeHint.getType())) { @@ -597,8 +603,28 @@ public T mapDocument(@Nullable Document document, Class type) { : type.cast(mappedResult); } + @Override + public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { + + Assert.notNull(type, "type must not be null"); + Assert.notNull(searchDocumentResponse, "searchDocumentResponse must not be null"); + + long totalHits = searchDocumentResponse.getTotalHits(); + float maxScore = searchDocumentResponse.getMaxScore(); + String scrollId = searchDocumentResponse.getScrollId(); + List> searchHits = searchDocumentResponse.getSearchDocuments().stream() // + .map(searchDocument -> read(type, searchDocument)) // + .collect(Collectors.toList()); + Aggregations aggregations = searchDocumentResponse.getAggregations(); + return new SearchHits(totalHits, maxScore, scrollId, searchHits, aggregations); + } + @Override public SearchHit read(Class type, SearchDocument searchDocument) { + + Assert.notNull(type, "type must not be null"); + Assert.notNull(searchDocument, "searchDocument must not be null"); + String id = searchDocument.hasId() ? searchDocument.getId() : null; float score = searchDocument.getScore(); Object[] sortValues = searchDocument.getSortValues(); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index a750e022d..d2b870e09 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -18,6 +18,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHitSupport; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; @@ -71,7 +72,8 @@ public Object execute(Object[] parameters) { elasticsearchOperations.delete(query, clazz, index); } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); - result = elasticsearchOperations.searchForPage(query, clazz, index); + SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); + result = SearchHitSupport.page(searchHits, query.getPageable()); } else if (queryMethod.isStreamQuery()) { Class entityType = clazz; if (accessor.getPageable().isUnpaged()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 48a79e93d..79348e9c0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -21,6 +21,7 @@ import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHitSupport; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.convert.DateTimeConverters; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.StringQuery; @@ -77,7 +78,8 @@ public Object execute(Object[] parameters) { if (queryMethod.isPageQuery()) { stringQuery.setPageable(accessor.getPageable()); - result = elasticsearchOperations.searchForPage(stringQuery, clazz, index); + SearchHits searchHits = elasticsearchOperations.search(stringQuery, clazz, index); + result = SearchHitSupport.page(searchHits, stringQuery.getPageable()); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isPaged()) { stringQuery.setPageable(accessor.getPageable()); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index f4f156cb8..04437b862 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -39,6 +39,7 @@ import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHitSupport; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -139,8 +140,9 @@ public Iterable findAll() { @Override public Page findAll(Pageable pageable) { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); - AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); + SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override @@ -152,12 +154,9 @@ public Iterable findAll(Sort sort) { } NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); - AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); - } - - private Page unwrapSearchHits(AggregatedPage> page) { - return (Page) SearchHitSupport.unwrapSearchHits(page); + List> searchHitList = operations.search(query, getEntityClass(), getIndexCoordinates()) + .getSearchHits(); + return (List) SearchHitSupport.unwrapSearchHits(searchHitList); } @Override @@ -226,21 +225,24 @@ public Iterable search(QueryBuilder query) { return new PageImpl<>(Collections. emptyList()); } searchQuery.setPageable(PageRequest.of(0, count)); - AggregatedPage> page = operations.searchForPage(searchQuery, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); + SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override public Page search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); - AggregatedPage> page = operations.searchForPage(searchQuery, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); + SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override public Page search(Query query) { - AggregatedPage> page = operations.searchForPage(query, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); + SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override @@ -255,8 +257,9 @@ public Page searchSimilar(T entity, String[] fields, Pageable pageable) { query.addFields(fields); } - AggregatedPage> page = operations.search(query, getEntityClass(), getIndexCoordinates()); - return unwrapSearchHits(page); + SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); + AggregatedPage> page = SearchHitSupport.page(searchHits, pageable); + return (Page) SearchHitSupport.unwrapSearchHits(page); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 566ac5055..29c6f3644 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -38,16 +38,13 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; -import org.springframework.data.domain.Page; 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.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -196,11 +193,11 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - Page> personIndexed = elasticsearchTemplate.searchForPage(searchQuery, + SearchHits personIndexed = elasticsearchTemplate.search(searchQuery, PersonMultipleLevelNested.class, index); assertThat(personIndexed).isNotNull(); - assertThat(personIndexed.getTotalElements()).isEqualTo(1); - assertThat(personIndexed.getContent().get(0).getContent().getId()).isEqualTo("1"); + assertThat(personIndexed.getTotalHits()).isEqualTo(1); + assertThat(personIndexed.getSearchHit(0).getContent().getId()).isEqualTo("1"); } private List createPerson() { @@ -381,10 +378,10 @@ public void shouldIndexAndSearchMapAsNestedType() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); - AggregatedPage> books = elasticsearchTemplate.searchForPage(searchQuery, Book.class, index); + SearchHits books = elasticsearchTemplate.search(searchQuery, Book.class, index); - assertThat(books.getContent()).hasSize(1); - assertThat(books.getContent().get(0).getContent().getId()).isEqualTo(book2.getId()); + assertThat(books.getSearchHits()).hasSize(1); + assertThat(books.getSearchHit(0).getContent().getId()).isEqualTo(book2.getId()); } @Setter diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index aab98f596..4f4b7cefb 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -60,7 +60,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; -import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -73,7 +72,6 @@ import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; @@ -271,7 +269,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { } @Test - public void shouldReturnPageForGivenSearchQuery() { + public void shouldReturnSearchHitsForGivenSearchQuery() { // given String documentId = randomNumeric(5); @@ -286,15 +284,15 @@ public void shouldReturnPageForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities).isNotNull(); - assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test // DATAES-595 - public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { + public void shouldReturnSearchHitsUsingLocalPreferenceForGivenSearchQuery() { // given String documentId = randomNumeric(5); @@ -310,12 +308,11 @@ public void shouldReturnPageUsingLocalPreferenceForGivenSearchQuery() { .withPreference("_local").build(); // when - Page> sampleEntities = operations.searchForPage(searchQueryWithValidPreference, - SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQueryWithValidPreference, SampleEntity.class, index); // then - assertThat(sampleEntities).isNotNull(); - assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test // DATAES-595 @@ -336,7 +333,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { // when assertThatThrownBy(() -> { - operations.searchForPage(searchQueryWithInvalidPreference, SampleEntity.class, index); + operations.search(searchQueryWithInvalidPreference, SampleEntity.class, index); }).isInstanceOf(Exception.class); } @@ -353,15 +350,16 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { operations.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - Page> entities = operations.searchForPage(searchQuery, SampleEntity.class, + + // when + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); // then - assertThat(entities).isNotNull(); - assertThat(entities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -381,15 +379,16 @@ public void shouldDoBulkIndex() { .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); - - // when operations.bulkIndex(indexQueries, index); indexOperations.refresh(SampleEntity.class); - // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(2); + + // when + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + + // then + assertThat(searchHits.getTotalHits()).isEqualTo(2); } @Test @@ -443,8 +442,9 @@ public void shouldDeleteDocumentForGivenId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(0); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + + assertThat(searchHits.getTotalHits()).isEqualTo(0); } @Test @@ -465,8 +465,8 @@ public void shouldDeleteEntityForGivenId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(0); + SearchHits sampleEntities = operations.search(searchQuery, SampleEntity.class, index); + assertThat(sampleEntities.getTotalHits()).isEqualTo(0); } @Test @@ -490,8 +490,8 @@ public void shouldDeleteDocumentForGivenQuery() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(0); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits.getTotalHits()).isEqualTo(0); } @Test // DATAES-547 @@ -578,10 +578,10 @@ public void shouldFilterSearchResultsForGivenFilter() { .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); + assertThat(searchHits.getTotalHits()).isEqualTo(1); } @Test @@ -613,11 +613,11 @@ public void shouldSortResultsGivenSortCriteria() { .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHit(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); } @Test @@ -650,12 +650,12 @@ public void shouldSortResultsGivenMultipleSortCriteria() { .withSort(new FieldSortBuilder("message").order(SortOrder.ASC)).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); - assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHit(0).getContent().getRate()).isEqualTo(sampleEntity2.getRate()); + assertThat(searchHits.getSearchHit(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-312 @@ -688,12 +688,12 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity3.getRate()); - assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHit(0).getContent().getRate()).isEqualTo(sampleEntity3.getRate()); + assertThat(searchHits.getSearchHit(1).getContent().getMessage()).isEqualTo(sampleEntity1.getMessage()); } @Test // DATAES-312 @@ -726,12 +726,12 @@ public void shouldSortResultsGivenNullLastSortCriteria() { .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(3); - assertThat(sampleEntities.getContent().get(0).getContent().getRate()).isEqualTo(sampleEntity1.getRate()); - assertThat(sampleEntities.getContent().get(1).getContent().getMessage()).isEqualTo(sampleEntity2.getMessage()); + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHit(0).getContent().getRate()).isEqualTo(sampleEntity1.getRate()); + assertThat(searchHits.getSearchHit(1).getContent().getMessage()).isEqualTo(sampleEntity2.getMessage()); } @Test // DATAES-467, DATAES-657 @@ -752,12 +752,12 @@ public void shouldSortResultsByScore() { .build(); // when - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page.getTotalElements()).isEqualTo(2); - assertThat(page.getContent().get(0).getContent().getId()).isEqualTo("2"); - assertThat(page.getContent().get(1).getContent().getId()).isEqualTo("1"); + assertThat(searchHits.getTotalHits()).isEqualTo(2); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isEqualTo("2"); + assertThat(searchHits.getSearchHit(1).getContent().getId()).isEqualTo("1"); } @Test @@ -776,10 +776,10 @@ public void shouldExecuteStringQuery() { StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); // when - Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(stringQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); + assertThat(searchHits.getTotalHits()).isEqualTo(1); } @Test @@ -807,11 +807,11 @@ public void shouldUseScriptedFields() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withScriptField( new ScriptField("scriptedRate", new Script(ScriptType.INLINE, "expression", "doc['rate'] * factor", params))) .build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getContent().getScriptedRate()).isEqualTo(4.0); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getScriptedRate()).isEqualTo(4.0); } @Test @@ -830,14 +830,14 @@ public void shouldReturnPageableResultsGivenStringQuery() { StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10)); // when - Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(stringQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test - public void shouldReturnSortedPageableResultsGivenStringQuery() { + public void shouldReturnSortedResultsGivenStringQuery() { // given String documentId = randomNumeric(5); @@ -857,10 +857,10 @@ public void shouldReturnSortedPageableResultsGivenStringQuery() { Sort.by(Order.asc("message"))); // when - Page> sampleEntities = operations.searchForPage(stringQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(stringQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -962,12 +962,12 @@ public void shouldReturnSpecifiedFields() { .build(); // when - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isEqualTo(1); - final SampleEntity actual = page.getContent().get(0).getContent(); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + final SampleEntity actual = searchHits.getSearchHit(0).getContent(); assertThat(actual.message).isEqualTo(message); assertThat(actual.getType()).isNull(); assertThat(actual.getLocation()).isNull(); @@ -994,12 +994,12 @@ public void shouldReturnFieldsBasedOnSourceFilter() { .withSourceFilter(sourceFilter.build()).build(); // when - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo(message); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo(message); } @Test @@ -1034,11 +1034,11 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { moreLikeThisQuery.setMinDocFreq(1); // when - Page> sampleEntities = operations.search(moreLikeThisQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(moreLikeThisQuery, SampleEntity.class, index); // then - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - List content = sampleEntities.getContent().stream().map(SearchHit::getContent) + assertThat(searchHits.getTotalHits()).isEqualTo(1); + List content = searchHits.getSearchHits().stream().map(SearchHit::getContent) .collect(Collectors.toList()); assertThat(content).contains(sampleEntity); } @@ -1564,10 +1564,9 @@ public void shouldReturnSameEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ac")).build()); // then - List>> sampleEntities = operations.multiSearchForPage(queries, - SampleEntity.class, index); - for (Page> sampleEntity : sampleEntities) { - assertThat(sampleEntity.getTotalElements()).isEqualTo(1); + List> searchHits = operations.multiSearch(queries, SampleEntity.class, index); + for (SearchHits sampleEntity : searchHits) { + assertThat(sampleEntity.getTotalHits()).isEqualTo(1); } } @@ -1593,18 +1592,17 @@ public void shouldReturnDifferentEntityForMultiSearch() { queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("message", "ab")).build()); queries.add(new NativeSearchQueryBuilder().withQuery(termQuery("description", "bc")).build()); - List>> pages = operations.multiSearchForPage(queries, - Lists.newArrayList(SampleEntity.class, clazz), + List> searchHitsList = operations.multiSearch(queries, Lists.newArrayList(SampleEntity.class, clazz), IndexCoordinates.of(index.getIndexName(), bookIndex.getIndexName())); // then - Page page0 = pages.get(0); - assertThat(page0.getTotalElements()).isEqualTo(1L); - SearchHit searchHit0 = (SearchHit) page0.getContent().get(0); + SearchHits searchHits0 = searchHitsList.get(0); + assertThat(searchHits0.getTotalHits()).isEqualTo(1L); + SearchHit searchHit0 = (SearchHit) searchHits0.getSearchHit(0); assertThat(searchHit0.getContent().getClass()).isEqualTo(SampleEntity.class); - Page page1 = pages.get(1); - assertThat(page1.getTotalElements()).isEqualTo(1L); - SearchHit searchHit1 = (SearchHit) page1.getContent().get(0); + SearchHits searchHits1 = searchHitsList.get(1); + assertThat(searchHits1.getTotalHits()).isEqualTo(1L); + SearchHit searchHit1 = (SearchHit) searchHits1.getSearchHit(0); assertThat(searchHit1.getContent().getClass()).isEqualTo(clazz); } @@ -1629,8 +1627,8 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(0); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits.getTotalHits()).isEqualTo(0); } @Test @@ -1649,10 +1647,10 @@ public void shouldIndexDocumentForSpecifiedSource() { .build(); // then - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(page).isNotNull(); - assertThat(page.getContent()).hasSize(1); - assertThat(page.getContent().get(0).getContent().getId()).isEqualTo(indexQuery.getId()); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isEqualTo(indexQuery.getId()); } @Test @@ -1699,11 +1697,11 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { .withQuery(boolQuery().must(wildcardQuery("message", "*a*")).should(wildcardQuery("message", "*b*"))) .withMinScore(2.0F).build(); - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("ab"); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo("ab"); } @Test // DATAES-462 @@ -1723,12 +1721,11 @@ public void shouldReturnScores() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) .withSort(SortBuilders.fieldSort("message")).withTrackScores(true).build(); - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page).isInstanceOf(AggregatedPage.class); - assertThat(((AggregatedPage) page).getMaxScore()).isGreaterThan(0f); - assertThat(page.getContent().get(0).getScore()).isGreaterThan(0f); + assertThat(searchHits.getMaxScore()).isGreaterThan(0f); + assertThat(searchHits.getSearchHit(0).getScore()).isGreaterThan(0f); } @Test @@ -1784,12 +1781,12 @@ public void shouldDoBulkIndexWithoutId() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(2); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + + assertThat(searchHits.getTotalHits()).isEqualTo(2); - List> content = sampleEntities.getContent(); - assertThat(content.get(0).getContent().getId()).isNotNull(); - assertThat(content.get(1).getContent().getId()).isNotNull(); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isNotNull(); + assertThat(searchHits.getSearchHit(1).getContent().getId()).isNotNull(); } @Test @@ -1828,12 +1825,11 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, Map.class, index); + SearchHits searchHits = operations.search(searchQuery, Map.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(2); - List> content = sampleEntities.getContent(); - assertThat(content.get(0).getContent().get("userId")).isEqualTo(person1.get("userId")); - assertThat(content.get(1).getContent().get("userId")).isEqualTo(person2.get("userId")); + assertThat(searchHits.getTotalHits()).isEqualTo(2); + assertThat(searchHits.getSearchHit(0).getContent().get("userId")).isEqualTo(person1.get("userId")); + assertThat(searchHits.getSearchHit(1).getContent().get("userId")).isEqualTo(person2.get("userId")); } @Test // DATAES-523 @@ -1852,10 +1848,10 @@ public void shouldIndexGteEntityWithVersionType() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page> entities = operations.searchForPage(searchQuery, GTEVersionEntity.class, index); + SearchHits entities = operations.search(searchQuery, GTEVersionEntity.class, index); // then assertThat(entities).isNotNull(); - assertThat(entities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(entities.getTotalHits()).isGreaterThanOrEqualTo(1); // reindex with same version operations.index(indexQueryBuilder.build(), index); @@ -1883,11 +1879,11 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(sampleEntities).isNotNull(); - assertThat(sampleEntities.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test // DATAES-106 @@ -2287,10 +2283,10 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> page = operations.searchForPage(searchQuery, ResultAggregator.class, + SearchHits page = operations.search(searchQuery, ResultAggregator.class, IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); - assertThat(page.getTotalElements()).isEqualTo(2); + assertThat(page.getTotalHits()).isEqualTo(2); } @Test @@ -2348,9 +2344,9 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2379,9 +2375,9 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(1); - assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2408,9 +2404,9 @@ public void shouldDeleteDocumentForGivenIdOnly() { // then // document with id "remainingDocumentId" should still be indexed NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - Page> sampleEntities = operations.searchForPage(searchQuery, SampleEntity.class, index); - assertThat(sampleEntities.getTotalElements()).isEqualTo(1L); - assertThat(sampleEntities.getContent().get(0).getContent().getId()).isEqualTo(remainingDocumentId); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); + assertThat(searchHits.getTotalHits()).isEqualTo(1L); + assertThat(searchHits.getSearchHit(0).getContent().getId()).isEqualTo(remainingDocumentId); } @Test // DATAES-525 @@ -2634,14 +2630,14 @@ public void shouldReturnDocumentWithCollapsedField() { .build(); // when - Page> page = operations.searchForPage(searchQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isEqualTo(3); - assertThat(page.getContent()).hasSize(2); - assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("message 1"); - assertThat(page.getContent().get(1).getContent().getMessage()).isEqualTo("message 2"); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHits()).hasSize(2); + assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo("message 1"); + assertThat(searchHits.getSearchHit(1).getContent().getMessage()).isEqualTo("message 2"); } private IndexQuery getIndexQuery(SampleEntity sampleEntity) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index f05a43000..a8db95146 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -42,6 +42,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; @@ -120,12 +121,9 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { .addAggregation(terms("subjects").field("subject")) // .build(); // when - Aggregations aggregations = operations.query(searchQuery, new ResultsExtractor() { - @Override - public Aggregations extract(SearchResponse response) { - return response.getAggregations(); - } - }, null, IndexCoordinates.of(INDEX_NAME).withTypes("article")); + SearchHits searchHits = operations.search(searchQuery, ArticleEntity.class, IndexCoordinates.of(INDEX_NAME)); + Aggregations aggregations = searchHits.getAggregations(); + // then assertThat(aggregations).isNotNull(); assertThat(aggregations.asMap().get("subjects")).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index ade03dcb9..bc206b2d1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -37,12 +37,12 @@ import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; -import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -137,11 +137,11 @@ public void shouldPerformOrOperation() { new Criteria("message").contains("some").or("message").contains("test")); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -168,14 +168,13 @@ public void shouldPerformAndOperationWithinCriteria() { // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } - // @Ignore("DATAES-30") @Test public void shouldPerformOrOperationWithinCriteria() { @@ -199,11 +198,11 @@ public void shouldPerformOrOperationWithinCriteria() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -228,11 +227,11 @@ public void shouldPerformIsOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -270,11 +269,11 @@ public void shouldPerformMultipleIsOperations() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().getField().getName()).isEqualTo("message"); - assertThat(page.getTotalElements()).isEqualTo(1); + assertThat(searchHits.getTotalHits()).isEqualTo(1); } @Test @@ -520,12 +519,12 @@ public void shouldPerformIsNotOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then assertThat(criteriaQuery.getCriteria().isNegating()).isTrue(); - assertThat(page).isNotNull(); - assertThat(page.iterator().next().getContent().getMessage()).doesNotContain("foo"); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.iterator().next().getContent().getMessage()).doesNotContain("foo"); } @Test @@ -606,11 +605,11 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -649,11 +648,11 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -692,11 +691,11 @@ public void shouldPerformLessThanEqualOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -735,11 +734,11 @@ public void shouldPerformGreaterThanEquals() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page).isNotNull(); - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -778,10 +777,10 @@ public void shouldPerformBoostOperation() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page.getTotalElements()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } @Test @@ -801,11 +800,11 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("a").or(new Criteria("message").contains("b"))); criteriaQuery.setMinScore(2.0F); - Page> page = operations.searchForPage(criteriaQuery, SampleEntity.class, index); + SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then - assertThat(page.getTotalElements()).isEqualTo(1); - assertThat(page.getContent().get(0).getContent().getMessage()).isEqualTo("ab"); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getSearchHit(0).getContent().getMessage()).isEqualTo("ab"); } @Test // DATAES-213 From a68c6ba5d744f016807c66ea9c3ae0a77d46d67a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 28 Dec 2019 19:25:25 +0100 Subject: [PATCH 0025/1191] Dataes 716 - Add value mapping to the ElasticsearchMappingConverter. Original PR: #366 --- .../core/convert/ConversionException.java | 42 ++ .../core/convert/ElasticsearchConverter.java | 90 ++-- .../convert/ElasticsearchDateConverter.java | 99 +++++ .../MappingElasticsearchConverter.java | 403 +++++++++--------- .../ElasticsearchPersistentProperty.java | 29 +- ...sticsearchPersistentPropertyConverter.java | 40 ++ ...SimpleElasticsearchPersistentProperty.java | 57 +++ .../elasticsearch/core/query/Criteria.java | 5 + .../data/elasticsearch/core/query/Field.java | 8 +- .../elasticsearch/core/query/SimpleField.java | 11 +- .../query/ElasticsearchPartQuery.java | 8 +- .../parser/ElasticsearchQueryCreator.java | 6 +- .../repository/query/parser/package-info.java | 5 + .../core/CriteriaQueryMappingTests.java | 104 +++++ .../ElasticsearchDateConverterTests.java | 50 +++ ...appingElasticsearchConverterUnitTests.java | 56 ++- .../core/index/MappingBuilderTests.java | 3 +- ...sticsearchPersistentPropertyUnitTests.java | 53 +++ 18 files changed, 822 insertions(+), 247 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java new file mode 100644 index 000000000..33a504610 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java @@ -0,0 +1,42 @@ +/* + * Copyright 2019 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.convert; + +/** + * @author Peter-Josef Meisch + */ +public class ConversionException extends RuntimeException { + public ConversionException() { + super(); + } + + public ConversionException(String message) { + super(message); + } + + public ConversionException(String message, Throwable cause) { + super(message, cause); + } + + public ConversionException(Throwable cause) { + super(cause); + } + + protected ConversionException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index e377d8962..ed3d27af9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.convert; import java.util.List; +import java.util.stream.Collectors; import org.springframework.data.convert.EntityConverter; import org.springframework.data.domain.Pageable; @@ -27,6 +28,7 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.lang.Nullable; @@ -41,28 +43,6 @@ public interface ElasticsearchConverter extends EntityConverter, ElasticsearchPersistentProperty, Object, Document> { - /** - * Convert a given {@literal idValue} to its {@link String} representation taking potentially registered - * {@link org.springframework.core.convert.converter.Converter Converters} into account. - * - * @param idValue must not be {@literal null}. - * @return never {@literal null}. - * @since 3.2 - */ - default String convertId(Object idValue) { - - Assert.notNull(idValue, "idValue must not be null!"); - - if (!getConversionService().canConvert(idValue.getClass(), String.class)) { - return idValue.toString(); - } - - return getConversionService().convert(idValue, String.class); - } - - AggregatedPage> mapResults(SearchDocumentResponse response, Class clazz, - @Nullable Pageable pageable); - /** * Get the configured {@link ProjectionFactory}.
* NOTE Should be overwritten in implementation to make use of the type cache. @@ -73,20 +53,35 @@ default ProjectionFactory getProjectionFactory() { return new SpelAwareProxyProjectionFactory(); } + // region read /** * Map a single {@link Document} to an instance of the given type. * * @param document the document to map * @param type must not be {@literal null}. - * @param + * @param the class of type * @return can be {@literal null} if the document is null or {@link Document#isEmpty()} is true. * @since 4.0 */ @Nullable T mapDocument(@Nullable Document document, Class type); + /** + * Map a list of {@link Document}s to a list of instance of the given type. + * + * @param documents must not be {@literal null}. + * @param type must not be {@literal null}. + * @param the class of type + * @return a list obtained by calling {@link #mapDocument(Document, Class)} on the elements of the list. + * @since 4.0 + */ + default List mapDocuments(List documents, Class type) { + return documents.stream().map(document -> mapDocument(document, type)).collect(Collectors.toList()); + } + /** * builds a {@link SearchHits} from a {@link SearchDocumentResponse}. + * * @param the clazz of the type, must not be {@literal null}. * @param type the type of the returned data, must not be {@literal null}. * @param searchDocumentResponse the response to read from, must not be {@literal null}. @@ -106,22 +101,53 @@ default ProjectionFactory getProjectionFactory() { */ SearchHit read(Class type, SearchDocument searchDocument); + AggregatedPage> mapResults(SearchDocumentResponse response, Class clazz, + @Nullable Pageable pageable); + + // endregion + + // region write /** - * Map a list of {@link Document}s to alist of instance of the given type. + * Convert a given {@literal idValue} to its {@link String} representation taking potentially registered + * {@link org.springframework.core.convert.converter.Converter Converters} into account. * - * @param documents must not be {@literal null}. - * @param type must not be {@literal null}. - * @param - * @return a list obtained by calling {@link #mapDocument(Document, Class)} on the elements of the list. - * @since 4.0 + * @param idValue must not be {@literal null}. + * @return never {@literal null}. + * @since 3.2 */ - List mapDocuments(List documents, Class type); + default String convertId(Object idValue) { + + Assert.notNull(idValue, "idValue must not be null!"); + + if (!getConversionService().canConvert(idValue.getClass(), String.class)) { + return idValue.toString(); + } + + return getConversionService().convert(idValue, String.class); + } /** * Map an object to a {@link Document}. * - * @param source + * @param source the object to map * @return will not be {@literal null}. */ - Document mapObject(Object source); + default Document mapObject(@Nullable Object source) { + Document target = Document.create(); + write(source, target); + return target; + } + // endregion + + /** + * Updates a query by renaming the property names in the query to the correct mapped field names and the values to the + * converted values if the {@link ElasticsearchPersistentProperty} for a property has a + * {@link org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter}. + * + * @param criteriaQuery the query that is internally updated + * @param domainClass the class of the object that is searched with the query + */ + // region query + void updateQuery(CriteriaQuery criteriaQuery, Class domainClass); + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java new file mode 100644 index 000000000..0d6d25240 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java @@ -0,0 +1,99 @@ +/* + * Copyright 2019 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.convert; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.time.temporal.TemporalAccessor; +import java.util.concurrent.ConcurrentHashMap; + +import org.elasticsearch.common.time.DateFormatter; +import org.springframework.data.elasticsearch.annotations.DateFormat; +import org.springframework.util.Assert; + +/** + * Provides Converter instances to convert to and from Dates in the different date and time formats that elasticsearch + * understands. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +final public class ElasticsearchDateConverter { + + private static final ConcurrentHashMap converters = new ConcurrentHashMap<>(); + + private final DateFormatter dateFormatter; + + /** + * Creates an ElasticsearchDateConverter for the given {@link DateFormat}. + * + * @param dateFormat must not be @{literal null} + * @return converter + */ + public static ElasticsearchDateConverter of(DateFormat dateFormat) { + + Assert.notNull(dateFormat, "dateFormat must not be null"); + + return of(dateFormat.name()); + } + + /** + * Creates an ElasticsearchDateConverter for the given pattern. + * + * @param pattern must not be {@literal null} + * @return converter + */ + public static ElasticsearchDateConverter of(String pattern) { + Assert.notNull(pattern, "pattern must not be null"); + + return converters.computeIfAbsent(pattern, p -> new ElasticsearchDateConverter(DateFormatter.forPattern(p))); + } + + private ElasticsearchDateConverter(DateFormatter dateFormatter) { + this.dateFormatter = dateFormatter; + } + + /** + * Formats the given {@link TemporalAccessor} int a String + * + * @param accessor must not be {@literal null} + * @return the formatted object + */ + public String format(TemporalAccessor accessor) { + return dateFormatter.format(accessor); + } + + /** + * Parses a String into an object + * + * @param input the String to parse, must not be {@literal null}. + * @param type the class to return + * @param the class of type + * @return the new created object + */ + public T parse(String input, Class type) { + TemporalAccessor accessor = dateFormatter.parse(input); + try { + Method method = type.getMethod("from", TemporalAccessor.class); + Object o = method.invoke(null, accessor); + return type.cast(o); + } catch (NoSuchMethodException e) { + throw new ConversionException("no 'from' factory method found in class " + type.getName()); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new ConversionException("could not create object of class " + type.getName(), e); + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 2a7243d47..b383c346b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,8 +15,6 @@ */ package org.springframework.data.elasticsearch.core.convert; -import lombok.RequiredArgsConstructor; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -54,6 +52,8 @@ import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; @@ -133,40 +133,86 @@ public void setConversions(CustomConversions conversions) { this.conversions = conversions; } - /** - * Set the {@link ElasticsearchTypeMapper} to use for reading / writing type hints. - * - * @param typeMapper must not be {@literal null}. - */ - public void setTypeMapper(ElasticsearchTypeMapper typeMapper) { - this.typeMapper = typeMapper; - } - /* * (non-Javadoc) * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ @Override public void afterPropertiesSet() { - DateFormatterRegistrar.addDateConverters(conversionService); conversions.registerConvertersIn(conversionService); } - @SuppressWarnings("unchecked") + // region read + + @Override + public AggregatedPage> mapResults(SearchDocumentResponse response, Class type, + Pageable pageable) { + + List> results = response.getSearchDocuments().stream() // + .map(searchDocument -> read(type, searchDocument)) // + .collect(Collectors.toList()); + + return new AggregatedPageImpl<>(results, pageable, response); + } + + @Override + public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { + + Assert.notNull(type, "type must not be null"); + Assert.notNull(searchDocumentResponse, "searchDocumentResponse must not be null"); + + long totalHits = searchDocumentResponse.getTotalHits(); + float maxScore = searchDocumentResponse.getMaxScore(); + String scrollId = searchDocumentResponse.getScrollId(); + List> searchHits = searchDocumentResponse.getSearchDocuments().stream() // + .map(searchDocument -> read(type, searchDocument)) // + .collect(Collectors.toList()); + Aggregations aggregations = searchDocumentResponse.getAggregations(); + return new SearchHits(totalHits, maxScore, scrollId, searchHits, aggregations); + } + + public SearchHit read(Class type, SearchDocument searchDocument) { + + Assert.notNull(type, "type must not be null"); + Assert.notNull(searchDocument, "searchDocument must not be null"); + + String id = searchDocument.hasId() ? searchDocument.getId() : null; + float score = searchDocument.getScore(); + Object[] sortValues = searchDocument.getSortValues(); + T content = mapDocument(searchDocument, type); + + return new SearchHit(id, score, sortValues, content); + } + @Override @Nullable - public R read(Class type, Document source) { - return doRead(source, ClassTypeInformation.from((Class) ClassUtils.getUserClass(type))); + public T mapDocument(@Nullable Document document, Class type) { + + if (document == null) { + return null; + } + + T mappedResult = read(type, document); + + return type.isInterface() || !ClassUtils.isAssignableValue(type, mappedResult) + ? getProjectionFactory().createProjection(type, mappedResult) + : type.cast(mappedResult); } @SuppressWarnings("unchecked") - @Nullable - protected R doRead(Document source, TypeInformation typeHint) { + @Override + public R read(Class type, Document source) { + TypeInformation typeHint = ClassTypeInformation.from((Class) ClassUtils.getUserClass(type)); typeHint = (TypeInformation) typeMapper.readType(source, typeHint); if (conversions.hasCustomReadTarget(Map.class, typeHint.getType())) { - return conversionService.convert(source, typeHint.getType()); + R converted = conversionService.convert(source, typeHint.getType()); + if (converted == null) { + // EntityReader.read is defined as non nullable , so we cannot return null + throw new ConversionException("conversion service to type " + typeHint.getType().getName() + " returned null"); + } + return converted; } if (typeHint.isMap() || ClassTypeInformation.OBJECT.equals(typeHint)) { @@ -177,7 +223,6 @@ protected R doRead(Document source, TypeInformation typeHint) { return readEntity(entity, source); } - @SuppressWarnings("unchecked") protected R readEntity(ElasticsearchPersistentEntity entity, Map source) { ElasticsearchPersistentEntity targetEntity = computeClosestEntity(entity, source); @@ -187,6 +232,7 @@ protected R readEntity(ElasticsearchPersistentEntity entity, Map(targetEntity, propertyValueProvider, null)); @@ -248,7 +294,7 @@ protected R readProperties(ElasticsearchPersistentEntity entity, R instan Object value = valueProvider.getPropertyValue(prop); if (value != null) { - accessor.setProperty(prop, valueProvider.getPropertyValue(prop)); + accessor.setProperty(prop, value); } } @@ -256,6 +302,7 @@ protected R readProperties(ElasticsearchPersistentEntity entity, R instan } @SuppressWarnings("unchecked") + @Nullable protected R readValue(@Nullable Object source, ElasticsearchPersistentProperty property, TypeInformation targetType) { @@ -263,11 +310,15 @@ protected R readValue(@Nullable Object source, ElasticsearchPersistentProper return null; } + if (property.hasPropertyConverter() && String.class.isAssignableFrom(source.getClass())) { + source = property.getPropertyConverter().read((String) source); + } + Class rawType = targetType.getType(); if (conversions.hasCustomReadTarget(source.getClass(), rawType)) { return rawType.cast(conversionService.convert(source, rawType)); } else if (source instanceof List) { - return readCollectionValue((List) source, property, targetType); + return readCollectionValue((List) source, property, targetType); } else if (source instanceof Map) { return readMapValue((Map) source, property, targetType); } @@ -275,11 +326,40 @@ protected R readValue(@Nullable Object source, ElasticsearchPersistentProper return (R) readSimpleValue(source, targetType); } + @SuppressWarnings("unchecked") + @Nullable + private R readCollectionValue(@Nullable List source, ElasticsearchPersistentProperty property, + TypeInformation targetType) { + + if (source == null) { + return null; + } + + Collection target = createCollectionForValue(targetType, source.size()); + + for (Object value : source) { + + if (isSimpleType(value)) { + target.add( + readSimpleValue(value, targetType.getComponentType() != null ? targetType.getComponentType() : targetType)); + } else { + + if (value instanceof List) { + target.add(readValue(value, property, property.getTypeInformation().getActualType())); + } else { + target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value)); + } + } + } + + return (R) target; + } + @SuppressWarnings("unchecked") private R readMapValue(@Nullable Map source, ElasticsearchPersistentProperty property, TypeInformation targetType) { - TypeInformation information = typeMapper.readType(source); + TypeInformation information = typeMapper.readType(source); if (property.isEntity() && !property.isMap() || information != null) { ElasticsearchPersistentEntity targetEntity = information != null @@ -300,9 +380,9 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe if (targetEntity.getTypeInformation().isMap()) { - Map valueMap = (Map) entry.getValue(); + Map valueMap = (Map) entry.getValue(); if (typeMapper.containsTypeInformation(valueMap)) { - target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue())); + target.put(entry.getKey(), readEntity(targetEntity, valueMap)); } else { target.put(entry.getKey(), readValue(valueMap, property, targetEntity.getTypeInformation())); } @@ -311,7 +391,7 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe target.put(entry.getKey(), readValue(entry.getValue(), property, targetEntity.getTypeInformation().getActualType())); } else { - target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue())); + target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue())); } } } @@ -319,40 +399,13 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe return (R) target; } - @SuppressWarnings("unchecked") - private R readCollectionValue(@Nullable List source, ElasticsearchPersistentProperty property, - TypeInformation targetType) { - - if (source == null) { - return null; - } - - Collection target = createCollectionForValue(targetType, source.size()); - - for (Object value : source) { - - if (isSimpleType(value)) { - target.add( - readSimpleValue(value, targetType.getComponentType() != null ? targetType.getComponentType() : targetType)); - } else { - - if (value instanceof List) { - target.add(readValue(value, property, property.getTypeInformation().getActualType())); - } else { - target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value)); - } - } - } - - return (R) target; - } - - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Nullable private Object readSimpleValue(@Nullable Object value, TypeInformation targetType) { Class target = targetType.getType(); - if (value == null || target == null || ClassUtils.isAssignableValue(target, value)) { + if (value == null || ClassUtils.isAssignableValue(target, value)) { return value; } @@ -367,16 +420,38 @@ private Object readSimpleValue(@Nullable Object value, TypeInformation target return conversionService.convert(value, target); } - @SuppressWarnings("unchecked") + private void populateScriptFields(T result, SearchDocument searchDocument) { + Map> fields = searchDocument.getFields(); + if (!fields.isEmpty()) { + for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) { + ScriptedField scriptedField = field.getAnnotation(ScriptedField.class); + if (scriptedField != null) { + String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name(); + Object value = searchDocument.getFieldValue(name); + if (value != null) { + field.setAccessible(true); + try { + field.set(result, value); + } catch (IllegalArgumentException e) { + throw new ElasticsearchException("failed to set scripted field: " + name + " with value: " + value, e); + } catch (IllegalAccessException e) { + throw new ElasticsearchException("failed to access scripted field: " + name, e); + } + } + } + } + } + } + // endregion + + // region write @Override - public void write(@Nullable Object source, Document sink) { + public void write(Object source, Document sink) { - if (source == null) { - return; - } + Assert.notNull(source, "source to map must not be null"); if (source instanceof Map) { - + // noinspection unchecked sink.putAll((Map) source); return; } @@ -388,41 +463,22 @@ public void write(@Nullable Object source, Document sink) { typeMapper.writeType(source.getClass(), sink); } - doWrite(source, sink, type); - } - - protected void doWrite(@Nullable Object source, Document sink, @Nullable TypeInformation typeHint) { - - if (source == null) { - return; - } - - Class entityType = source.getClass(); Optional> customTarget = conversions.getCustomWriteTarget(entityType, Map.class); if (customTarget.isPresent()) { - sink.putAll(conversionService.convert(source, Map.class)); return; } - if (typeHint != null) { - - ElasticsearchPersistentEntity entity = typeHint.getType().equals(entityType) - ? mappingContext.getRequiredPersistentEntity(typeHint) - : mappingContext.getRequiredPersistentEntity(entityType); + ElasticsearchPersistentEntity entity = type.getType().equals(entityType) + ? mappingContext.getRequiredPersistentEntity(type) + : mappingContext.getRequiredPersistentEntity(entityType); - writeEntity(entity, source, sink, null); - return; - } - - // write Entity - ElasticsearchPersistentEntity entity = mappingContext.getRequiredPersistentEntity(entityType); writeEntity(entity, source, sink, null); } protected void writeEntity(ElasticsearchPersistentEntity entity, Object source, Document sink, - @Nullable TypeInformation containingStructure) { + @Nullable TypeInformation containingStructure) { PersistentPropertyAccessor accessor = entity.getPropertyAccessor(source); @@ -448,10 +504,18 @@ protected void writeProperties(ElasticsearchPersistentEntity entity, Persiste continue; } + if (property.hasPropertyConverter()) { + ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); + value = propertyConverter.write(value); + } + if (!isSimpleType(value)) { writeProperty(property, value, sink); } else { - sink.set(property, getWriteSimpleValue(value)); + Object writeSimpleValue = getWriteSimpleValue(value); + if (writeSimpleValue != null) { + sink.set(property, writeSimpleValue); + } } } } @@ -461,7 +525,6 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va Optional> customWriteTarget = conversions.getCustomWriteTarget(value.getClass()); if (customWriteTarget.isPresent()) { - Class writeTarget = customWriteTarget.get(); sink.set(property, conversionService.convert(value, writeTarget)); return; @@ -484,12 +547,8 @@ protected void writeProperty(ElasticsearchPersistentProperty property, Object va sink.set(property, getWriteComplexValue(property, typeHint, value)); } + @Nullable protected Object getWriteSimpleValue(Object value) { - - if (value == null) { - return null; - } - Optional> customTarget = conversions.getCustomWriteTarget(value.getClass()); if (customTarget.isPresent()) { @@ -583,67 +642,30 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert } return target; } + // endregion - @Override - @Nullable - public T mapDocument(@Nullable Document document, Class type) { - - if (document == null) { - return null; - } - - Object mappedResult = read(type, document); - - if (mappedResult == null) { - return (T) null; - } - - return type.isInterface() || !ClassUtils.isAssignableValue(type, mappedResult) - ? getProjectionFactory().createProjection(type, mappedResult) - : type.cast(mappedResult); - } - - @Override - public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { - - Assert.notNull(type, "type must not be null"); - Assert.notNull(searchDocumentResponse, "searchDocumentResponse must not be null"); - - long totalHits = searchDocumentResponse.getTotalHits(); - float maxScore = searchDocumentResponse.getMaxScore(); - String scrollId = searchDocumentResponse.getScrollId(); - List> searchHits = searchDocumentResponse.getSearchDocuments().stream() // - .map(searchDocument -> read(type, searchDocument)) // - .collect(Collectors.toList()); - Aggregations aggregations = searchDocumentResponse.getAggregations(); - return new SearchHits(totalHits, maxScore, scrollId, searchHits, aggregations); - } - - @Override - public SearchHit read(Class type, SearchDocument searchDocument) { - - Assert.notNull(type, "type must not be null"); - Assert.notNull(searchDocument, "searchDocument must not be null"); + // region helper methods + private Collection createCollectionForValue(TypeInformation collectionTypeInformation, int size) { - String id = searchDocument.hasId() ? searchDocument.getId() : null; - float score = searchDocument.getScore(); - Object[] sortValues = searchDocument.getSortValues(); - T content = mapDocument(searchDocument, type); + Class collectionType = collectionTypeInformation.isSubTypeOf(Collection.class) // + ? collectionTypeInformation.getType() // + : List.class; - return new SearchHit(id, score, sortValues, content); - } + TypeInformation componentType = collectionTypeInformation.getComponentType() != null // + ? collectionTypeInformation.getComponentType() // + : ClassTypeInformation.OBJECT; - @Override - public List mapDocuments(List documents, Class type) { - return documents.stream().map(it -> mapDocument(it, type)).collect(Collectors.toList()); + return collectionTypeInformation.getType().isArray() // + ? new ArrayList<>(size) // + : CollectionFactory.createCollection(collectionType, componentType.getType(), size); } - @Override - public Document mapObject(Object source) { + private ElasticsearchPersistentEntity computeGenericValueTypeForRead(ElasticsearchPersistentProperty property, + Object value) { - Document target = Document.create(); - write(source, target); - return target; + return ClassTypeInformation.OBJECT.equals(property.getTypeInformation().getActualType()) + ? mappingContext.getRequiredPersistentEntity(value.getClass()) + : mappingContext.getRequiredPersistentEntity(property.getTypeInformation().getActualType()); } private boolean requiresTypeHint(TypeInformation type, Class actualType, @@ -697,29 +719,6 @@ private ElasticsearchPersistentEntity computeClosestEntity(ElasticsearchPersi return mappingContext.getRequiredPersistentEntity(typeToUse); } - private ElasticsearchPersistentEntity computeGenericValueTypeForRead(ElasticsearchPersistentProperty property, - Object value) { - - return ClassTypeInformation.OBJECT.equals(property.getTypeInformation().getActualType()) - ? mappingContext.getRequiredPersistentEntity(value.getClass()) - : mappingContext.getRequiredPersistentEntity(property.getTypeInformation().getActualType()); - } - - private Collection createCollectionForValue(TypeInformation collectionTypeInformation, int size) { - - Class collectionType = collectionTypeInformation.isSubTypeOf(Collection.class) // - ? collectionTypeInformation.getType() // - : List.class; - - TypeInformation componentType = collectionTypeInformation.getComponentType() != null // - ? collectionTypeInformation.getComponentType() // - : ClassTypeInformation.OBJECT; - - return collectionTypeInformation.getType().isArray() // - ? new ArrayList<>(size) // - : CollectionFactory.createCollection(collectionType, componentType.getType(), size); - } - private boolean isSimpleType(Object value) { return isSimpleType(value.getClass()); } @@ -727,40 +726,40 @@ private boolean isSimpleType(Object value) { private boolean isSimpleType(Class type) { return conversions.isSimpleType(type); } + // endregion + // region queries @Override - public AggregatedPage> mapResults(SearchDocumentResponse response, Class type, - Pageable pageable) { - - List> results = response.getSearchDocuments().stream() // - .map(searchDocument -> read(type, searchDocument)) // - .collect(Collectors.toList()); - - return new AggregatedPageImpl<>(results, pageable, response); - } - - private void populateScriptFields(T result, SearchDocument searchDocument) { - Map> fields = searchDocument.getFields(); - if (!fields.isEmpty()) { - for (java.lang.reflect.Field field : result.getClass().getDeclaredFields()) { - ScriptedField scriptedField = field.getAnnotation(ScriptedField.class); - if (scriptedField != null) { - String name = scriptedField.name().isEmpty() ? field.getName() : scriptedField.name(); - Object value = searchDocument.getFieldValue(name); - if (value != null) { - field.setAccessible(true); - try { - field.set(result, value); - } catch (IllegalArgumentException e) { - throw new ElasticsearchException("failed to set scripted field: " + name + " with value: " + value, e); - } catch (IllegalAccessException e) { - throw new ElasticsearchException("failed to access scripted field: " + name, e); - } + public void updateQuery(CriteriaQuery criteriaQuery, Class domainClass) { + ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(domainClass); + + if (persistentEntity != null) { + criteriaQuery.getCriteria().getCriteriaChain().forEach(criteria -> { + String name = criteria.getField().getName(); + ElasticsearchPersistentProperty property = persistentEntity.getPersistentProperty(name); + + if (property != null && property.getName().equals(name)) { + criteria.getField().setName(property.getFieldName()); + + if (property.hasPropertyConverter()) { + ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); + criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> { + Object value = criteriaEntry.getValue(); + if (value.getClass().isArray()) { + Object[] objects = (Object[]) value; + for (int i = 0; i < objects.length; i++) { + objects[i] = propertyConverter.write(objects[i]); + } + } else { + criteriaEntry.setValue(propertyConverter.write(value)); + } + }); } } - } + }); } } + // endregion static class MapValueAccessor { @@ -770,6 +769,7 @@ static class MapValueAccessor { this.target = target; } + @Nullable public Object get(ElasticsearchPersistentProperty property) { if (target instanceof Document) { @@ -801,7 +801,7 @@ public Object get(ElasticsearchPersistentProperty property) { Map source = target; Object result = null; - while (source != null && parts.hasNext()) { + while (parts.hasNext()) { result = source.get(parts.next()); @@ -826,22 +826,25 @@ public void set(ElasticsearchPersistentProperty property, Object value) { target.put(property.getFieldName(), value); } - @SuppressWarnings("unchecked") private Map getAsMap(Object result) { if (result instanceof Map) { - return (Map) result; + // noinspection unchecked + return (Map) result; } throw new IllegalArgumentException(String.format("%s is not a Map.", result)); } } - @RequiredArgsConstructor class ElasticsearchPropertyValueProvider implements PropertyValueProvider { final MapValueAccessor mapValueAccessor; + ElasticsearchPropertyValueProvider(MapValueAccessor mapValueAccessor) { + this.mapValueAccessor = mapValueAccessor; + } + @SuppressWarnings("unchecked") @Override public T getPropertyValue(ElasticsearchPersistentProperty property) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java index 170c39f8d..e62052741 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java @@ -17,6 +17,7 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.mapping.PersistentProperty; +import org.springframework.lang.Nullable; /** * ElasticsearchPersistentProperty @@ -60,7 +61,20 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty { + /** + * @return true if an {@link ElasticsearchPersistentPropertyConverter} is available for this instance. + * @since 4.0 + */ + boolean hasPropertyConverter(); + + /** + * @return the {@link ElasticsearchPersistentPropertyConverter} for this instance. + * @since 4.0 + */ + @Nullable + ElasticsearchPersistentPropertyConverter getPropertyConverter(); + + enum PropertyToFieldNameConverter implements Converter { INSTANCE; @@ -68,4 +82,17 @@ public String convert(ElasticsearchPersistentProperty source) { return source.getFieldName(); } } + + /** + * when building CriteriaQueries use the name; the fieldname is set later with + * {@link org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter}. + */ + enum QueryPropertyToFieldNameConverter implements Converter { + + INSTANCE; + + public String convert(ElasticsearchPersistentProperty source) { + return source.getName(); + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java new file mode 100644 index 000000000..24da65fe5 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java @@ -0,0 +1,40 @@ +/* + * Copyright 2019 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.mapping; + +/** + * Interface defining methods to convert a property value to a String and back. + * + * @author Peter-Josef Meisch + */ +public interface ElasticsearchPersistentPropertyConverter { + + /** + * converts the property value to a String. + * + * @param property the property value to convert, must not be {@literal null} + * @return String representation. + */ + String write(Object property); + + /** + * converts a property value from a String. + * + * @param s the property to convert, must not be {@literal null} + * @return property value + */ + Object read(String s); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index cdedcaad3..ee0825e52 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -15,12 +15,16 @@ */ package org.springframework.data.elasticsearch.core.mapping; +import java.time.temporal.TemporalAccessor; import java.util.Arrays; import java.util.List; +import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Score; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentEntity; @@ -49,6 +53,7 @@ public class SimpleElasticsearchPersistentProperty extends private final boolean isParent; private final boolean isId; private final @Nullable String annotatedFieldName; + private ElasticsearchPersistentPropertyConverter propertyConverter; public SimpleElasticsearchPersistentProperty(Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { @@ -72,6 +77,58 @@ public SimpleElasticsearchPersistentProperty(Property property, if (isParent && !getType().equals(String.class)) { throw new MappingException(String.format("Parent property %s must be of type String!", property.getName())); } + + initDateConverter(); + } + + @Override + public boolean hasPropertyConverter() { + return propertyConverter != null; + } + + @Override + public ElasticsearchPersistentPropertyConverter getPropertyConverter() { + return propertyConverter; + } + + /** + * Initializes an {@link ElasticsearchPersistentPropertyConverter} if this property is annotated as a Field with type + * {@link FieldType#Date}, has a {@link DateFormat} set and if the type of the property is one of the Java8 temporal + * classes. + */ + private void initDateConverter() { + Field field = findAnnotation(Field.class); + if (field != null && field.type() == FieldType.Date && TemporalAccessor.class.isAssignableFrom(getType())) { + DateFormat dateFormat = field.format(); + + ElasticsearchDateConverter converter = null; + + if (dateFormat == DateFormat.custom) { + String pattern = field.pattern(); + + if (StringUtils.hasLength(pattern)) { + converter = ElasticsearchDateConverter.of(pattern); + } + } else if (dateFormat != DateFormat.none) { + converter = ElasticsearchDateConverter.of(dateFormat); + } + + if (converter != null) { + ElasticsearchDateConverter dateConverter = converter; + propertyConverter = new ElasticsearchPersistentPropertyConverter() { + @Override + public String write(Object property) { + return dateConverter.format((TemporalAccessor) property); + } + + @SuppressWarnings("unchecked") + @Override + public Object read(String s) { + return dateConverter.parse(s, (Class) getType()); + } + }; + } + } } @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index 83ae04429..3a7bc43c4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -624,6 +624,7 @@ public enum OperationKey { // public static class CriteriaEntry { private OperationKey key; + private Object value; CriteriaEntry(OperationKey key, Object value) { @@ -635,6 +636,10 @@ public OperationKey getKey() { return key; } + public void setValue(Object value) { + this.value = value; + } + public Object getValue() { return value; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java index e41ddbd3b..936445231 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java @@ -20,13 +20,11 @@ * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public interface Field { - /** - * Get the name of the field used in schema.xml of elasticsearch server - * - * @return - */ + void setName(String name); + String getName(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index 5dc6f6cb8..42dac159d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -15,17 +15,26 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.util.Assert; + /** * The most trivial implementation of a Field * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class SimpleField implements Field { - private final String name; + private String name; public SimpleField(String name) { + setName(name); + } + + @Override + public void setName(String name) { + Assert.notNull(name, "name must not be null"); this.name = name; } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index d2b870e09..38d75d05e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -19,6 +19,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; @@ -45,12 +46,14 @@ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery private static final int DEFAULT_STREAM_BATCH_SIZE = 500; private final PartTree tree; + private final ElasticsearchConverter elasticsearchConverter; private final MappingContext mappingContext; public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOperations elasticsearchOperations) { super(method, elasticsearchOperations); this.tree = new PartTree(method.getName(), method.getEntityInformation().getJavaType()); - this.mappingContext = elasticsearchOperations.getElasticsearchConverter().getMappingContext(); + this.elasticsearchConverter = elasticsearchOperations.getElasticsearchConverter(); + this.mappingContext = elasticsearchConverter.getMappingContext(); } @Override @@ -58,7 +61,10 @@ public Object execute(Object[] parameters) { ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); CriteriaQuery query = createQuery(accessor); Assert.notNull(query, "unsupported query"); + Class clazz = queryMethod.getEntityInformation().getJavaType(); + elasticsearchConverter.updateQuery(query, clazz); + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); Object result = null; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java index f7f327efd..4f4d9b707 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java @@ -65,7 +65,8 @@ protected CriteriaQuery create(Part part, Iterator iterator) { PersistentPropertyPath path = context .getPersistentPropertyPath(part.getProperty()); return new CriteriaQuery(from(part, - new Criteria(path.toDotPath(ElasticsearchPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator)); + new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)), + iterator)); } @Override @@ -76,7 +77,8 @@ protected CriteriaQuery and(Part part, CriteriaQuery base, Iterator iter PersistentPropertyPath path = context .getPersistentPropertyPath(part.getProperty()); return base.addCriteria(from(part, - new Criteria(path.toDotPath(ElasticsearchPersistentProperty.PropertyToFieldNameConverter.INSTANCE)), iterator)); + new Criteria(path.toDotPath(ElasticsearchPersistentProperty.QueryPropertyToFieldNameConverter.INSTANCE)), + iterator)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java new file mode 100644 index 000000000..3086bad78 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java @@ -0,0 +1,5 @@ +/** + * Infrastructure for the Elasticsearch document-to-object mapping subsystem. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.repository.query.parser; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java new file mode 100644 index 000000000..3176498e4 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -0,0 +1,104 @@ +/* + * Copyright 2019 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; + +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import java.time.LocalDate; +import java.util.Collections; + +import org.json.JSONException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.DateFormat; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; + +/** + * Tests for the mapping of {@link CriteriaQuery} by a + * {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. In the same package as + * {@link CriteriaQueryProcessor} as this is needed to get the String represenation to assert. + * + * @author Peter-Josef Meisch + */ +public class CriteriaQueryMappingTests { + + MappingElasticsearchConverter mappingElasticsearchConverter; + + @BeforeEach + void setUp() { + SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext(); + mappingContext.setInitialEntitySet(Collections.singleton(Person.class)); + mappingContext.afterPropertiesSet(); + + mappingElasticsearchConverter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService()); + mappingElasticsearchConverter.afterPropertiesSet(); + + } + + @Test + void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException { + + // use POJO properties and types in the query building + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("birthDate").between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28))); + + // mapped field name and converted parameter + String expected = '{' + // + " \"bool\" : {" + // + " \"should\" : [" + // + " {" + // + " \"range\" : {" + // + " \"birth-date\" : {" + // + " \"from\" : \"09.11.1989\"," + // + " \"to\" : \"09.11.1990\"," + // + " \"include_lower\" : true," + // + " \"include_upper\" : true" + // + " }" + // + " }" + // + " }," + // + " {" + // + " \"query_string\" : {" + // + " \"query\" : \"28.12.2019\"," + // + " \"fields\" : [" + // + " \"birth-date^1.0\"" + // + " ]" + // + " }" + // + " }" + // + " ]" + // + " }" + // + '}'; // + + mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class); + String queryString = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()).toString(); + + assertEquals(expected, queryString, false); + } + + static class Person { + @Id String id; + @Field(name = "first-name") String firstName; + @Field(name = "last-name") String lastName; + @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, + pattern = "dd.MM.yyyy") LocalDate birthDate; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java new file mode 100644 index 000000000..50fe532f3 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -0,0 +1,50 @@ +package org.springframework.data.elasticsearch.core.convert; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDate; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.springframework.data.elasticsearch.annotations.DateFormat; + +/** + * @author Peter-Josef Meisch + */ +class ElasticsearchDateConverterTests { + + @ParameterizedTest + @EnumSource(DateFormat.class) + void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) { + + if (dateFormat == DateFormat.none) { + return; + } + String pattern = (dateFormat != DateFormat.custom) ? dateFormat.name() : "dd.MM.yyyy"; + + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(pattern); + + assertThat(converter).isNotNull(); + } + + @Test + void shouldConvertToString() { + LocalDate localDate = LocalDate.of(2019, 12, 27); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date); + + String formatted = converter.format(localDate); + + assertThat(formatted).isEqualTo("20191227"); + } + + @Test + void shouldParseFromString() { + LocalDate localDate = LocalDate.of(2019, 12, 27); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date); + + LocalDate parsed = converter.parse("20191227", LocalDate.class); + + assertThat(parsed).isEqualTo(localDate); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index adea4003d..009618c8d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.convert; import static org.assertj.core.api.Assertions.*; +import static org.skyscreamer.jsonassert.JSONAssert.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -26,16 +27,17 @@ import lombok.RequiredArgsConstructor; import java.io.IOException; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.convert.ConversionService; @@ -47,10 +49,15 @@ import org.springframework.data.annotation.TypeAlias; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; +import org.springframework.data.elasticsearch.annotations.DateFormat; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; @@ -294,7 +301,7 @@ public void ignoresReadOnlyProperties() throws IOException { public void writesNestedEntity() { Person person = new Person(); - person.birthdate = new Date(); + person.birthDate = LocalDate.now(); person.gender = Gender.MAN; person.address = observatoryRoad; @@ -574,6 +581,45 @@ public void readSubTypeCorrectly() { assertThat(target.address).isEqualTo(bigBunsCafe); } + @Test // DATAES-716 + void shouldWriteLocalDate() throws JSONException { + Person person = new Person(); + person.id = "4711"; + person.firstName = "John"; + person.lastName = "Doe"; + person.birthDate = LocalDate.of(2000, 8, 22); + person.gender = Gender.MAN; + + String expected = '{' + // + " \"id\": \"4711\"," + // + " \"first-name\": \"John\"," + // + " \"last-name\": \"Doe\"," + // + " \"birth-date\": \"22.08.2000\"," + // + " \"gender\": \"MAN\"" + // + '}'; + Document document = Document.create(); + mappingElasticsearchConverter.write(person, document); + String json = document.toJson(); + + assertEquals(expected, json, false); + } + + @Test + void shouldReadLocalDate() { + Document document = Document.create(); + document.put("id", "4711"); + document.put("first-name", "John"); + document.put("last-name", "Doe"); + document.put("birth-date", "22.08.2000"); + document.put("gender", "MAN"); + + Person person = mappingElasticsearchConverter.read(Person.class, document); + + assertThat(person.getId()).isEqualTo("4711"); + assertThat(person.getBirthDate()).isEqualTo(LocalDate.of(2000, 8, 22)); + assertThat(person.getGender()).isEqualTo(Gender.MAN); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -598,7 +644,10 @@ static class Person { @Id String id; String name; - Date birthdate; + @Field(name = "first-name") String firstName; + @Field(name = "last-name") String lastName; + @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, + pattern = "dd.MM.yyyy") LocalDate birthDate; Gender gender; Address address; @@ -759,5 +808,4 @@ static class GeoEntity { @GeoPointField private double[] pointD; } - } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 6cc8d75d1..508a64f81 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -33,6 +33,7 @@ import java.lang.Double; import java.lang.Integer; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -957,7 +958,7 @@ static class FieldMappingParameters { @Field(copyTo = { "foo", "bar" }) private String copyTo; @Field(ignoreAbove = 42) private String ignoreAbove; @Field(type = FieldType.Integer) private String type; - @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private String date; + @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private LocalDate date; @Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers; @Field(type = Keyword, docValues = true) private String docValuesTrue; @Field(type = Keyword, docValues = false) private String docValuesFalse; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 88f7355d7..38da81b2a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -17,8 +17,14 @@ import static org.assertj.core.api.Assertions.*; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Date; + import org.junit.jupiter.api.Test; +import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.mapping.MappingException; @@ -62,6 +68,47 @@ public void fieldAnnotationWithValueSetsFieldname() { assertThat(persistentProperty.getFieldName()).isEqualTo("by-value"); } + @Test + // DATAES-716 + void shouldSetPropertyConverters() { + SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); + + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("date"); + assertThat(persistentProperty.hasPropertyConverter()).isFalse(); + + persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); + assertThat(persistentProperty.hasPropertyConverter()).isTrue(); + assertThat(persistentProperty.getPropertyConverter()).isNotNull(); + + persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateTime"); + assertThat(persistentProperty.hasPropertyConverter()).isTrue(); + assertThat(persistentProperty.getPropertyConverter()).isNotNull(); + } + + @Test + // DATAES-716 + void shouldConvertFromLocalDate() { + SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); + LocalDate localDate = LocalDate.of(2019, 12, 27); + + String converted = persistentProperty.getPropertyConverter().write(localDate); + + assertThat(converted).isEqualTo("27.12.2019"); + } + + @Test + // DATAES-716 + void shouldConvertToLocalDate() { + SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); + + Object converted = persistentProperty.getPropertyConverter().read("27.12.2019"); + + assertThat(converted).isInstanceOf(LocalDate.class); + assertThat(converted).isEqualTo(LocalDate.of(2019, 12, 27)); + } + static class InvalidScoreProperty { @Score String scoreProperty; } @@ -73,4 +120,10 @@ static class FieldNameProperty { static class FieldValueProperty { @Field(value = "by-value") String fieldProperty; } + + static class DatesProperty { + @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date; + @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.yyyy") LocalDate localDate; + @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; + } } From d026884c121fa6200e80c3473292eda0267e5858 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 29 Dec 2019 21:46:58 +0100 Subject: [PATCH 0026/1191] DATAES-721 - Deprecation and Warnings cleanup. Original PR: #367 --- .../reactive-elasticsearch-operations.adoc | 2 +- .../annotations/IndexPrefixes.java | 4 +- .../elasticsearch/client/ClusterNodes.java | 2 +- .../client/ElasticsearchHost.java | 2 +- .../client/NodeClientFactoryBean.java | 4 +- .../client/RestClientFactoryBean.java | 6 +- .../client/TransportClientFactoryBean.java | 6 +- .../DefaultReactiveElasticsearchClient.java | 10 +- .../reactive/DefaultWebClientProvider.java | 2 +- .../reactive/MultiNodeHostProvider.java | 1 + .../client/reactive/RawActionResponse.java | 3 - .../client/util/RequestConverters.java | 22 +- .../ElasticsearchConfigurationSupport.java | 2 +- .../core/AbstractElasticsearchTemplate.java | 1 + .../core/CriteriaFilterProcessor.java | 72 ++--- .../core/CriteriaQueryProcessor.java | 6 +- .../core/DefaultIndexOperations.java | 19 +- .../core/DefaultTransportIndexOperations.java | 12 +- .../core/ElasticsearchRestTemplate.java | 1 - .../core/ElasticsearchTemplate.java | 6 +- .../elasticsearch/core/EntityOperations.java | 17 +- .../core/ReactiveElasticsearchTemplate.java | 11 +- .../elasticsearch/core/RequestFactory.java | 254 ++++++++---------- .../elasticsearch/core/SearchHitSupport.java | 2 +- .../elasticsearch/core/SearchOperations.java | 1 + .../core/client/support/AliasData.java | 9 +- .../DefaultElasticsearchTypeMapper.java | 2 + .../ElasticsearchCustomConversions.java | 5 +- .../MappingElasticsearchConverter.java | 5 +- .../core/document/DocumentAdapters.java | 6 +- .../core/document/MapDocument.java | 2 +- .../core/index/MappingBuilder.java | 50 ++-- .../ElasticsearchPersistentEntity.java | 1 + .../ElasticsearchPersistentProperty.java | 6 +- .../core/mapping/IndexCoordinates.java | 2 + .../elasticsearch/core/query/BulkOptions.java | 5 +- .../elasticsearch/core/query/Criteria.java | 6 +- .../core/query/CriteriaQuery.java | 3 +- .../core/query/FetchSourceFilterBuilder.java | 3 +- .../elasticsearch/core/query/UpdateQuery.java | 1 - .../repository/ElasticsearchRepository.java | 1 - ...tReactiveElasticsearchRepositoryQuery.java | 2 +- .../query/ElasticsearchEntityMetadata.java | 6 + .../query/ElasticsearchParameters.java | 13 +- .../query/ElasticsearchPartQuery.java | 3 +- .../query/ElasticsearchQueryMethod.java | 1 + ...sticsearchParametersParameterAccessor.java | 5 +- .../ReactiveElasticsearchQueryExecution.java | 6 +- .../ReactiveElasticsearchQueryMethod.java | 4 +- .../ReactivePartTreeElasticsearchQuery.java | 3 +- .../SimpleElasticsearchEntityMetadata.java | 4 +- .../AbstractElasticsearchRepository.java | 2 +- ...eactiveElasticsearchRepositoryFactory.java | 1 + .../JUnit5ClusterConnectionTests.java | 2 - .../data/elasticsearch/NestedObjectTests.java | 52 ++-- .../data/elasticsearch/TestUtils.java | 6 - .../ReactiveElasticsearchClientTests.java | 105 +++----- .../ReactiveElasticsearchClientUnitTests.java | 1 - .../ReactiveMockClientTestsUtils.java | 6 + .../ElasticsearchConfigurationTests.java | 2 +- .../ElasticsearchNamespaceHandlerTests.java | 2 +- ...eNestedElasticsearchRepositoriesTests.java | 7 +- ...asticsearchRepositoriesTransportTests.java | 33 +++ .../EnableElasticsearchRepositoriesTests.java | 8 +- .../core/DocumentAdaptersUnitTests.java | 10 +- .../core/ElasticsearchRestTemplateTests.java | 6 +- .../core/ElasticsearchTemplateTests.java | 50 ++-- .../ElasticsearchTransportTemplateTests.java | 7 +- .../core/IndexCoordinatesTest.java | 12 +- .../elasticsearch/core/LogEntityTests.java | 15 +- .../ReactiveElasticsearchTemplateTests.java | 19 +- ...eactiveElasticsearchTemplateUnitTests.java | 2 +- ...ElasticsearchTemplateAggregationTests.java | 17 +- .../ElasticsearchTemplateCompletionTests.java | 11 +- ...chTemplateCompletionWithContextsTests.java | 7 +- ...appingElasticsearchConverterUnitTests.java | 25 +- .../geo/ElasticsearchTemplateGeoTests.java | 11 +- .../core/index/MappingBuilderTests.java | 135 +++++----- .../SimpleDynamicTemplatesMappingTests.java | 24 +- .../SimpleElasticsearchDateMappingTests.java | 8 +- ...pleElasticsearchPersistentEntityTests.java | 5 +- .../core/query/CriteriaQueryTests.java | 59 ++-- .../junit/jupiter/ClusterConnection.java | 2 +- ...lasticsearchRestTemplateConfiguration.java | 1 - .../junit/jupiter/IntegrationTest.java | 1 - .../SpringDataElasticsearchExtension.java | 2 +- .../cdi/CdiProductRepository.java | 1 + .../repositories/cdi/CdiRepositoryTests.java | 6 +- .../repositories/cdi/OtherQualifier.java | 2 +- .../repositories/cdi/PersonDB.java | 2 +- .../cdi/QualifiedProductRepository.java | 2 +- .../cdi/SamplePersonRepository.java | 2 +- .../cdi/SamplePersonRepositoryCustom.java | 2 +- .../cdi/SamplePersonRepositoryImpl.java | 2 +- .../ComplexCustomMethodRepositoryTests.java | 15 +- .../ComplexElasticsearchRepositoryCustom.java | 2 +- ...stomMethodRepositoryManualWiringTests.java | 13 +- .../CustomMethodRepositoryBaseTests.java | 21 +- .../CustomMethodRepositoryRestTests.java | 11 - .../CustomMethodRepositoryTests.java | 10 - .../doubleid/DoubleIDRepositoryTests.java | 10 +- .../dynamicindex/DynamicIndexEntityTests.java | 2 +- .../geo/SpringDataGeoRepositoryTests.java | 14 +- .../integer/IntegerIDRepositoryTests.java | 13 +- .../nestedobject/InnerObjectTests.java | 13 +- ...ettingAndMappingEntityRepositoryTests.java | 37 +-- ...ldDynamicMappingEntityRepositoryTests.java | 13 +- .../repositories/spel/SpELEntityTests.java | 13 +- .../synonym/SynonymRepositoryTests.java | 12 +- .../UUIDElasticsearchRepositoryTests.java | 12 +- ...asticsearchRepositoriesRegistrarTests.java | 2 +- ...sitoryConfigurationExtensionUnitTests.java | 2 +- .../ElasticsearchStringQueryUnitTests.java | 6 +- ...tiveElasticsearchQueryMethodUnitTests.java | 11 +- ...tiveElasticsearchStringQueryUnitTests.java | 6 +- .../query/StubParameterAccessor.java | 5 + .../query/keywords/QueryKeywordsTests.java | 15 +- ...archEntityInformationCreatorImplTests.java | 8 +- ...eReactiveElasticsearchRepositoryTests.java | 89 +++--- .../SimpleElasticsearchRepositoryTests.java | 15 +- .../elasticsearch/utils/IndexInitializer.java | 1 + .../resources/mappings/test-mappings.json | 12 +- src/test/resources/synonyms/mappings.json | 12 +- 123 files changed, 881 insertions(+), 811 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java diff --git a/src/main/asciidoc/reference/reactive-elasticsearch-operations.adoc b/src/main/asciidoc/reference/reactive-elasticsearch-operations.adoc index 4f9554bd3..98e1f4b5b 100644 --- a/src/main/asciidoc/reference/reactive-elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/reactive-elasticsearch-operations.adoc @@ -82,7 +82,7 @@ Consider the following: ==== [source,java] ---- -@Document(indexName = "marvel", type = "characters") +@Document(indexName = "marvel") public class Person { private @Id String id; diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java index 30f7d13b5..1ad56153e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java @@ -20,8 +20,8 @@ * @since 4.0 */ public @interface IndexPrefixes { - static final int MIN_DEFAULT = 2; - static final int MAX_DEFAULT = 2; + int MIN_DEFAULT = 2; + int MAX_DEFAULT = 2; int minChars() default MIN_DEFAULT; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java b/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java index f6acd0358..5621c5715 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java @@ -66,7 +66,7 @@ private ClusterNodes(String source) { Assert.hasText(host, () -> String.format("No host name given cluster node %s!", node)); Assert.hasText(port, () -> String.format("No port given in cluster node %s!", node)); - return new TransportAddress(toInetAddress(host), Integer.valueOf(port)); + return new TransportAddress(toInetAddress(host), Integer.parseInt(port)); }).collect(Collectors.toList()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java index 27f7174e9..852bb2663 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java @@ -104,7 +104,7 @@ public Instant getTimestamp() { @Override public String toString() { - return "ElasticsearchHost(" + endpoint + ", " + state.name() + ")"; + return "ElasticsearchHost(" + endpoint + ", " + state.name() + ')'; } public enum State { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java index 465d60e8e..4a313a1ce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java @@ -81,7 +81,7 @@ public NodeClientFactoryBean(boolean local) { } @Override - public NodeClient getObject() throws Exception { + public NodeClient getObject() { return nodeClient; } @@ -148,7 +148,7 @@ public void setPathConfiguration(String configuration) { } @Override - public void destroy() throws Exception { + public void destroy() { try { // NodeClient.close() is a noop, no need to call it here nodeClient = null; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java index 1b0264893..a26a2b6d4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java @@ -41,7 +41,7 @@ public class RestClientFactoryBean implements FactoryBean, static final String COMMA = ","; @Override - public void destroy() throws Exception { + public void destroy() { try { log.info("Closing elasticSearch client"); if (client != null) { @@ -58,7 +58,7 @@ public void afterPropertiesSet() throws Exception { } @Override - public RestHighLevelClient getObject() throws Exception { + public RestHighLevelClient getObject() { return client; } @@ -75,7 +75,7 @@ public boolean isSingleton() { protected void buildClient() throws Exception { Assert.hasText(hosts, "[Assertion Failed] At least one host must be set."); - ArrayList httpHosts = new ArrayList(); + ArrayList httpHosts = new ArrayList<>(); for (String host : hosts.split(COMMA)) { URL hostUrl = new URL(host); httpHosts.add(new HttpHost(hostUrl.getHost(), hostUrl.getPort(), hostUrl.getProtocol())); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java index 18416506a..90b679ebe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java @@ -52,7 +52,7 @@ public class TransportClientFactoryBean implements FactoryBean, private Properties properties; @Override - public void destroy() throws Exception { + public void destroy() { try { logger.info("Closing elasticSearch client"); if (client != null) { @@ -64,7 +64,7 @@ public void destroy() throws Exception { } @Override - public TransportClient getObject() throws Exception { + public TransportClient getObject() { return client; } @@ -83,7 +83,7 @@ public void afterPropertiesSet() throws Exception { buildClient(); } - protected void buildClient() throws Exception { + protected void buildClient() { client = new PreBuiltTransportClient(settings()); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index c59d27707..961da02d4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -440,6 +440,7 @@ private Publisher cleanupScroll(HttpHeaders headers, ScrollState state) { * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.http.HttpHeaders, org.elasticsearch.index.reindex.DeleteByQueryRequest) */ + @Override public Mono deleteBy(HttpHeaders headers, DeleteByQueryRequest deleteRequest) { return sendRequest(deleteRequest, RequestCreator.deleteByQuery(), BulkByScrollResponse.class, headers) // @@ -764,14 +765,7 @@ static Function delete() { static Function deleteByQuery() { - return request -> { - - try { - return RequestConverters.deleteByQuery(request); - } catch (IOException e) { - throw new ElasticsearchException("Could not parse request", e); - } - }; + return request -> RequestConverters.deleteByQuery(request); } static Function bulk() { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java index 188a7c51f..9dd97118e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java @@ -61,7 +61,7 @@ class DefaultWebClientProvider implements WebClientProvider { /** * Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}. * - * @param pathPrefixcan be {@literal null} + * @param pathPrefix can be {@literal null} * @param scheme must not be {@literal null}. * @param connector can be {@literal null}. * @param errorListener must not be {@literal null}. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java index e3a6ce45e..144c2219c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java @@ -60,6 +60,7 @@ class MultiNodeHostProvider implements HostProvider { * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.HostProvider#clusterInfo() */ + @Override public Mono clusterInfo() { return nodes(null).map(this::updateNodeState).buffer(hosts.size()) .then(Mono.just(new ClusterInformation(new LinkedHashSet<>(this.hosts.values())))); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java index 400d16508..a2e79330d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java @@ -16,11 +16,8 @@ package org.springframework.data.elasticsearch.client.reactive; import org.elasticsearch.common.io.stream.StreamOutput; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; import java.io.IOException; -import java.util.List; import org.elasticsearch.action.ActionResponse; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index a11ebf830..65a5be626 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -103,6 +103,7 @@ * @author Peter-Josef Meisch * @since 3.2 */ +@SuppressWarnings("JavadocReference") public class RequestConverters { private static final XContentType REQUEST_BODY_CONTENT_TYPE = XContentType.JSON; @@ -364,7 +365,7 @@ public static Request update(UpdateRequest updateRequest) { XContentType upsertContentType = updateRequest.upsertRequest().getContentType(); if ((xContentType != null) && (xContentType != upsertContentType)) { throw new IllegalStateException("Update request cannot have different content types for doc [" + xContentType - + "]" + " and upsert [" + upsertContentType + "] documents"); + + ']' + " and upsert [" + upsertContentType + "] documents"); } else { xContentType = upsertContentType; } @@ -460,7 +461,7 @@ public static Request multiSearch(MultiSearchRequest multiSearchRequest) throws return request; } - public static Request explain(ExplainRequest explainRequest) throws IOException { + public static Request explain(ExplainRequest explainRequest) { Request request = new Request(HttpMethod.GET.name(), endpoint(explainRequest.index(), explainRequest.type(), explainRequest.id(), "_explain")); @@ -482,7 +483,7 @@ public static Request fieldCaps(FieldCapabilitiesRequest fieldCapabilitiesReques return request; } - public static Request rankEval(RankEvalRequest rankEvalRequest) throws IOException { + public static Request rankEval(RankEvalRequest rankEvalRequest) { Request request = new Request(HttpMethod.GET.name(), endpoint(rankEvalRequest.indices(), Strings.EMPTY_ARRAY, "_rank_eval")); @@ -501,8 +502,7 @@ static Request submitReindex(ReindexRequest reindexRequest) throws IOException { return prepareReindexRequest(reindexRequest, false); } - private static Request prepareReindexRequest(ReindexRequest reindexRequest, boolean waitForCompletion) - throws IOException { + private static Request prepareReindexRequest(ReindexRequest reindexRequest, boolean waitForCompletion) { String endpoint = new EndpointBuilder().addPathPart("_reindex").build(); Request request = new Request(HttpMethod.POST.name(), endpoint); Params params = new Params(request).withWaitForCompletion(waitForCompletion).withRefresh(reindexRequest.isRefresh()) @@ -516,7 +516,7 @@ private static Request prepareReindexRequest(ReindexRequest reindexRequest, bool return request; } - public static Request updateByQuery(UpdateByQueryRequest updateByQueryRequest) throws IOException { + public static Request updateByQuery(UpdateByQueryRequest updateByQueryRequest) { String endpoint = endpoint(updateByQueryRequest.indices(), updateByQueryRequest.getDocTypes(), "_update_by_query"); Request request = new Request(HttpMethod.POST.name(), endpoint); Params params = new Params(request).withRouting(updateByQueryRequest.getRouting()) @@ -541,7 +541,7 @@ public static Request updateByQuery(UpdateByQueryRequest updateByQueryRequest) t return request; } - public static Request deleteByQuery(DeleteByQueryRequest deleteByQueryRequest) throws IOException { + public static Request deleteByQuery(DeleteByQueryRequest deleteByQueryRequest) { String endpoint = endpoint(deleteByQueryRequest.indices(), deleteByQueryRequest.getDocTypes(), "_delete_by_query"); Request request = new Request(HttpMethod.POST.name(), endpoint); Params params = new Params(request).withRouting(deleteByQueryRequest.getRouting()) @@ -587,7 +587,7 @@ private static Request rethrottle(RethrottleRequest rethrottleRequest, String fi return request; } - public static Request putScript(PutStoredScriptRequest putStoredScriptRequest) throws IOException { + public static Request putScript(PutStoredScriptRequest putStoredScriptRequest) { String endpoint = new EndpointBuilder().addPathPartAsIs("_scripts").addPathPart(putStoredScriptRequest.id()) .build(); Request request = new Request(HttpMethod.POST.name(), endpoint); @@ -601,7 +601,7 @@ public static Request putScript(PutStoredScriptRequest putStoredScriptRequest) t return request; } - public static Request analyze(AnalyzeRequest request) throws IOException { + public static Request analyze(AnalyzeRequest request) { EndpointBuilder builder = new EndpointBuilder(); String index = request.index(); if (index != null) { @@ -1145,7 +1145,7 @@ static XContentType enforceSameContentType(IndexRequest indexRequest, @Nullable } if (requestContentType != xContentType) { throw new IllegalArgumentException("Mismatching content-type found for request with content-type [" - + requestContentType + "], previous requests have content-type [" + xContentType + "]"); + + requestContentType + "], previous requests have content-type [" + xContentType + ']'); } return xContentType; } @@ -1194,7 +1194,7 @@ private static String encodePart(String pathPart) { // encode each part (e.g. index, type and id) separately before merging them into the path // we prepend "/" to the path part to make this path absolute, otherwise there can be issues with // paths that start with `-` or contain `:` - URI uri = new URI(null, null, null, -1, "/" + pathPart, null, null); + URI uri = new URI(null, null, null, -1, '/' + pathPart, null, null); // manually encode any slash that each part may contain return uri.getRawPath().substring(1).replaceAll("/", "%2F"); } catch (URISyntaxException e) { diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index 3e2419f3b..f78c91612 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -127,7 +127,7 @@ protected Set> scanForEntities(String basePackage) throws ClassNotFound return Collections.emptySet(); } - Set> initialEntitySet = new HashSet>(); + Set> initialEntitySet = new HashSet<>(); if (StringUtils.hasText(basePackage)) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 3adf37130..bd845ea5b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -79,6 +79,7 @@ public IndexOperations getIndexOperations() { // endregion // region DocumentOperations + @Override public void delete(Query query, Class clazz, IndexCoordinates index) { Assert.notNull(query, "Query must not be null."); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java index 35cf44012..ef73dc50a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java @@ -20,10 +20,13 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; import org.elasticsearch.common.geo.GeoDistance; -import org.elasticsearch.index.query.*; +import org.elasticsearch.index.query.BoolQueryBuilder; +import org.elasticsearch.index.query.GeoBoundingBoxQueryBuilder; +import org.elasticsearch.index.query.GeoDistanceQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.Criteria; @@ -39,28 +42,25 @@ * @author Franck Marchand * @author Mohsin Husen * @author Artur Konczak - * + * @author Peter-Josef Meisch */ class CriteriaFilterProcessor { - QueryBuilder createFilterFromCriteria(Criteria criteria) { List fbList = new LinkedList<>(); QueryBuilder filter = null; - ListIterator chainIterator = criteria.getCriteriaChain().listIterator(); - - while (chainIterator.hasNext()) { + for (Criteria chainedCriteria : criteria.getCriteriaChain()) { QueryBuilder fb = null; - Criteria chainedCriteria = chainIterator.next(); if (chainedCriteria.isOr()) { fb = QueryBuilders.boolQuery(); - for(QueryBuilder f: createFilterFragmentForCriteria(chainedCriteria)){ - ((BoolQueryBuilder)fb).should(f); + for (QueryBuilder f : createFilterFragmentForCriteria(chainedCriteria)) { + ((BoolQueryBuilder) fb).should(f); } fbList.add(fb); } else if (chainedCriteria.isNegating()) { - List negationFilters = buildNegationFilter(criteria.getField().getName(), criteria.getFilterCriteriaEntries().iterator()); + List negationFilters = buildNegationFilter(criteria.getField().getName(), + criteria.getFilterCriteriaEntries().iterator()); if (!negationFilters.isEmpty()) { fbList.addAll(negationFilters); @@ -75,15 +75,14 @@ QueryBuilder createFilterFromCriteria(Criteria criteria) { filter = fbList.get(0); } else { filter = QueryBuilders.boolQuery(); - for(QueryBuilder f: fbList) { - ((BoolQueryBuilder)filter).must(f); + for (QueryBuilder f : fbList) { + ((BoolQueryBuilder) filter).must(f); } } } return filter; } - private List createFilterFragmentForCriteria(Criteria chainedCriteria) { Iterator it = chainedCriteria.getFilterCriteriaEntries().iterator(); List filterList = new LinkedList<>(); @@ -101,7 +100,6 @@ private List createFilterFragmentForCriteria(Criteria chainedCrite return filterList; } - private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String fieldName) { if (value == null) { return null; @@ -116,8 +114,10 @@ private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String Object[] valArray = (Object[]) value; Assert.noNullElements(valArray, "Geo distance filter takes 2 not null elements array as parameter."); Assert.isTrue(valArray.length == 2, "Geo distance filter takes a 2-elements array as parameter."); - Assert.isTrue(valArray[0] instanceof GeoPoint || valArray[0] instanceof String || valArray[0] instanceof Point, "First element of a geo distance filter must be a GeoPoint, a Point or a text"); - Assert.isTrue(valArray[1] instanceof String || valArray[1] instanceof Distance, "Second element of a geo distance filter must be a text or a Distance"); + Assert.isTrue(valArray[0] instanceof GeoPoint || valArray[0] instanceof String || valArray[0] instanceof Point, + "First element of a geo distance filter must be a GeoPoint, a Point or a text"); + Assert.isTrue(valArray[1] instanceof String || valArray[1] instanceof Distance, + "Second element of a geo distance filter must be a text or a Distance"); StringBuilder dist = new StringBuilder(); @@ -129,15 +129,18 @@ private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String if (valArray[0] instanceof GeoPoint) { GeoPoint loc = (GeoPoint) valArray[0]; - geoDistanceQueryBuilder.point(loc.getLat(),loc.getLon()).distance(dist.toString()).geoDistance(GeoDistance.PLANE); + geoDistanceQueryBuilder.point(loc.getLat(), loc.getLon()).distance(dist.toString()) + .geoDistance(GeoDistance.PLANE); } else if (valArray[0] instanceof Point) { GeoPoint loc = GeoPoint.fromPoint((Point) valArray[0]); - geoDistanceQueryBuilder.point(loc.getLat(), loc.getLon()).distance(dist.toString()).geoDistance(GeoDistance.PLANE); + geoDistanceQueryBuilder.point(loc.getLat(), loc.getLon()).distance(dist.toString()) + .geoDistance(GeoDistance.PLANE); } else { String loc = (String) valArray[0]; if (loc.contains(",")) { - String c[] = loc.split(","); - geoDistanceQueryBuilder.point(Double.parseDouble(c[0]), Double.parseDouble(c[1])).distance(dist.toString()).geoDistance(GeoDistance.PLANE); + String[] c = loc.split(","); + geoDistanceQueryBuilder.point(Double.parseDouble(c[0]), Double.parseDouble(c[1])).distance(dist.toString()) + .geoDistance(GeoDistance.PLANE); } else { geoDistanceQueryBuilder.geohash(loc).distance(dist.toString()).geoDistance(GeoDistance.PLANE); } @@ -150,20 +153,22 @@ private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String case BBOX: { filter = QueryBuilders.geoBoundingBoxQuery(fieldName); - Assert.isTrue(value instanceof Object[], "Value of a boundedBy filter should be an array of one or two values."); + Assert.isTrue(value instanceof Object[], + "Value of a boundedBy filter should be an array of one or two values."); Object[] valArray = (Object[]) value; Assert.noNullElements(valArray, "Geo boundedBy filter takes a not null element array as parameter."); if (valArray.length == 1) { - //GeoEnvelop + // GeoEnvelop oneParameterBBox((GeoBoundingBoxQueryBuilder) filter, valArray[0]); } else if (valArray.length == 2) { - //2x GeoPoint - //2x text + // 2x GeoPoint + // 2x text twoParameterBBox((GeoBoundingBoxQueryBuilder) filter, valArray); } else { - //error - Assert.isTrue(false, "Geo distance filter takes a 1-elements array(GeoBox) or 2-elements array(GeoPoints or Strings(format lat,lon or geohash))."); + // error + Assert.isTrue(false, + "Geo distance filter takes a 1-elements array(GeoBox) or 2-elements array(GeoPoints or Strings(format lat,lon or geohash))."); } break; } @@ -172,7 +177,6 @@ private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String return filter; } - /** * extract the distance string from a {@link org.springframework.data.geo.Distance} object. * @@ -196,7 +200,8 @@ private void extractDistanceString(Distance distance, StringBuilder sb) { } private void oneParameterBBox(GeoBoundingBoxQueryBuilder filter, Object value) { - Assert.isTrue(value instanceof GeoBox || value instanceof Box, "single-element of boundedBy filter must be type of GeoBox or Box"); + Assert.isTrue(value instanceof GeoBox || value instanceof Box, + "single-element of boundedBy filter must be type of GeoBox or Box"); GeoBox geoBBox; if (value instanceof Box) { @@ -206,7 +211,8 @@ private void oneParameterBBox(GeoBoundingBoxQueryBuilder filter, Object value) { geoBBox = (GeoBox) value; } - filter.setCorners(geoBBox.getTopLeft().getLat(), geoBBox.getTopLeft().getLon(), geoBBox.getBottomRight().getLat(), geoBBox.getBottomRight().getLon()); + filter.setCorners(geoBBox.getTopLeft().getLat(), geoBBox.getTopLeft().getLon(), geoBBox.getBottomRight().getLat(), + geoBBox.getBottomRight().getLon()); } private static boolean isType(Object[] array, Class clazz) { @@ -219,7 +225,8 @@ private static boolean isType(Object[] array, Class clazz) { } private void twoParameterBBox(GeoBoundingBoxQueryBuilder filter, Object[] values) { - Assert.isTrue(isType(values, GeoPoint.class) || isType(values, String.class), " both elements of boundedBy filter must be type of GeoPoint or text(format lat,lon or geohash)"); + Assert.isTrue(isType(values, GeoPoint.class) || isType(values, String.class), + " both elements of boundedBy filter must be type of GeoPoint or text(format lat,lon or geohash)"); if (values[0] instanceof GeoPoint) { GeoPoint topLeft = (GeoPoint) values[0]; GeoPoint bottomRight = (GeoPoint) values[1]; @@ -236,7 +243,8 @@ private List buildNegationFilter(String fieldName, Iterator getMapping(IndexCoordinates index) { RestClient restClient = client.getLowLevelClient(); try { - Request request = new Request("GET", - '/' + index.getIndexName() + "/_mapping/" + index.getTypeName() + "?include_type_name=true"); + Request request = new Request("GET", '/' + index.getIndexName() + "/_mapping"); Response response = restClient.performRequest(request); - return convertMappingResponse(EntityUtils.toString(response.getEntity()), index.getTypeName()); + return convertMappingResponse(EntityUtils.toString(response.getEntity())); } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() - + " type : " + index.getTypeName() + ' ', e); + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName(), e); } } @@ -210,14 +208,14 @@ public void refresh(IndexCoordinates index) { } // region Helper methods - private Map convertMappingResponse(String mappingResponse, String type) { + private Map convertMappingResponse(String mappingResponse) { ObjectMapper mapper = new ObjectMapper(); try { Map result = null; JsonNode node = mapper.readTree(mappingResponse); - node = node.findValue("mappings").findValue(type); + node = node.findValue("mappings"); result = mapper.readValue(mapper.writeValueAsString(node), HashMap.class); return result; @@ -248,7 +246,7 @@ private List convertAliasResponse(String aliasResponse) { new TypeReference>() {}); Iterable> aliasIter = aliasData.entrySet(); - List aliasMetaDataList = new ArrayList(); + List aliasMetaDataList = new ArrayList<>(); for (Map.Entry aliasentry : aliasIter) { AliasData data = aliasentry.getValue(); @@ -261,6 +259,5 @@ private List convertAliasResponse(String aliasResponse) { throw new ElasticsearchException("Could not map alias response : " + aliasResponse, e); } } - // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 2c34c2e9f..39a910269 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -87,15 +87,15 @@ public boolean putMapping(IndexCoordinates index, Object mapping) { @Override public Map getMapping(IndexCoordinates index) { - Assert.notNull(index, "No index defined for putMapping()"); + Assert.notNull(index, "No index defined for getMapping()"); try { - return client.admin().indices() - .getMappings(new GetMappingsRequest().indices(index.getIndexNames()).types(index.getTypeNames())).actionGet() - .getMappings().get(index.getIndexName()).get(index.getTypeName()).getSourceAsMap(); + return client.admin().indices().getMappings( // + new GetMappingsRequest().indices(index.getIndexNames())).actionGet() // + .getMappings().get(index.getIndexName()).get(IndexCoordinates.TYPE) // + .getSourceAsMap(); } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName() - + " type : " + index.getTypeName() + ' ' + e.getMessage()); + throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName(), e); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index bbe47971b..2fe6da806 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -41,7 +41,6 @@ import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index c282b1197..a452f7806 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -35,7 +35,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -128,8 +127,7 @@ public String index(IndexQuery query, IndexCoordinates index) { public T get(GetQuery query, Class clazz, IndexCoordinates index) { GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, query, index); GetResponse response = getRequestBuilder.execute().actionGet(); - T entity = elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); - return entity; + return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); } @Override @@ -163,7 +161,7 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index @Override public String delete(String id, IndexCoordinates index) { - return client.prepareDelete(index.getIndexName(), index.getTypeName(), id).execute().actionGet().getId(); + return client.prepareDelete(index.getIndexName(), IndexCoordinates.TYPE, id).execute().actionGet().getId(); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index f376ac270..9c09fbad7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -99,8 +99,6 @@ AdaptibleEntity forEntity(T entity, ConversionService conversionService) * @param index index name override can be {@literal null}. * @param type index type override can be {@literal null}. * @return the {@link IndexCoordinates} containing index name and index type. - * @see ElasticsearchPersistentEntity#getIndexName() - * @see ElasticsearchPersistentEntity#getIndexType() */ IndexCoordinates determineIndex(Entity entity, @Nullable String index, @Nullable String type) { return determineIndex(entity.getPersistentEntity(), index, type); @@ -116,12 +114,10 @@ IndexCoordinates determineIndex(Entity entity, @Nullable String index, @Nulla * @param index index name override can be {@literal null}. * @param type index type override can be {@literal null}. * @return the {@link IndexCoordinates} containing index name and index type. - * @see ElasticsearchPersistentEntity#getIndexName() - * @see ElasticsearchPersistentEntity#getIndexType() */ IndexCoordinates determineIndex(ElasticsearchPersistentEntity persistentEntity, @Nullable String index, @Nullable String type) { - return IndexCoordinates.of(indexName(persistentEntity, index)).withTypes(typeName(persistentEntity, type)); + return persistentEntity.getIndexCoordinates(); } private static String indexName(@Nullable ElasticsearchPersistentEntity entity, @Nullable String index) { @@ -134,16 +130,6 @@ private static String indexName(@Nullable ElasticsearchPersistentEntity entit return index; } - private static String typeName(@Nullable ElasticsearchPersistentEntity entity, @Nullable String type) { - - if (StringUtils.isEmpty(type)) { - Assert.notNull(entity, "Cannot determine index type"); - return entity.getIndexCoordinates().getTypeName(); - } - - return type; - } - /** * A representation of information about an entity. * @@ -268,6 +254,7 @@ interface AdaptibleEntity extends Entity { * @return the current version or {@literal null} in case it's uninitialized or the entity doesn't expose a version * property. */ + @Override @Nullable Number getVersion(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8c234a8ee..fc71a7af2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -182,8 +182,8 @@ private Mono doIndex(Object value, AdaptibleEntity entity, Ind Object id = entity.getId(); IndexRequest request = id != null - ? new IndexRequest(index.getIndexName(), index.getTypeName(), converter.convertId(id)) - : new IndexRequest(index.getIndexName(), index.getTypeName()); + ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) + : new IndexRequest(index.getIndexName()); request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); @@ -223,7 +223,7 @@ private Mono doFindById(String id, ElasticsearchPersistentEntity e return Mono.defer(() -> { - return doFindById(new GetRequest(index.getIndexName(), index.getTypeName(), id)); + return doFindById(new GetRequest(index.getIndexName(), id)); }); } @@ -241,7 +241,7 @@ public Mono exists(String id, Class entityType, IndexCoordinates ind private Mono doExists(String id, ElasticsearchPersistentEntity entity, @Nullable IndexCoordinates index) { - return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), index.getTypeName(), id))); + return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), id))); } /* @@ -285,7 +285,7 @@ private Mono doDeleteById(@Nullable Object source, String id, Elasticsea return Mono.defer(() -> { - return doDelete(prepareDeleteRequest(source, new DeleteRequest(index.getIndexName(), index.getTypeName(), id))); + return doDelete(prepareDeleteRequest(source, new DeleteRequest(index.getIndexName(), id))); }); } @@ -312,7 +312,6 @@ private Flux doDeleteBy(Query query, ElasticsearchPersiste return Flux.defer(() -> { DeleteByQueryRequest request = new DeleteByQueryRequest(index.getIndexNames()); - request.types(index.getTypeNames()); request.setQuery(mappedQuery(query, entity)); return doDeleteBy(prepareDeleteByRequest(request)); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index de5fb02d2..02558c058 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -21,12 +21,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Optional; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; -import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; @@ -42,6 +39,8 @@ import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.client.Requests; +import org.elasticsearch.client.indices.CreateIndexRequest; +import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; @@ -176,24 +175,26 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, Bul return bulkRequestBuilder; } + @SuppressWarnings("unchecked") public CreateIndexRequest createIndexRequest(String indexName, Object settings) { CreateIndexRequest request = new CreateIndexRequest(indexName); if (settings instanceof String) { request.settings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); } else if (settings instanceof Map) { - request.settings((Map) settings); + request.settings((Map) settings); } else if (settings instanceof XContentBuilder) { request.settings((XContentBuilder) settings); } return request; } + @SuppressWarnings("unchecked") public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, Object settings) { CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); if (settings instanceof String) { createIndexRequestBuilder.setSettings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); } else if (settings instanceof Map) { - createIndexRequestBuilder.setSettings((Map) settings); + createIndexRequestBuilder.setSettings((Map) settings); } else if (settings instanceof XContentBuilder) { createIndexRequestBuilder.setSettings((XContentBuilder) settings); } @@ -202,7 +203,6 @@ public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexCoordinates index) { DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) // - .setDocTypes(index.getTypeNames()) // .setQuery(deleteQuery.getQuery()) // .setAbortOnVersionConflict(false) // .setRefresh(true); @@ -224,8 +224,7 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, De .abortOnVersionConflict(false) // .refresh(true); - SearchRequestBuilder source = requestBuilder.source() // - .setTypes(index.getTypeNames()); + SearchRequestBuilder source = requestBuilder.source(); if (deleteQuery.getScrollTimeInMillis() != null) source.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); @@ -234,11 +233,11 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, De } public GetRequest getRequest(GetQuery query, IndexCoordinates index) { - return new GetRequest(index.getIndexName(), index.getTypeName(), query.getId()); + return new GetRequest(index.getIndexName(), query.getId()); } public GetRequestBuilder getRequestBuilder(Client client, GetQuery query, IndexCoordinates index) { - return client.prepareGet(index.getIndexName(), index.getTypeName(), query.getId()); + return client.prepareGet(index.getIndexName(), null, query.getId()); } public HighlightBuilder highlightBuilder(Query query) { @@ -265,7 +264,6 @@ public HighlightBuilder highlightBuilder(Query query) { public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { String indexName = index.getIndexName(); - String type = index.getTypeName(); IndexRequest indexRequest; @@ -273,17 +271,17 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { String id = StringUtils.isEmpty(query.getId()) ? getPersistentEntityId(query.getObject()) : query.getId(); // If we have a query id and a document id, do not ask ES to generate one. if (id != null) { - indexRequest = new IndexRequest(indexName, type, id); + indexRequest = new IndexRequest(indexName).id(id); } else { - indexRequest = new IndexRequest(indexName, type); + indexRequest = new IndexRequest(indexName); } indexRequest.source(elasticsearchConverter.mapObject(query.getObject()).toJson(), Requests.INDEX_CONTENT_TYPE); } else if (query.getSource() != null) { - indexRequest = new IndexRequest(indexName, type, query.getId()).source(query.getSource(), + indexRequest = new IndexRequest(indexName).id(query.getId()).source(query.getSource(), Requests.INDEX_CONTENT_TYPE); } else { throw new ElasticsearchException( - "object or source is null, failed to index the document [id: " + query.getId() + "]"); + "object or source is null, failed to index the document [id: " + query.getId() + ']'); } if (query.getVersion() != null) { indexRequest.version(query.getVersion()); @@ -296,7 +294,7 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, IndexCoordinates index) { String indexName = index.getIndexName(); - String type = index.getTypeName(); + String type = IndexCoordinates.TYPE; IndexRequestBuilder indexRequestBuilder; @@ -315,7 +313,7 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, Requests.INDEX_CONTENT_TYPE); } else { throw new ElasticsearchException( - "object or source is null, failed to index the document [id: " + query.getId() + "]"); + "object or source is null, failed to index the document [id: " + query.getId() + ']'); } if (query.getVersion() != null) { indexRequestBuilder.setVersion(query.getVersion()); @@ -327,8 +325,7 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, } public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) { - MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), index.getTypeName(), - query.getId()); + MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), query.getId()); MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders .moreLikeThisQuery(new MoreLikeThisQueryBuilder.Item[] { item }); @@ -414,7 +411,7 @@ public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { UpdateRequest queryUpdateRequest = query.getUpdateRequest(); - UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), index.getTypeName(), query.getId()) // + UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), query.getId()) // .routing(queryUpdateRequest.routing()) // .retryOnConflict(queryUpdateRequest.retryOnConflict()) // .timeout(queryUpdateRequest.timeout()) // @@ -455,7 +452,7 @@ public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery q UpdateRequest queryUpdateRequest = query.getUpdateRequest(); UpdateRequestBuilder updateRequestBuilder = client - .prepareUpdate(index.getIndexName(), index.getTypeName(), query.getId()) // + .prepareUpdate(index.getIndexName(), IndexCoordinates.TYPE, query.getId()) // .setRouting(queryUpdateRequest.routing()) // .setRetryOnConflict(queryUpdateRequest.retryOnConflict()) // .setTimeout(queryUpdateRequest.timeout()) // @@ -490,24 +487,82 @@ public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery q } private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { - return prepareSearchRequest(query, Optional.empty(), clazz, index); + Assert.notNull(index.getIndexNames(), "No index defined for Query"); + Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); + + SearchRequest request = new SearchRequest(index.getIndexNames()); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.version(true); + sourceBuilder.trackScores(query.getTrackScores()); + + if (query.getSourceFilter() != null) { + SourceFilter sourceFilter = query.getSourceFilter(); + sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); + } + + if (query.getPageable().isPaged()) { + sourceBuilder.from((int) query.getPageable().getOffset()); + sourceBuilder.size(query.getPageable().getPageSize()); + } + + if (!query.getFields().isEmpty()) { + sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); + } + + if (query.getIndicesOptions() != null) { + request.indicesOptions(query.getIndicesOptions()); + } + + if (query.isLimiting()) { + sourceBuilder.size(query.getMaxResults()); + } + + if (query.getMinScore() > 0) { + sourceBuilder.minScore(query.getMinScore()); + } + + if (query.getPreference() != null) { + request.preference(query.getPreference()); + } + + if (query.getSearchType() != null) { + request.searchType(query.getSearchType()); + } + + prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); + + HighlightBuilder highlightBuilder = highlightBuilder(query); + + if (highlightBuilder != null) { + sourceBuilder.highlighter(highlightBuilder); + } + + if (query instanceof NativeSearchQuery) { + prepareNativeSearch((NativeSearchQuery) query, sourceBuilder); + + } + + request.source(sourceBuilder); + return request; } + @SuppressWarnings("unchecked") public PutMappingRequest putMappingRequest(IndexCoordinates index, Object mapping) { - PutMappingRequest request = new PutMappingRequest(index.getIndexName()).type(index.getTypeName()); + PutMappingRequest request = new PutMappingRequest(index.getIndexName()); if (mapping instanceof String) { request.source(String.valueOf(mapping), XContentType.JSON); } else if (mapping instanceof Map) { - request.source((Map) mapping); + request.source((Map) mapping); } else if (mapping instanceof XContentBuilder) { request.source((XContentBuilder) mapping); } return request; } + @SuppressWarnings("rawtypes") public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Object mapping) { PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(index.getIndexName()) - .setType(index.getTypeName()); + .setType(IndexCoordinates.TYPE); if (mapping instanceof String) { requestBuilder.setSource(String.valueOf(mapping), XContentType.JSON); } else if (mapping instanceof Map) { @@ -537,7 +592,7 @@ private List getMultiRequestItems(Query searchQuery, Index } for (String id : searchQuery.getIds()) { - MultiGetRequest.Item item = new MultiGetRequest.Item(index.getIndexName(), index.getTypeName(), id); + MultiGetRequest.Item item = new MultiGetRequest.Item(index.getIndexName(), id); if (searchQuery.getRoute() != null) { item = item.routing(searchQuery.getRoute()); @@ -547,80 +602,63 @@ private List getMultiRequestItems(Query searchQuery, Index return items; } - private SearchRequest prepareSearchRequest(Query query, Optional builder, @Nullable Class clazz, - IndexCoordinates index) { - Assert.notNull(index.getIndexNames(), "No index defined for Query"); - Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); - Assert.notNull(index.getTypeNames(), "No type defined for Query"); - - SearchRequest request = new SearchRequest(index.getIndexNames()); - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - request.types(index.getTypeNames()); - sourceBuilder.version(true); - sourceBuilder.trackScores(query.getTrackScores()); - - builder.ifPresent(sourceBuilder::query); + private void prepareNativeSearch(NativeSearchQuery query, SearchSourceBuilder sourceBuilder) { - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); + if (!query.getScriptFields().isEmpty()) { + for (ScriptField scriptedField : query.getScriptFields()) { + sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script()); + } } - if (query.getPageable().isPaged()) { - sourceBuilder.from((int) query.getPageable().getOffset()); - sourceBuilder.size(query.getPageable().getPageSize()); + if (query.getCollapseBuilder() != null) { + sourceBuilder.collapse(query.getCollapseBuilder()); } - if (!query.getFields().isEmpty()) { - sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); + if (!isEmpty(query.getIndicesBoost())) { + for (IndexBoost indexBoost : query.getIndicesBoost()) { + sourceBuilder.indexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); + } } - if (query.isLimiting()) { - sourceBuilder.size(query.getMaxResults()); + if (!isEmpty(query.getAggregations())) { + for (AbstractAggregationBuilder aggregationBuilder : query.getAggregations()) { + sourceBuilder.aggregation(aggregationBuilder); + } } - if (query.getMinScore() > 0) { - sourceBuilder.minScore(query.getMinScore()); - } + } - if (query.getPreference() != null) { - request.preference(query.getPreference()); + private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, NativeSearchQuery nativeSearchQuery) { + if (!isEmpty(nativeSearchQuery.getScriptFields())) { + for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { + searchRequestBuilder.addScriptField(scriptedField.fieldName(), scriptedField.script()); + } } - if (query.getSearchType() != null) { - request.searchType(query.getSearchType()); + if (nativeSearchQuery.getCollapseBuilder() != null) { + searchRequestBuilder.setCollapse(nativeSearchQuery.getCollapseBuilder()); } - prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); - - HighlightBuilder highlightBuilder = highlightBuilder(query); - - if (highlightBuilder != null) { - sourceBuilder.highlighter(highlightBuilder); + if (!isEmpty(nativeSearchQuery.getIndicesBoost())) { + for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) { + searchRequestBuilder.addIndexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); + } } - if (query instanceof NativeSearchQuery) { - prepareNativeSearch((NativeSearchQuery) query, sourceBuilder); - + if (!isEmpty(nativeSearchQuery.getAggregations())) { + for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) { + searchRequestBuilder.addAggregation(aggregationBuilder); + } } - - request.source(sourceBuilder); - return request; } - private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, - @Nullable ElasticsearchPersistentEntity entity, IndexCoordinates index) { + private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class clazz, + IndexCoordinates index) { Assert.notNull(index.getIndexNames(), "No index defined for Query"); Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); - Assert.notNull(index.getTypeNames(), "No type defined for Query"); SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index.getIndexNames()) // .setSearchType(query.getSearchType()) // - .setTypes(index.getTypeNames()) // .setVersion(true) // .setTrackScores(query.getTrackScores()); @@ -654,7 +692,7 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli searchRequestBuilder.setPreference(query.getPreference()); } - prepareSort(query, searchRequestBuilder, entity); + prepareSort(query, searchRequestBuilder, getPersistentEntity(clazz)); HighlightBuilder highlightBuilder = highlightBuilder(query); @@ -669,62 +707,7 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli return searchRequestBuilder; } - private void prepareNativeSearch(NativeSearchQuery query, SearchSourceBuilder sourceBuilder) { - NativeSearchQuery nativeSearchQuery = query; - - if (!nativeSearchQuery.getScriptFields().isEmpty()) { - for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { - sourceBuilder.scriptField(scriptedField.fieldName(), scriptedField.script()); - } - } - - if (nativeSearchQuery.getCollapseBuilder() != null) { - sourceBuilder.collapse(nativeSearchQuery.getCollapseBuilder()); - } - - if (!isEmpty(nativeSearchQuery.getIndicesBoost())) { - for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) { - sourceBuilder.indexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); - } - } - - if (!isEmpty(nativeSearchQuery.getAggregations())) { - for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) { - sourceBuilder.aggregation(aggregationBuilder); - } - } - - } - - private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, NativeSearchQuery nativeSearchQuery) { - if (!isEmpty(nativeSearchQuery.getScriptFields())) { - for (ScriptField scriptedField : nativeSearchQuery.getScriptFields()) { - searchRequestBuilder.addScriptField(scriptedField.fieldName(), scriptedField.script()); - } - } - - if (nativeSearchQuery.getCollapseBuilder() != null) { - searchRequestBuilder.setCollapse(nativeSearchQuery.getCollapseBuilder()); - } - - if (!isEmpty(nativeSearchQuery.getIndicesBoost())) { - for (IndexBoost indexBoost : nativeSearchQuery.getIndicesBoost()) { - searchRequestBuilder.addIndexBoost(indexBoost.getIndexName(), indexBoost.getBoost()); - } - } - - if (!isEmpty(nativeSearchQuery.getAggregations())) { - for (AbstractAggregationBuilder aggregationBuilder : nativeSearchQuery.getAggregations()) { - searchRequestBuilder.addAggregation(aggregationBuilder); - } - } - } - - private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class clazz, - IndexCoordinates index) { - return prepareSearchRequestBuilder(query, client, getPersistentEntity(clazz), index); - } - + @SuppressWarnings("rawtypes") private void prepareSort(Query query, SearchSourceBuilder sourceBuilder, @Nullable ElasticsearchPersistentEntity entity) { @@ -741,6 +724,7 @@ private void prepareSort(Query query, SearchSourceBuilder sourceBuilder, } } + @SuppressWarnings("rawtypes") private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder, @Nullable ElasticsearchPersistentEntity entity) { if (query.getSort() != null) { @@ -756,7 +740,7 @@ private void prepareSort(Query query, SearchRequestBuilder searchRequestBuilder, } } - private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchPersistentEntity entity) { + private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchPersistentEntity entity) { SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC; if (ScoreSortBuilder.NAME.equals(order.getProperty())) { @@ -854,7 +838,7 @@ private String getPersistentEntityId(Object entity) { return null; } - private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { + private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { if (clazz != null) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz).getVersionType(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 6dda54ba5..590b6c984 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -60,7 +60,7 @@ public static Object unwrapSearchHits(Object result) { if (result instanceof AggregatedPage) { AggregatedPage page = (AggregatedPage) result; - List list = page.getContent().stream().map(o -> unwrapSearchHits(o)).collect(Collectors.toList()); + List list = page.getContent().stream().map(SearchHitSupport::unwrapSearchHits).collect(Collectors.toList()); return new AggregatedPageImpl<>(list, null, page.getTotalElements(), page.getAggregations(), page.getScrollId(), page.getMaxScore()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 0165c04af..7dc92f6f4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -237,6 +237,7 @@ default ScrolledPage startScroll(long scrollTimeInMillis, Query query, Cl * @return scrolled page result * @deprecated since 4.0, use {@link #searchScrollContinue(String, long, Class)}. */ + @SuppressWarnings("unchecked") @Deprecated default ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { return (ScrolledPage) SearchHitSupport diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java index b25d4ab2b..f8b326a9d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java @@ -16,19 +16,14 @@ package org.springframework.data.elasticsearch.core.client.support; import lombok.Data; -import lombok.Getter; -import org.elasticsearch.cluster.metadata.AliasMetaData; - -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -@JsonIgnoreProperties(ignoreUnknown=true) +@JsonIgnoreProperties(ignoreUnknown = true) @Data public class AliasData { String filter = null; String routing = null; String search_routing = null; - String index_routing= null; + String index_routing = null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java index 5929a6264..a6a5306ac 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java @@ -84,6 +84,7 @@ public MapTypeAliasAccessor(@Nullable String typeKey) { * (non-Javadoc) * @see org.springframework.data.convert.TypeAliasAccessor#readAliasFrom(java.lang.Object) */ + @Override public Alias readAliasFrom(Map source) { return Alias.ofNullable(source.get(typeKey)); } @@ -92,6 +93,7 @@ public Alias readAliasFrom(Map source) { * (non-Javadoc) * @see org.springframework.data.convert.TypeAliasAccessor#writeTypeTo(java.lang.Object, java.lang.Object) */ + @Override public void writeTypeTo(Map sink, Object alias) { if (typeKey == null) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java index 18cc1c2e0..14b62aee3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java @@ -33,6 +33,7 @@ * Elasticsearch specific {@link CustomConversions}. * * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class ElasticsearchCustomConversions extends CustomConversions { @@ -42,9 +43,7 @@ public class ElasticsearchCustomConversions extends CustomConversions { static { - List converters = new ArrayList<>(); - - converters.addAll(GeoConverters.getConvertersToRegister()); + List converters = new ArrayList<>(GeoConverters.getConvertersToRegister()); converters.add(StringToUUIDConverter.INSTANCE); converters.add(UUIDToStringConverter.INSTANCE); converters.add(BigDecimalToDoubleConverter.INSTANCE); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index b383c346b..f42cce959 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -169,9 +169,10 @@ public SearchHits read(Class type, SearchDocumentResponse searchDocume .map(searchDocument -> read(type, searchDocument)) // .collect(Collectors.toList()); Aggregations aggregations = searchDocumentResponse.getAggregations(); - return new SearchHits(totalHits, maxScore, scrollId, searchHits, aggregations); + return new SearchHits<>(totalHits, maxScore, scrollId, searchHits, aggregations); } + @Override public SearchHit read(Class type, SearchDocument searchDocument) { Assert.notNull(type, "type must not be null"); @@ -182,7 +183,7 @@ public SearchHit read(Class type, SearchDocument searchDocument) { Object[] sortValues = searchDocument.getSortValues(); T content = mapDocument(searchDocument, type); - return new SearchHit(id, score, sortValues, content); + return new SearchHit<>(id, score, sortValues, content); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 28dd733d9..814009b4d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -372,9 +372,7 @@ public void forEach(BiConsumer action) { Objects.requireNonNull(action); - documentFields.forEach(field -> { - action.accept(field.getName(), getValue(field)); - }); + documentFields.forEach(field -> action.accept(field.getName(), getValue(field))); } /* @@ -719,7 +717,7 @@ public String toString() { String id = hasId() ? getId() : "?"; String version = hasVersion() ? Long.toString(getVersion()) : "?"; - return getClass().getSimpleName() + "@" + id + "#" + version + " " + toJson(); + return getClass().getSimpleName() + '@' + id + '#' + version + ' ' + toJson(); } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java index 78ad9c08f..439aeb3b9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java @@ -281,6 +281,6 @@ public String toString() { String id = hasId() ? getId() : "?"; String version = hasVersion() ? Long.toString(getVersion()) : "?"; - return getClass().getSimpleName() + "@" + id + "#" + version + " " + toJson(); + return getClass().getSimpleName() + '@' + id + '#' + version + ' ' + toJson(); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index b12ef55cb..082c7ecfd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -31,7 +31,17 @@ import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.data.annotation.Transient; -import org.springframework.data.elasticsearch.annotations.*; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.annotations.CompletionContext; +import org.springframework.data.elasticsearch.annotations.CompletionField; +import org.springframework.data.elasticsearch.annotations.DynamicMapping; +import org.springframework.data.elasticsearch.annotations.DynamicTemplates; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.GeoPointField; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.completion.Completion; @@ -39,6 +49,7 @@ import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; @@ -95,31 +106,34 @@ public MappingBuilder(ElasticsearchConverter elasticsearchConverter) { * builds the Elasticsearch mapping for the given clazz. * * @return JSON string - * @throws IOException + * @throws ElasticsearchException on errors while building the mapping */ - public String buildPropertyMapping(Class clazz) throws IOException { + public String buildPropertyMapping(Class clazz) throws ElasticsearchException { - ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() - .getRequiredPersistentEntity(clazz); + try { + ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() + .getRequiredPersistentEntity(clazz); - XContentBuilder builder = jsonBuilder().startObject().startObject(entity.getIndexCoordinates().getTypeName()); + XContentBuilder builder = jsonBuilder().startObject(); - // Dynamic templates - addDynamicTemplatesMapping(builder, entity); + // Dynamic templates + addDynamicTemplatesMapping(builder, entity); - // Parent - String parentType = entity.getParentType(); - if (hasText(parentType)) { - builder.startObject(FIELD_PARENT).field(FIELD_PARAM_TYPE, parentType).endObject(); - } + // Parent + String parentType = entity.getParentType(); + if (hasText(parentType)) { + builder.startObject(FIELD_PARENT).field(FIELD_PARAM_TYPE, parentType).endObject(); + } - mapEntity(builder, entity, true, "", false, FieldType.Auto, null, entity.findAnnotation(DynamicMapping.class)); + mapEntity(builder, entity, true, "", false, FieldType.Auto, null, entity.findAnnotation(DynamicMapping.class)); - builder.endObject() // indexType - .endObject() // root object - .close(); + builder.endObject() // root object + .close(); - return builder.getOutputStream().toString(); + return builder.getOutputStream().toString(); + } catch (MappingException | IOException e) { + throw new ElasticsearchException("could not build mapping", e); + } } private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersistentEntity entity, boolean isRootObject, diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 759d38745..8b08f321b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -44,6 +44,7 @@ public interface ElasticsearchPersistentEntity extends PersistentEntitypotential score property of the owning * {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity} * implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should - * rather call {@link ElasticsearchPersistentEntity#isScoreProperty(PersistentProperty)} to determine whether the + * rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the * current property is the score property of that {@link ElasticsearchPersistentEntity} under consideration. * * @return @@ -53,7 +53,7 @@ public interface ElasticsearchPersistentProperty extends PersistentPropertypotential parent property of the owning * {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity} * implementation to discover parent property candidates on {@link ElasticsearchPersistentEntity} creation you should - * rather call {@link ElasticsearchPersistentEntity#isParentProperty()} to determine whether the current property is + * rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the current property is * the parent property of that {@link ElasticsearchPersistentEntity} under consideration. * * @return @@ -78,6 +78,7 @@ enum PropertyToFieldNameConverter implements Converter + * {@link org.springframework.data.elasticsearch.core.DocumentOperations#bulkIndex(List, BulkOptions, IndexCoordinates)} or + * {@link org.springframework.data.elasticsearch.core.DocumentOperations#bulkUpdate(List, BulkOptions, IndexCoordinates)} call.
* Use {@link BulkOptions#builder()} to obtain a builder, then set the desired properties and call * {@link BulkOptionsBuilder#build()} to get the BulkOptions object. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index 3a7bc43c4..91d25e41e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -515,8 +515,8 @@ public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) { private void assertNoBlankInWildcardedQuery(String searchString, boolean leadingWildcard, boolean trailingWildcard) { if (searchString != null && searchString.contains(CRITERIA_VALUE_SEPERATOR)) { - throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + "\"" - + searchString + "\"" + (trailingWildcard ? "*" : "") + "'. Use expression or multiple clauses instead."); + throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + '"' + + searchString + '"' + (trailingWildcard ? "*" : "") + "'. Use expression or multiple clauses instead."); } } @@ -618,7 +618,7 @@ public enum OperationKey { // /** * @since 4.0 */ - EXISTS; + EXISTS } public static class CriteriaEntry { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java index 8a4f31466..b348c85bb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java @@ -24,6 +24,7 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Mark Paluch + * @author Peter-Josef Meisch */ public class CriteriaQuery extends AbstractQuery { @@ -45,7 +46,7 @@ public CriteriaQuery(Criteria criteria, Pageable pageable) { this.addSort(pageable.getSort()); } - public static final Query fromQuery(CriteriaQuery source) { + public static Query fromQuery(CriteriaQuery source) { return fromQuery(source, new CriteriaQuery()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java index ae9113936..317877947 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java @@ -39,7 +39,6 @@ public SourceFilter build() { if (includes == null) includes = new String[0]; if (excludes == null) excludes = new String[0]; - SourceFilter sourceFilter = new FetchSourceFilter(includes, excludes); - return sourceFilter; + return new FetchSourceFilter(includes, excludes); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index 961c7d164..1e4081bdd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -15,7 +15,6 @@ */ package org.springframework.data.elasticsearch.core.query; -import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.update.UpdateRequest; /** diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index c04043df3..9e7ad0bd8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -18,7 +18,6 @@ import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.NoRepositoryBean; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index d361d5708..f2a044b57 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -90,7 +90,7 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) { IndexCoordinates index = IndexCoordinates.of(indexName).withTypes(indexTypeName); ReactiveElasticsearchQueryExecution execution = getExecution(parameterAccessor, - new ResultProcessingConverter(processor, elasticsearchOperations)); + new ResultProcessingConverter(processor)); return execution.execute(query, processor.getReturnedType().getDomainType(), targetType, index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java index 7c3df3b03..2e90241f0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java @@ -19,11 +19,17 @@ /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public interface ElasticsearchEntityMetadata extends EntityMetadata { String getIndexName(); + /** + * @return the type for the index + * @deprecated since 4.0 + */ + @Deprecated String getIndexTypeName(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java index 735b19645..df9d7b67f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java @@ -26,6 +26,7 @@ /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class ElasticsearchParameters extends Parameters { @@ -55,26 +56,14 @@ protected ElasticsearchParameters createFrom(List parame */ class ElasticsearchParameter extends Parameter { - private final MethodParameter parameter; - /** * Creates a new {@link ElasticsearchParameter}. * * @param parameter must not be {@literal null}. */ ElasticsearchParameter(MethodParameter parameter) { - super(parameter); - this.parameter = parameter; } - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.Parameter#isSpecialParameter() - */ - @Override - public boolean isSpecialParameter() { - return super.isSpecialParameter(); - } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 38d75d05e..b529bf8b3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -81,13 +81,12 @@ public Object execute(Object[] parameters) { SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); result = SearchHitSupport.page(searchHits, query.getPageable()); } else if (queryMethod.isStreamQuery()) { - Class entityType = clazz; if (accessor.getPageable().isUnpaged()) { query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE)); } else { query.setPageable(accessor.getPageable()); } - result = StreamUtils.createStreamFromIterator(elasticsearchOperations.stream(query, entityType, index)); + result = StreamUtils.createStreamFromIterator(elasticsearchOperations.stream(query, clazz, index)); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java index d9eaf1a08..8fd8a97d9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java @@ -67,6 +67,7 @@ public String getAnnotatedQuery() { * @return the {@link ElasticsearchEntityMetadata} for the query methods {@link #getReturnedObjectType() return type}. * @since 3.2 */ + @Override public ElasticsearchEntityMetadata getEntityInformation() { if (metadata == null) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java index 6be298523..4ef0b9992 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java @@ -44,9 +44,7 @@ class ReactiveElasticsearchParametersParameterAccessor extends ElasticsearchPara this.subscriptions = new ArrayList<>(values.length); - for (int i = 0; i < values.length; i++) { - - Object value = values[i]; + for (Object value : values) { if (value == null || !ReactiveWrappers.supports(value.getClass())) { @@ -95,6 +93,7 @@ public Object[] getValues() { * (non-Javadoc) * @see org.springframework.data.repository.query.ParametersParameterAccessor#getBindableValue(int) */ + @Override public Object getBindableValue(int index) { return getValue(getParameters().getBindableParameter(index).getIndex()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java index 7ef44c08e..e3fbc76b1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java @@ -17,7 +17,6 @@ import org.springframework.core.convert.converter.Converter; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.query.ResultProcessor; import org.springframework.data.repository.query.ReturnedType; @@ -66,13 +65,10 @@ public Object execute(Query query, Class type, @Nullable Class targetType, final class ResultProcessingConverter implements Converter { private final ResultProcessor processor; - private final ReactiveElasticsearchOperations operations; - public ResultProcessingConverter(ResultProcessor processor, ReactiveElasticsearchOperations operations) { + public ResultProcessingConverter(ResultProcessor processor) { Assert.notNull(processor, "processor must not be null"); - Assert.notNull(operations, "operations must not be null"); this.processor = processor; - this.operations = operations; } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java index 414fc52b6..da6b7dba0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java @@ -38,6 +38,7 @@ /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class ReactiveElasticsearchQueryMethod extends ElasticsearchQueryMethod { @@ -45,13 +46,10 @@ public class ReactiveElasticsearchQueryMethod extends ElasticsearchQueryMethod { private static final ClassTypeInformation PAGE_TYPE = ClassTypeInformation.from(Page.class); private static final ClassTypeInformation SLICE_TYPE = ClassTypeInformation.from(Slice.class); - private final Method method; - public ReactiveElasticsearchQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory, MappingContext, ElasticsearchPersistentProperty> mappingContext) { super(method, metadata, factory, mappingContext); - this.method = method; if (hasParameterOfType(method, Pageable.class)) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java index 88ee4d9c4..ee90dfef0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java @@ -30,13 +30,12 @@ public class ReactivePartTreeElasticsearchQuery extends AbstractReactiveElasticsearchRepositoryQuery { private final PartTree tree; - private final ResultProcessor processor; public ReactivePartTreeElasticsearchQuery(ReactiveElasticsearchQueryMethod queryMethod, ReactiveElasticsearchOperations elasticsearchOperations) { super(queryMethod, elasticsearchOperations); - this.processor = queryMethod.getResultProcessor(); + ResultProcessor processor = queryMethod.getResultProcessor(); this.tree = new PartTree(queryMethod.getName(), processor.getReturnedType().getDomainType()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java index d900f89ac..80aae45b4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java @@ -16,10 +16,12 @@ package org.springframework.data.elasticsearch.repository.query; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.util.Assert; /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class SimpleElasticsearchEntityMetadata implements ElasticsearchEntityMetadata { @@ -43,7 +45,7 @@ public String getIndexName() { @Override public String getIndexTypeName() { - return entity.getIndexCoordinates().getTypeName(); + return IndexCoordinates.TYPE; } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 04437b862..5977febef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -101,7 +101,7 @@ public AbstractElasticsearchRepository(ElasticsearchEntityInformation met putMapping(); } } catch (ElasticsearchException exception) { - LOGGER.error("failed to load elasticsearch nodes : {}", exception.getDetailedMessage()); + LOGGER.warn("Cannot create index: {}", exception.getDetailedMessage()); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java index 0ecb9024e..b9c64c871 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java @@ -106,6 +106,7 @@ protected Optional getQueryLookupStrategy(@Nullable Key key * (non-Javadoc) * @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class) */ + @Override public ElasticsearchEntityInformation getEntityInformation(Class domainClass) { return getEntityInformation(domainClass, null); } diff --git a/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java b/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java index a2a04cae4..a35685425 100644 --- a/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java @@ -19,10 +19,8 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnectionInfo; import org.springframework.data.elasticsearch.junit.jupiter.IntegrationTest; -import org.springframework.data.elasticsearch.junit.jupiter.SpringDataElasticsearchExtension; /** * Testing the setup and parameter injection of the CusterConnectionInfo. diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 29c6f3644..e42b53652 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -44,6 +44,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.GetQuery; @@ -66,14 +67,15 @@ @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class NestedObjectTests { - @Autowired private ElasticsearchOperations elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - - IndexInitializer.init(elasticsearchTemplate, Book.class); - IndexInitializer.init(elasticsearchTemplate, Person.class); - IndexInitializer.init(elasticsearchTemplate, PersonMultipleLevelNested.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, Book.class); + IndexInitializer.init(indexOperations, Person.class); + IndexInitializer.init(indexOperations, PersonMultipleLevelNested.class); } @Test @@ -124,14 +126,14 @@ public void shouldIndexInitialLevelNestedObject() { indexQueries.add(indexQuery2); IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(Person.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(Person.class); QueryBuilder builder = nestedQuery("car", boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - SearchHits persons = elasticsearchTemplate.search(searchQuery, Person.class, index); + SearchHits persons = operations.search(searchQuery, Person.class, index); assertThat(persons).hasSize(1); } @@ -143,14 +145,14 @@ public void shouldIndexMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - elasticsearchTemplate.bulkIndex(indexQueries, + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); - elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); + indexOperations.refresh(PersonMultipleLevelNested.class); // then GetQuery getQuery = new GetQuery(); getQuery.setId("1"); - PersonMultipleLevelNested personIndexed = elasticsearchTemplate.get(getQuery, PersonMultipleLevelNested.class, + PersonMultipleLevelNested personIndexed = operations.get(getQuery, PersonMultipleLevelNested.class, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); assertThat(personIndexed).isNotNull(); } @@ -162,11 +164,11 @@ public void shouldIndexMultipleLevelNestedObjectWithIncludeInParent() { List indexQueries = createPerson(); // when - elasticsearchTemplate.bulkIndex(indexQueries, + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); // then - Map mapping = elasticsearchTemplate.getMapping(PersonMultipleLevelNested.class); + Map mapping = indexOperations.getMapping(PersonMultipleLevelNested.class); assertThat(mapping).isNotNull(); Map propertyMap = (Map) mapping.get("properties"); @@ -183,8 +185,8 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { // when IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user"); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(PersonMultipleLevelNested.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(PersonMultipleLevelNested.class); // then BoolQueryBuilder builder = boolQuery(); @@ -193,7 +195,7 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - SearchHits personIndexed = elasticsearchTemplate.search(searchQuery, + SearchHits personIndexed = operations.search(searchQuery, PersonMultipleLevelNested.class, index); assertThat(personIndexed).isNotNull(); assertThat(personIndexed.getTotalHits()).isEqualTo(1); @@ -323,14 +325,14 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { indexQueries.add(indexQuery2); IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(Person.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(Person.class); // when QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build(); - SearchHits persons = elasticsearchTemplate.search(searchQuery, Person.class, index); + SearchHits persons = operations.search(searchQuery, Person.class, index); // then assertThat(persons).hasSize(1); @@ -372,13 +374,13 @@ public void shouldIndexAndSearchMapAsNestedType() { // when IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes("book"); - elasticsearchTemplate.bulkIndex(indexQueries, index); - elasticsearchTemplate.refresh(Book.class); + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(Book.class); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(nestedQuery("buckets", termQuery("buckets.1", "test3"), ScoreMode.None)).build(); - SearchHits books = elasticsearchTemplate.search(searchQuery, Book.class, index); + SearchHits books = operations.search(searchQuery, Book.class, index); assertThat(books.getSearchHits()).hasSize(1); assertThat(books.getSearchHit(0).getContent().getId()).isEqualTo(book2.getId()); @@ -386,7 +388,7 @@ public void shouldIndexAndSearchMapAsNestedType() { @Setter @Getter - @Document(indexName = "test-index-book-nested-objects", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-nested-objects", replicas = 0, refreshInterval = "-1") static class Book { @@ -400,7 +402,7 @@ static class Book { } @Data - @Document(indexName = "test-index-person", type = "user", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-person", replicas = 0, refreshInterval = "-1") static class Person { @Id private String id; @@ -425,7 +427,7 @@ static class Car { * @author Artur Konczak */ @Data - @Document(indexName = "test-index-person-multiple-level-nested", type = "user", shards = 1, replicas = 0, + @Document(indexName = "test-index-person-multiple-level-nested", replicas = 0, refreshInterval = "-1") static class PersonMultipleLevelNested { diff --git a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java b/src/test/java/org/springframework/data/elasticsearch/TestUtils.java index 7e6be5287..bd879cb78 100644 --- a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/TestUtils.java @@ -34,7 +34,6 @@ import org.springframework.data.elasticsearch.support.SearchHitsUtil; import org.springframework.data.util.Version; import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; /** * @author Christoph Strobl @@ -115,7 +114,6 @@ public interface OfType extends ExistsIn { private static class DocumentLookup implements OfType { private String id; - private String type; public DocumentLookup(String id) { this.id = id; @@ -126,9 +124,6 @@ public DocumentLookup(String id) { public boolean existsIn(String index) { GetRequest request = new GetRequest(index).id(id); - if (StringUtils.hasText(type)) { - request = request.type(type); - } try (RestHighLevelClient client = restHighLevelClient()) { return client.get(request, RequestOptions.DEFAULT).isExists(); } @@ -136,7 +131,6 @@ public boolean existsIn(String index) { @Override public ExistsIn ofType(String type) { - this.type = type; return this; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index cea61945c..aa1c0fc0b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import lombok.SneakyThrows; +import org.elasticsearch.client.indices.GetIndexRequest; import reactor.test.StepVerifier; import java.io.IOException; @@ -31,7 +32,6 @@ import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.Version; -import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; @@ -134,17 +134,14 @@ public void pingForUnknownHostShouldReturnFalse() { public void infoShouldReturnClusterInformation() { client.info().as(StepVerifier::create) // - .consumeNextWith(it -> { - - assertThat(it.getVersion()).isGreaterThanOrEqualTo(Version.CURRENT); - }) // + .consumeNextWith(it -> assertThat(it.getVersion()).isGreaterThanOrEqualTo(Version.CURRENT)) // .verifyComplete(); } @Test // DATAES-519 public void getOnNonExistingIndexShouldThrowException() { - client.get(new GetRequest(INDEX_I, TYPE_I, "nonono")) // + client.get(new GetRequest(INDEX_I, "nonono")) // .as(StepVerifier::create) // .expectError(ElasticsearchStatusException.class) // .verify(); @@ -155,7 +152,7 @@ public void getShouldFetchDocumentById() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - client.get(new GetRequest(INDEX_I, TYPE_I, id)) // + client.get(new GetRequest(INDEX_I, id)) // .as(StepVerifier::create) // .consumeNextWith(it -> { @@ -171,17 +168,7 @@ public void getShouldCompleteForNonExistingDocuments() { addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = "this-one-does-not-exist"; - client.get(new GetRequest(INDEX_I, TYPE_I, id)) // - .as(StepVerifier::create) // - .verifyComplete(); - } - - @Test // DATAES-488 - public void getShouldCompleteForNonExistingType() { - - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - - client.get(new GetRequest(INDEX_I, "fantasy-books", id)) // + client.get(new GetRequest(INDEX_I, id)) // .as(StepVerifier::create) // .verifyComplete(); } @@ -193,17 +180,13 @@ public void multiGetShouldReturnAllDocumentsFromSameCollection() { String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // - .add(INDEX_I, TYPE_I, id1) // - .add(INDEX_I, TYPE_I, id2); + .add(INDEX_I, id1) // + .add(INDEX_I, id2); client.multiGet(request) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(it.getId()).isEqualTo(id1); - }) // - .consumeNextWith(it -> { - assertThat(it.getId()).isEqualTo(id2); - }) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo(id1)) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo(id2)) // .verifyComplete(); } @@ -214,14 +197,12 @@ public void multiGetShouldReturnAllExistingDocumentsFromSameCollection() { addSourceDocument().ofType(TYPE_I).to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // - .add(INDEX_I, TYPE_I, id1) // - .add(INDEX_I, TYPE_I, "this-one-does-not-exist"); + .add(INDEX_I, id1) // + .add(INDEX_I, "this-one-does-not-exist"); client.multiGet(request) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(it.getId()).isEqualTo(id1); - }) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo(id1)) // .verifyComplete(); } @@ -232,9 +213,9 @@ public void multiGetShouldSkipNonExistingDocuments() { String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // - .add(INDEX_I, TYPE_I, id1) // - .add(INDEX_I, TYPE_I, "this-one-does-not-exist") // - .add(INDEX_I, TYPE_I, id2); // + .add(INDEX_I,id1) // + .add(INDEX_I,"this-one-does-not-exist") // + .add(INDEX_I,id2); // client.multiGet(request) // .map(GetResult::getId) // @@ -249,7 +230,9 @@ public void multiGetShouldCompleteIfNothingFound() { String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - client.multiGet(new MultiGetRequest().add(INDEX_II, TYPE_I, id1).add(INDEX_II, TYPE_I, id2)) // + client.multiGet(new MultiGetRequest() // + .add(INDEX_II, id1) + .add(INDEX_II, id2)) // .as(StepVerifier::create) // .verifyComplete(); } @@ -261,8 +244,8 @@ public void multiGetShouldReturnAllExistingDocumentsFromDifferentCollection() { String id2 = addSourceDocument().ofType(TYPE_II).to(INDEX_II); MultiGetRequest request = new MultiGetRequest() // - .add(INDEX_I, TYPE_I, id1) // - .add(INDEX_II, TYPE_II, id2); + .add(INDEX_I, id1) // + .add(INDEX_II, id2); client.multiGet(request) // .map(GetResult::getId) // @@ -276,7 +259,7 @@ public void existsReturnsTrueForExistingDocuments() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - client.exists(new GetRequest(INDEX_I, TYPE_I, id)) // + client.exists(new GetRequest(INDEX_I, id)) // .as(StepVerifier::create) // .expectNext(true)// .verifyComplete(); @@ -287,7 +270,7 @@ public void existsReturnsFalseForNonExistingDocuments() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - client.exists(new GetRequest(INDEX_II, TYPE_I, id)) // + client.exists(new GetRequest(INDEX_II, id)) // .as(StepVerifier::create) // .expectNext(false)// .verifyComplete(); @@ -325,7 +308,7 @@ public void indexShouldErrorForExistingDocuments() { public void updateShouldUpsertNonExistingDocumentWhenUsedWithUpsert() { String id = UUID.randomUUID().toString(); - UpdateRequest request = new UpdateRequest(INDEX_I, TYPE_I, id) // + UpdateRequest request = new UpdateRequest(INDEX_I, id) // .doc(DOC_SOURCE) // .docAsUpsert(true); @@ -344,7 +327,7 @@ public void updateShouldUpdateExistingDocument() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - UpdateRequest request = new UpdateRequest(INDEX_I, TYPE_I, id) // + UpdateRequest request = new UpdateRequest(INDEX_I, id) // .doc(Collections.singletonMap("dutiful", "farseer")); client.update(request) // @@ -362,7 +345,7 @@ public void updateShouldUpdateExistingDocument() { public void updateShouldErrorNonExistingDocumentWhenNotUpserted() { String id = UUID.randomUUID().toString(); - UpdateRequest request = new UpdateRequest(INDEX_I, TYPE_I, id) // + UpdateRequest request = new UpdateRequest(INDEX_I, id) // .doc(DOC_SOURCE); client.update(request) // @@ -375,13 +358,11 @@ public void deleteShouldRemoveExistingDocument() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - DeleteRequest request = new DeleteRequest(INDEX_I, TYPE_I, id); + DeleteRequest request = new DeleteRequest(INDEX_I, id); client.delete(request) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(it.status()).isEqualTo(RestStatus.OK); - }) // + .consumeNextWith(it -> assertThat(it.status()).isEqualTo(RestStatus.OK)) // .verifyComplete(); } @@ -390,13 +371,11 @@ public void deleteShouldReturnNotFoundForNonExistingDocument() { addSourceDocument().ofType(TYPE_I).to(INDEX_I); - DeleteRequest request = new DeleteRequest(INDEX_I, TYPE_I, "this-one-does-not-exist"); + DeleteRequest request = new DeleteRequest(INDEX_I, "this-one-does-not-exist"); client.delete(request) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(it.status()).isEqualTo(RestStatus.NOT_FOUND); - }) // + .consumeNextWith(it -> assertThat(it.status()).isEqualTo(RestStatus.NOT_FOUND)) // .verifyComplete(); } @@ -406,7 +385,7 @@ public void searchShouldFindExistingDocuments() { addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().ofType(TYPE_I).to(INDEX_I); - SearchRequest request = new SearchRequest(INDEX_I).types(TYPE_I) // + SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); client.search(request) // @@ -420,7 +399,7 @@ public void searchShouldCompleteIfNothingFound() throws IOException { syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); - SearchRequest request = new SearchRequest(INDEX_I).types(TYPE_I) // + SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); client.search(request) // @@ -435,7 +414,6 @@ public void deleteByShouldRemoveExistingDocument() { String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // - .setDocTypes(TYPE_I) // .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", id))); client.deleteBy(request) // @@ -452,7 +430,6 @@ public void deleteByEmitResultWhenNothingRemoved() { addSourceDocument().ofType(TYPE_I).to(INDEX_I); DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // - .setDocTypes(TYPE_I) // .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", "it-was-not-me"))); client.deleteBy(request) // @@ -467,7 +444,7 @@ public void scrollShouldReadWhileEndNotReached() { IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); - SearchRequest request = new SearchRequest(INDEX_I).types(TYPE_I) // + SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); request = request.scroll(TimeValue.timeValueMinutes(1)); @@ -483,7 +460,7 @@ public void scrollShouldReadWhileTakeNotReached() { IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); - SearchRequest request = new SearchRequest(INDEX_I).types(TYPE_I) // + SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); request = request.scroll(TimeValue.timeValueMinutes(1)); @@ -524,7 +501,7 @@ public void createIndex() throws IOException { .as(StepVerifier::create) // .verifyComplete(); - assertThat(syncClient.indices().exists(new GetIndexRequest().indices(INDEX_I), RequestOptions.DEFAULT)).isTrue(); + assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isTrue(); } @Test // DATAES-569 @@ -546,7 +523,7 @@ public void deleteExistingIndex() throws IOException { .as(StepVerifier::create) // .verifyComplete(); - assertThat(syncClient.indices().exists(new GetIndexRequest().indices(INDEX_I), RequestOptions.DEFAULT)).isFalse(); + assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse(); } @Test // DATAES-569 @@ -658,9 +635,9 @@ public void bulkShouldUpdateExistingDocument() { String idFirstDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String idSecondDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - UpdateRequest requestFirstDoc = new UpdateRequest(INDEX_I, TYPE_I, idFirstDoc) // + UpdateRequest requestFirstDoc = new UpdateRequest(INDEX_I, idFirstDoc) // .doc(Collections.singletonMap("dutiful", "farseer")); - UpdateRequest requestSecondDoc = new UpdateRequest(INDEX_I, TYPE_I, idSecondDoc) // + UpdateRequest requestSecondDoc = new UpdateRequest(INDEX_I, idSecondDoc) // .doc(Collections.singletonMap("secondDocUpdate", "secondDocUpdatePartTwo")); BulkRequest bulkRequest = new BulkRequest(); @@ -683,13 +660,13 @@ private AddToIndexOfType addSourceDocument() { return add(DOC_SOURCE); } - private AddToIndexOfType add(Map source) { + private AddToIndexOfType add(Map source) { return new AddDocument(source); } private IndexRequest indexRequest(Map source, String index, String type) { - return new IndexRequest(index, type) // + return new IndexRequest(index) // .id(UUID.randomUUID().toString()) // .source(source) // .setRefreshPolicy(RefreshPolicy.IMMEDIATE) // @@ -711,10 +688,10 @@ interface AddToIndex { class AddDocument implements AddToIndexOfType { - Map source; + Map source; @Nullable String type; - AddDocument(Map source) { + AddDocument(Map source) { this.source = source; } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index 4a7488c68..01e4ee615 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.client.reactive; import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*; diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index 49063946b..2ff13a387 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -129,10 +129,12 @@ public MockDelegatingElasticsearchHostProvider(HttpHeaders httpHeaders, MockWebC this.activeDefaultHost = activeDefaultHost; } + @Override public Mono lookupActiveHost() { return delegate.lookupActiveHost(); } + @Override public Mono lookupActiveHost(Verification verification) { if (StringUtils.hasText(activeDefaultHost)) { @@ -142,14 +144,17 @@ public Mono lookupActiveHost(Verification verification) { return delegate.lookupActiveHost(verification); } + @Override public Mono getActive() { return delegate.getActive(); } + @Override public Mono getActive(Verification verification) { return delegate.getActive(verification); } + @Override public WebClient createWebClient(InetSocketAddress endpoint) { return delegate.createWebClient(endpoint); } @@ -210,6 +215,7 @@ public WebClient get(String host) { return get(getInetSocketAddress(host)); } + @Override public WebClient get(InetSocketAddress endpoint) { synchronized (lock) { diff --git a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java index 4ec7d5fbf..f234bc959 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java @@ -65,7 +65,7 @@ public void bootstrapsRepository() { assertThat(repository).isNotNull(); } - @Document(indexName = "test-index-config-abstractelasticsearchconfiguraiton", type = "test-type", createIndex = false) + @Document(indexName = "test-index-config-abstractelasticsearchconfiguraiton", createIndex = false) static class CreateIndexFalseEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java index 1618e0732..591fcdc17 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java @@ -63,7 +63,7 @@ public void shouldCreateRestClient() { assertThat(context.getBean(RestClientFactoryBean.class)).isInstanceOf(RestClientFactoryBean.class); } - @Document(indexName = "test-index-config-namespace", type = "test-type", createIndex = false) + @Document(indexName = "test-index-config-namespace", createIndex = false) static class CreateIndexFalseEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java index 8c232a9dd..72df2ec51 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java @@ -35,7 +35,7 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.geo.GeoPoint; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.repository.Repository; @@ -50,7 +50,7 @@ public class EnableNestedElasticsearchRepositoriesTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) + @Import({ ElasticsearchRestTemplateConfiguration.class }) @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.config.nested" }, considerNestedRepositories = true) static class Config {} @@ -64,8 +64,7 @@ public void hasNestedRepository() { @Data @Builder - @Document(indexName = "test-index-sample-config-nested", type = "test-type", shards = 1, replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-config-nested", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java new file mode 100644 index 000000000..f21ab286e --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 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.config.nested; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { EnableNestedElasticsearchRepositoriesTransportTests.Config.class }) +public class EnableNestedElasticsearchRepositoriesTransportTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index 348abe6e5..fb6107bac 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -83,7 +83,7 @@ interface SampleRepository extends Repository fields = Collections.singletonMap("field", - new DocumentField("field", Arrays.asList("value"))); + new DocumentField("field", Collections.singletonList("value"))); GetResult getResult = new GetResult("index", "type", "my-id", 1, 1, 42, true, null, fields, null); GetResponse response = new GetResponse(getResult); @@ -80,7 +80,7 @@ public void shouldAdaptGetResponseSource() { public void shouldAdaptSearchResponse() { Map fields = Collections.singletonMap("field", - new DocumentField("field", Arrays.asList("value"))); + new DocumentField("field", Collections.singletonList("value"))); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); searchHit.score(42); @@ -99,7 +99,7 @@ public void searchResponseShouldReturnContainsKey() { Map fields = new LinkedHashMap<>(); - fields.put("string", new DocumentField("string", Arrays.asList("value"))); + fields.put("string", new DocumentField("string", Collections.singletonList("value"))); fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); @@ -115,7 +115,7 @@ public void searchResponseShouldReturnContainsValue() { Map fields = new LinkedHashMap<>(); - fields.put("string", new DocumentField("string", Arrays.asList("value"))); + fields.put("string", new DocumentField("string", Collections.singletonList("value"))); fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); fields.put("null", new DocumentField("null", Collections.emptyList())); @@ -133,7 +133,7 @@ public void shouldRenderToJson() { Map fields = new LinkedHashMap<>(); - fields.put("string", new DocumentField("string", Arrays.asList("value"))); + fields.put("string", new DocumentField("string", Collections.singletonList("value"))); fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 83a286cb3..01271dd76 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -60,14 +60,12 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() IndexRequest indexRequest = new IndexRequest(); indexRequest.source("{}", XContentType.JSON); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); - assertThatThrownBy(() -> { - operations.update(updateQuery, index); - }).isInstanceOf(ElasticsearchStatusException.class); + assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(ElasticsearchStatusException.class); } @Data @Builder - @Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-core-rest-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 4f4b7cefb..64036be37 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -332,9 +332,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { .withPreference("_only_nodes:oops").build(); // when - assertThatThrownBy(() -> { - operations.search(searchQueryWithInvalidPreference, SampleEntity.class, index); - }).isInstanceOf(Exception.class); + assertThatThrownBy(() -> operations.search(searchQueryWithInvalidPreference, SampleEntity.class, index)).isInstanceOf(Exception.class); } @Test // DATAES-422 - Add support for IndicesOptions in search queries @@ -515,7 +513,7 @@ public void shouldDeleteAcrossIndex() { // when DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(typeQuery(TYPE_NAME)); + deleteQuery.setQuery(termQuery("message", "foo")); operations.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); @@ -1390,8 +1388,8 @@ public void shouldPutMappingWithCustomIndexName() { indexOperations.createIndex(INDEX_1_NAME); // when - indexOperations.putMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME), entity); + // then Map mapping = indexOperations.getMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME)); assertThat(mapping.get("properties")).isNotNull(); @@ -1441,7 +1439,7 @@ public void shouldDoPartialUpdateForExistingDocument() { } @Test // DATAES-227 - public void shouldUseUpsertOnUpdate() throws IOException { + public void shouldUseUpsertOnUpdate() { // given Map doc = new HashMap<>(); @@ -1465,7 +1463,7 @@ public void shouldUseUpsertOnUpdate() throws IOException { } @Test // DATAES-693 - public void shouldReturnSourceWhenRequested() throws IOException { + public void shouldReturnSourceWhenRequested() { // given Map doc = new HashMap<>(); doc.put("id", "1"); @@ -1525,12 +1523,10 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - List> entities = new ArrayList<>(); - ScrolledPage> scroll = operations.searchScrollStart(scrollTimeInMillis, searchQuery, SampleEntity.class, index); - entities.addAll(scroll.getContent()); + List> entities = new ArrayList<>(scroll.getContent()); while (scroll.hasContent()) { scroll = operations.searchScrollContinue(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); @@ -1858,9 +1854,7 @@ public void shouldIndexGteEntityWithVersionType() { indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // reindex with version one below - assertThatThrownBy(() -> { - operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index); - }).hasMessageContaining("version").hasMessageContaining("conflict"); + assertThatThrownBy(() -> operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index)).hasMessageContaining("version").hasMessageContaining("conflict"); } @Test @@ -2140,9 +2134,7 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - assertThatThrownBy(() -> { - operations.count(criteriaQuery, (IndexCoordinates) null); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> operations.count(criteriaQuery, (IndexCoordinates) null)).isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-67 @@ -2159,9 +2151,7 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - assertThatThrownBy(() -> { - operations.count(searchQuery, (IndexCoordinates) null); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> operations.count(searchQuery, (IndexCoordinates) null)).isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-71 @@ -2173,7 +2163,7 @@ public void shouldCreateIndexWithGivenSettings() { + " \"analyzer\": {\n" + " \"emailAnalyzer\": {\n" + " \"type\": \"custom\",\n" + " \"tokenizer\": \"uax_url_email\"\n" + " }\n" - + " }\n" + " }\n" + " }\n" + "}"; + + " }\n" + " }\n" + " }\n" + '}'; indexOperations.deleteIndex(INDEX_3_NAME); @@ -2215,7 +2205,7 @@ public void shouldCreateIndexWithGivenClassAndSettings() { + " \"analyzer\": {\n" + " \"emailAnalyzer\": {\n" + " \"type\": \"custom\",\n" + " \"tokenizer\": \"uax_url_email\"\n" + " }\n" - + " }\n" + " }\n" + " }\n" + "}"; + + " }\n" + " }\n" + " }\n" + '}'; // when indexOperations.deleteIndex(SampleEntity.class); @@ -2798,7 +2788,7 @@ public void shouldRemoveAlias() { assertThat(aliases).isEmpty(); } - @Document(indexName = INDEX_2_NAME, replicas = 0, shards = 1) + @Document(indexName = INDEX_2_NAME, replicas = 0) class ResultAggregator { private String id; @@ -2900,7 +2890,7 @@ protected RequestFactory getRequestFactory() { @AllArgsConstructor @EqualsAndHashCode(exclude = "score") @Builder - @Document(indexName = INDEX_NAME_SAMPLE_ENTITY, type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = INDEX_NAME_SAMPLE_ENTITY, replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; @@ -2923,7 +2913,7 @@ static class SampleEntity { @Data @AllArgsConstructor @Builder - @Document(indexName = "test-index-uuid-keyed-core-template", type = "test-type-uuid-keyed", shards = 1, replicas = 0, + @Document(indexName = "test-index-uuid-keyed-core-template", replicas = 0, refreshInterval = "-1") private static class SampleEntityUUIDKeyed { @@ -2945,7 +2935,7 @@ private static class SampleEntityUUIDKeyed { @Builder @AllArgsConstructor @NoArgsConstructor - @Document(indexName = "test-index-book-core-template", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-core-template", replicas = 0, refreshInterval = "-1") static class Book { @@ -2969,7 +2959,7 @@ static class Author { @Builder @AllArgsConstructor @NoArgsConstructor - @Document(indexName = "test-index-version-core-template", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-version-core-template", replicas = 0, refreshInterval = "-1", versionType = VersionType.EXTERNAL_GTE) private static class GTEVersionEntity { @@ -2981,7 +2971,7 @@ private static class GTEVersionEntity { } @Data - @Document(indexName = "test-index-hetro1-core-template", type = "hetro", replicas = 0, shards = 1) + @Document(indexName = "test-index-hetro1-core-template", replicas = 0) static class HetroEntity1 { @Id private String id; @@ -2996,7 +2986,7 @@ static class HetroEntity1 { } @Data - @Document(indexName = "test-index-hetro2-core-template", type = "hetro", replicas = 0, shards = 1) + @Document(indexName = "test-index-hetro2-core-template", replicas = 0) static class HetroEntity2 { @Id private String id; @@ -3011,7 +3001,7 @@ static class HetroEntity2 { } @Data - @Document(indexName = "test-index-server-configuration", type = "test-type", useServerConfiguration = true, + @Document(indexName = "test-index-server-configuration", useServerConfiguration = true, shards = 10, replicas = 10, refreshInterval = "-1") private static class UseServerConfigurationEntity { @@ -3021,7 +3011,7 @@ private static class UseServerConfigurationEntity { } @Data - @Document(indexName = "test-index-sample-mapping", type = "mapping", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-sample-mapping", replicas = 0, refreshInterval = "-1") static class SampleMappingEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index e9e150b21..683e2571c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -59,11 +59,10 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() IndexRequest indexRequest = new IndexRequest(); indexRequest.source("{}", XContentType.JSON); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); - assertThatThrownBy(() -> { - operations.update(updateQuery, index); - }).isInstanceOf(DocumentMissingException.class); + assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(DocumentMissingException.class); } + @Override @Test // DATAES-187 public void shouldUsePageableOffsetToSetFromInSearchRequest() { @@ -88,7 +87,7 @@ public long getOffset() { } @Data - @Document(indexName = "test-index-sample-core-transport-template", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-core-transport-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java index 12bc66bce..0f1a6a14c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java @@ -27,23 +27,17 @@ class IndexCoordinatesTest { @Test void cannotBeInitializedWithNullIndexName() { - assertThatThrownBy(() -> { - IndexCoordinates.of(null); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> IndexCoordinates.of(null)).isInstanceOf(IllegalArgumentException.class); } @Test void cannotBeInitializedWithNullIndexNames() { - assertThatThrownBy(() -> { - IndexCoordinates.of((String[]) null); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> IndexCoordinates.of((String[]) null)).isInstanceOf(IllegalArgumentException.class); } @Test void cannotBeInitializedWithEmptyIndexNames() { - assertThatThrownBy(() -> { - IndexCoordinates.of(new String[] {}); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> IndexCoordinates.of(new String[] {})).isInstanceOf(IllegalArgumentException.class); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 633a497c4..ff16c14a2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -27,6 +27,7 @@ import java.util.Date; import org.elasticsearch.ElasticsearchException; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -61,11 +62,12 @@ static class Config {} private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes("test-log-type"); @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() throws ParseException { - - IndexInitializer.init(operations, LogEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, LogEntity.class); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); IndexQuery indexQuery1 = new LogEntityBuilder("1").action("update").date(dateFormatter.parse("2013-10-18 18:01")) @@ -81,7 +83,12 @@ public void before() throws ParseException { .code(2).ip("10.10.10.4").buildIndex(); operations.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index); - operations.refresh(LogEntity.class); + indexOperations.refresh(LogEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(LogEntity.class); } @Test // DATAES-66 @@ -122,7 +129,7 @@ public void shouldReturnLogsForGivenIPRanges() { * Simple type to test facets */ @Data - @Document(indexName = "test-index-log-core", type = "test-log-type", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-log-core", replicas = 0, refreshInterval = "-1") static class LogEntity { private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index d85e25e4b..4d74cb592 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -24,6 +24,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -99,7 +100,7 @@ public void setUp() { } @AfterEach - public void tearDown() { + public void after() { deleteIndices(); } @@ -110,7 +111,7 @@ private void deleteIndices() { @Test // DATAES-504 public void executeShouldProvideResource() { - Mono.from(template.execute(client -> client.ping())) // + Mono.from(template.execute(ReactiveElasticsearchClient::ping)) // .as(StepVerifier::create) // .expectNext(true) // .verifyComplete(); @@ -456,10 +457,7 @@ public void shouldReturnProjectedTargetEntity() { @Test // DATAES-518 public void searchShouldApplyPagingCorrectly() { - List source = IntStream.range(0, 100).mapToObj(it -> randomEntity("entity - " + it)) - .collect(Collectors.toList()); - - index(source.toArray(new SampleEntity[0])); + index(IntStream.range(0, 100).mapToObj(it -> randomEntity("entity - " + it)).toArray(SampleEntity[]::new)); CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("entity")) // .addSort(Sort.by("message"))// @@ -473,10 +471,7 @@ public void searchShouldApplyPagingCorrectly() { @Test // DATAES-518 public void findWithoutPagingShouldReadAll() { - List source = IntStream.range(0, 100).mapToObj(it -> randomEntity("entity - " + it)) - .collect(Collectors.toList()); - - index(source.toArray(new SampleEntity[0])); + index(IntStream.range(0, 100).mapToObj(it -> randomEntity("entity - " + it)).toArray(SampleEntity[]::new)); CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("entity")) // .addSort(Sort.by("message"))// @@ -717,7 +712,7 @@ void shouldReturnSortFields() { } @Data - @Document(indexName = "marvel", type = "characters") + @Document(indexName = "marvel") static class Person { private @Id String id; @@ -780,7 +775,7 @@ static class Message { @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(exclude = "score") - @Document(indexName = DEFAULT_INDEX, type = "test-type", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = DEFAULT_INDEX, replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index ce95568c9..dd917e301 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -258,7 +258,7 @@ public void deleteByShouldApplyIndicesOptionsIfSet() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-core-reactive-template-Unit", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-core-reactive-template-Unit", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index a8db95146..71c8cf285 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -27,7 +27,6 @@ import java.util.ArrayList; import java.util.List; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.search.aggregations.Aggregations; import org.junit.jupiter.api.AfterEach; @@ -42,9 +41,9 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.ResultsExtractor; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -78,11 +77,12 @@ static class Config {} static final String INDEX_NAME = "test-index-articles-core-aggregation"; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - - IndexInitializer.init(operations, ArticleEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, ArticleEntity.class); IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").subject("computing") .addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10) @@ -107,8 +107,7 @@ public void before() { @AfterEach public void after() { - - operations.deleteIndex(ArticleEntity.class); + indexOperations.deleteIndex(ArticleEntity.class); } @Test @@ -136,7 +135,7 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { * @author Mohsin Husen */ @Data - @Document(indexName = "test-index-articles-core-aggregation", type = "article", shards = 1, replicas = 0, + @Document(indexName = "test-index-articles-core-aggregation", replicas = 0, refreshInterval = "-1") static class ArticleEntity { @@ -154,10 +153,6 @@ static class ArticleEntity { private int score; - private ArticleEntity() { - - } - public ArticleEntity(String id) { this.id = id; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index acb204390..3f4296f85 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -26,6 +26,7 @@ import org.elasticsearch.search.suggest.SuggestBuilders; import org.elasticsearch.search.suggest.SuggestionBuilder; import org.elasticsearch.search.suggest.completion.CompletionSuggestion; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -72,6 +73,12 @@ private void setup() { IndexInitializer.init(indexOperations, AnnotatedCompletionEntity.class); } + @AfterEach + void after() { + indexOperations.deleteIndex("test-index-annotated-completion"); + indexOperations.deleteIndex("test-index-core-completion"); + } + private void loadCompletionObjectEntities() { List indexQueries = new ArrayList<>(); @@ -237,7 +244,7 @@ public void setSomeField2(String someField2) { /** * @author Mewes Kochheim */ - @Document(indexName = "test-index-core-completion", type = "completion-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-core-completion", replicas = 0, refreshInterval = "-1") static class CompletionEntity { @@ -321,7 +328,7 @@ public IndexQuery buildIndex() { /** * @author Mewes Kochheim */ - @Document(indexName = "test-index-annotated-completion", type = "annotated-completion-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-annotated-completion", replicas = 0, refreshInterval = "-1") static class AnnotatedCompletionEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index 71864d076..470962714 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -33,6 +33,7 @@ import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.elasticsearch.search.suggest.completion.context.CategoryQueryContext; import org.elasticsearch.search.suggest.completion.context.ContextMapping; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -71,7 +72,11 @@ static class Config {} @BeforeEach void setup() { indexOperations = operations.getIndexOperations(); + indexOperations.deleteIndex(ContextCompletionEntity.class); + } + @AfterEach + void after() { indexOperations.deleteIndex(ContextCompletionEntity.class); } @@ -238,7 +243,7 @@ public void setSomeField2(String someField2) { * @author Mewes Kochheim * @author Robert Gruendler */ - @Document(indexName = "test-index-context-completion", type = "context-completion-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-context-completion", replicas = 0, refreshInterval = "-1") static class ContextCompletionEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 009618c8d..2c92e4963 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -56,8 +56,6 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; -import org.springframework.data.elasticsearch.core.query.Criteria; -import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; @@ -201,9 +199,7 @@ public void init() { public void shouldFailToInitializeGivenMappingContextIsNull() { // given - assertThatThrownBy(() -> { - new MappingElasticsearchConverter(null); - }).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> new MappingElasticsearchConverter(null)).isInstanceOf(IllegalArgumentException.class); } @Test @@ -233,7 +229,7 @@ public void shouldReturnDefaultConversionService() { } @Test // DATAES-530 - public void shouldMapObjectToJsonString() throws IOException { + public void shouldMapObjectToJsonString() { // Given // When @@ -245,7 +241,7 @@ public void shouldMapObjectToJsonString() throws IOException { } @Test // DATAES-530 - public void shouldMapJsonStringToObject() throws IOException { + public void shouldMapJsonStringToObject() { // Given // When @@ -258,7 +254,7 @@ public void shouldMapJsonStringToObject() throws IOException { } @Test // DATAES-530 - public void shouldMapGeoPointElasticsearchNames() throws IOException { + public void shouldMapGeoPointElasticsearchNames() { // given Point point = new Point(10, 20); String pointAsString = point.getX() + "," + point.getY(); @@ -277,7 +273,7 @@ public void shouldMapGeoPointElasticsearchNames() throws IOException { } @Test // DATAES-530 - public void ignoresReadOnlyProperties() throws IOException { + public void ignoresReadOnlyProperties() { // given Sample sample = new Sample(); @@ -311,7 +307,7 @@ public void writesNestedEntity() { } @Test // DATAES-530 - public void writesConcreteList() throws IOException { + public void writesConcreteList() { Person ginger = new Person(); ginger.id = "ginger"; @@ -324,7 +320,7 @@ public void writesConcreteList() throws IOException { } @Test // DATAES-530 - public void writesInterfaceList() throws IOException { + public void writesInterfaceList() { Inventory gun = new Gun("Glock 19", 33); Inventory grenade = new Grenade("40 mm"); @@ -346,7 +342,7 @@ public void readTypeCorrectly() { @Test // DATAES-530 public void readListOfConcreteTypesCorrectly() { - sarahAsMap.put("coWorkers", Arrays.asList(kyleAsMap)); + sarahAsMap.put("coWorkers", Collections.singletonList(kyleAsMap)); Person target = mappingElasticsearchConverter.read(Person.class, sarahAsMap); @@ -447,7 +443,7 @@ public void genericWriteListWithList() { public void readGenericListList() { Document source = Document.create(); - source.put("objectList", Arrays.asList(Arrays.asList(t800AsMap, gunAsMap))); + source.put("objectList", Collections.singletonList(Arrays.asList(t800AsMap, gunAsMap))); Skynet target = mappingElasticsearchConverter.read(Skynet.class, source); @@ -738,6 +734,7 @@ static class Address { String city; } + @EqualsAndHashCode(callSuper = true) @Data static class Place extends Address { @@ -789,7 +786,7 @@ static class Car { @AllArgsConstructor @Builder @org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-geo-core-entity-mapper", - type = "geo-test-index", shards = 1, replicas = 0, refreshInterval = "-1") + type = "geo-test-index", replicas = 0, refreshInterval = "-1") static class GeoEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index 3469d2d14..adeefe32e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -29,6 +29,7 @@ import org.elasticsearch.geometry.utils.Geohash; import org.elasticsearch.index.query.QueryBuilders; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -89,6 +90,12 @@ public void before() { IndexInitializer.init(indexOperations, LocationMarkerEntity.class); } + @AfterEach + void after() { + indexOperations.deleteIndex(AuthorMarkerEntity.class); + indexOperations.deleteIndex(LocationMarkerEntity.class); + } + private void loadClassBaseEntities() { List indexQueries = new ArrayList<>(); @@ -368,7 +375,7 @@ private IndexQuery buildIndex(LocationMarkerEntity result) { * @author Mohsin Husen */ @Data - @Document(indexName = "test-index-author-marker-core-geo", type = "geo-class-point-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-author-marker-core-geo", replicas = 0, refreshInterval = "-1") static class AuthorMarkerEntity { @@ -427,7 +434,7 @@ public IndexQuery buildIndex() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-location-marker-core-geo", type = "geo-annotation-point-type", shards = 1, + @Document(indexName = "test-index-location-marker-core-geo", replicas = 0, refreshInterval = "-1") static class LocationMarkerEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 508a64f81..921c8cbe1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -111,10 +111,10 @@ public void shouldNotFailOnCircularReference() { } @Test // DATAES-568 - public void testInfiniteLoopAvoidance() throws IOException, JSONException { + public void testInfiniteLoopAvoidance() throws JSONException { - String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" - + "type\":\"text\",\"index\":false," + "\"analyzer\":\"standard\"}}}}"; + String expected = "{\"properties\":{\"message\":{\"store\":true,\"" + + "type\":\"text\",\"index\":false," + "\"analyzer\":\"standard\"}}}"; String mapping = getMappingBuilder().buildPropertyMapping(SampleTransientEntity.class); @@ -122,10 +122,10 @@ public void testInfiniteLoopAvoidance() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseValueFromAnnotationType() throws IOException, JSONException { + public void shouldUseValueFromAnnotationType() throws JSONException { // Given - String expected = "{\"price\":{\"properties\":{\"price\":{\"type\":\"double\"}}}}"; + String expected = "{\"properties\":{\"price\":{\"type\":\"double\"}}}"; // When String mapping = getMappingBuilder().buildPropertyMapping(StockPrice.class); @@ -165,9 +165,9 @@ public void shouldAddStockPriceDocumentToIndex() { } @Test // DATAES-568 - public void shouldCreateMappingForSpecifiedParentType() throws IOException, JSONException { + public void shouldCreateMappingForSpecifiedParentType() throws JSONException { - String expected = "{\"mapping\":{\"_parent\":{\"type\":\"parentType\"},\"properties\":{}}}"; + String expected = "{\"_parent\":{\"type\":\"parentType\"},\"properties\":{}}"; String mapping = getMappingBuilder().buildPropertyMapping(MinimalChildEntity.class); @@ -175,11 +175,11 @@ public void shouldCreateMappingForSpecifiedParentType() throws IOException, JSON } @Test // DATAES-76 - public void shouldBuildMappingWithSuperclass() throws IOException, JSONException { + public void shouldBuildMappingWithSuperclass() throws JSONException { - String expected = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true,\"" + String expected = "{\"properties\":{\"message\":{\"store\":true,\"" + "type\":\"text\",\"index\":false,\"analyzer\":\"standard\"}" + ",\"createdDate\":{" - + "\"type\":\"date\",\"index\":false}}}}"; + + "\"type\":\"date\",\"index\":false}}}"; String mapping = getMappingBuilder().buildPropertyMapping(SampleInheritedEntity.class); @@ -214,12 +214,12 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() { } @Test // DATAES-568 - public void shouldBuildMappingsForGeoPoint() throws IOException, JSONException { + public void shouldBuildMappingsForGeoPoint() throws JSONException { // given - String expected = "{\"geo-test-index\": {\"properties\": {" + "\"pointA\":{\"type\":\"geo_point\"}," + String expected = "{\"properties\": {" + "\"pointA\":{\"type\":\"geo_point\"}," + "\"pointB\":{\"type\":\"geo_point\"}," + "\"pointC\":{\"type\":\"geo_point\"}," - + "\"pointD\":{\"type\":\"geo_point\"}" + "}}}"; + + "\"pointD\":{\"type\":\"geo_point\"}" + "}}"; // when String mapping; @@ -300,8 +300,8 @@ public void shouldUseKeywordNormalizer() { public void shouldUseCopyTo() { // given - operations.createIndex(CopyToEntity.class); - operations.putMapping(CopyToEntity.class); + indexOperations.createIndex(CopyToEntity.class); + indexOperations.putMapping(CopyToEntity.class); // when Map mapping = operations.getMapping(CopyToEntity.class); @@ -316,11 +316,11 @@ public void shouldUseCopyTo() { } @Test // DATAES-568 - public void shouldUseFieldNameOnId() throws IOException, JSONException { + public void shouldUseFieldNameOnId() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" - + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" + + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.IdEntity.class); @@ -330,11 +330,11 @@ public void shouldUseFieldNameOnId() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseFieldNameOnText() throws IOException, JSONException { + public void shouldUseFieldNameOnText() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"text-property\":{\"type\":\"text\"}" + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"text-property\":{\"type\":\"text\"}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.TextEntity.class); @@ -344,11 +344,11 @@ public void shouldUseFieldNameOnText() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseFieldNameOnMapping() throws IOException, JSONException { + public void shouldUseFieldNameOnMapping() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"mapping-property\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}" + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"mapping-property\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MappingEntity.class); @@ -358,11 +358,11 @@ public void shouldUseFieldNameOnMapping() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseFieldNameOnGeoPoint() throws IOException, JSONException { + public void shouldUseFieldNameOnGeoPoint() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"geopoint-property\":{\"type\":\"geo_point\"}" + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"geopoint-property\":{\"type\":\"geo_point\"}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.GeoPointEntity.class); @@ -372,11 +372,11 @@ public void shouldUseFieldNameOnGeoPoint() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseFieldNameOnCircularEntity() throws IOException, JSONException { + public void shouldUseFieldNameOnCircularEntity() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{}}}" + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{}}}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CircularEntity.class); @@ -386,12 +386,12 @@ public void shouldUseFieldNameOnCircularEntity() throws IOException, JSONExcepti } @Test // DATAES-568 - public void shouldUseFieldNameOnCompletion() throws IOException, JSONException { + public void shouldUseFieldNameOnCompletion() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + "\"completion-property\":{\"type\":\"completion\",\"max_input_length\":100,\"preserve_position_increments\":true,\"preserve_separators\":true,\"search_analyzer\":\"simple\",\"analyzer\":\"simple\"},\"completion-property\":{}" - + "}}}"; + + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CompletionEntity.class); @@ -401,12 +401,11 @@ public void shouldUseFieldNameOnCompletion() throws IOException, JSONException { } @Test // DATAES-568 - public void shouldUseFieldNameOnMultiField() throws IOException, JSONException { + public void shouldUseFieldNameOnMultiField() throws JSONException { // given - String expected = "{\"fieldname-type\":{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"multifield-property\":{\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}" - + "}}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," + + "\"multifield-property\":{\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MultiFieldEntity.class); @@ -416,10 +415,10 @@ public void shouldUseFieldNameOnMultiField() throws IOException, JSONException { } @Test // DATAES-639 - public void shouldUseIgnoreAbove() throws IOException, JSONException { + public void shouldUseIgnoreAbove() throws JSONException { // given - String expected = "{\"ignore-above-type\":{\"properties\":{\"message\":{\"type\":\"keyword\",\"ignore_above\":10}}}}"; + String expected = "{\"properties\":{\"message\":{\"type\":\"keyword\",\"ignore_above\":10}}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(IgnoreAboveEntity.class); @@ -429,9 +428,8 @@ public void shouldUseIgnoreAbove() throws IOException, JSONException { } @Test - public void shouldSetFieldMappingProperties() throws JSONException, IOException { + public void shouldSetFieldMappingProperties() throws JSONException { String expected = "{\n" + // - " \"fmp\": {\n" + // " \"properties\": {\n" + // " \"storeTrue\": {\n" + // " \"store\": true\n" + // @@ -516,7 +514,6 @@ public void shouldSetFieldMappingProperties() throws JSONException, IOException " \"scaling_factor\": 100.0\n" + // " }\n" + // " }\n" + // - " }\n" + // "}\n"; // // when @@ -527,10 +524,9 @@ public void shouldSetFieldMappingProperties() throws JSONException, IOException } @Test - void shouldWriteDynamicMappingSettings() throws IOException, JSONException { + void shouldWriteDynamicMappingSettings() throws JSONException { String expected = "{\n" + // - " \"dms\": {\n" + // " \"dynamic\": \"false\",\n" + // " \"properties\": {\n" + // " \"author\": {\n" + // @@ -539,7 +535,6 @@ void shouldWriteDynamicMappingSettings() throws IOException, JSONException { " \"properties\": {}\n" + // " }\n" + // " }\n" + // - " }\n" + // "}\n"; String mapping = getMappingBuilder().buildPropertyMapping(ConfigureDynamicMappingEntity.class); @@ -555,7 +550,7 @@ void shouldWriteDynamicMappingSettings() throws IOException, JSONException { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "ignore-above-index", type = "ignore-above-type") + @Document(indexName = "ignore-above-index") static class IgnoreAboveEntity { @Id private String id; @@ -569,12 +564,12 @@ static class IgnoreAboveEntity { @SuppressWarnings("unused") static class FieldNameEntity { - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class IdEntity { @Id @Field("id-property") private String id; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class TextEntity { @Id @Field("id-property") private String id; @@ -583,7 +578,7 @@ static class TextEntity { private String textProperty; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class MappingEntity { @Id @Field("id-property") private String id; @@ -592,7 +587,7 @@ static class MappingEntity { private byte[] mappingProperty; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class GeoPointEntity { @Id @Field("id-property") private String id; @@ -600,7 +595,7 @@ static class GeoPointEntity { @Field("geopoint-property") private GeoPoint geoPoint; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class CircularEntity { @Id @Field("id-property") private String id; @@ -609,7 +604,7 @@ static class CircularEntity { private CircularEntity circularProperty; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class CompletionEntity { @Id @Field("id-property") private String id; @@ -618,7 +613,7 @@ static class CompletionEntity { private Completion suggest; } - @Document(indexName = "fieldname-index", type = "fieldname-type") + @Document(indexName = "fieldname-index") static class MultiFieldEntity { @Id @Field("id-property") private String id; @@ -635,7 +630,7 @@ static class MultiFieldEntity { * * @author Peter-Josef Meisch */ - @Document(indexName = "test-index-minimal", type = "mapping") + @Document(indexName = "test-index-minimal") static class MinimalChildEntity { @Id private String id; @@ -653,7 +648,7 @@ static class MinimalChildEntity { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-mapping-builder", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-mapping-builder", replicas = 0, refreshInterval = "-1") static class Book { @@ -670,7 +665,7 @@ static class Book { * @author Stuart Stevenson * @author Mohsin Husen */ - @Document(indexName = "test-index-simple-recursive-mapping-builder", type = "circular-object", shards = 1, + @Document(indexName = "test-index-simple-recursive-mapping-builder", replicas = 0, refreshInterval = "-1") static class SimpleRecursiveEntity { @@ -686,7 +681,7 @@ static class SimpleRecursiveEntity { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-copy-to-mapping-builder", type = "test", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-copy-to-mapping-builder", replicas = 0, refreshInterval = "-1") static class CopyToEntity { @Id private String id; @@ -706,7 +701,7 @@ static class CopyToEntity { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-normalizer-mapping-builder", type = "test", shards = 1, replicas = 0, + @Document(indexName = "test-index-normalizer-mapping-builder", replicas = 0, refreshInterval = "-1") @Setting(settingPath = "/settings/test-normalizer.json") static class NormalizerEntity { @@ -748,7 +743,7 @@ public void setName(String name) { /** * @author Kevin Leturc */ - @Document(indexName = "test-index-sample-inherited-mapping-builder", type = "mapping", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-inherited-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleInheritedEntity extends AbstractInheritedEntity { @@ -806,7 +801,7 @@ public IndexQuery buildIndex() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-stock-mapping-builder", type = "price", shards = 1, replicas = 0, + @Document(indexName = "test-index-stock-mapping-builder", replicas = 0, refreshInterval = "-1") static class StockPrice { @@ -846,7 +841,7 @@ public void setCreatedDate(Date createdDate) { /** * @author Jakub Vavrik */ - @Document(indexName = "test-index-recursive-mapping-mapping-builder", type = "mapping", shards = 1, replicas = 0, + @Document(indexName = "test-index-recursive-mapping-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleTransientEntity { @@ -882,7 +877,7 @@ public SampleTransientEntity.NestedEntity getSomeField() { } public void setSomeField(SampleTransientEntity.NestedEntity someField) { - this.someField = someField; + NestedEntity.someField = someField; } public Boolean getSomething() { @@ -903,7 +898,7 @@ public void setSomething(Boolean something) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-geo-mapping-builder", type = "geo-test-index", shards = 1, replicas = 0, + @Document(indexName = "test-index-geo-mapping-builder", replicas = 0, refreshInterval = "-1") static class GeoEntity { @@ -927,7 +922,7 @@ static class GeoEntity { /** * Created by akonczak on 21/08/2016. */ - @Document(indexName = "test-index-user-mapping-builder", type = "user") + @Document(indexName = "test-index-user-mapping-builder") static class User { @Id private String id; @@ -937,7 +932,7 @@ static class User { /** * Created by akonczak on 21/08/2016. */ - @Document(indexName = "test-index-group-mapping-builder", type = "group") + @Document(indexName = "test-index-group-mapping-builder") static class Group { @Id String id; @@ -945,7 +940,7 @@ static class Group { @Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set users = new HashSet<>(); } - @Document(indexName = "test-index-field-mapping-parameters", type = "fmp") + @Document(indexName = "test-index-field-mapping-parameters") static class FieldMappingParameters { @Field private String indexTrue; @Field(index = false) private String indexFalse; @@ -960,14 +955,14 @@ static class FieldMappingParameters { @Field(type = FieldType.Integer) private String type; @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private LocalDate date; @Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers; - @Field(type = Keyword, docValues = true) private String docValuesTrue; + @Field(type = Keyword) private String docValuesTrue; @Field(type = Keyword, docValues = false) private String docValuesFalse; @Field(ignoreMalformed = true) private String ignoreMalformedTrue; - @Field(ignoreMalformed = false) private String ignoreMalformedFalse; + @Field() private String ignoreMalformedFalse; @Field(indexOptions = IndexOptions.none) private String indexOptionsNone; @Field(indexOptions = IndexOptions.positions) private String indexOptionsPositions; @Field(indexPhrases = true) private String indexPhrasesTrue; - @Field(indexPhrases = false) private String indexPhrasesFalse; + @Field() private String indexPhrasesFalse; @Field(indexPrefixes = @IndexPrefixes) private String defaultIndexPrefixes; @Field(indexPrefixes = @IndexPrefixes(minChars = 1, maxChars = 10)) private String customIndexPrefixes; @Field private String normsTrue; @@ -982,7 +977,7 @@ static class FieldMappingParameters { @Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat; } - @Document(indexName = "test-index-configure-dynamic-mapping", type = "dms") + @Document(indexName = "test-index-configure-dynamic-mapping") @DynamicMapping(DynamicMappingValue.False) static class ConfigureDynamicMappingEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java index ad8d1750c..0d56d60e6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java @@ -42,28 +42,28 @@ public class SimpleDynamicTemplatesMappingTests extends MappingContextBaseTests { @Test // DATAES-568 - public void testCorrectDynamicTemplatesMappings() throws IOException { + public void testCorrectDynamicTemplatesMappings() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntity.class); - String EXPECTED_MAPPING_ONE = "{\"test-dynamictemplatestype\":{\"dynamic_templates\":" + String EXPECTED_MAPPING_ONE = "{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," - + "\"path_match\":\"names.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}}"; + + "\"path_match\":\"names.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}"; assertThat(mapping).isEqualTo(EXPECTED_MAPPING_ONE); } @Test // DATAES-568 - public void testCorrectDynamicTemplatesMappingsTwo() throws IOException { + public void testCorrectDynamicTemplatesMappingsTwo() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntityTwo.class); - String EXPECTED_MAPPING_TWO = "{\"test-dynamictemplatestype\":{\"dynamic_templates\":" + String EXPECTED_MAPPING_TWO = "{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"names.*\"}}," + "{\"participantA1_with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," - + "\"path_match\":\"participantA1.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}}"; + + "\"path_match\":\"participantA1.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}"; assertThat(mapping).isEqualTo(EXPECTED_MAPPING_TWO); } @@ -71,27 +71,27 @@ public void testCorrectDynamicTemplatesMappingsTwo() throws IOException { /** * @author Petr Kukral */ - @Document(indexName = "test-dynamictemplates", type = "test-dynamictemplatestype", indexStoreType = "memory", - shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", + replicas = 0, refreshInterval = "-1") @DynamicTemplates(mappingPath = "/mappings/test-dynamic_templates_mappings.json") static class SampleDynamicTemplatesEntity { @Id private String id; - @Field(type = FieldType.Object) private Map names = new HashMap(); + @Field(type = FieldType.Object) private Map names = new HashMap<>(); } /** * @author Petr Kukral */ - @Document(indexName = "test-dynamictemplates", type = "test-dynamictemplatestype", indexStoreType = "memory", - shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", + replicas = 0, refreshInterval = "-1") @DynamicTemplates(mappingPath = "/mappings/test-dynamic_templates_mappings_two.json") static class SampleDynamicTemplatesEntityTwo { @Id private String id; - @Field(type = FieldType.Object) private Map names = new HashMap(); + @Field(type = FieldType.Object) private Map names = new HashMap<>(); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java index da52ed63f..8e2f19611 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java @@ -38,13 +38,13 @@ */ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests { - private static final String EXPECTED_MAPPING = "{\"mapping\":{\"properties\":{\"message\":{\"store\":true," + private static final String EXPECTED_MAPPING = "{\"properties\":{\"message\":{\"store\":true," + "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.yyyy hh:mm\"}," + "\"defaultFormatDate\":{\"type\":\"date\"},\"basicFormatDate\":{\"" - + "type\":\"date\",\"format\":\"basic_date\"}}}}"; + + "type\":\"date\",\"format\":\"basic_date\"}}}"; @Test // DATAES-568 - public void testCorrectDateMappings() throws IOException { + public void testCorrectDateMappings() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDateMappingEntity.class); @@ -55,7 +55,7 @@ public void testCorrectDateMappings() throws IOException { * @author Jakub Vavrik */ @Data - @Document(indexName = "test-index-date-mapping-core", type = "mapping", shards = 1, replicas = 0, + @Document(indexName = "test-index-date-mapping-core", replicas = 0, refreshInterval = "-1") static class SampleDateMappingEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index b3d74fdce..735d9428d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -39,7 +39,7 @@ public class SimpleElasticsearchPersistentEntityTests { @Test - public void shouldThrowExceptionGivenVersionPropertyIsNotLong() throws NoSuchFieldException, IntrospectionException { + public void shouldThrowExceptionGivenVersionPropertyIsNotLong() { // given TypeInformation typeInformation = ClassTypeInformation.from(EntityWithWrongVersionType.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( @@ -51,8 +51,7 @@ public void shouldThrowExceptionGivenVersionPropertyIsNotLong() throws NoSuchFie } @Test - public void shouldThrowExceptionGivenMultipleVersionPropertiesArePresent() - throws NoSuchFieldException, IntrospectionException { + public void shouldThrowExceptionGivenMultipleVersionPropertiesArePresent() { // given TypeInformation typeInformation = ClassTypeInformation.from(EntityWithMultipleVersionField.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index bc206b2d1..04c737a87 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.List; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -41,6 +42,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -65,14 +67,21 @@ static class Config {} private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes("test-type"); @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { + indexOperations = operations.getIndexOperations(); - operations.deleteIndex(SampleEntity.class); - operations.createIndex(SampleEntity.class); - operations.putMapping(SampleEntity.class); - operations.refresh(SampleEntity.class); + indexOperations.deleteIndex(SampleEntity.class); + indexOperations.createIndex(SampleEntity.class); + indexOperations.putMapping(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(SampleEntity.class); } @Test @@ -89,7 +98,7 @@ public void shouldPerformAndOperation() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("test").and("message").contains("some")); @@ -132,7 +141,7 @@ public void shouldPerformOrOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").or("message").contains("test")); @@ -163,7 +172,7 @@ public void shouldPerformAndOperationWithinCriteria() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); // when @@ -194,7 +203,7 @@ public void shouldPerformOrOperationWithinCriteria() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when @@ -223,7 +232,7 @@ public void shouldPerformIsOperation() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when @@ -265,7 +274,7 @@ public void shouldPerformMultipleIsOperations() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when @@ -307,7 +316,7 @@ public void shouldPerformEndsWithOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").endsWith("end"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); @@ -349,7 +358,7 @@ public void shouldPerformStartsWithOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); Criteria criteria = new Criteria("message").startsWith("start"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); @@ -391,7 +400,7 @@ public void shouldPerformContainsOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); // when @@ -432,7 +441,7 @@ public void shouldExecuteExpression() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); // when @@ -473,7 +482,7 @@ public void shouldExecuteCriteriaChain() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); @@ -515,7 +524,7 @@ public void shouldPerformIsNotOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when @@ -559,7 +568,7 @@ public void shouldPerformBetweenOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); // when @@ -601,7 +610,7 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when @@ -644,7 +653,7 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when @@ -687,7 +696,7 @@ public void shouldPerformLessThanEqualOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when @@ -730,7 +739,7 @@ public void shouldPerformGreaterThanEquals() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when @@ -773,7 +782,7 @@ public void shouldPerformBoostOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when @@ -794,7 +803,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); operations.bulkIndex(indexQueries, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); // when CriteriaQuery criteriaQuery = new CriteriaQuery( @@ -821,7 +830,7 @@ public void shouldEscapeValue() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - operations.refresh(SampleEntity.class); + indexOperations.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); @@ -837,7 +846,7 @@ public void shouldEscapeValue() { @Getter @NoArgsConstructor @AllArgsConstructor - @Document(indexName = "test-index-sample-core-query", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-core-query", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java index 541a0191e..87cea98a4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java @@ -112,7 +112,7 @@ private ClusterConnectionInfo parseUrl(String clusterUrl) { } @Override - public void close() throws Exception { + public void close() { if (node != null) { LOGGER.debug("closing node"); diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java index 8e55e790a..aaf800ab1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java @@ -24,7 +24,6 @@ import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.RestClients; import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; -import org.springframework.util.Assert; /** * Configuration for Spring Data Elasticsearch using diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java index 7725648e3..17e3032bb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java @@ -21,7 +21,6 @@ import java.lang.annotation.Target; import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.test.context.junit.jupiter.SpringExtension; /** * Wraps the {@link SpringDataElasticsearchExtension}. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java index 4ca24daa7..4f5a17940 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java @@ -57,7 +57,7 @@ public class SpringDataElasticsearchExtension private static final Lock initLock = new ReentrantLock(); @Override - public void beforeAll(ExtensionContext extensionContext) throws Exception { + public void beforeAll(ExtensionContext extensionContext) { initLock.lock(); try { ExtensionContext.Store store = getStore(extensionContext); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java index 1bce2df2c..f4d36723c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java @@ -27,5 +27,6 @@ */ public interface CdiProductRepository extends CrudRepository { + @Override Optional findById(String id); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index 9031540c3..913ffc76e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -158,7 +158,7 @@ public void returnOneFromCustomImpl() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-product-cdi-repository", type = "test-product-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-product-cdi-repository", replicas = 0, refreshInterval = "-1") static class Product { @@ -188,7 +188,7 @@ static class Product { } @Data - @Document(indexName = "test-index-person-cdi-repository", type = "user", shards = 1, replicas = 0, + @Document(indexName = "test-index-person-cdi-repository", replicas = 0, refreshInterval = "-1") static class Person { @@ -206,7 +206,7 @@ static class Person { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-cdi-repository", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-cdi-repository", replicas = 0, refreshInterval = "-1") static class Book { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java index 02b2ef124..28062174b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java @@ -25,7 +25,7 @@ /** * @author Mark Paluch - * @see DATAES-234 + * @see DATAES-234 */ @Qualifier @Retention(RetentionPolicy.RUNTIME) diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java index 8881fe662..74a7ef51e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java @@ -25,7 +25,7 @@ /** * @author Mark Paluch - * @see DATAES-234 + * @see DATAES-234 */ @Qualifier @Retention(RetentionPolicy.RUNTIME) diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java index 8f29926cc..ec3124fdb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java @@ -19,7 +19,7 @@ /** * @author Mark Paluch - * @see DATAES-234 + * @see DATAES-234 */ @PersonDB @OtherQualifier diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java index 1cb8cc98e..f82bd24b0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java @@ -19,7 +19,7 @@ /** * @author Mark Paluch - * @see DATAES-113 + * @see DATAES-113 */ public interface SamplePersonRepository extends Repository, SamplePersonRepositoryCustom { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java index e53e940e2..1d44c249e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java @@ -17,8 +17,8 @@ package org.springframework.data.elasticsearch.repositories.cdi; /** - * @see DATAES-113 * @author Mark Paluch + * @see DATAES-113 */ interface SamplePersonRepositoryCustom { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java index 953263c27..d7219d5af 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java @@ -17,8 +17,8 @@ package org.springframework.data.elasticsearch.repositories.cdi; /** - * @see DATAES-113 * @author Mark Paluch + * @see DATAES-113 */ class SamplePersonRepositoryImpl implements SamplePersonRepositoryCustom { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index 05ed308fd..268ec79c0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -20,6 +20,7 @@ import lombok.Data; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +30,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -52,10 +54,17 @@ static class Config {} @Autowired private ComplexElasticsearchRepository complexRepository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, SampleEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SampleEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(SampleEntity.class); } @Test @@ -71,8 +80,8 @@ public void shouldExecuteComplexCustomMethod() { } @Data - @Document(indexName = "test-index-sample-repositories-complex-custommethod-autowiring", type = "test-type", - shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-sample-repositories-complex-custommethod-autowiring", + replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java index ce9e0fafd..9e1f4e93d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java @@ -21,5 +21,5 @@ */ public interface ComplexElasticsearchRepositoryCustom { - public String doSomethingSpecial(); + String doSomethingSpecial(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java index ed1f3172b..aa61d0e14 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java @@ -20,6 +20,7 @@ import lombok.Data; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -29,6 +30,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -51,10 +53,17 @@ static class Config {} @Autowired private ComplexElasticsearchRepositoryManualWiring complexRepository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, SampleEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SampleEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(SampleEntity.class); } @Test @@ -70,7 +79,7 @@ public void shouldExecuteComplexCustomMethod() { } @Data - @Document(indexName = "test-index-sample-repository-manual-wiring", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-repository-manual-wiring", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index da38a6e57..a7c0ebd12 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -32,6 +32,8 @@ import java.util.UUID; import java.util.stream.Stream; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.annotation.Id; @@ -44,10 +46,13 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Query; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.data.geo.Box; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Metrics; @@ -70,6 +75,20 @@ public abstract class CustomMethodRepositoryBaseTests { @Autowired private SampleStreamingCustomMethodRepository streamingRepository; + @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; + + @BeforeEach + public void before() { + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SampleEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(SampleEntity.class); + } + @Test public void shouldExecuteCustomMethod() { @@ -1367,7 +1386,7 @@ private List createSampleEntities(String type, int numberOfEntitie @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-repositories-custo-method", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-repositories-custo-method", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java index 2089a5f6b..84f1fd07e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java @@ -15,14 +15,10 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import org.junit.jupiter.api.BeforeEach; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; -import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; /** @@ -39,11 +35,4 @@ public class CustomMethodRepositoryRestTests extends CustomMethodRepositoryBaseT basePackages = { "org.springframework.data.elasticsearch.repositories.custommethod" }, considerNestedRepositories = true) static class Config {} - - @Autowired private ElasticsearchRestTemplate elasticsearchTemplate; - - @BeforeEach - public void before() { - IndexInitializer.init(elasticsearchTemplate, SampleEntity.class); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java index 4d91b80f1..7a0541b8b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java @@ -15,14 +15,10 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import org.junit.jupiter.api.BeforeEach; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; -import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; /** @@ -40,10 +36,4 @@ public class CustomMethodRepositoryTests extends CustomMethodRepositoryBaseTests considerNestedRepositories = true) static class Config {} - @Autowired private ElasticsearchOperations operations; - - @BeforeEach - public void before() { - IndexInitializer.init(operations, SampleEntity.class); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index fd55e5a71..620180dd1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -31,6 +31,7 @@ import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -57,16 +58,17 @@ static class Config {} @Autowired private DoubleIDRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, DoubleIDEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, DoubleIDEntity.class); } @AfterEach public void after() { - - operations.deleteIndex(DoubleIDEntity.class); + indexOperations.deleteIndex(DoubleIDEntity.class); } @Test @@ -119,7 +121,7 @@ public void shouldSaveDocument() { * @author Mohsin Husen */ - @Document(indexName = "test-index-double-keyed-entity", type = "double-keyed-entity", shards = 1, replicas = 0, + @Document(indexName = "test-index-double-keyed-entity", replicas = 0, refreshInterval = "-1") static class DoubleIDEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 09e080041..75b1cf813 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -73,7 +73,7 @@ public void init() { } @AfterEach - public void teardown() { + public void after() { deleteIndexes(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index a2de6313e..47ba36cc8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -26,6 +26,7 @@ import java.util.Locale; import java.util.Optional; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -35,6 +36,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -62,12 +64,20 @@ public class SpringDataGeoRepositoryTests { static class Config {} @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired SpringDataGeoRepository repository; @BeforeEach public void init() { - IndexInitializer.init(operations, GeoEntity.class); + + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, GeoEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(GeoEntity.class); } @Test @@ -111,7 +121,7 @@ private double[] toGeoArray(Point point) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-geo-repository", type = "geo-test-index", shards = 1, replicas = 0, + @Document(indexName = "test-index-geo-repository", replicas = 0, refreshInterval = "-1") static class GeoEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index 680e4d374..da84a2ea6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -21,6 +21,7 @@ import java.util.Optional; import org.apache.commons.lang.math.RandomUtils; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,7 @@ import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -56,10 +58,17 @@ static class Config {} @Autowired private IntegerIDRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, IntegerIDEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, IntegerIDEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(IntegerIDEntity.class); } @Test @@ -112,7 +121,7 @@ public void shouldSaveDocument() { * @author Mohsin Husen */ - @Document(indexName = "test-index-integer-keyed-entity", type = "integer-keyed-entity", shards = 1, replicas = 0, + @Document(indexName = "test-index-integer-keyed-entity", replicas = 0, refreshInterval = "-1") static class IntegerIDEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index 4079afc3a..a51f1ad7c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.Map; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -41,6 +42,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -65,10 +67,17 @@ static class Config {} @Autowired private SampleElasticSearchBookRepository bookRepository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, Book.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, Book.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(Book.class); } @Test @@ -101,7 +110,7 @@ public void shouldIndexInnerObject() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book", type = "book", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-book", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 1b9d9e26b..ab972d8a0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -21,6 +21,7 @@ import org.apache.commons.lang.RandomStringUtils; import org.elasticsearch.index.query.QueryBuilders; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -31,6 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -59,12 +61,19 @@ public class DynamicSettingAndMappingEntityRepositoryTests { static class Config {} @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired private DynamicSettingAndMappingEntityRepository repository; @BeforeEach public void before() { - IndexInitializer.init(operations, DynamicSettingAndMappingEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, DynamicSettingAndMappingEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(DynamicSettingAndMappingEntity.class); } @Test // DATAES-64 @@ -74,8 +83,8 @@ public void shouldCreateGivenDynamicSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - assertThat(operations.indexExists(DynamicSettingAndMappingEntity.class)).isTrue(); - Map map = operations.getSetting(DynamicSettingAndMappingEntity.class); + assertThat(indexOperations.indexExists(DynamicSettingAndMappingEntity.class)).isTrue(); + Map map = indexOperations.getSettings(DynamicSettingAndMappingEntity.class); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); @@ -126,7 +135,7 @@ public void shouldGetMappingForGivenIndexAndType() { // delete , create and apply mapping in before method // when - Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); // then Map properties = (Map) mapping.get("properties"); @@ -141,23 +150,21 @@ public void shouldGetMappingForGivenIndexAndType() { public void shouldCreateMappingWithSpecifiedMappings() { // given - operations.deleteIndex(DynamicSettingAndMappingEntity.class); - operations.createIndex(DynamicSettingAndMappingEntity.class); - operations.refresh(DynamicSettingAndMappingEntity.class); + indexOperations.deleteIndex(DynamicSettingAndMappingEntity.class); + indexOperations.createIndex(DynamicSettingAndMappingEntity.class); + indexOperations.refresh(DynamicSettingAndMappingEntity.class); // when String mappings = "{\n" + // - " \"test-setting-type\" : {\n" + // " \"properties\" : {\n" + // " \"email\" : {\"type\" : \"text\", \"analyzer\" : \"emailAnalyzer\" }\n" + // " }\n" + // - " }\n" + // - "}"; - operations.putMapping(DynamicSettingAndMappingEntity.class, mappings); - operations.refresh(DynamicSettingAndMappingEntity.class); + '}'; + indexOperations.putMapping(DynamicSettingAndMappingEntity.class, mappings); + indexOperations.refresh(DynamicSettingAndMappingEntity.class); // then - Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); @@ -172,7 +179,7 @@ public void shouldCreateMappingWithUsingMappingAnnotation() { // given // then - Map mapping = operations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); @@ -184,7 +191,7 @@ public void shouldCreateMappingWithUsingMappingAnnotation() { /** * @author Mohsin Husen */ - @Document(indexName = "test-index-dynamic-setting-and-mapping", type = "test-setting-type") + @Document(indexName = "test-index-dynamic-setting-and-mapping") @Setting(settingPath = "/settings/test-settings.json") @Mapping(mappingPath = "/mappings/test-mappings.json") static class DynamicSettingAndMappingEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index 3ac5c7145..aee8fe076 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -19,6 +19,7 @@ import java.util.Map; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -28,6 +29,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; @@ -54,9 +56,16 @@ static class Config {} @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, FieldDynamicMappingEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, FieldDynamicMappingEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex(FieldDynamicMappingEntity.class); } @Test // DATAES-209 @@ -92,7 +101,7 @@ public void shouldCreateMappingWithMappingAnnotationAtFieldLevel() { /** * @author Ted Liang */ - @Document(indexName = "test-index-field-dynamic-mapping", type = "test-field-mapping-type") + @Document(indexName = "test-index-field-dynamic-mapping") static class FieldDynamicMappingEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 1eef7734f..bb304f0ac 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import org.elasticsearch.index.query.QueryBuilders; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +27,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -53,10 +55,17 @@ static class Config {} @Autowired private SpELRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, SpELEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SpELEntity.class); + } + + @AfterEach + void after() { + indexOperations.deleteIndex("test-index-abz-*"); } @Test @@ -94,7 +103,7 @@ public void shouldSupportSpelInType() { * * @author Artur Konczak */ - @Document(indexName = "#{'test-index-abz'+'-'+'entity'}", type = "#{'my'+'Type'}", shards = 1, replicas = 0, + @Document(indexName = "#{'test-index-abz'+'-'+'entity'}", replicas = 0, refreshInterval = "-1") static class SpELEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 54a2db4bf..cfd9d7cbe 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -20,6 +20,7 @@ import lombok.Data; import org.elasticsearch.index.query.QueryBuilders; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +31,7 @@ import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -58,12 +60,18 @@ static class Config {} @Autowired private SynonymRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(operations, SynonymEntity.class); + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SynonymEntity.class); } + @AfterEach + void after() { + indexOperations.deleteIndex(SynonymEntity.class); + } @Test public void shouldDo() { @@ -90,7 +98,7 @@ public void shouldDo() { * @author Mohsin Husen */ @Data - @Document(indexName = "test-index-synonym", type = "synonym-type") + @Document(indexName = "test-index-synonym") @Setting(settingPath = "/synonyms/settings.json") @Mapping(mappingPath = "/synonyms/mappings.json") static class SynonymEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 4ad24d3c6..1a9673c6f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -29,6 +29,7 @@ import java.util.Optional; import java.util.UUID; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -45,6 +46,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -76,11 +78,17 @@ static class Config {} @Autowired private SampleUUIDKeyedElasticsearchRepository repository; @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { + indexOperations = operations.getIndexOperations(); + IndexInitializer.init(indexOperations, SampleEntityUUIDKeyed.class); + } - IndexInitializer.init(operations, SampleEntityUUIDKeyed.class); + @AfterEach + void after() { + indexOperations.deleteIndex(SampleEntityUUIDKeyed.class); } @Test @@ -593,7 +601,7 @@ private static List createSampleEntitiesWithMessage(Strin @AllArgsConstructor @Builder @Data - @Document(indexName = "test-index-uuid-keyed", type = "test-type-uuid-keyed", shards = 1, replicas = 0, + @Document(indexName = "test-index-uuid-keyed", replicas = 0, refreshInterval = "-1") static class SampleEntityUUIDKeyed { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java index 674ab6055..84f554c87 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java @@ -72,7 +72,7 @@ interface ReactiveSampleEntityRepository extends ReactiveElasticsearchRepository @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-reactive-repositories-registrar", type = "test-type", shards = 1, + @Document(indexName = "test-index-sample-reactive-repositories-registrar", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java index b3fa4de59..aea0b777c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java @@ -100,7 +100,7 @@ static class Config { } - @Document(indexName = "star-wars", type = "character") + @Document(indexName = "star-wars") static class SwCharacter {} static class Store {} diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java index 99e20da5b..299e3ed53 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java @@ -90,7 +90,7 @@ public void shouldReplaceRepeatedParametersCorrectly() throws Exception { private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, String... args) throws NoSuchMethodException { - Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(size -> new Class[size]); + Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new); ElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes); ElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod); return elasticsearchStringQuery.createQuery(new ElasticsearchParametersParameterAccessor(queryMethod, args)); @@ -123,7 +123,7 @@ Person findWithRepeatedPlaceholder(String arg0, String arg1, String arg2, String * @author Artur Konczak */ - @Document(indexName = "test-index-person-query-unittest", type = "user", shards = 1, replicas = 0, + @Document(indexName = "test-index-person-query-unittest", replicas = 0, refreshInterval = "-1") static class Person { @@ -178,7 +178,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-query-unittest", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-query-unittest", replicas = 0, refreshInterval = "-1") static class Book { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java index f514f26dc..e57f9c6ba 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java @@ -71,7 +71,6 @@ public void detectsCollectionFromRepoTypeIfReturnTypeNotAssignable() throws Exce assertThat(metadata.getJavaType()).isAssignableFrom(Person.class); assertThat(metadata.getIndexName()).isEqualTo(INDEX_NAME); - assertThat(metadata.getIndexTypeName()).isEqualTo("user"); } @Test // DATAES-519 @@ -85,19 +84,19 @@ public void rejectsNullMappingContext() throws Exception { } @Test // DATAES-519 - public void rejectsMonoPageableResult() throws Exception { + public void rejectsMonoPageableResult() { assertThatThrownBy(() -> queryMethod(PersonRepository.class, "findMonoByName", String.class, Pageable.class)) .isInstanceOf(IllegalStateException.class); } @Test // DATAES-519 - public void throwsExceptionOnWrappedPage() throws Exception { + public void throwsExceptionOnWrappedPage() { assertThatThrownBy(() -> queryMethod(PersonRepository.class, "findMonoPageByName", String.class, Pageable.class)) .isInstanceOf(InvalidDataAccessApiUsageException.class); } @Test // DATAES-519 - public void throwsExceptionOnWrappedSlice() throws Exception { + public void throwsExceptionOnWrappedSlice() { assertThatThrownBy(() -> queryMethod(PersonRepository.class, "findMonoSliceByName", String.class, Pageable.class)) .isInstanceOf(InvalidDataAccessApiUsageException.class); } @@ -150,7 +149,7 @@ interface NonReactiveRepository extends Repository { * @author Artur Konczak */ - @Document(indexName = INDEX_NAME, type = "user", shards = 1, replicas = 0, refreshInterval = "-1") + @Document(indexName = INDEX_NAME, replicas = 0, refreshInterval = "-1") static class Person { @Id private String id; @@ -204,7 +203,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-reactive-repository-query", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-reactive-repository-query", replicas = 0, refreshInterval = "-1") static class Book { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java index c86ec0b4d..1d68dd1ba 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java @@ -126,7 +126,7 @@ public void shouldReplaceRepeatedParametersCorrectly() throws Exception { private org.springframework.data.elasticsearch.core.query.Query createQuery(String methodName, String... args) throws NoSuchMethodException { - Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(size -> new Class[size]); + Class[] argTypes = Arrays.stream(args).map(Object::getClass).toArray(Class[]::new); ReactiveElasticsearchQueryMethod queryMethod = getQueryMethod(methodName, argTypes); ReactiveElasticsearchStringQuery elasticsearchStringQuery = queryForMethod(queryMethod); @@ -175,7 +175,7 @@ Person findWithRepeatedPlaceholder(String arg0, String arg1, String arg2, String * @author Artur Konczak */ - @Document(indexName = "test-index-person-reactive-repository-string-query", type = "user", shards = 1, replicas = 0, + @Document(indexName = "test-index-person-reactive-repository-string-query", replicas = 0, refreshInterval = "-1") public class Person { @@ -230,7 +230,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-reactive-repository-string-query", type = "book", shards = 1, replicas = 0, + @Document(indexName = "test-index-book-reactive-repository-string-query", replicas = 0, refreshInterval = "-1") static class Book { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java index 3ec897f18..98613b757 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java @@ -41,6 +41,7 @@ class StubParameterAccessor implements ElasticsearchParameterAccessor { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#getPageable() */ + @Override public Pageable getPageable() { return null; } @@ -49,6 +50,7 @@ public Pageable getPageable() { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#getBindableValue(int) */ + @Override public Object getBindableValue(int index) { return values[index]; } @@ -57,6 +59,7 @@ public Object getBindableValue(int index) { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#hasBindableNullValue() */ + @Override public boolean hasBindableNullValue() { return false; } @@ -65,6 +68,7 @@ public boolean hasBindableNullValue() { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#getSort() */ + @Override public Sort getSort() { return Sort.unsorted(); } @@ -73,6 +77,7 @@ public Sort getSort() { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#iterator() */ + @Override public Iterator iterator() { return Arrays.asList(values).iterator(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index a5679e89f..2636a00ba 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.stream.Collectors; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -37,6 +38,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -64,12 +66,14 @@ static class Config {} @Autowired private ProductRepository repository; - @Autowired private ElasticsearchOperations elasticsearchTemplate; + @Autowired private ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { + indexOperations = operations.getIndexOperations(); - IndexInitializer.init(elasticsearchTemplate, Product.class); + IndexInitializer.init(indexOperations, Product.class); Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false) .sortName("sort5").build(); @@ -87,6 +91,11 @@ public void before() { repository.saveAll(Arrays.asList(product1, product2, product3, product4, product5, product6)); } + @AfterEach + void after() { + indexOperations.deleteIndex(Product.class); + } + @Test public void shouldSupportAND() { @@ -266,7 +275,7 @@ void shouldDeleteWithNullValues() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-product-query-keywords", type = "test-product-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-product-query-keywords", replicas = 0, refreshInterval = "-1") static class Product { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java index 689d63d4e..dcb8b9cfd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java @@ -45,16 +45,12 @@ public void before() { @Test public void shouldThrowMappingExceptionOnMissingEntity() { - assertThatThrownBy(() -> { - entityInfoCreator.getEntityInformation(String.class); - }).isInstanceOf(MappingException.class); + assertThatThrownBy(() -> entityInfoCreator.getEntityInformation(String.class)).isInstanceOf(MappingException.class); } @Test public void shouldThrowIllegalArgumentExceptionOnMissingIdAnnotation() { - assertThatThrownBy(() -> { - entityInfoCreator.getEntityInformation(EntityNoId.class); - }).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("No id property found"); + assertThatThrownBy(() -> entityInfoCreator.getEntityInformation(EntityNoId.class)).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("No id property found"); } @Document(indexName = "whatever") diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index f35c20444..8738e6c15 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -23,10 +23,12 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import org.junit.jupiter.api.AfterEach; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.io.IOException; import java.lang.Boolean; import java.lang.Long; import java.lang.Object; @@ -96,14 +98,17 @@ public void setUp() { TestUtils.deleteIndex(INDEX); } + @AfterEach + void after() { + TestUtils.deleteIndex(INDEX); + } + @Test // DATAES-519 public void saveShouldSaveSingleEntity() { repository.save(SampleEntity.builder().build()) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(TestUtils.documentWithId(it.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); - }) // + .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .verifyComplete(); } @@ -114,15 +119,9 @@ public void saveShouldComputeMultipleEntities() { .saveAll(Arrays.asList(SampleEntity.builder().build(), SampleEntity.builder().build(), SampleEntity.builder().build())) // .as(StepVerifier::create) // - .consumeNextWith(it -> { - assertThat(TestUtils.documentWithId(it.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); - }) // - .consumeNextWith(it -> { - assertThat(TestUtils.documentWithId(it.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); - }) // - .consumeNextWith(it -> { - assertThat(TestUtils.documentWithId(it.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); - }) // + .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // + .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // + .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .verifyComplete(); } @@ -132,21 +131,19 @@ public void findByIdShouldCompleteIfIndexDoesNotExist() { } @Test // DATAES-519 - public void findShouldRetrieveSingleEntityById() { + public void findShouldRetrieveSingleEntityById() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-three").build()); repository.findById("id-two").as(StepVerifier::create)// - .consumeNextWith(it -> { - assertThat(it.getId()).isEqualTo("id-two"); - }) // + .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-two")) // .verifyComplete(); } @Test // DATAES-519 - public void findByIdShouldCompleteIfNothingFound() { + public void findByIdShouldCompleteIfNothingFound() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // @@ -157,7 +154,7 @@ public void findByIdShouldCompleteIfNothingFound() { } @Test // DATAES-720 - public void findAllShouldReturnAllElements() { + public void findAllShouldReturnAllElements() throws IOException { // make sure to be above the default page size of the Query interface int count = DEFAULT_PAGE_SIZE * 2; bulkIndex(IntStream.range(1, count + 1) // @@ -176,7 +173,7 @@ public void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() { } @Test // DATAES-519 - public void findAllByIdShouldRetrieveMatchingDocuments() { + public void findAllByIdShouldRetrieveMatchingDocuments() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // @@ -189,7 +186,7 @@ public void findAllByIdShouldRetrieveMatchingDocuments() { } @Test // DATAES-519 - public void findAllByIdShouldCompleteWhenNothingFound() { + public void findAllByIdShouldCompleteWhenNothingFound() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // @@ -206,7 +203,7 @@ public void countShouldReturnZeroWhenIndexDoesNotExist() { } @Test // DATAES-519 - public void countShouldCountDocuments() { + public void countShouldCountDocuments() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build()); @@ -215,7 +212,7 @@ public void countShouldCountDocuments() { } @Test // DATAES-519 - public void existsByIdShouldReturnTrueIfExists() { + public void existsByIdShouldReturnTrueIfExists() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -228,7 +225,7 @@ public void existsByIdShouldReturnTrueIfExists() { } @Test // DATAES-519 - public void existsByIdShouldReturnFalseIfNotExists() { + public void existsByIdShouldReturnFalseIfNotExists() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -241,7 +238,7 @@ public void existsByIdShouldReturnFalseIfNotExists() { } @Test // DATAES-519 - public void countShouldCountMatchingDocuments() { + public void countShouldCountMatchingDocuments() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -254,7 +251,7 @@ public void countShouldCountMatchingDocuments() { } @Test // DATAES-519 - public void existsShouldReturnTrueIfExists() { + public void existsShouldReturnTrueIfExists() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -267,7 +264,7 @@ public void existsShouldReturnTrueIfExists() { } @Test // DATAES-519 - public void existsShouldReturnFalseIfNotExists() { + public void existsShouldReturnFalseIfNotExists() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -280,7 +277,7 @@ public void existsShouldReturnFalseIfNotExists() { } @Test // DATAES-519 - public void deleteByIdShouldCompleteIfNothingDeleted() { + public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build()); @@ -294,7 +291,7 @@ public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { } @Test // DATAES-519 - public void deleteByIdShouldDeleteEntry() { + public void deleteByIdShouldDeleteEntry() throws IOException { SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); @@ -305,7 +302,7 @@ public void deleteByIdShouldDeleteEntry() { } @Test // DATAES-519 - public void deleteShouldDeleteEntry() { + public void deleteShouldDeleteEntry() throws IOException { SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); @@ -316,7 +313,7 @@ public void deleteShouldDeleteEntry() { } @Test // DATAES-519 - public void deleteAllShouldDeleteGivenEntries() { + public void deleteAllShouldDeleteGivenEntries() throws IOException { SampleEntity toBeDeleted = SampleEntity.builder().id("id-one").build(); SampleEntity hangInThere = SampleEntity.builder().id("id-two").build(); @@ -332,7 +329,7 @@ public void deleteAllShouldDeleteGivenEntries() { } @Test // DATAES-519 - public void deleteAllShouldDeleteAllEntries() { + public void deleteAllShouldDeleteAllEntries() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // @@ -344,7 +341,7 @@ public void deleteAllShouldDeleteAllEntries() { } @Test // DATAES-519 - public void derivedFinderMethodShouldBeExecutedCorrectly() { + public void derivedFinderMethodShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -357,7 +354,7 @@ public void derivedFinderMethodShouldBeExecutedCorrectly() { } @Test // DATAES-519 - public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() { + public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -370,7 +367,7 @@ public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() { } @Test // DATAES-519 - public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() { + public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // @@ -385,7 +382,7 @@ public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() { } @Test // DATAES-519 - public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() { + public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // @@ -400,7 +397,7 @@ public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() { } @Test // DATAES-519 - public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() { + public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // @@ -414,7 +411,7 @@ public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() } @Test // DATAES-519 - public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() { + public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -427,7 +424,7 @@ public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() { } @Test // DATAES-519 - public void annotatedFinderMethodShouldBeExecutedCorrectly() { + public void annotatedFinderMethodShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -440,7 +437,7 @@ public void annotatedFinderMethodShouldBeExecutedCorrectly() { } @Test // DATAES-519 - public void derivedDeleteMethodShouldBeExecutedCorrectly() { + public void derivedDeleteMethodShouldBeExecutedCorrectly() throws IOException { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // @@ -456,15 +453,15 @@ public void derivedDeleteMethodShouldBeExecutedCorrectly() { assertThat(TestUtils.documentWithId("id-three").ofType(TYPE).existsIn(INDEX)).isTrue(); } - IndexRequest indexRequest(Map source, String index, String type) { + private IndexRequest indexRequest(Map source, String index) { - return new IndexRequest(index, type) // + return new IndexRequest(index) // .id(source.containsKey("id") ? source.get("id").toString() : UUID.randomUUID().toString()) // .source(source) // .create(true); } - IndexRequest indexRequestFrom(SampleEntity entity) { + private IndexRequest indexRequestFrom(SampleEntity entity) { Map target = new LinkedHashMap<>(); @@ -483,17 +480,17 @@ IndexRequest indexRequestFrom(SampleEntity entity) { target.put("rate", entity.getRate()); target.put("available", entity.isAvailable()); - return indexRequest(target, INDEX, TYPE); + return indexRequest(target, INDEX); } - void bulkIndex(SampleEntity... entities) { + void bulkIndex(SampleEntity... entities) throws IOException { BulkRequest request = new BulkRequest(); Arrays.stream(entities).forEach(it -> request.add(indexRequestFrom(it))); try (RestHighLevelClient client = TestUtils.restHighLevelClient()) { client.bulk(request.setRefreshPolicy(RefreshPolicy.IMMEDIATE), RequestOptions.DEFAULT); - } catch (Exception e) {} + } } interface ReactiveSampleEntityRepository extends ReactiveCrudRepository { @@ -530,7 +527,7 @@ interface ReactiveSampleEntityRepository extends ReactiveCrudRepository createSampleEntitiesWithMessage(String message @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-simple-repository", type = "test-type", shards = 1, replicas = 0, + @Document(indexName = "test-index-sample-simple-repository", replicas = 0, refreshInterval = "-1") static class SampleEntity { diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java index 58a1b2d69..d0281942a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java @@ -34,6 +34,7 @@ private IndexInitializer() {} * @param clazz * @deprecated since 4.0, use {@link IndexInitializer#init(IndexOperations, Class)} */ + @Deprecated public static void init(ElasticsearchOperations operations, Class clazz) { operations.getIndexOperations().deleteIndex(clazz); diff --git a/src/test/resources/mappings/test-mappings.json b/src/test/resources/mappings/test-mappings.json index 74373cabb..fcb7b647c 100644 --- a/src/test/resources/mappings/test-mappings.json +++ b/src/test/resources/mappings/test-mappings.json @@ -1,10 +1,8 @@ { - "test-setting-type": { - "properties": { - "email": { - "type": "text", - "analyzer": "emailAnalyzer" - } - } + "properties": { + "email": { + "type": "text", + "analyzer": "emailAnalyzer" } + } } diff --git a/src/test/resources/synonyms/mappings.json b/src/test/resources/synonyms/mappings.json index 489d750c8..30cc91c68 100644 --- a/src/test/resources/synonyms/mappings.json +++ b/src/test/resources/synonyms/mappings.json @@ -1,10 +1,8 @@ { - "synonym-type": { - "properties": { - "text": { - "type": "text", - "analyzer": "synonym_analyzer" - } + "properties": { + "text": { + "type": "text", + "analyzer": "synonym_analyzer" } } -} \ No newline at end of file +} From 90d29994f1d75187af53accb0d4a656c3fa3987f Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 30 Dec 2019 17:08:52 +0100 Subject: [PATCH 0027/1191] DATAES-715 - Highlight results should be returned in the SearchHits. Original PR: #368 --- .../elasticsearch/core/ResultsExtractor.java | 24 ------- .../data/elasticsearch/core/SearchHit.java | 26 ++++++- .../MappingElasticsearchConverter.java | 3 +- .../core/document/DocumentAdapters.java | 48 +++++++++---- .../core/document/SearchDocument.java | 7 ++ .../core/ElasticsearchTemplateTests.java | 70 ++++++++++++++----- 6 files changed, 119 insertions(+), 59 deletions(-) delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/ResultsExtractor.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ResultsExtractor.java b/src/main/java/org/springframework/data/elasticsearch/core/ResultsExtractor.java deleted file mode 100644 index a1d1b9563..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/ResultsExtractor.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2013-2019 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; - -import org.elasticsearch.action.search.SearchResponse; - -public interface ResultsExtractor { - - T extract(SearchResponse response); -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index a4188bf0c..7b947030f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -18,9 +18,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Encapsulates the found data with additional information from the search. @@ -35,11 +38,17 @@ public class SearchHit { private final float score; private final List sortValues; private final T content; + private final Map> highlightFields = new LinkedHashMap<>(); - public SearchHit(@Nullable String id, float score, Object[] sortValues, T content) { + public SearchHit(@Nullable String id, float score, @Nullable Object[] sortValues, + @Nullable Map> highlightFields, T content) { this.id = id; this.score = score; this.sortValues = (sortValues != null) ? Arrays.asList(sortValues) : new ArrayList<>(); + if (highlightFields != null) { + this.highlightFields.putAll(highlightFields); + } + this.content = content; } @@ -69,9 +78,22 @@ public List getSortValues() { return Collections.unmodifiableList(sortValues); } + /** + * gets the highlight values for a field. + * + * @param field must not be {@literal null} + * @return possibly empty List, never null + */ + public List getHighlightField(String field) { + + Assert.notNull(field, "field must not be null"); + + return Collections.unmodifiableList(highlightFields.getOrDefault(field, Collections.emptyList())); + } + @Override public String toString() { return "SearchHit{" + "id='" + id + '\'' + ", score=" + score + ", sortValues=" + sortValues + ", content=" - + content + '}'; + + content + ", highlightFields=" + highlightFields + '}'; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index f42cce959..2664e0f5b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -181,9 +181,10 @@ public SearchHit read(Class type, SearchDocument searchDocument) { String id = searchDocument.hasId() ? searchDocument.getId() : null; float score = searchDocument.getScore(); Object[] sortValues = searchDocument.getSortValues(); + Map> highlightFields = searchDocument.getHighlightFields(); T content = mapDocument(searchDocument, type); - return new SearchHit<>(id, score, sortValues, content); + return new SearchHit(id, score, sortValues, highlightFields, content); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 814009b4d..4e2af31bc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -34,11 +34,13 @@ import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.common.bytes.BytesReference; import org.elasticsearch.common.document.DocumentField; +import org.elasticsearch.common.text.Text; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.search.SearchHit; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.core.JsonFactory; @@ -139,10 +141,14 @@ public static SearchDocument from(SearchHit source) { Assert.notNull(source, "SearchHit must not be null"); + Map> highlightFields = new HashMap<>(source.getHighlightFields().entrySet().stream() // + .collect(Collectors.toMap(Map.Entry::getKey, + entry -> Arrays.stream(entry.getValue().getFragments()).map(Text::string).collect(Collectors.toList())))); + BytesReference sourceRef = source.getSourceRef(); if (sourceRef == null || sourceRef.length() == 0) { - return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), + return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, fromDocumentFields(source, source.getId(), source.getVersion())); } @@ -153,7 +159,8 @@ public static SearchDocument from(SearchHit source) { document.setVersion(source.getVersion()); } - return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), document); + return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, + document); } /** @@ -195,7 +202,7 @@ static class DocumentFieldAdapter implements Document { */ @Override public boolean hasId() { - return id != null; + return StringUtils.hasLength(id); } /* @@ -287,16 +294,14 @@ public boolean containsValue(Object value) { * @see java.util.Map#get(java.lang.Object) */ @Override + @Nullable public Object get(Object key) { + return documentFields.stream() // + .filter(documentField -> documentField.getName().equals(key)) // + .map(DocumentField::getValue) + .findFirst() // + .orElse(null); // - for (DocumentField documentField : documentFields) { - if (documentField.getName().equals(key)) { - - return getValue(documentField); - } - } - - return null; } /* @@ -439,12 +444,16 @@ static class SearchDocumentAdapter implements SearchDocument { private final Object[] sortValues; private final Map> fields = new HashMap<>(); private final Document delegate; + private final Map> highlightFields = new HashMap<>(); + + SearchDocumentAdapter(float score, Object[] sortValues, Map fields, + Map> highlightFields, Document delegate) { - SearchDocumentAdapter(float score, Object[] sortValues, Map fields, Document delegate) { this.score = score; this.sortValues = sortValues; this.delegate = delegate; fields.forEach((name, documentField) -> this.fields.put(name, documentField.getValues())); + this.highlightFields.putAll(highlightFields); } /* @@ -485,6 +494,15 @@ public Object[] getSortValues() { return sortValues; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getHighlightFields() + */ + @Override + public Map> getHighlightFields() { + return highlightFields; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.document.Document#hasId() @@ -672,10 +690,12 @@ public Set> entrySet() { */ @Override public boolean equals(Object o) { - if (this == o) + if (this == o) { return true; - if (!(o instanceof SearchDocumentAdapter)) + } + if (!(o instanceof SearchDocumentAdapter)) { return false; + } SearchDocumentAdapter that = (SearchDocumentAdapter) o; return Float.compare(that.score, score) == 0 && delegate.equals(that.delegate); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java index ec66da0a2..6ea162475 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java @@ -63,4 +63,11 @@ default V getFieldValue(final String name) { default Object[] getSortValues() { return null; } + + /** + * @return the highlightFields for the search hit. + */ + @Nullable + default Map> getHighlightFields() { + return null;} } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 64036be37..a6c276cdb 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -27,7 +27,6 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.io.IOException; import java.lang.Double; import java.lang.Integer; import java.lang.Long; @@ -51,6 +50,7 @@ import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortOrder; @@ -148,6 +148,7 @@ private void deleteIndices() { indexOperations.deleteIndex(INDEX_2_NAME); indexOperations.deleteIndex(INDEX_3_NAME); indexOperations.deleteIndex(SearchHitsEntity.class); + indexOperations.deleteIndex(HighlightEntity.class); } @Test // DATAES-106 @@ -332,7 +333,8 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { .withPreference("_only_nodes:oops").build(); // when - assertThatThrownBy(() -> operations.search(searchQueryWithInvalidPreference, SampleEntity.class, index)).isInstanceOf(Exception.class); + assertThatThrownBy(() -> operations.search(searchQueryWithInvalidPreference, SampleEntity.class, index)) + .isInstanceOf(Exception.class); } @Test // DATAES-422 - Add support for IndicesOptions in search queries @@ -1854,7 +1856,8 @@ public void shouldIndexGteEntityWithVersionType() { indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); // reindex with version one below - assertThatThrownBy(() -> operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index)).hasMessageContaining("version").hasMessageContaining("conflict"); + assertThatThrownBy(() -> operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index)) + .hasMessageContaining("version").hasMessageContaining("conflict"); } @Test @@ -2134,7 +2137,8 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when - assertThatThrownBy(() -> operations.count(criteriaQuery, (IndexCoordinates) null)).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> operations.count(criteriaQuery, (IndexCoordinates) null)) + .isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-67 @@ -2151,7 +2155,8 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when - assertThatThrownBy(() -> operations.count(searchQuery, (IndexCoordinates) null)).isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> operations.count(searchQuery, (IndexCoordinates) null)) + .isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-71 @@ -2881,6 +2886,34 @@ void shouldReturnSortFieldsInSearchHits() { } } + @Test // DATAES-715 + void shouldReturnHighlightFieldsInSearchHit() { + IndexCoordinates index = IndexCoordinates.of("test-index-highlight-entity-template"); + HighlightEntity entity = HighlightEntity.builder().id("1") + .message("This message is a long text which contains the word to search for " + + "in two places, the first being near the beginning and the second near the end of the message") + .build(); + IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build(); + operations.index(indexQuery, index); + indexOperations.refresh(index); + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withQuery(termQuery("message", "message")) // + .withHighlightFields(new HighlightBuilder.Field("message")) // + .build(); + + SearchHits searchHits = operations.search(query, HighlightEntity.class, index); + + assertThat(searchHits).isNotNull(); + assertThat(searchHits.getSearchHits()).hasSize(1); + + SearchHit searchHit = searchHits.getSearchHit(0); + List highlightField = searchHit.getHighlightField("message"); + assertThat(highlightField).hasSize(2); + assertThat(highlightField.get(0)).contains("message"); + assertThat(highlightField.get(1)).contains("message"); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @@ -2899,7 +2932,6 @@ static class SampleEntity { private int rate; @ScriptedField private Double scriptedRate; private boolean available; - private String highlightedMessage; private GeoPoint location; @Version private Long version; @Score private float score; @@ -2913,8 +2945,7 @@ static class SampleEntity { @Data @AllArgsConstructor @Builder - @Document(indexName = "test-index-uuid-keyed-core-template", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-uuid-keyed-core-template", replicas = 0, refreshInterval = "-1") private static class SampleEntityUUIDKeyed { @Id private UUID id; @@ -2923,10 +2954,7 @@ private static class SampleEntityUUIDKeyed { private int rate; @ScriptedField private Long scriptedRate; private boolean available; - private String highlightedMessage; - private GeoPoint location; - @Version private Long version; } @@ -2935,8 +2963,7 @@ private static class SampleEntityUUIDKeyed { @Builder @AllArgsConstructor @NoArgsConstructor - @Document(indexName = "test-index-book-core-template", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-core-template", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -2950,7 +2977,6 @@ static class Book { @Data static class Author { - private String id; private String name; } @@ -2959,8 +2985,8 @@ static class Author { @Builder @AllArgsConstructor @NoArgsConstructor - @Document(indexName = "test-index-version-core-template", replicas = 0, - refreshInterval = "-1", versionType = VersionType.EXTERNAL_GTE) + @Document(indexName = "test-index-version-core-template", replicas = 0, refreshInterval = "-1", + versionType = VersionType.EXTERNAL_GTE) private static class GTEVersionEntity { @Version private Long version; @@ -3001,8 +3027,8 @@ static class HetroEntity2 { } @Data - @Document(indexName = "test-index-server-configuration", useServerConfiguration = true, - shards = 10, replicas = 10, refreshInterval = "-1") + @Document(indexName = "test-index-server-configuration", useServerConfiguration = true, shards = 10, replicas = 10, + refreshInterval = "-1") private static class UseServerConfigurationEntity { @Id private String id; @@ -3042,4 +3068,12 @@ static class SearchHitsEntity { @Field(type = FieldType.Keyword) String keyword; } + @Data + @AllArgsConstructor + @Builder + @Document(indexName = "test-index-highlight-entity-template") + static class HighlightEntity { + @Id private String id; + private String message; + } } From 5c862e80bf6005f3708af450b1d282d56454cd02 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 31 Dec 2019 13:55:56 +0100 Subject: [PATCH 0028/1191] DATAES-722 - Return total count relation in the SearchHits object. Original PR: #369 --- .../data/elasticsearch/core/SearchHits.java | 47 ++++++++++++++----- .../MappingElasticsearchConverter.java | 5 +- .../core/document/SearchDocumentResponse.java | 30 ++++++++---- .../core/ElasticsearchTemplateTests.java | 5 +- 4 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java index 3591078b3..c5a2e4317 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -39,38 +39,50 @@ public class SearchHits implements Streamable> { private final String scrollId; private final List> searchHits; private final Aggregations aggregations; + private final TotalHitsRelation totalHitsRelation; /** - * @param totalHits - * @param maxScore + * @param totalHits the number of total hits for the search + * @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null} + * @param maxScore the maximum score + * @param scrollId the scroll id if available * @param searchHits must not be {@literal null} - * @param aggregations + * @param aggregations the aggregations if available */ - public SearchHits(long totalHits, float maxScore, @Nullable String scrollId, List> searchHits, - @Nullable Aggregations aggregations) { + public SearchHits(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId, + List> searchHits, @Nullable Aggregations aggregations) { Assert.notNull(searchHits, "searchHits must not be null"); this.totalHits = totalHits; + this.totalHitsRelation = totalHitsRelation; this.maxScore = maxScore; this.scrollId = scrollId; this.searchHits = searchHits; this.aggregations = aggregations; } + @SuppressWarnings("unchecked") @Override public Iterator> iterator() { return (Iterator>) searchHits.iterator(); } + // region getter /** * @return the number of total hits. */ - // region getter public long getTotalHits() { return totalHits; } + /** + * @return the relation for the total hits + */ + public TotalHitsRelation getTotalHitsRelation() { + return totalHitsRelation; + } + /** * @return the maximum score */ @@ -107,19 +119,20 @@ public SearchHit getSearchHit(int index) { @Override public String toString() { - return "SearchHits{" + - "totalHits=" + totalHits + - ", maxScore=" + maxScore + - ", scrollId='" + scrollId + '\'' + - ", searchHits=" + StringUtils.collectionToCommaDelimitedString(searchHits) + - ", aggregations=" + aggregations + + return "SearchHits{" + // + "totalHits=" + totalHits + // + ", totalHitsRelation=" + totalHitsRelation + // + ", maxScore=" + maxScore + // + ", scrollId='" + scrollId + '\'' + // + ", searchHits={" + searchHits.size() + " elements}" + // + ", aggregations=" + aggregations + // '}'; } + // region aggregations /** * @return true if aggregations are available */ - // region aggregations public boolean hasAggregations() { return aggregations != null; } @@ -133,4 +146,12 @@ public Aggregations getAggregations() { } // endregion + /** + * Enum to represent the relation that Elasticsearch returns for the totalHits value {@see Ekasticsearch + * docs} + */ + public enum TotalHitsRelation { + EQUAL_TO, GREATER_THAN_OR_EQUAL_TO + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 2664e0f5b..2b204e9a7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -169,7 +169,10 @@ public SearchHits read(Class type, SearchDocumentResponse searchDocume .map(searchDocument -> read(type, searchDocument)) // .collect(Collectors.toList()); Aggregations aggregations = searchDocumentResponse.getAggregations(); - return new SearchHits<>(totalHits, maxScore, scrollId, searchHits, aggregations); + SearchHits.TotalHitsRelation totalHitsRelation = SearchHits.TotalHitsRelation + .valueOf(searchDocumentResponse.getTotalHitsRelation()); + + return new SearchHits<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java index fd1b0e714..89cf9ea74 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java @@ -20,14 +20,14 @@ import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import org.apache.lucene.search.TotalHits; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.search.aggregations.Aggregations; -import org.springframework.data.elasticsearch.support.SearchHitsUtil; import org.springframework.util.Assert; /** * This represents the complete search response from Elasticsearch, including the returned documents. Instances must be - * created with the {@link #from(org.elasticsearch.action.search.SearchResponse)} method. + * created with the {@link #from(SearchResponse)} method. * * @author Peter-Josef Meisch * @since 4.0 @@ -35,14 +35,16 @@ public class SearchDocumentResponse { private long totalHits; + private String totalHitsRelation; private float maxScore; private final String scrollId; private final List searchDocuments; private final Aggregations aggregations; - private SearchDocumentResponse(long totalHits, float maxScore, String scrollId, List searchDocuments, - Aggregations aggregations) { + private SearchDocumentResponse(long totalHits, String totalHitsRelation, float maxScore, String scrollId, + List searchDocuments, Aggregations aggregations) { this.totalHits = totalHits; + this.totalHitsRelation = totalHitsRelation; this.maxScore = maxScore; this.scrollId = scrollId; this.searchDocuments = searchDocuments; @@ -53,6 +55,10 @@ public long getTotalHits() { return totalHits; } + public String getTotalHitsRelation() { + return totalHitsRelation; + } + public float getMaxScore() { return maxScore; } @@ -70,23 +76,29 @@ public Aggregations getAggregations() { } /** - * creates a SearchDocumentResponse from the {@link org.elasticsearch.action.search.SearchResponse} + * creates a SearchDocumentResponse from the {@link SearchResponse} * - * @param searchResponse must not be {@literal null} - * @return + * @param searchResponse + * must not be {@literal null} + * @return the SearchDocumentResponse */ public static SearchDocumentResponse from(SearchResponse searchResponse) { Assert.notNull(searchResponse, "searchResponse must not be null"); - long totalHits = SearchHitsUtil.getTotalCount(searchResponse.getHits()); + TotalHits responseTotalHits = searchResponse.getHits().getTotalHits(); + long totalHits = responseTotalHits.value; + String totalHitsRelation = responseTotalHits.relation.name(); + float maxScore = searchResponse.getHits().getMaxScore(); String scrollId = searchResponse.getScrollId(); + List searchDocuments = StreamSupport.stream(searchResponse.getHits().spliterator(), false) // .filter(Objects::nonNull) // .map(DocumentAdapters::from) // .collect(Collectors.toList()); + Aggregations aggregations = searchResponse.getAggregations(); - return new SearchDocumentResponse(totalHits, maxScore, scrollId, searchDocuments, aggregations); + return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments, aggregations); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index a6c276cdb..3b8205f94 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -192,7 +192,7 @@ public void shouldReturnCountForGivenSearchQuery() { assertThat(count).isEqualTo(1); } - @Test + @Test // DATAES-722 public void shouldReturnObjectForGivenId() { // given @@ -289,7 +289,8 @@ public void shouldReturnSearchHitsForGivenSearchQuery() { // then assertThat(searchHits).isNotNull(); - assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getTotalHits()).isEqualTo(1); + assertThat(searchHits.getTotalHitsRelation()).isEqualByComparingTo(SearchHits.TotalHitsRelation.EQUAL_TO); } @Test // DATAES-595 From bd047776e2b096d9e77ce2f4ee9ec65732caccd6 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 31 Dec 2019 19:39:20 +0100 Subject: [PATCH 0029/1191] DATAES-711 - Update to Elasticsearch 7.5.1. Original PR: #370 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 2 +- .../asciidoc/reference/elasticsearch-new.adoc | 2 +- .../client/util/RequestConverters.java | 12 +++++++++--- .../core/CriteriaQueryMappingTests.java | 2 +- .../ElasticsearchDateConverterTests.java | 2 +- ...appingElasticsearchConverterUnitTests.java | 2 +- .../SimpleElasticsearchDateMappingTests.java | 9 +++++---- ...sticsearchPersistentPropertyUnitTests.java | 2 +- ...on-7.4.1.jar => analysis-common-7.5.1.jar} | Bin 193638 -> 193639 bytes .../plugin-descriptor.properties | 4 ++-- ....1.jar => elasticsearch-dissect-7.5.1.jar} | Bin 24485 -> 24487 bytes ...7.4.1.jar => elasticsearch-grok-7.5.1.jar} | Bin 32100 -> 32240 bytes ...mmon-7.4.1.jar => ingest-common-7.5.1.jar} | Bin 106715 -> 107326 bytes .../modules/ingest-common/joni-2.1.29.jar | Bin 0 -> 214815 bytes .../modules/ingest-common/joni-2.1.6.jar | Bin 189961 -> 0 bytes .../plugin-descriptor.properties | 4 ++-- ...on-7.4.1.jar => lang-expression-7.5.1.jar} | Bin 61106 -> 61186 bytes ...8.2.0.jar => lucene-expressions-8.3.0.jar} | Bin 73072 -> 73071 bytes .../plugin-descriptor.properties | 4 ++-- .../lang-expression/plugin-security.policy | 2 +- ...icsearch-scripting-painless-spi-7.5.1.jar} | Bin 26239 -> 26241 bytes .../lang-painless/lang-painless-7.4.1.jar | Bin 542811 -> 0 bytes .../lang-painless/lang-painless-7.5.1.jar | Bin 0 -> 552146 bytes .../plugin-descriptor.properties | 4 ++-- .../lang-painless/plugin-security.policy | 2 +- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../modules/reindex/plugin-security.policy | 2 +- .../plugin-descriptor.properties | 4 ++-- .../repository-url/plugin-security.policy | 2 +- ...url-7.4.1.jar => repository-url-7.5.1.jar} | Bin 14564 -> 14569 bytes 32 files changed, 39 insertions(+), 32 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.4.1.jar => analysis-common-7.5.1.jar} (88%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.4.1.jar => elasticsearch-dissect-7.5.1.jar} (86%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.4.1.jar => elasticsearch-grok-7.5.1.jar} (68%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.4.1.jar => ingest-common-7.5.1.jar} (84%) create mode 100644 src/test/resources/test-home-dir/modules/ingest-common/joni-2.1.29.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/joni-2.1.6.jar rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.4.1.jar => lang-expression-7.5.1.jar} (85%) rename src/test/resources/test-home-dir/modules/lang-expression/{lucene-expressions-8.2.0.jar => lucene-expressions-8.3.0.jar} (91%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.4.1.jar => elasticsearch-scripting-painless-spi-7.5.1.jar} (87%) delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.4.1.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.1.jar rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.4.1.jar => repository-url-7.5.1.jar} (81%) diff --git a/pom.xml b/pom.xml index 4b990ec3e..d790d6756 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.4.1 + 7.5.1 2.9.1 2.3.0.BUILD-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 1cec65a97..60ddff34b 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,7 +35,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.4.1 |2.3.xfootnote:cdv[] +| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.5.1 |2.3.xfootnote:cdv[] | Moore | 3.2.x |6.8.4 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index fc8449a08..807d3d62d 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -5,7 +5,7 @@ == New in Spring Data Elasticsearch 4.0 * Uses Spring 5.2. -* Upgrade to Elasticsearch 7.4.1. +* Upgrade to Elasticsearch 7.5.1. * Deprecation of `TransportClient` usage. * Implements most of the mapping-types available for the index mappings. * Removal of the Jackson `ObjectMapper`, now using the <> diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index 65a5be626..ab428764f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -77,6 +77,7 @@ import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.VersionType; +import org.elasticsearch.index.mapper.MapperService; import org.elasticsearch.index.rankeval.RankEvalRequest; import org.elasticsearch.index.reindex.AbstractBulkByScrollRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequest; @@ -183,7 +184,9 @@ public static Request bulk(BulkRequest bulkRequest) throws IOException { metadata.field("_index", action.index()); } if (Strings.hasLength(action.type())) { - metadata.field("_type", action.type()); + if (MapperService.SINGLE_MAPPING_NAME.equals(action.type()) == false) { + metadata.field("_type", action.type()); + } } if (Strings.hasLength(action.id())) { metadata.field("_id", action.id()); @@ -201,11 +204,14 @@ public static Request bulk(BulkRequest bulkRequest) throws IOException { metadata.field("version_type", "external"); } else if (versionType == VersionType.EXTERNAL_GTE) { metadata.field("version_type", "external_gte"); - } else if (versionType == VersionType.FORCE) { - metadata.field("version_type", "force"); } } + if (action.ifSeqNo() != SequenceNumbers.UNASSIGNED_SEQ_NO) { + metadata.field("if_seq_no", action.ifSeqNo()); + metadata.field("if_primary_term", action.ifPrimaryTerm()); + } + if (opType == DocWriteRequest.OpType.INDEX || opType == DocWriteRequest.OpType.CREATE) { IndexRequest indexRequest = (IndexRequest) action; if (Strings.hasLength(indexRequest.getPipeline())) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java index 3176498e4..ee82bef3b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -99,6 +99,6 @@ static class Person { @Field(name = "first-name") String firstName; @Field(name = "last-name") String lastName; @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, - pattern = "dd.MM.yyyy") LocalDate birthDate; + pattern = "dd.MM.uuuu") LocalDate birthDate; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index 50fe532f3..a05f734b5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -21,7 +21,7 @@ void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) { if (dateFormat == DateFormat.none) { return; } - String pattern = (dateFormat != DateFormat.custom) ? dateFormat.name() : "dd.MM.yyyy"; + String pattern = (dateFormat != DateFormat.custom) ? dateFormat.name() : "dd.MM.uuuu"; ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(pattern); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 2c92e4963..daa24cfcc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -643,7 +643,7 @@ static class Person { @Field(name = "first-name") String firstName; @Field(name = "last-name") String lastName; @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, - pattern = "dd.MM.yyyy") LocalDate birthDate; + pattern = "dd.MM.uuuu") LocalDate birthDate; Gender gender; Address address; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java index 8e2f19611..1c3230b27 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java @@ -21,6 +21,7 @@ import lombok.Data; import java.io.IOException; +import java.time.LocalDateTime; import java.util.Date; import org.junit.jupiter.api.Test; @@ -39,7 +40,7 @@ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests { private static final String EXPECTED_MAPPING = "{\"properties\":{\"message\":{\"store\":true," - + "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.yyyy hh:mm\"}," + + "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.uuuu hh:mm\"}," + "\"defaultFormatDate\":{\"type\":\"date\"},\"basicFormatDate\":{\"" + "type\":\"date\",\"format\":\"basic_date\"}}}"; @@ -64,10 +65,10 @@ static class SampleDateMappingEntity { @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; @Field(type = Date, format = DateFormat.custom, - pattern = "dd.MM.yyyy hh:mm") private java.util.Date customFormatDate; + pattern = "dd.MM.uuuu hh:mm") private LocalDateTime customFormatDate; - @Field(type = FieldType.Date) private Date defaultFormatDate; + @Field(type = FieldType.Date) private LocalDateTime defaultFormatDate; - @Field(type = FieldType.Date, format = DateFormat.basic_date) private Date basicFormatDate; + @Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDateTime basicFormatDate; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 38da81b2a..083d4743b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -123,7 +123,7 @@ static class FieldValueProperty { static class DatesProperty { @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date; - @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.yyyy") LocalDate localDate; + @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate; @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; } } diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.4.1.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.1.jar similarity index 88% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.4.1.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.1.jar index b63aaa00339c3e51a6b47612ecbb0b2d063f4b72..8c77e44cea1adb189e53186785f94815384269fb 100644 GIT binary patch delta 8245 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 Y11y3AwIC}5;Q;)d0`uUTRKO|x4>?D}IsgCw delta 8172 zcmZuW30%$D_uqTlp0r0KrKD6!F|tKuk0QoS)NBW<8&$ph}fB4MjeVude*|&S=MRDEd#dVE?`swHzN|Hh$&094z#@M+I z{0wN8Y+EohrjtW>;D9GyW@m@J3SXH$$^5vDPvEFjHsp%o`~7w!ch^@R{wdJC!@OU7 zLMqCQJeJWb<4t{kFWk1J-OT4E+wV;Xcw^VSP2u5ycZ=GmO!HaoaauPja{7$eo*OHI z=AJN9-Y|D4UOqoLag7f#`0Tp%(utX)N*DL9*u2_vNa4uT%(B9}*+aws`aE#b1*aof zYZokeKEUk{UBlC13XfrKXS@@t&X^8BYYt}65 zxZ__6)1F$kT(Pug*PNsCg8%B&V%3|At(PQk_E=Q>ZA{L~-Fe=fGGqKVgujU2nUk=n zNgMx$C(nd8{_kH}nI!ERjG0Ob2H zvnzh&7MBtsU~&-ci=g^bWg?dr?gj!k(4D3WoO)jdaa0JHzdLbmExuOk(~+p!zTx9{ zzR;1R5<@mSh`O-rmuUmFogJ+ddZ_-)TY(CZUUV7Cx^dJ?7gP0c@$Bzx{0!=$3Vz~* zWDOjNmH0Y&n+`|N@2`o6jyZQjm04y)caXKgK$3c}m?gxSH7cVH>S6n7ppIZ!dFP!1 zS+Z?!sI9U|w2|6!HvNW@Z3_+cxcaJZk!R61hX~q2NKw5^e~(Vt^o0B=Jg4?@Cf!hl zQ8VZWBs&&56hFQ-y^Q|d>M!eAVM?zd`HszGF-mkAw_is@uqU~ddX-3$m+r>L)J2`V zgnSUR8uE_~Be>FlwB%n+`y` zmX7pAeF81WJ(RRR^ZLJ0;C2%Q8>l2MtmD7bPCe0xD)B^`btE#$xlBHzQC)hWPgEug zUyIaH8RTc{3z66E1)z5q+mL=lnEC453Vk#)>J*x(GMQhA4m7YFkIc7N)AqW;q%)7B zhV9Xlq$b89aq$IZK&!OctnI(ZMTgqLLt*bNJq?Ft70-1ISmb@#`smziEhVK zOxescMrylJ3b=sWGDklnc-Pxpqh_rf|=(SExtIj!cB>I~YIjvg7jT8J-Q-1A@ zf!i0o?f|RWL|dv>wRS~W(SCFe>Qp#^jz&FO>C$0nrXMRoHUGDXj>e41?C$s`7;4^H zpE(qR*F6iULY?PI!!bNLmh`Hg@W-sS*$t-YN|MSDLu}uf>arH;w1Fx;B@9JoT_IIy z=p<7+ciGVX=coY-xk>HS-C_vARua}}Q66D=3nAqylc*i9ACBMd|}latBd`UmlJY+`kfs(MZ`qyI^wf?8eL^L7UqOrTtVF_AZ}VtL@*D zSfuM5LT&Vf*3YiDYZ*F_U5*4Zl89XXWDWEPq1*|Zo>k@G0-}d45mLrL zo!gPxqFy@-NH`u|IEj=ZtXM&t~h)#huvz*`qd_qgk^o`EpbKqfMhbHuIR*3 zeP|8_Ie0zwMy$e~7@>q#cgQrvZd^-(5PP*T=^(JGm`Ycy*W8J|=#6PkJ}bX~^i8@V z>6D{dSTgJP#6*321*C`&xTu0uA@c!$(ZT4PF!!fjD&bfccJ3o_WefAEGc)-_%+=eY zt6ReV2KCbu$>V#epr5D>^#Ucq;!rNW^j$QEywxL7Gxv4Lx}xQ;DKv;&3vM@3NKz1Q z`OR6;HR`U;A44{y76x<40%M`s`Rha&d=zlvF&~KWa&%NZ>A#4p{p9Qfalaw{fj5f z#YVU6c~4|?EuW0T*j_4YWLAcWA)4|0G-|_)Hd2M^Ui>EvaeO4XiE4&UAa$^t{OmS2 zSd^P;o~<(~((Y`cY-xLHk7CTrNeC4lzMa23m0jaC9DkBFff}x(Y65*;_^4cuY(f3b zes719{_;XP2D$!f6@(ulpPaEBsRmIOGm+FcGxWBdfQrjC5Eeu8uvHB{o`$kdek3Er zmnwCcnPAVn zgxZiCw($sU2CEc1!~Z#z-8n*=a%0#x_;&+m3rU(eXNqS~KP{Flsf=3dR{Hg|P-e`l z$HpF|V&t*Vqtu2j;y_z=2!QsyB}woHY!iQ)%D<9iCRO^WIb}2UrTX~V6L7r3g2gl> zE!gc7w24q;dj>$;)CW>0mhJ}~&$vp#(z0Zcrf&fo+fXnHdP`dhk(!kb%BDu7B%O$e zvfJMlKj^~7XHzFOJ%f4(6)PP(FWLg>>J0Vgqs9G|n^1-g zxJQjx(L<`oMqHqlLWub*VD-TL2mIJqa=03+0p;o`{1B{$#f!(#?HB<6XvJbykaleG zF=`=18@8RhWC%oLAI$k6Ezy6s7w5B|(T;*LZ`I?2XJH@ov67^IT9h+DcjI(;g_Q-1`NkxYwsgoADvODVhr#rD`Yp=<^w|)%jrTzvoo!B{jXlpf5IsF7M z*1x0AW z=~XzVv#KT}7A*Uu?2gHM^8Kqo12ae7bIC@29jm%}I@2@3EkkCKF%Bo!z2e%5l zg9>dm>ECtE;rxl9{bcZ;HuZ^J%7_$aHu<#dx(Hr^VS9v0gCnSeCX5;BfZ4OZ#yObJ z%9a@h%qBxFvk6n_@P?q(X7G}BoHiX4EEhbWZG;yR{`ieN1C9QM+0aeP3sy%2<(6FP zE`n0>8sv^j6u_2msH-@>XG?3(?{K^h2>Q}+GjQHd>wLR3p^v*6ZKCl|=q+HR$OMcN zgM@4;xZgVoz^H6(x53((EGL%czEeA~T3zBP>daDZP-nqv#6@5=B1cGuL0X?BUZnMe zp;CQX_}}i>b5)R!u20Y|!6-2q7=6tXIw`wN#tIM_XUQ*8kIq1W(0rb}ei~6txyoD|qV)|IQqYXg5tXjS>MmnX=jcP(B_^V;ku+|6I9e8Q%lsYgk(W$;3`= zmO~V5DztfFcLE7(@Zas?sR16cQpuIPF*?0uJtSBqjOVUeN!Fz5O@u`hL*R~F=b`f+L@Oi6kG z*g#)_W&Xv)UX!kU=+IRsLF+6SdD6Yw~T5b>gg3RxLcA!>QEw!?TAo;4+b{Z>ore$v6drlUN1?^mL9D!klf^*a) zc?DlWHU}do&!q;e;Y3IkKDtF}{a$bS%1^M^c){GzUYp7%pmEQNT;eVSPW) zCc9U>4=AlHefz$D7sa6N%LqSNjj zZ|7j%p;N&z+Bb~m&yn88p5Pr$IOFYo5Z(4=O)qc|(8PRz?k&LskRF&cW_*+XT*}q# z#%5lXy|B`-f%ioS*%Z)HyPdTzLk9d&URh9S!oJ^?-O!cqN@G3>bnGv{X z)vnK+I!LHD`Vky2|AO2TD+n&sg29CYDdXROucGQoQlM5MReTfl;!@hNlzItH9k`)E zlw}mb$^j2Y;{Pu&d$?v36-zIIi46~*X3EY#n`n}RKOz11^dN@F2%eUH7$4Th#}*`j zDi!dbx0Xudj0Jt{OCvTmQ@+6x-mAu&Afs+)s(TfOrkNuYTB;Q@IW3Rt9oGOg-wIKM z*W`<7$NV~XY+*-?Z(6%R<~Bl7lWZuc{x@hd^jqBN;B}BU(U3QzwUjJvF6fo-zS}9g z9IVem?#qF{nfGk#W;mh;N3;X~#SKM3Yp%o0?ob!u>+MfL(N7+Tf@*YN-=E4hZ0Bzb zn_K@V$ekTYlC#BwAM|L42O*j2u#ru{18b`9y7AC_h{VRffN;T9)>;@8&?U4jf9?AJ zQ}(Y;$jNvWankg*LcWCzkfzf z=k8N?VYlX$ulBq#9)_gw?uR$}$2Wk%s1XP)j3hs-FgCn%wjP71(RuP?+HCG4-|+&f zoM-#Pt~HR~W4HdoF;2=~&;D?KE8zA9gdnHJFXUTSQ6WHQPD3cvoe>KvmxqS9ZtzD$ zsLCXmclW0w6}%?mn@wXrf_-KoH25<06m}~beki-8FG=IgYiHw~d4d!Y*h%v$7FPmH z%oih*ZwukZ$%lZ5=8gnF&51x%VFGO-_}{pFEIt=9-4Xa}zg3+73;A#R)L7GpJ6+k- z<$|dst#qiZ&f93V`xPA`L>cpC!+Hmbf*l7(_B8Gsw>ac#mZi_$ew2M94y`{8=;eD5 zUAoLcqd7b}+R!bBSZ*1$7o_hv;L0Ip{E_z3e)D8~IcmaT6ur8PHms)y-jk$5@ONAv LNqQF#r7is*pd9@n diff --git a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties index cba78bbaa..48b3dc4ce 100644 --- a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds "built in" analyzers to Elasticsearch. # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=analysis-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.4.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.5.1.jar similarity index 86% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.4.1.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.5.1.jar index eb0aee19f10d02ea84359717a90c229d4da5fb1e..a209b817769dc8f0e5fa3d619f6b1e3573b09b52 100644 GIT binary patch delta 1257 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

YGaKbH*|Ul@Q8^NAiX8KB+RGFU7!I25 z&Hy$Bipsd^8YWE_x>JlMbqrE$b-N7P|rV5vBQqx)K!S ziYK^AM1^63ik8@e2izOL-6LztwNHzr^?>3dVE3t#@eNMg)TcrO+(o@!gJpljh@;OlH=bn*2f}|Qt?&eo*M=D zJyI!Q>iZo>%fAbt7WSF4F0{Xpz<94arK(Pb8%o$wUeR*ovXEtwUyjYwBxUg&efY?v zwGy7V_0t{R30bIeQc}Y7;&D?Pz0@?h*vm3|P6{K)YmTE0(SJv&#pn!}USb8`Hdv?1 z^R$LHxk0T#F7w0M2iL9%pZU1 z7$Wf9-klxF!Ff@HO_RZ~k{NB!E^Ad^&g-*(FK{XaC$*77C+JMYaX2VkbQXd7B_l1% zoNWS}=(Go~&xq^7Wt~8eqH&F)+M!Efi#4u-NStu-Xzat8k%NzoIigN;>b17OPb0hb zjhzs6>7EDWofx!VKlY5exA;S2{IpyL;}3vGhec@Bc&E*yCH~F)G9#$f+Po9$k!5S% z_pCM;v-L9vT&-%nv$bdp8N0nD{hDtp`i2oKvb`;<=@8`1!PP^2fXuRn#p4%8jS-cs zE9IeDd5fx}OB4i`HRq>B*(gVX;!lt%C1=RXAw-eZ)EuTocdVIZ)-R+pRKx+G>O8B= zMUl~P$*hBUlOm4XH@&~RrhXQg5Lf;=AF1o)_b|oL8cZQx@Np>q!>>0))2I&pzV{Tg z$PNYDo{-wZAN5MU38uLmZXPs7qy;ojY9}rVSKvz6J593uzQ%WfL8qcP#%&qJ?JD|w zSzS*z1qw}Iw;^4|ipw>p_UlCxxmMfWHw6T8Gw0tqXFEB{O-?nxwwbx2=m-lkzGyPn z;*Ek{!Fm?U6sf<%N}pKDG4n*4UP0th4F=WkeZG1=*+-%nN?C@zU+GsnMj*st+H^-_&T$nVf zI4ydzm?<3I@_n-HIV4{wd>6z7c;4^+92~xxjs68X=o;@=qB0<@>ZF8zVgHy zy^P1McelOm-_>^${V4JdC+>RJgK;IQ+_jD z{!0S54IYNU6;Qrif8BMJr-&?jk{CJX##s3?Qt}_m1+)A_XRMZI^u=3adM#o-W>P`s zm?Bs|mfjm+o2E~c6>2N-2A9gQ7#$vVu-df;@!>B+V0UoP&46je(q_Mo*qE*kd)&ul zy-tUGapgLpLZV+~lzR?DOT2o@@>&TKJa+1$G|z&Kbkk>nZ5Ip9ijS!2SB2;n6U~Z^ ztV5Kl$V%GyYLiNj{AFrDAY>R8rQ_F+iKOl{8yPnC?M6fWdw=gNyCd%SKv-zph!UzH zi8d^G^^1)nX6?15oRN9fKc$Bq+>dY4UuiFx+3wQ=+>dlpKxvPI{PmijC2Evsd0A>F zCJDnAG1M~cYvE;LTB4BZFJa33o{o=Zji(^tIV?ToAH3!heG11kqiT1h;=-Od~pB}&YrkZTUE)C2n z5WE%B>N3L7Yy#;aG;>>EtyhD&I|b-un&Pba*4fm;F~@0q5zd*V1;MQ{Ler=HA->_{ z|4da_SUgIth>qi=TzSe|eWg9`SX20mqEXc+x^I~D7HA=NXCie1d84)$U+5UVs=Co9 zo{BvuRcppr6PCSd7cp}j6?ik594xOG%pW(%9r}$L*_%lpkav?*cY}Y^=hkoWnB#;u zajKL~_VRGJa+7!AhkX4``)tDLmCyHVqUYS1&NsvwE7C$?m{U3wnF%hO2`@i?<=A>+XkbZIE#uOiI$uU8*; zki$mgtz-kruPSZ!c0v5_2P=cW2JWoD3dJ2mOOaS9yV#MH$_SuFaC*r+0>!QruxK9X zw!w=$A2q^$t?AUGPJOd7Iegm;n^g07wAp1l%B%Dxv7yVeEm!)`OPQK2o#qqkX@Q=^xkQ>0g&Q+B=3YK3Tp zXR<@<1AmV1aY}`Ucyr8%hIlkU#?4tVcCA^wIU6A z#|AxYZlhU3>n5{&*A%nDrj1tRwuRLKH(gfC2c3l_qUOJowdofKT18tVXgRFowQp7k zns}?fRvu!WQ;xx}wWbW3F=@k_f7f(uRIQL)yV=w{moAs}nAy#LoAQbI%zCFi_dfAn z&#u@s&(^fr80h#HeI<p_-;GfgUdU}Jnw)4O(U*G^AQKRzbE zze*BsLE66FJ-W8>@bS%D%geav9QDb<7GiO1eXv}Or$B{sg+HTaWK?-m>OC%_jCKw% zFXpU&QGNNvVbkZ?n;OBWz8mZ6Hozl3llK&|g7CSP8eq@XnLOanct!51`%#tS2MKK$ zVO4*DkUEK=xuZ(0<_b-^-Rd<#E0)=@98}RV!AQK zw+MbN8~P-cWum}1zxn6$HIg4oDT6Ixp*JLwVxi97DTKu^T@#n|5?3}p#?gjOee20wiqAcUgl zgXQ3aa(=SKsyh`-&4q=3M}j)@LRyGt9$637_``kpYes5Y|LPLw*8=wyQnAa{6-Mjw z+Lbb|w6yK>OPteBx{JW)5^#9TqwYd@%{!FjvIIqm@<*0~_7D$JXLrV(iIA(I+byWmkrj3zOuXOfINHWMvooaRBBA>d%xX-O z_DoCZ0l#ITn&!eL=R3)s@kFxBtNsM~=yN0PE1%&H;eY2Af?Zoa0{+E*6aSYwA-4Y{ zf8A8|9B{?Z{*edyp1rpytkMpGpy$x8iX-JL<(xK}BXNTVq-2y+qexO`yq)l}^)wxb z5X%J$Zo5gy^xuJ$)%Zh@3=WD4BLu*Xr#Y<$0*-rLu5vnFa(&FNc>Mj|*a9r>qhj&o zOO<8}F=ovaN2%;`S4&H0f@VS&adH}*K%&{HIcc2ajird(I&obO#R5eeT($Zu!|e?A z46AToZMt}}{9Grtub7y3VEEcR)?+*0e+gKQ=xp}}SVII7F8kQ`-Tr-2q>14^zGgg2 zI~tn1*J&IF`sZ{Bp-cbr1xJc#4D1tV}2zneGpCmsZYRM}tIz0D6U zADcI6SvOAqAu`5-zg>v=?9ntlx@Z(sK8ywtF0<-JX$EJ;scB-#AS3NNyoHY82ej0Z z(x%*jD(u}E4!~|6tufSrfflci+7Cy%nt{?^OhRPP%a)<5k~VaFlnUCDy7#oHZ@0xd zqqs!|4SPkR1N)F}#q##eFDIEpCe2s{dLmq{!G73wT#Wq-@f8+00zpc79ZxEMEwq?_ zX&(;0SIJzSqUR1Pg;L?EcmjimVlq|CEuD~eSI;e2qT9e=3O1VjaFfdO;Ms)C``8Z) z9sOeErtRzx^pB$4`z*7}HZSK#?B8|ai%MtCZC-%Df=*uV&vF#`3d@S;W3V%tqcu7V*B+Y{>@q21p8va@ePb4gk!W~Zl zcl>pNfzqPN?*^+bXZ^dnq(w%JWn-f9T64KN+0B-6v30{PIGIq0d&0U^QH`Z7vGy46 zpZR0hm;c%n?}KxE`~*v2lzBSdRdh zCGny$MytoZKY!Ch%;r!4|2f335+*;a8QezDdg0kaG!y!q%IO;;}_U2L4QAsz%z34 zbM{#Nqz~>To4Bq^|A7CuXw%XNzuo_d*64o`Ez^HQYp47l(VEnGbYHe)72{tt7pExp z+w*T3Gme~V9FUESO9ksGSCW+I_&DiiyS413ML?1j^FPLNgea0%!cbK%g_Ece-S;Ez zMG_9=30gy2tSG^TrJn3GdEE54++@66*BSVMD-MI>vPVgE+Zn;!YNiWGWqGu4mCX3C zn=7TICv(yn=H9&K+*J$m{x-m5r0z+htglT)bP^?-q&h0n|ylm7!f-ile!KXRS;I#wG`;yS9Uk>9$l^MP`rm@l)B`Gb~!SNwn#!KSE3}$L|ED zT+AV@FXfQ{aEBf@2UQm17Hodnj`Uz#Q97v`3m;?;djWUNccHWP9LHg>u_4*1%M54j zX>IH0h1YoQo7a&u-4cO^!~f>bt<&Am?A7e!H860!qo%;`4l_Z(VBF6Ssty*jORJ}4 ze9z3N*1zk(O{n*c6AueTAOF-L1Agi|Ncd3nhq<=vl8Z7E&($U;MUpae=j+2~ zmO6Q~JFVh`iFVNPccMptmzPt`$9#-D6cG88L=p*Gi3u{hDsqE>{-?t)sOQ6e{rhQs zCtuoU&+^A<0qMh88FYP|l&IZxMT@O0?;y{0JdV76fXp?@ak0Dk#DaX9tyzjPb&0K6 zON=_rU?d@tT472ifNN5z0#Y+iUEYbeqWa)hwsM?PO^P~(ow!-b7f^UdDwTZIV@@-` z577m3B`0QW{Y%7QH@qTSViNneZDCAaLbtlJyF1}1f!NlQY!x0(`l&6fsX+lyH0Sgf zVG^{=_(uA?!gWa4$lTH?M12mAnyKMtf4DI_lnjA+bE8(mlgS zg-ucY2XV-YgdZW~_sDvL%n&MFWPeH(3-_!kUW4r3yH9GMQd&(R^R zGL@gQ@Q~uHT8`hwI}oVHQLQnYQBz5X;-48hjEN;Z>eVeimc+4eB4%R1BK$ZeK3jxq zt6zzZB6eBw6^oJBl}apPQt!he5n_pQxrqwbv;C!LWcA|e@dL~&6WV>?<6_r131bk) zR%qX0SBe^sjf9e0vkAVz?6F*!Mb@gyF=Gyc5$N?^sDA&qbMim!Ylt-oNBh)3K+Vek zU;CPnv$K(xh=ZM@mF@rJG;@5Qebq*u?zmW9dg(ZhP#!>}^oc@7?m)nVifEz1ppfJS z<7|cXlOVkkx`%0L7di`}v^g$7sP}NH%Ebcr!nEm{Z&oT>YPwolmOGbYM|@AGdv1Gw z16}+C?`HYjOlPoI{K>XEkS8y=E%Jc9%v7VF43p1Y=?4EnhCMSs#*y* z(j6Uf_N)0jNRH)n2qUgJ!SKY76$#HDRHz?>gIzTNOL)Mg%jzNG`dZr_4f zx`)G1J5r&WJ=LT;R?~Mk0P$IZJA3&1Z_lGMFeaw66S7BVdRLvtA^B(bQaJ7%Ghy?- zxR;-W1?8&U!@}k9))!2e-^fVnr#HHY28%2Fq2AOsyUTXn+Y@(K?db}x?;Z8d*(jZE zQ)+Y;)|0t?S7@}IuI*_UzW!Q7o3oHB$AR6JBTwJXK%EEkcGqjmcDTo(L;DRuZP)LD z9Q*Fs*cYEW;F~8M@y(GZMDKm)?#yVOcFX+(V#4zwd-W(jf~~2l<$;`Mr~7(b!u``C zd*7J6_%0^_fjq~<hL%7zdm7f(rg6 z9DAXJXbd?~$*5)3RyLyIKh!x&+RPT`)k%{TB{DLTQ)LRmlDSJ*c2@9WI;Wu*n}bQV z1Hnk?Ty4e9^6M#$3tBQVr?Y^H?C$37>O$K;3+raEGT0VmK{mQ%I97DxlCv}pw)*<@ zg-ke9fXJ|m)z*-#F@y|>X?f-8(iDlpX+gJkFZuG$Tx;biTpQu1zrr)fer+@@E1ghG zJCuQ%E-seW#iL=Rl6*>{cOkYHP(5)hWI()fcm*S3|6|BNg@66GEF4V&$5pW93|~+$zbPT0$;|*lI!qdM32( zH1xIB2Z@{ebHgsyygw>eTe+ieqiN&W*~2MAwV`k$tJ}n4OL4xQ!A@Djhf3h(YHTQ% zLv7R-@H%HycD)BOWJ0-*|1@Uv`Zfk8)ij_D#9&^?=4)#B0Neb z&I-aVpkhlBN2?1{VI*wmp0w2d(3GiFfiGpA?~htYQpF98RnJ*RrwZ;sOBjbKTScMU zJ=G*evc5^Dddop%bmeB0ohuDf&*i|Zji}f4Rw&9wvY>rza1a zX7cuR1H`T@akPfyV4LT*bJ>dtWbJjgbJD7#Xh$xxIpth0lyuFs< zI;bR%a~j$BA_)B6>h{EpMnvGj`&SEKp~1PaFuI>nL}=7$Oe}2E5X9;=*$Aj8tRmm4 z1mc@jw$(UnG*cbp612M(r3q_S%idFOTdoVOu}xGf5nJl|t)0!dVF`-o0)Qp5m`;=_ z5oew(iN`Syy_B)GnE$Fm&9Tff@`5blj_f{>0Q_zj9x3FyfaF;X398`Ugt*Ih+0&gTo8_1@DXcWBt#S zJJ;X0zq|dK7U*!u1JMhc1&=3QJwUK#({C@1HJJ_3julx1H$CuOd`B7431NQV1JN5# zh;`>v2+rVi&&oRlPl$7e_W39Fhw+Yd^qum1s$Un+u-{;BMzljdruh#-8_p|}$rtXA z$sVOBlECpnAMMHNK0K&^iM~L%1l(uPY3`vbVqFDv6&pRk&fea(7OJf|B&}(~e8ec;f?SqH2gmLYm(RtI_6L4Yy`Hp zgC`sTM@aPj78%^W(fCwo{5=9HdSb{eG2ADU*k0&Cf&)~rWt1t7(xag>l_tcFc9 zwJKr74DqN9DeXT9ea&p$L~LXrTbE{;sA0t^g&|_T zE@tEk4$1GQhuOPKVE+IC_tgVWb+dkheFroo`4k(h@*%|SP1J*+z=^YKdH$P9_^ZeY zi01*ghc)Ow!wWIPoto}B<>GqG><>CK`^QEw3g*0w(+4;(M0}kqWX!6_)-@Hd|C%x3 zl}!F>J0B*?l%-75tvxQQLe?KEQfWsjg(m`G-PR?-`Jxyu2xarDrw>|@v!)!EsV zjJG!|UDhy407Jc*ZUr)N+#C&NwuQ7O?$@Nh#Vpf$9y+6gzB+rOIM%a4LrI>X#9dyq zTP0mI?WCwM$gY;;n+Gz=N;MCUTF_+1FI(;gX)JAJE4n!54w~81TzV%qhu3m>9H1PA zV=RB?;MwJJc||v;Xl9Xl8=Qq~Hi`nfZzdz5kf*umc;eb19kJ?=-Xn{Nkm11Q7iM-F z%|6&8cvRzP*{MqDH+$G0Z9BV#6m{q?N>h)`XVUyCNXwKQF3rP$ucL4JC1W-HltlY5 z$)%66gqns=oC3G4oU^cP z@BOFou)d4i^b}9KMca*ZK{>7dmx6uVEzTrvSFb|ROn3%kUJG4~QR=UHl{zb1l1Ok= zO5PrCvG!6o+jXZ()g)7K?dqex>4`sjQ&Ml%>sV5hp5MNmbIKU8b|}iULMfxOAj((` z4F#R9a>+FU-6Agf%c@#*C*>tFabc^?^0497*Dgp5O@fs})XB0q7T1sCM45+?WSb(# z*^;0V3J!YRb(9MzGDWO1Oyyx-=Ek`f>XUz@y$o(iZcXt6+~(OPfi|^0v9+a*GfsqC zoSO#O>}KeqY88}>+@Z+n7MQzQ8mx>jub{|n_tPbnrJl^|Vq3#j$N;%zVXyT`{6p@D zDkL`POa}0BjOL(x>(bdCQ+K~+_E%a@%H2H0F&Jr@al{3|b-{t?k+Khw$v9_J6ec&9 z{(3*Rbbnl9$1gMBruKxpHEJK&#PTvAG$n4veEtFZq3WYBkLJFN@ zU~Iv(0RtiygbNcPJO=gHYp~hr79V3^&G}9?L74$B0T^YOFgU3uLW7(*1yIVCpPX)s zrS!zu8|brEj%^}eMEgX18elC5#v0BIxLc1!OuX#n*T8k~3wKiNmREtM5QHHFK188J zE*y_r@D-5x2A`qG&%z8{ATNR!^dqo;`S6m;vn3bOMSXt<5ta%f$cFl+i!)OPLpxH` zC~(mhFoP^EXTwG7_{jGa0XwM&ILsU=ltxgn`xk1zo9d+;?l%&l|{ZFWR9$Rt3jFqLV6Oc+CJEBsx+1{AZH3~ zt>fo?Ir)cJEbV~IlVeViWGv<^29>d3h&jJ&v0a6HST2BU?D++O#V&v#&QZ%0>H+tWOR6X{3kkqv z;;I{MAWM#9`-RBpfa$=huW@5cGjDGe_@`ww<2N?Sn((|fO&?t+B$<`kLOP^rH3f$( zAY^WxPtTXA7c&VR1|j$hc}iMsIiTg@0Vo;kx^kSxINg($fwg$>V_Pk2xdLM~S-~Al zXt|A{dpgRm6^W{(t7a-0mYUl7Mf?01mUBb}n*I5#CO~|MKY%=^FWl#52trx2EKsa% z+Sx;GZf83sVm*Fu|DHWRj8b?>Xik-1{mPt|=trm8t{E9^LzE%`HI){-?fLO_3- zQEA;-aZ$RS0wgbwMJd<^Oe>(`hHdEmhRpcu^Day3^UMh6(=lrzG}9ouZcI1{tDj*2 z_B46KKoG-?SZh(tRN{AnxLp9v9`l0}?u3gS$-18W_X!Mhw!wU+E+~V_6fW6z+r-CL z@aHb&(K$b*!VCIat3xDr-B|J*toXbpBGopvOMVsJ88>9-M4-J}ei!~3Fywm^=+{i( zjz@kx{+SD8VT(KK0g@{q*3gnrNLUDQh&1G@W^oACpuY(0TpBlA_+1GF{uv+?>#qgs z`hMzc*7a&Y`Q+SD0P>c%Aia^j{)aqr!}C+^ipX7L_n;pG3&jItaV>a54u2B06BDUi z?K-e`z}J~DL?5kw^)toZhCkwo(lQM>*8L&p1RLfKVumGynk&Q4X_q zF0ne=W|8U)w)7*NV8|9HFruCC$977Kp{rtiw;`%o2l~afSS< zML6pN@4nn_#9vspS;2T1w14dS(pD?jyk$=ISVMQ>`=d6TTYR4zL~zIY7`7|IK2k;8 z+=mN1n{?|be=jhFv$WqA5l@EpBjzhx&|DyC6`?xEuj3z;684YhQoMkK8LOP{Tc$I! z2)Us&E-vfrCDjUPX=?N3qvXKRvPvndA~$I^Gc+PccOoI1MN3pEcd| zO>;tip@a>)N@vNzyfr;ACa%L0_hfH8oBcAnyz4hlWGW~goBHx`@J_v>H^m_6s%Ed= zK7|nw$QR#5f&+?05Neh;Tk9xn;dY7Wt7xme7H2}oeC9hpgwwBST{~n(g}Dj3->ILU zrbd5rm2#dy*7sA1pMK(fzcPrwVTP}4$9sCnZal$hg9nd{WBZcrlDI9&tO)dXrE!mS zk#F%On<>>0pB}>B8;Lan$&smWj;73F8x=jRGM6X{_`qfp+dLH}p(X}F#>9SftCdOL zHqnwpCyVb%nibuT*4>l0hi=@9*fPg8Nfl#mAq8{~Iw8J=<6;T@JV1O%@OgAcz(6-t>IYQC1MelJbKcbNIMi2F%> zdxT1-G;)vmMEDD!nI<5M2Gw_b0Qa(0iP`FW6GfE5kM&AeQ>6k^e~{QPvQZxO^!Yz< zq(Yd_;^?C{QHQ5OlF5pn$$)Vp-vSq-CU%^6KKBB*89N0o=oZG1g-x3T=@)YAP^C5i zv7$7z7I0=!QqamOC?E%oSCb~8<$I*7@lifw!%plFAN=r*dGL+dLo;HpaO6zbXZ*}P zgU9E$u8cMtkqcQ>s=xkKZ>^}tBG8Dk1pu{@LvtV%eT!(>pF+&rbz0c{czdgJr4C8 z$lU3n1L+YS@}WZqsIg%m?17i|#MS)^^FZW+o836IBMK#8MoFkoRASO<8it1k82VPV zI7F9gHJz-%yT%L>&vj53kLv=ID|wMy>pvJfe!%jA6-7n5i=- zuGCd%yVFekB>&Pko6#ZP7|h;8%-TWIAnyTdW`xgykqPlplVD{43fW_V%rWURrwqDP z6|K(%DP{qg9%z$~HtLbixDsx{bNR+2XBy10gJqoYN8u#)QQxE9P&wxS;K37*v9()q zThj5bY>&d=Jukp~fw!48%C7I|#6W0q4OmfyWAwt2mNj4FXl*{yCMsvjX-j8#vlbmH zg6om%7p7#_DHK`}=#<_QIaI93M_S=bLuNdLlb4G_+?1bj*waZLOrIUubZSE*bx!uh zP7)wpBChaFrhB7KfB*HPwEb-D-k9Cw*j#1O;=ztXj+ofDuYSzdlHTa11KOt>a z8vENLi?-_n;TFidD)PmWEz4DG2z5h#n;Fzztuq7P^tfmWQu2WVgh<2TB_)maPq?V3 z8y{ZvqNI%QFDgBy*+!Z4PC(0yXg>Elfif{?&e)V)Md)CR)<_T4G*K9Vlx$XOtbgc% zfRV|{1D{9utQIBjdQYCCISt}M6QgB zTBwQF?5VtEC}K)2Szaq8PtTZ$P1~sEkIZps&L-8Qj$3umov$`hVRJifB*Kp zHw583P(pTOAR8Zf;CT3Wosq;J@Im%$S&^RmkY4CD!(xcCYOGuiThi%Uu97jC6uFH@ zZ5r3%#K${mcWgW#PR0;!Tof~xlu8zcZwjhP^Wzv=U6OTXaDzwpNX+MC7VyYNa9pOO zhv(zmZ;Y)tKh&VP;&y$!l1r>YS4GlpO8`>}ulH~oajMX=R#adVOQ0tbnyHF}MICdG$oJ3}!TuFTwKyzaIHXur^s@*jc zHx(P@Bt7zwwy!K~)g=)IwqTY090Op4Y-JyDX7 zo-0h9X%US6+aA4GNqj5tr&*HDR$p53H5ey6)4W0Ok@FgFxdTAqm4W<#9-aeA0>ugP z`UHyVKP9Jd%kjE{szd%u%y!FI%v(E1cLyWsyAveyiu!icx{vAw_HW2_oTdxz2byl*chCA0`CGuVLGG666|>iG@D=6#)^`o5cLe$q)bWmMYIKktG4_D@ z6W~rjJNCYEr=rU5wuV)^s7XkGaY;*2%kWlw}XRm^Ck7c)9`W z+WZopUmNuy_y_ER08FhD&6^kcpx0wv6xRZ+ zXB1W1et|bCn$VKJ03n1}YT${YNW?-6G>FlNR>~0Qx#JXmCpMO|2I~bOmiI)6&LS8{yAih=fyXo3Zx`1Q+{hBn>nQOV-9PGG23YDpo$K-N;9G;*G5Q6 zkv!tZ+E|hltt|HN@RwPd>$N^I%4^~=LIX|gEi}@i!O*i{$+5y(ja1cnbiL?wBiQ+( zGi3%QLAcnNq;c^vamo4+sk*Z0rm}}?egPFBFW~?qS4yEzzgKT0X~)*TY((Z+7Y{A~ z_)&h6b7MreAb=8a&|YzWp8~Qd#BRMP@j!|JI7bmq<;a~nMWa3rLa3F9KUs9|1I7h- zTlfxpqVZ6!5de0%=-{5idTxTy{(*$xbdmYD9prwk!{D#-Q9-_8i+hIloL&?oeQXBU zkP1P%3Q;`6Zd1QLW_&zg5#j90(gX1Zj5)ND_6cbbC|+s0T;}2)OW(cOv$zJrpSiy}~Fyq=K*2Wg~?J zqT&iv(Dl+q;bCWFs$ojQk_yBZ!^HFW6T-?<$T9{!W(X<;$(pJNO`26mmP5e?)ob`Z z`Ci)w5uvH`sNr(B+DRswy0gPAxDVpM8o1-gmR7MxXf!Qi7i5GjVwfZ+8@T6KT`MI6 zJElO7KLDa@JEqJR(-OcqVRoK#}Y|hcN z<}0N}CgrvPDOw3T9$mvXdxxH{PQ|<0A(I8NSpg^O&AAz#E4cpgND%pOMtOlSuN~%J zozNPeI<(E~?9wq<_pTk1_NyrLucqI@Jasaz+zcme#|}Y>Y=>o&mQ{k$R?sSahikp! zo@{y0P07Zx$@GGB)H?+b#>f4n3&2kJdNZo}CBn3Udqhg%t7$_H4uP@u)x|vO?I@2dm!yI#69BvI#65#<`6!3w0gh zxh-!?jdCP=MtwCHZt6Qq+Q?!K)5uruNm#w#+EYHi+DWW1D^jGYdjso8{M4*Jt zK>F;6sL;0W!p@g!B2iAo(VuM+C50rhha8<|lojrujF;zQExNP{RsHiV-t8(P?_G5g zsB_@>UO#_J+pvbR5@i` z-|UVVFLc~tDn_3Q3NhtApvi{?t#)2@=vkeCk8B1?jidfNJ<2q zeab5&TIA0@;~fiYgzYW&9gPkA?tbm?i(4RjP;0~>vRCXLQ2~-K89;7gn5|^^PZFjN zsWUgR4xyCCklr~8k#Pb#84QCMY2+}l+9YzlY{miMx{_5w`2lA-sZIQOOs|Fkn1+rw zT}#&hJ-QKyu2q!4fiikYO!QV#SX7~PGfGq|N55MpQdF%|z?~==dakW!PG)f3i2Sz+ zy3yyK#qr&cdUKuPmLS1n@!>X%`k#UJ32>^RWz=or7dVW+&SqEwl zSTZ0SSwL2@fScZpQZP7mGQqaM&nw9t+9Ox~FIn7IzvB#bbdl>kDVHgj7tKx%`9={I zTPPoYpRUux`nSS9hXS;1K%^&r6i?{tinRnPNzxvDZHWIZ#RY+V%m znRKK!dBZqAmKuX!%C7VcY?{8auCeRMq?pJ$K*?Er zX&0s)^5(#iLwac!5VeQl05TItWglKOT4&WKiZP739)>nSs!ccBFVg_xOR{O#s2#jI z$>P?i9l3eLS)9ry2x*j2Sv#3A81u&Ao?Rwjj#M@dS4ub?fO&GJtne^|FL$(CJ#D9~>vyhv}#fqeg1G%52#__d}Mw;i^c29M|7hUHXhh zp{mgC(TQN47&IJ^%eO7a+d$b{TpH(sI^Bcov9FXrA`Ovpxi))d51P6@+Pni+$Z;Q> zctv?>Tw1KuV)iHI!;hvwq5{;k&<8sg3zcsl(Xk8>-be(oRbnKC`TPa zuGJ|62gjwcOWyEuJo1Z=}jx<;ee-u zAqvS}i##^T%I%XIF;dPVUWd&omqJM1@k>j+=lG^NXfdSX4s=vfm?=(bN7y4Vl#=r} z)MSitr{`y?s841aL`=P{of|6S>J6OUIw+b#(!Y?-kQ1*!r~HF|ugb1{m8R z2=5)()pP;W#;Ep5-C4Fs*#?E~S8vO@U~}Tx`WhXmJ|%X5eUn@JJRPvSC|V1(b|NtD zU9RYE`trJvWR-{Yp@encnihy5hZDvCa3!QZ>j3-#bH z97h)9dPzVh(?up8QyEl!CZ>`8MPWM19oD#KsaNiyO_^j9?*5E4OSX+zzOOw*TOjm3`fJModRR3He6%n^VM=jF06A45 zTQrDxOjwK#RXBenE%_Mu=5ooBM7y?%Jj6?ew`s~Hg}t4c{{cJryZpDq?Cd6r3*POwn+4A%e;!i)z*@26 z@;s~_kGE(6qH)U0aKm<_m11f_@{A|`q+cyjTqTJ~-#Z^BFlie-yr<^}AcFaFX=x1} z61WQIwP%3nIZZYIi+a-YUh3I_CG4!~1L$o41lxj1*;7YF@>6p5gF1VuSjOS4?~T25 zf#w{)h*7Hg=N7Y!gV!`yZ#y@oQ}5jT9Y8b3l;)8y z3BnVlVx=S0G_J1Z*%8aKiFx^xYBrbUs2vK8*KejdsB4#=0=jDEvsO_&c&%x>R{rGA zqX~Mo3V7>DgQdIl-k;n2eH+3Gzq10`&)1x|r(_N8RRa@f+q_@oLo`<$Em-S$O^RC zwB9D08Hi@?cqeI%yHhd!D@GgaR@(xOw}5)6YfbTQwc<7pbs)9b!b_;KAFfIBQ&cM? zw3*WZ3t@j=H4Jw{a$YGiVnRE*nL0#Ux?xE4; zmHe-@mQg;goePPI$fdJ#X99>}Q(!h8*p`n@W%XfG4bk6hT;sOq0TC^HjuD0 znwI4&s)I2$+UxkWz#^L;@-(^d1~!82Vq6fKEYJquHar%-r1l)H85e${>qIt%-+e*0 z3Uwe}%vbw#uQlD&J8^NBZSb|$AZN|k1|K$PZb@Y>ysuT+i?%})JAo3LT^2q(8B{jI zeXQA@m!A!Mul1oVV)y8;?WvcZ6aVoAA2yq2K^Yd$VR<@^mGDf%KZy}w2I!aV~=)5iHv+djnn?4 zN-i&FEu(;c>2eDKZg%s@dYcwoyCu#cU18D_!DIzD*2bsEM&Hcmr}jbgxReuYbzodLIyn~&2sr2S3~rhrn#JxECAg-qp$HJjD_u39&o!&F1eN{F zoBtD_n2hbsXWizs;I+=J`3(XTUZ36dV2~vz2rL%J49hd%DW<2trkF&#L`(;`wa%h_ z;NA_Cclhit;pAamk8bVHu&LkMRBKAmU-xL#vUkIuqnMUC-s`_}Vjt)Z&Awz|W`2X4 zf3U@=0wE`wM3~3slV5WoOq~1tYlkiunaIvr$49LATB!8d(WJkBzL5OzxS1rk(6mC2r-YV!iEI2Ok{r&9hJI} z?FNpO!n;3^jiap{i75u?$L|_rA$@QdQayrS#11BV_L=Hrv%SKJzufp?hdgmw7;xtv z!@+FgythSI&&b#GkLBXHLR{DeJnHVPEaI!YEY48j+&}Kfm%aGcdypnwYQQeK&qZz> zI7=R(zd?d91JJ@s6 z-THC$ud(yyJX6f~2MhtHc-Fuv?p|R-00b2@a*{fNI>i85wF7Ps!m`UU zNvin8pegt7j_SF0_&`WzD*x=MfmPUL)jN!r2Yc`6ggWS-}VSg@#3@hxV)U^SAk{DB)=`>&lC>6sF2l zRp@ZSz!GE5K}4SU2OtJ*>}eBE)BVRH9l!n=iABZ|wG_1IiKrg+0ST{#nag60ZiD+q zS8^^X(t(}BfQ^*&@nh#nM#}bNhxHnE@#=Cj_FwC5o^ElffItRVZr$L29F-QRG=+Qb zfCbjo)Q0;-`UJQcjxjmCzq0{PZMnxFgrN!@y1SzWowYtW&lpI~!0Kay@VxP226I(G zf5my3SGnjcL}}%R-N$IWnK=XA0#N88V>v%Lf#FlB-dPHilH)fxAG}| zN~0R3yW!T6;Pu81j2OD);8M=~89Yz&SLS4}t!#n86L24hF-uW{mR1QExFfXzZ zRnhbi3%gfG#A~>@tr-?7-Gs8{cwXKg<$_$0KfrVCo|{dA`UA8mZA_g&SEH0Dos7rN z!0%KD?B`}!jUE%!8E5S!fVGX>Br+yX0j`)j)i`3;8@!4e8CkgYT1M_Us1Hmnp2lva zjSg%zqk%!l_QNfX`S$BAj@9)O+MxB%;VeVW@UwD}EHl^mD^afBQR*)Xjp`&GvTJ5Z zeVK)i+_JiT<1|?mRmnd5iXFCrg6D%+$g-uZ;<98%FpA%VSMMN-zzt~6<`IMusKRwn zJ1>0?k!}xNk-~KIlfnk07~%$_96>`djo^_uqZCBF0GuZxiTxArlJB;}yAL>GL;H;b z;U|=CvK!{~bL!^IJ_K`aV{G5B8;mPV^fAyOp$jh(I)$nA%=^Scr7sj6qTA#9MwV9L zxxFQ81M-yaTs7O;L?lkO-Va)3Y_);iH82sx96@#9`MDVcV0*9V)~PK_y0?(ggBehjg1*3=@K$e|)IXuh5+1b3 z0s)2m$Pkj0qG{*2b&5!?QqB|fi~!xC{o<9z(y0l~R6^iV?v z266RuT#H5_ggmkLbuOh`&*dxrx?~dX)D{s|LKy3_6O>+L9A8$ONCcEBN0$IJfyKw% zqQ;xyK4|s@VWgc*rfm{#m_mrK2<)K9JEI6E^C!#H5}B8nqTk^T(^crlU*VHJCW)hR zyb9BRd))4WG>?KPP|}M6E07IkwaGlvanfv@otkmE%E}6+LfA+>gxSo|>L$Zj)aoG7 z6v*Mw_XI@zt;FhL^}Qwa?nC40BL}+P$Pyyig+QMPC=nV&JbGYNvJ2OtOJFc-SG3>~g=7Zga z6n*>i78A*JDRj}N=7q<5FnZfv^M?2MIf>p-?fDP%lZgNb;2+oz+NsV9W|wckC$C7a zH>hnd%8qL%?&nqRke_2~^8;K=Uc@zQ+1e@oV`N{%@uv|j{vRJ#JF1b+CNlh5=Y+xL zH;1>M2H5vJFmFNa%KR@P>3gWQ!opABi$4+$G=~H(3L~i(4R%0)$IBz{<_#`+5Uh)EnJVT4MQAo+Xgi z1Kca*GC1>H>{Q-#NmN{USHD=kk6h)oS6)tUyzGNj3Gpk&1JtB_7$3)7MdbOGA zsq|{fDNW&l$`z*o9ed0%tm?GK_JQG~`ZUdHibYIzX1#Q)`uQ2}g4EnZ3Y$KyqqBMncc59Pw-m-kxDq21yf+o(*`~?{uVsghFDolz6KdYW^kJsM6OCLo z7$VFKmM9Ci1o-Uo>NXL}p_HJ}j3C^UtGlE&r)JgDjl&eR@?>Uuy7B88Fw2<-7Y#9N zh=H8_x9|S-VE?<|@bUHF^ZoYV`0;bo_tH?OtynN8?y#zu(z%*L^QLq3L<4PHGWzkP zZ`XpULD@s`Y43TbH`xtV$!ly7f;(GHhy&mAt_M;ktw@9h)oH@T%J+aiD%IHUgg{Y?zAVxF& z?0~+S>b=mGfWY*cD+Is-f@v0flkiFvI=tL^K|K z=FVGAZBV3{iD2c@{xeA$!cM7+jlVK;jC2qG*YD$tnb`$(%}o^!TlYJs zyf7$wE%lQRDS7?%L8v-xBjkfJ%Q~lVafFamFe^CDSrJ|gj zlew+Ue`82+%C7685&CFu({_gS_1OeEBMMob4K#Ted)!~C#VXMSqo#E_V8fM=gn5!; z3IFmlc?E&)`v|_i!)P=QAY7i&!{(oWAAeszHQdl%qs>1HZ440S!i{=%DYx#wu}8!o%q3I*At< zkDlKv<`tioK}{MGbe6FqJtm1eGNs$tq``74jao0-SvDCRB^Oz&FR5v-H&9xQHJw49 zr6ZIUGJLdVS)3|!E{p6Xd#`0iEI83%HAwVyI}R?EGfBG7t22UXZ!ywh)LXAo`Y&P2 zfz;XpEHh&4R#~bt*zyBh*`h#gfaUs}B(Fm(U6ePRPNXYI*HyRew69WPQmoa~Z9A~q zzGMNhT1;Fdr!r!!mYi4f%G0RVQYJ5DTDKV^Xgaqa^|+AKQ4$_p3@;V&Q`HB%uG3s6 zMYpy7K%Hb&n5WoZhT&dryrJ4`+qH`pT3)eclXR*~ZdzBaOqNKvyNau1m-Gd{-b?Qc zO~dHLW2N-isE)^u+O$@TWJ$oj6Ndf!5JMO?7lulP$WDJAhnd1Nez$>SA2 zGAwaO;)!_&EYueAN}RLF=N3F>mYI@!V?JR>_6EOG7tiMN%AG@%(J6YMvWT5?TjVT& zECCju%A-+u|9RR>LRIJ$I+rRVk;D_$DQJq)T)*Rf*<*P|8eueX*wI4HySY^g`?``T z*SmU2Fw6rq=duN)?jwu=TGN}%&P?yMXLWC1Zm>81L=)!@>FyQSolrW<^#L5Gj@*ZU zhPRwEg?XwABG)-dF?w4L>sF}=RjIOM&2%Xtcz z^{6+!e$k+Ns)ERUa#+pyhRF5a;>v`ogF1w+Sgga#e1K*xj*u}oWa1q#`NTE-^p|-> zW8LNJV<3t%jrlW+oZnYv&{)1R?r{oAwT3xn?9>K$b5O1;!UB2jtM7|g6RqUy_V4xn zoE7HO+p3;v1PPBX#OMG_e8_jJrgo8waG9(8AE#P3Zv@PNsgGY*K~Dcu@PVWPyEj(q z&B4MU25XXQ`a!YleF*oC1;6{a{Fb1y`*PkrV}4h1*}a88SGfF6GkFfe5Et&mVxik= zpj%@;H&KMz?#Z3b&h0C>RS2LABzqT9+PxoJfZwaHE4m#Iq!}oH;eMZ%LSHk!9wGKx z4B!qlV8ec2G`SuTcp3!QP9$Ir7y#LT|4X5tD!d&l_A5T58Q7!qGe7x_zVctTKsPWU z_g&FD8|#M{r`{_DI6>c)-a`C(+93aw(yafB;Vv747@WVt5a_=+j{d(fT*+A9!O)DD zf&RZ?+*naZ4oeJ~XZ88t+K?ZCE-#`u#av459|{^~{secFycgU;j zsE;3^rZhePYZ5b;RMz0F+0>b+JsYQWrh=bT9dhIcvLH`r0aa zR6d&oGgYr!%-2+{=M=6q8xgO$cnNyVI~S+cto6{jr%$PN->=CoJC8UlJV$JPsg0Pv z691(G-v+t?mvWKcO4*qbwNUU4tWvtlCVt9)5_T@*1_#fNM(&q?#S#qE*;s!GRMA18 zOt*J$OA~DGdq&=+s{@^NnM@FfqzhcqouK{aW9wPGRpS^s_l>7R)j$o`M0p)i3y}|_ zDh7*pSIl z!p?ReoLtkq`#<<&O`lg+^x1jNEy34H0zPZ*VEdr730W-FqE2S>5VByBwofX=Y|u%z z)Eh`nP9O91_yo$YfEHQ9Aw(n^_V0N_Z603EZ?SZg6(C(j!ZTiAoPucFyhz-FRNOnI zcZl7ES&v(qXTJUh&-qb9uOZZD%e%k#YhTR__ogjJ>38)lB(ZW9Ek_LUjU=%G)>3FS z%kNJHkU|?N`Zcb7Rv%~~ePfow;kpFlRIt}w9}PVz3O%lNq4wXl%e`?e%H9EuYDDv` z|JgGgvsGzU{i-_@|EfC>{YSpJ+c@dF5z81m=?j_ZJ1FZLSQ-C!>Uk^3$Zhh&duOt< z%4WgwF3^D!c!A=LGV272&=Bz7$ZHuwLeH zF9tK&8krt)Tz$X3?~wYmnj&xOPYeNILYzZL2SJ4*^%n| zv$DljCG$S>q`B#VsvEdhEc9dz5|5LuP9}2!Uf35D?lt;sU#?pDknK9|K(bXn;#Eu8 zR*8&fj?E;Ki+#9L7W0`APBrEwY6>tUvde_;|5af>HmR0yB{!xQ9GdX4re;f270#@8 z%N}h%|NRmJ9BzCaiCSI_E0uaE2@LN_20*RH$_rEU^UI%-*DqsSlE1Gbn|rMd;Ezsq zE>ZmJ0$Lc3N#>Mk{k?m^7icyg{qe|5OOZ%jFQVE~pEWFrTB%XBE-okJ6>gW_Aa=B; zum#gA6jVv!u&){6wI;qF&5o65PX{-n}Xpk9OnwKgF2 zI{Tl&UaXX7A^Q#X?C*p9zk@BS?_};`ETeB|W^VI8QMQ)nkpmQf_jbh2vzrLT4M--5 zkkoe%0Ypla@)LxCS$43}gV;%b!hdh9lBWIy_$EKRvS2RDoSMqaj(u_2-TA8vkd?2% z58BNAd|!s-a7w9a9y(|BjL2g>o2cGgd!)<@Y}qb(ptl4wI7ranEl!#se^IUuo6>4n zZad`G&$g_K7(Og-W_({O#g<*}Dfnf&&0l0e@d0Vw2sCO2!mW73nQ96t83)|f{L;}RzPF5X#+=+ zM3Wi{Sutfi2TL^AZt42*f3(PuhV}EPf2-Hd?=l1Je}CZrsa{O~Q@oUPY>|G8m*LI7 zE00xpKrHb6#$pmu3R-k+@juBy!i)}PMnst5p-%N`F-oQ|moUQMxa0~_OZO!C6}BSa z;i=qy!Ybwel~XuhNXZ)uOo!l_uEp7&Co?>&r#Tuw&o6YnfaH5lpscW)V_fWEu{cL| z!Zc#bigE0u_S$`%%TXEQ82*oT{}TKd)@womGbg9XyXv}}NTTRK)ikFbQ#YIQoGHRG zEqddb6M{{|`lv({(B)bJe)qL5mhCuf_mS6S>9rvO+FI=L=xA}#^zHD}@y*u1+z;p) zus2nBmiuL58&MckbsQb)I>%R?z;yg_nxMPa<8a0DBr1roN-q`ZHHUJ~isdK9qz=1a zmGVg>z>Y-RymPo)y}~;(*dJ=omBSoet{6l zl9L%(-K<*KDLG%&w@<6%tkCYYQ+;S5+!2PoePmGJmd{yp|LgAda~Ch7Fbbs}5$|pn z2&?y-Gvw99P}X27foN5A&IJf9AWVPnxX-nv#FI&cK8^7EsDOFyN2VdF0A%i(6xki& zl*(0_KGH{qXML!5wlO^GxW%vXRGy{HpMsKI#a08YRLT`+RCO%(=*Kh`v+fWEQWg5h z7D(0kyJ&-v+1D7`)#zXS!3T~aTU4gb$eNq?bW?V|i_Tzy^UdH=_WjNgG?CfXc9XBF z8}32)*oI(*U9BhKeKB>qy(*L8NVeX}!_qo0SMTNH@6x3X)Cy4c**8Bf>?0~z`_zPA zo!naY-d#Q57x^Jf*#j-Fh#UD4Z{^!Rj&5P@+ygA!BQV?qAD*f|c`|N&0#wW!qkleT z?`FHR#j~rd(F^Bbp)DF$>JocX7R=Bt7cj3$8JRbPj1)I@p1K)K?4dr!|lN1dJgzFOo3D-dR@x>$h>c_%!P4VreA=``Z z-hhi@z%2MrdwrxQp7F9aiVS{({U?GUo$bUB{kDcX;Qt4~1nlgr+=cWVjYVy(jQ%^z zoKg7Tu}>Gi05%!3$uM zk)$Ub82}TxX?e5}j~i3y?zdqI0Ft2)a*Bly>Vcn%MINrtZ_x`C>@8KCn~$>VY3+IRxt~^*2!!J~S3fT5Hp36s>F9L2qZwS(YSe zP560ES1|!QpC<`O9n+mW1e<#c$Z2)x$mG(>s6o4mbDns#a~qtifU-(p$#A6-trU^T z6ssO`z)JY`rh$ogFm_`8`f$ud| zrzsMJoc)%efWgq6U>#=4Z{kP!G3Gr}UpiIM2m1)$(;@-yhEfY*L{Dr7UJHetas-2o z&<3ichsgwpY64=#{`0aML`NTb3CJREwYia`)+Z9%$BhbXvxnoKDGt>|HSXz_tADxJ z4`DUh2z@syHF-M_qUn~|kkZ^@YqZ0vy;yHfyOEqM;BCQy7pvbLW66bUD|6x1m{W~K z+U$X!d{cN5o94`6>~0I3P|g~Cm<}rA@XupVB7xCzBUn`}F(gBKPFdowA@Z+QaiYa; z+1qDPmXL4v0c(65JShQ}79$0%&6$nkb7Hv{mbin|Sk2bhgu+xYYfIDWl=Vns?bljI zhxzzszr!dt1_hb;VNMOz^2{di^PEU3un-#$#5$fZ2)$!=}YHU6?L%`MJndLF8_2tLw+U?sRoTasXUowl3k z{6HnRDPe{KT!b%uM-De7xg~lB>0b>bhPykbm!6~p;uJXTb`K%v4&3wk!PfE~W##HsX?%|3L zdVz5UU zV)Sq1z}fit(YOZIfQZxAFni(teSks4uuE-;eF8AYAROBYB8+6lo)oDSl>U9BMO*^j zNIlcME7AAXGzr6fAtnF6N~-T8r}V79-HYlkz~cVz?nOx7&dJ%qSlPkYSk~6)|BV3& z)^dyT$fG~4+h?qi(!#>%VXsZjiEn;zVFq^nZALLcw8Upn)H+O&g(SsH_d7$g`Lx!1)yS)M*GSs!;FnJ<54^hg7Bky(-!=IjI~ijo?V z5;0{ZJUIvZ%AwUnC`^m97VUKL*C9V=Lj1}g%PM6fFWhAOb#zU;9Y(F$fJTwT*SC+y zsx$DKCMa!%*C4V)_t>3#&!@nTYSgAj1`h5e4efn=iZyFlRZlFMgC`<1x;g0P zwC=j6=k5ncD!1*G?@NI_XxnqJW*QuN>WJgY?5O;EGA=ouX5K51n5&jqdA?Y7TQ;Or z_as&Wu0msRc6U$*vsF5E?G0W^UqF+!T9Z{F=3TpWTOIM4N z29zxz66Nd8T=&6BtZkjAuBp)FxIujR3!cdho9YZe6qTixH+D&@x$&HwbxKA+aX z{ny6pe`nnP+jg=2&%lr{EsLb^n`H{Ic z?M-agOD>?Mpv1J=Z-}%S?fQm-1_uLRw*p?!w_92XBb*YBzAs*1vmC9xwZ7kg^8KQa zq`2#DQ3=uR)LQEGbrW%3`)|6R2?Pq7yhijc0Vzi4yANJ(?@hkcgFyCML{j>6W)VC2 z;5^Q~ESUDAk?0G~yQ%xKa>DUNmq)trEtA`QFB32n116?-zx=TzLT~*v8W^Bwk*%w- zI*%ru)m?||{tLJ$O($mg@QH^se>`iZw1{1LdP%8p)feUnxTaOb7@gi>Jt~VKLS>G5 zt_vb$A1%bRe5*;vkS+P+>V`Pc0y^0;N|?m_rIQbD`vS3++o1tqbC!U`I*PyU7Em*K z6HhhlNKG9&z3Whfv$i*rZAeYjRi*Jk#`#$zI$KhPsw(84y+k4B3Wu!bzQ_d846H*} zz1Imx;+WCQ9c&&Bf!}{F4j&7B_*udyoESN$lkxO+n>SYgjE;1Q!WIMnu#e593!xqc z8krCZ=;pO}fbXoEvI%Z4avgK0!jd#kPq??&; z&E)$`fFy1@3!t3%5O=`Cz{Q{C(~AjJKSId4Ls#)B!Fp$g@3t0KfOX$Cf&q~}gRo2s zl5$3oLBPoP2cMo%5}uF|A)HczQNYk(Q{h?=!?-3NE0W><|1tKCL6(I}x^Q)|%eHOX zwr$(C&93UQZChQoZL7=LWmnyrnKO6hoVZ_{FIKGBv3~7{=grJF^GQ`1#&*J8DVv~0 zT2E@GwE_ZU%SmZYhIj{wvcXgC=LNbPs-e5ONvkl8{r@Fn*69W1eEKbaasMCjD$9S1 zpRPQzAWGQI>4+V_n|59e8ltFZQ9vFVb#0Xj|m}Cq(xL;VL zfWo^#AtK97KmP7DK;9$&c{(X1qH&FLCWq7ch}ZmaB-eiDM-d}JU@Wy^Q$BZ$+x_Ti zMOMveTMaR7-WFYZ@fq$9e{U--0tS_7Zr~f6G1n_v`f0B1B;F1IdEu6_Dq}6+{Lx-Ibd#v98t1zokk+3^PTZyf>mTJHdg`{ z(;}m$-lNmBgd`i4mbJ)JR+mv@$AFz(z7A!3C}XJ>&9Uny3xd#UFJ}|RiST?cEeXs$ zF`>ejK08>#h;J~;&FUisl}m{0h&CC*TdSBAXG-LUgW4sI^>UKw7$H~{2JP%K|JdGv z^pHVz5uTPH_Qf;QjU=r&r}g*?4!C(C8W6JMIv3wV^OO<3pWhGbY;V9rIQD=y;7Pm) z(xhM>lsOD_GA+dtQ;j88y~tL$l_hd2vu(pP{d712Rn|Ulh6x0onUQ*&({6~?7+O{* zs)*_|7!w&BP$LHo!DNJ7yKc6R{Z#D0)Y!=X+K_>b= z5@n|lz22SMHp3NdgGV^z#XjG*F&;kPC;km+?hVXa#XW6Gs%ae7Z-JP2N;By)wkq5f z;e^n{3Q=p0(4w;_$ z2X+lyjbi!o1mV(Fc7#{xf40tW&9lSz-&Q&Jn=T{#-`3gK-p<*@(9Xq~{=ezb|I!oH zSzW0C0Ti%Z=S;RaE8CB9f~!7H2QWez26#ylSTJAAVFW8-2?AN&EO@%SXryb4=!Mo7 zxNvTFv!{<2uwBGfJUgCA$Qm8c&qfjjku*@-##7e?de<)6?`a3SFJsbxzvf~0BRo;X zdjSmI$(j}OGR2W9;hTG#X$KrrpLc|Ye{xHz7>WCNq)afz3F1xr}11`{6|qf~!iDIp<@ab2Rn7MW+swo5q2`iGjRHaHNRj=?(l6ve&6Z zPMfqHc}vqVEFI!^aKonmxlV=K-=v6U*qiu}K)#nk?pFtOc^}DOQF7CYPK&PQG!@mx zwNkEgSWFUQqX!B8pLS?*{|GWGu zy<@JvJuTmwYHw{jBFC_FsAew}?FklM>)pzKsP1&<>YwF`&g&s^@EaV0{~sW!7&@7o zx=7lY+5eY_eS-w`pCD;8H-FN11xPmnek$chSF94XC1@B~QbI1C?CE#_!IP4G8n6%e z#KCV*9(ZER2E1Wcj8u0vmPO#xoA3!`*v!zr3%%Uax%t!2gWKg`HHj z+4mh3^mTA`n!I7RE`Si`4iYE;M*=IGn3I_!@0fV+lMu58%5JvO zAS+s<#v+9HGf+f={?(%E1mr%yBDSl9!@rhiXY!)wD|Y4fnxEgFarklVnCMNzB$tDl zVn@-n57V7f+f8hsQPP~_WgRoi-Fb10lN!9g@%$lxr~@sdY!}iKgO$P}s>Ftsvoa(e z7xI!N#JMO@h7zH>u8^cemq=Z5di=(0UA-nog5DEqKGWS)w~14`;jn(84n)=}X?wKb zF_ge^F4oA{IqR^eDT9yqT}?vHshdb6POws7gq3!^1^IILl5=`FA;FtrfslK+(5+aw zG&e9MJd2hD+6OhE*0QXaY1mg;gQHG&Cge~-#LH`X9H!}e;XAivBzQ^C!C#T0rj((k z#)PAgs?v1V(G!8+JGV3wYf>eodFBMbO)da;q0ja}Kk#bwz(1tceWEVv3xB|#bb;dcjY$S zv`hR+bi(Wd*M(~&9QlBEKa|ETkTUNS{+fPYE7{!S;4MQP$pIi87>LcDSCj&qxWt(W!)^YU|%8*l45m~rZ#2W-TBTXO9{ler)ud35Z zUzN+Zis~PJRvl^+G)%N8$6jeFv$n$Bmr_PuW~frO>|+T{Zq2tj4rd1?PP>(5Xs`QWb4ZHi# zq$@vKzy@AN8EI(r0%J`OQ`C~$@=ekpqU+Ht5_N*&(bi$N7Cjo0?8#6h=m*wUwPf5S zYY*Gh^3^vRT*X@lf2!q~QQGmVAPuEl~B275b|%9b0}Kak~x;d&+vZmEyn^ zDwBc64LPF?;3bo>GnfdQhM;t@WIJdUZKaikZ{P38Q5L;tJA4ysBJ)?vwKlhn zblmgq(C7O`q4K)>cv=O@)Zb8N9 zyb^TuhQu=4#x2)zE@< z-&JkXX@|n?(A9tzt}M0($4<|bR+IMHH)T3~+3gaV?kr~N=mvI1y;0dNT`vD#UhMnX zPB~U{;Ojdwyg7vXO(vqG6g(pyuJ0?CYMYhhJ{Y7e6S^Asugl=d!0(rzFuf{;D+hk6 zw6Gf-JEz;w<5m9=l4V#q$Kf2D5OXnXRJFT0oiSnd{M4b zN<6!gzng=FIrN&}gAxCQdhAO5;;O*&`yBQj)`aJ_M<6}X&7bUu>;sjNE4|i{D}CpY?7i5L?0uP$t-acjt$iDj z!444`q1q9w95S0w;t{SM5RNEp5yo|rHhqr!*$zRgVYvGwn_`=A?g;Mv9T6S7TZ7)a zU4wL;aU5Xo$WOg*kqdwy`+CnX`!Jj0K4hEnJ_yrD@V(&?GeORS!45edKlx;Q*nHq_ z5TAAS?{@DZ=>zCV_@MMfd>DNoZ;An?gQ)}R2>OuvqCTuXus6*B*TIzmc7&auJ0d>J zKF~MS0NcUV0e6HQ$Q@B1b|3hgE`aag(*QgI|4)9AcZT<$H-!M>!MFi=1b#?<(RY@2 zn43m`^We+?JwngV9uXfHzw~F0cc`06fc0SQfIUJFWG;apv|r{k?lZ|v2f%yqdH^56 z|EIsmJL5a#O)0>9Fn6Fdq9>q-)(D|^f#kJ{cpS(WfwzZ>;L8d zF09!t2%v!PrvLes$zlmYDZM&A-=K^R1<&AEviLokSZ=W+KC+66&`IHp$T1v2eh3V{ zSNO-*AY+!!%iHnupa8`5S}Zmw$Wmgdhxkh$litB3OmJI4pXOF#&K2${(697z zkkh9=djsNxd=yBwmUs+_^)k7l26@t>8xah>PaCv#0{R+}y!mpEQC1;ctC^*r9TgRBE4$*#qd(iefnpSNS?u6DSUcTET z=!SHUv=?lRyzX_6yzcWJeA z?(*@wL;q)o_n{abH{e@D#=f22e-|VD2i^WHCN8ed|8V~k*6e}=P{L-)Tq~j7S}V6M zbR{>?5nOE|Y<{plMkz?ggb5U^p7W{GzXJJ|m6!{-*aci4Uz0sX>08n7tW@Kd9bhp(Bt~z#0)GQwF7yaYL!FwG9&>jLrBU zC%et^FcTtBhz3=?Y*{?bY(l5EMJQ`TUlw4$VB0obQYf=k3YG#vv#9=FE@f_^)lkFu zBASQsi;z-E1%e$Bp3Jr5$gB=!ovJaTXujsd>P#5K72K6_PNOZH4*s0agC_GxNJ+KO zL-8bn$^u)m>BG!gxLH;Hz$fb%gzbKV;+N zJ}zdcQk;^*35137>|L(t*0i8v&{KKZZ< z2;du@Emd5GoZ*QsNuNif1)&bbi`E9rYvZ+5E~z0$UNOBK0QJFnxTMxJ(S6J6d-%ugcoROKERzszH z$gMUAxi%;k7=0Orw8u6|m1Pah6i;$h#4zNcdDj6!hZV)=pxHDSYwTQO<0X=Z!H+5r zFyH3yalVWK7+(efr&k~|Zf|$?|EvuHErm0M-}o7P8_e(RHbC}H=JZzfc9!)2L$dr| z#^67+;eYIhDL25YbLN|(TN|&0w%l+ve?hg zorv}g@Wt#2yzz${;@!LYvi{bI9^2RJhZlOp?AdfNa;$8qC~iCD-wa@fF$`_ko_#0l z*qd*TG4Xjxh8m_L@kl`lVH;K|q((tVVrzC|IN~)dm8|K=qw03ml+H@O)tX@|ugXX% zFVtFo>ASir59FD0)l6D0QfO0|Eq14nI-{Lamu#rPHZuL1_&H87N*6RwRVal*E_)kK zZW|S3R-{>YXR+~Bol_vH$lRIc80y%8(S=`%MYfA$^ikq9$9CDG+9!GmHglSm3M-wh z*o!IW!GH1Gyxlv}iTnAuHNyWXxZ@1~P3|{TzYZ6azZR+elDh^Y_Q&u5@nxc>pf7z0 zM0a_3wcWXnQEJeJfuLD{8d6OzdZ$YYVm)HXGMw&bo@{i8eF5Pa$qMIZ@((&r=O2Kc zj0PYzUbOaiLRHH?yfH0ZpR45BE5D(qMFY6*z&pouf_j+k`!*)I0d#lp&*XP_oijc_ z=ab=Q{G3WJ&#?b|)K{NmTmQj(kbWQczdLFbCqp+=C+B~}`mS*k|G|2QUO!jZZ=J0- zYd(Y3Q$&H~!`eyH2x>_|Sw0--Jpb@ZN{a}B)`gi2bZ%#U8hHRW2#gO83@0?C67tgs zouhj6M4)N!iEfWr*hWthl5Df_7pXy_MFzyX|~i=(_nS_n)z-<->sZ{Kg{i8w=WhBlemBMXGBY0mmk~AhIL23iCI|H3B0G>1_LdXsI zmit{kA+h#4P9CT&m>Qmr=i7j+++^72A~Fc3iC14il!uG2T_g)j7J=?WgqVvFhltWW zm;4Mq5wx*nTw?5J*lb*uviFe=LaV+?LXJ3Oj7Cc|%IsBEO8{Ssb+wKdEdJ$g(3|M%ay< zk^#?Dh&=ex1*rtZoaf*Vj|0!6SSR#|eP~dnx$kyW%>_x%*XOgONXLD-4F34NqGEA5 ze}~^9&$@b%&UgJ;ik{5AixW;9T_RCfa>2_v;miYTYEZ$@`8;d>hV!qP=AyEy54Kt( zt*DB8J{RJ-vnZOQsRD4d+%%w-sra3vhVZ5CQ_;qUGq>35sG!D#Wb|x#lwB$I*=mYe zxNsz)OEwXWNDD$bk71X(jlUd*KL$hEFu=_3>fzM+RvKH~-fcx(h)r$ze;LhA(;Qin~tUs0HSYEV#r^lURMz zALQEktW-zWmvH_@8Nn0%XgY{F;pici4zeDIdPp?`6aDUc-u+K|sCy6q;XPFk*=NLi zjc3Srm1oROy3K%G=$-)f5dHqler*8t-U%fp+jHsv&mus$C?A6J z&C0Yw{`+fK#opS~?tdiUSF*PlAziY|<+xqnI~L?;|Ks83_T3pMFH|lCnS9UT@t*da32oeK z?eX^m-9@=t>p`c^ai)OQLnhCtichTaz-)|B><*nqxHLIlHZIt0^glr*DlB!+bR zpEArlC~1b>qzn^2+62Qs;s&uVHN8A{yn!5dzJXvz5WtW};lPqd;=q(gBf!y<8^CCH z$Uib)$^!=8Weg%;+IyMqpaW5lQh_TcYeDBHYr*IkdTtK1VUx|~=VsCAQ`q`5McMK7 z=>KdSepj5p9d9|+{569%EcKv0=4!1u9%lJDp)n>hA6wpsp3O=FyVPPlgv5*mJoh&# zU6Rxovf_jt>2&K6OKe!O)FOi4NaUE-IRgUwh69!jX>N_=Nveb?C7lTti@Gexk`{Y$ zJ8#@1Le3^oN(IaDOv##FbaF|BES(7%D`>pnrf8~Bq_Bdpt}V$$hSaq|VVtNji$xYQ zj&w4@6zdL)Yf^PYMkZZ39dklrDg&AfRlC6wvuV+DL1wO^tRf?TUrWp=j4w<{lDj1% zQlp7+L6KQixg$PppE#fKi*DFIq@~GZ9qX0;>ZP;N-UOPv-4-_Z1H>EuFdB{i_~d@y zlRb5HO=}`K>q09q=h?LVFDk6@$IaBmFPpaCuI&A8?Md$J!{CoRf)si>Gv6&8#XKvj zL%w!y)FZZElrnD^GaWCtAz{nMli1iAC3A8_HNofkaytUeN33~Mk3Mg8vR!ESK7S7tj(D+En$gb~#15C=VF zzzrQlI0|r-amYqkMqoy0#AA$OjdO^n>wDvOC7g;l&^T$}G6(iF_BD<)_B0M9oOOCh zY|qyY<`kOsDE>6<9DN3s#?rO7q-)bJq-XiP#v#(0w6>1qxKrm;bFpy>>Ek2cZ>{mJ z^>IT)gc*r2R&W$sP{~nGQ%qA0qa33gqaH*-M?nr18A&-R&M7sa;tr7xnGT^2sSY*m zgOzNLp$EC02*c_PQ_ub;q1QbW+SwVRjea1 zB)tBUAMXRK+htV$1!$kostD9a$*LH%vS?AVyf$T?K=eu4G6@MuDWizx{CodGQFBGC z?fm+~Ru1kw*8`TN?);yJfF|Gh$MfcSuOi&p;CVPH?xGb*Zko#oJ^E_(b;T}0t=uL* z-BdOLTLt?hHj>LUyaYF$^}1~mTAIs{Z5msVb;&N#bxO-Zuga!{dA-?2mdE9p0$*Ola&TLtsdN?w*#%bsvCZdx9eHOp+gW`q+> z>_9v>1S=jF#FP0;;zh3$LQq~Dl0{DrnX;!@X$!!t_$)6B0v0a}q7Yszat2QbA<(yCo`XN zYTrP5VS<6WfP8~`MiW8=q=oEjmWCWm-E{Oq&94Q1s*hRa+8@}Qqlp0aSzH?gBbDc-gYX63vc3vNm@e$OGxsk zq~!d31NbWu4+Osl(B~ajZ#)e-R`JeA59gDP2<+* zOHv4EPYB2#up5{Izj>Bc92e{|QJG+TS&W0MW^yhfX>RA>f>O_bqs{UUjtEi+j73Zr zwLrtriVKD#mIUd%Y4sS=OEC)KjwB9IheVn7Wn(#~mgdrgXaB_G8kM9*Wj&o2_{J@Y zt2>c>@3)Srx7fuec$~|Zh>{sx?`ik{y|`gnWA=e)1TPSRaazUChH^21c0Tj0Jb2Y^ z@AKoVg`eG}jv;A#a%XPSGkzLojE(+ST9F|xhPuS6I6V?cn+1!8rYYB~NCG+*TsdWE zAifF)T&pnsjLJZQbHaJsl*yQ~aMfVn(&WRcU!>FjU4OTvSz6 z4Z;?gy?Y+L*eGLo$bu` zfw}_>wo0HJwB59%!dgn|98U9ixm9mXxFo$d0(#Na6@R9&?t;Z=IeZDqHlHe=^liQ8 zh(SXgx-<+XqeOf1hd#_vh9!d ztCgpTQ!O3KI68v_x$!1%E$v3k+B}==%)q>w-zvQ=s(OV1>M-;{pSW<5=VqSOV6v@j z`du@*3+8FvTotq;fTKSc;V(@&-Jp%_7k87it7iuynwtfl8IR}@rz!CyQh^8!>-xc+ zt09M;E{YA%**sq8MqeSJ6R>P_4oxB)Z9ke6tZ_UuGm?tV+{1VmwOc(|MSw~G`0t+R z6(V{jynRHw`noRm8*0SxUkpt`!)Z9(#2Tc(d$lOEnhop{B=-9NyJVFMT&6kzl^0ec z*qoF0a}k^EUEdbGdd;@qasDhKV4K%wv`5ApDarJ%71gUt)mvE&58^Y`M6mWQ1#13 zy5;uFdFd8~IXApUg%m6ZG7~+(^Ad*hI>~gwV_Fxe4|e*0UBL|n)%4tPV?K<|`5g2e z%{v*J+G0MAFD~joy1#XXFipvvoEWcq)zG=Ra>&7!beEu z=xOWpu+v`E(9zrCt9`L8wpNPMA?bgmauj{?#}D+1)9?Vl$ArcK$7wxd034xnf%q)< z7=^bWY+NdGl(kNMtH zAb%Yoycb{711?RA0|<^5=LfU+S6HF{!d%bc$qeqtHOFf!?uW7XS8SpG{s}$KhqCyW zr})?89KZYh_m{NzS52Y+%v{Iy39rMwp2Pj;>f9T$__aK47r*m;O6+znw--H^*N*GG zp40tj|D5;Q+?zD{S5D$ra$?W^v+>f+$Vx2#GLFB`!L#w!%}Cfm+*>Svx9fZT=}F_^ zN#o_oUGLm+e&LLJEMFXsFP`?Z_bxuoJ25~W?NjrM^-J_?`{iE<|CL&9IiK(Hxj+Bf zk@7us;=kg}|0&*ZRk2mZRz>k+tCf}@kPH-3f=Z4;&{MLt-l;2YLMzC(5Jae$rZI$! zHe_$qhHyK@hLb^ zb}YmhvB8OBC9yjCXs1jP7^k`7h4{ESf@A@@x3$JLk%}lj3 zjpf=?P_~rDeu{)i1zXF2JdpaG(5)`l4U20(O1X<^buB!a%CP$mZLE?qL+q4ep{F~K zwcJ#N$#o|(hnWjCm@ljpZIuaR&z`=5%P${X7Y-ebw%6RKkBFrocQvXH`Y9uEZYA&Y zxFhdQmKiX93L|3Y7<&IIF!e66#%?Zf(pxRhl#Ja-3#(a(OkY+;^o)h9%21ua)85j% zmfvUgk^8YE_X~L*KWil$JkW04`j#rxHcfkZ710i{@zA~`+qe(;OP-46&2;g+XobORJ+yIXr7O=DSGd##Uj5n4Ezmg- zLEqpE{^mU1I>`SqtQ6e>wcSdmFtl~nuLMzuK9{k5?N_u9*%H`&zJ6Fc3dasnAcr+A zN|&|vWXGp+kjn`LWs&EDxPWpL z8oSTTP|z^{iQvc$o;=}&;-1`u5+Qy@FitC}A{wxc;vRJfb5{*x#wb8dSY~jAldcq? z?#B?ibeIWc`K1`9TbYN6=0=rn?Qw5k}$wg z&LW8_+{VgTKBn2W@2nX^%=3ENL-g9OPDB5fOF$|rfxkv9#S?_RY)sZ=mras9BjOEs zznkoP$A~!e$`i;st-k>TimlpQnBQjd;ANCXKl0*}1h3>DO1RMhva`SdukX$P^-7f! z2k_MQsJjGZm}mmn*B8I;L=F~_7d|OVq_0LGRiq`tgdo0*-qum*)liMPKKVj#5b31;lGydW>oY?-*U0Kl% za!AB$DeMw7hXqhgQV8kI%#dIUNM_7XreIiOIf)b4F7GHw zjBxoc$a2TPJ(Btgd7^CokzH>II{~KSjX|<}Jp<~`fp>l+=gvKwpxwvNZUfgw-1q(t ze6bo#=~Bh(N}Ju3-Y)0=!kRrWz^&MSGiKi3&g}oIQI+k#ymnWW8D|txlus{rb8q(+ zcQ#Nl4Pz9eUR|Vy=>4+Hh=eo=l0bnnoZW!zbTjvUCgCX?hHV~=cX+(!s)F%-Bh=6o zh%X@eoT^*({1l~kWHi7Z2x^St%Ga*iopV3_?yK}`JfAz-0Ck6HG1S@=M^HUX+Rl=p zbFI#N(GfB11vXFf`&(J;5eJ=(?R}5T15jZ{vY7rp$1tD5_F;vzXpkWVZ75<_ue-B9 zQqvO;e41gYM*5E{CP-%w#>R%T(8}QT7@}0^=MyZdO`BaP6Z+~@^8cSKqLx;eD28Oc&rZ>{rC4htMj7AJh#6Z_g(&%sKwd~>vMh$G_ z7^*wxPwlI-FSSjnco!g3@wUWJjI2-i5mvX? z{fCFc@XEf1JTXz~ObY8r^@Q9ov^&3X*5b?>y<28UXcHdowV~2}`$;t;wspfcEchrX zN4}lciIrX<#yaxPr##a|c;1Xe9FD9J)*@d%nx)t}*E{NJ>Tp-I$sC4%FN0*fZLeKh zQ8)nR(JXuoog$Nfoy?ASg>q%0HU4^43zZACnnvD2^}eF!khA7MO&1Xq9F<>ujCNb3 z+D`rt7?Xy3FR%GNoK$wkd5m9F;X@Sl=2_9>(xsQIIF&!_8#0RS@iOuVRgUxB-c!4_ zisZJ+b-J2=5uG2=J@ex(dd#kR%pM)w9{Vfz`}YPC_^Ms`sy+Imw(vN|9hW!F<+%ep z*7fi|hP&W7#T1;uIRg}j^CzA{V8MC>CYVjR3UhfNA#H-jAyOtE5K1x}!Hkp^vQ3!F7Ui4S4*!1tsU7Pd z%^^bH)dTK^PXFEQ`g`WP_84Kf$993NWN!Ht0udAu-WL97w|+k#j1b{L;dE%htb+yn z0GzFyFO|G67=BkcGO?QIC)~y41$$5S+E(05t2@x~>eJj{OEfNe2h1gOv8wCXEDp>u z%yg56M3`MwQ>P{`+5F}W33)L-deE`6ol4giS~is`X)ycV{$6?}m@tAR?G($gDP_46 z2D%xhS*Y5cj1%$v0=|n(p)@rk4y<3jwO*u3#?1#w16vHnyJkI;kY2f$nfcZU&4D~m zKyXSlZ&>ix5yQO|(`36|SgRzNsOZd_F!zYXZ0X{1o~W$gN+C_rC`F4{tpR<@MS{Kd z4Jh7=0jxnV6IZ0Hjb@FtFFbA(A0zDj9{2XY@K1oZ-{7;$cW=w%&#=wST0-!=nk`h3WKYz#y1xVaWPU6_3TC+<^B83Q@Qj;`%+s4Hz=ny#Ge2kL*c3& z8!SGr(U?|o_=kLQX`vnDUn6bRT-lKWjOD*he`6PBhu7l;=sKd2Q!pR{%?=ft2&Omo z8f@hoLn3oW3t}u@TnoW6GcR5RD|L#ac#8}QL-4u)d8L+=Ll{<37*P?0q0V*l?aHOu zrmWD=QRU3o&v$@_)mLVuE!)SIRn%_CxZtV5Lco0YgZ`q4=yEEhK3~nNu7mv|Ux2<% z`w(_0Z=Q8kyx{=_eT1K8PGRHVaY=LRH4{zAM{Y=tcezXXL9wX{%HQjVSjHXx8XhN? z85CSraxs!LXK7x_h;^OqYD44QR^N}rMG}W-gKE$4=8Y82$TqvhYht97p|duK)L3e- zv|%oGpfQQV5Xauw;tV5(yot|V`=hE)Zy}_k=&p&YyoL@8O*wc|dnSN558&l?px<(;Ko?$xLdS~CB5z*y6NH-y0yY=vX0KskY8+g<^8RkYcyQ)$Sbm0C;z%RW$Hj+?yF@l{kZ4a zmJ9s!SXMj^SIz)K%!yW986djZC_A^nWt4t78X7Egn_%?ilnZ=^nC)4V6l#5>VMlJ| z^;GxXj^8%`()Oj?qg|{}%i6J+-v$oZ~AvroXN5z?;Vx5Z;^N)f+>t8x7j&qZu(CDd* zlQYcs^bR*H=m(tz$*-tQr<6TyS()B#tJ0TvKR~Vuwcm~SpKx~frN*45n|?s3 zHrmJROEDp$pv&~AD{qykZq zb9l)mri5+Fs5B9*E^WslZ6W$bK-k3{oqZkHpK>;Nw?#M@XC9{;a7H*GCXWeKzRGPP z$x`@YF;~{9C{^AuQs}u_;noYtqDKvthPmQk&H@itb@k048&Ppi%Y3`>K@L0J_bfCR zHVyU21Zu`MFPi5yT{ChXm(eUSJHr_o72ZaLV%+%-Q_IroNXcfn#vwRZ)jL>2$>!x} z?~-!P4s$lfW2eq+El8+AZ!#I%#n{)w(FoXeVY%3hGH%X`UH0(c;`c74=GufFIXIr% zR^b+OXO{uKY^Pj0Eg`ex3AIF-)gTx$VZk zIK-tG#xRCpiDzOjzYI zt_94B{zy||xVY&8>lOFgIqG)wGCvd#>t?nrJQgwprKyyGr*Y@^C8=^#AkRX0g0&f} zM)Wq6@;kDwHD!{V03Y!d*j8Ik!DIw7>KEp?gPZI;@S?B$9G1B1=-I=jFxckER1;js z(Io>M3p+l#kIVwlkNOwmArIf6)Zky z&@rWKRw2=%V>M;dM!sN9CTiPXMyQKe4!r!{Zb_Zn_=S00jVs{tYc7eMK=n^K%858t zyIX2>)@LOZZns{fNq^2e|4q&)TkN(o3dhl$#w1kAKxy8xr7}D%!+@QyRcRj7ZMD_0xW3h?quutd7bvQuh$xsFo=yTjB9Iw(2 zpH{6)c%$5@OaII*$P~4FZ>j(`9oF#gt`C&8=Xg#nkXMYqFeV%`z5fc z`#~-#xNv1F_IH@ZA;%#Ht8g$eAW*T6TddNt&D#{>Q zd)FkT6U02?^C_D9TM@7iyG$~LMVX$5N-94)4ygr}rHyHh!BMMo4Z}R!y0gi5*9jo6 zJ2xD~E`zyBUYx}Oi|!fJB+~<)+N@x?M|>@Vdgojn8WOp?F4|V;bxx33W&3jIUD)ex zna7;wzvy|iX;squwtQ-Ih7Pl0yPp1lvG0C0P$0olXA?(V@1Ef=g<^c`5&(f91r?Ib>>Y* zA8D55vGl~50+Dcvq?Cl?f<(X}#tx*=hA0ub^M~2_4t}$olBSY}FC>@8fHzd%lZ2~j zR&B{sEy>gQ9-Ia@B`Qh?zDgs68p&3b2>ygfYaFEG-%qYpK72#A?^-$f&bQK(VO7~l zw@xRC&cB^z#LqIHKbF6u7eBacR4VG?(Z*aBNUGB*&pR0Qo|N`QGZK=6g?X?WtocUi zcb~plp1<;wLGJ->lkQX_O}z8Q-X@&6*HKI(phPP;BV)H?_(Gr31b4*aMfeB1Ju-x^ zkg*H$%2jG*bExyBD1U@pS9MkL;NSdDE)F835c*@v>sc21(xd_{x8C=T&?)>ONqT@2 z^g)K~m9B>B#1OJ!R`46d&}PJI8#I%&q*21 zdhO+5?G=IVN#)O$QLzhD^& zDD@DQ0QpG?lqImb%^-&?bumLqP{0OpY?5y)k#ZKtUGj`Jso%Pmemq#6;)-}XTE(-u zlPOF->b;5JVKa)zF#|c?EY8&L{@Xi-T;`XoFBgBhV@>dlBn^o$=qPam5N9SDf#3wH zU{r)o1wyn%hlWgtC?0Dhf-YG3ZYb1 zDUr#C^mKe*6Mr@Cku4PgN|~^NA$}0;1*59-sZO`tkkd(L!23S%I106Z0Vyqdr4o#O z9wFN9YxDOnEdFwszsWYotkFmy?VWb_Pl~8OB489!6r|$2!N8fxD3G{mYWAs=4p+bS z!{6FJ+N}xQasSrjieKqA{^cvFjq5sFYK}N$OEU4Y%t=l40gsT1*pzq&<5Jg2x_#9u z8f<5n@dE!#Fp@4G@%1ZIMQ~JYAAYHQf4_(LZ{r=8;-5>AjnzoHoSjH3f|`_PZ}*b2 z;89$Mg6unvIpp<7q{gfh$*CtIIoIdg#t=7IWU6arN6MGME6(|6oYySBJox?8k@4!| zGt#HRZlNpVkHqjV4_GJx~r+`II4q>SL$%<*8<)8}Ph%d39|GDN%5?-QS%}G=-$B;|ZD) ze4lSYXzu|?oA1Lx(iah}>)i@~imlB+qmFLK%bY()_2tYgw5_OQ25ul`@CJA#M2Lk` z`#UQaz~E>`jh0Wg>g|Hu zVim#QO>BJaSA+@N(ETh}P=un9l$;8G`Ml3`+X%Ag~S+V2GzG#4q zXmqrpAm=PUdPXU`9Vo!+N0N zBZ*&wNb0wgwZBFFJTI-@uP;M2csu1T{OVmM(22g*|E7ch$`Yj72!opt_6RhXxCvS=;YZDGOa=%HW@M>?TQOuN+u$b3|*Wzzrt3-Zp3L3QWB5nibC& zLATjSWLE{D`=AZwiL*;vO=6qE*n?e7lA93rcneQkLR4z**#6@6_K~t4ye-uHaKG<( zT6pB8NrP>=!Fmc}*?9=&VGpA)rnerJ&mkYIPBv#RnDsY^KfPd9 z@x|%hK$)V+13#Q4YI@3$`+)3-xDl%s;|rB~TBux8n$?`@kosgYg&{dKa;cn8tTP6w zHG2JBEL;Jl3kt<|ZOXSlxxP1}9=6*MRo?2L#Y=qR5*%cRfiI3wEM#o%@Do$#ySnETc$r_(FN8jmwVuay@0Dm+aEAJ!?8l2KXl6a>DJSMs<~8> zZBmTlA4=R7UR{vWF< zvFnR*)q)Lz^+`bf26_gXbJ$Jhn}5LD($9Oh9yoKzbbb6N^6_isi-@upRQ!zz_srz? z!k==P57fHoy#4}T$&`JyX4#L-^I^MkosZO7b~vG4Vcn+`oJ8}-TEmjiVN$6;_~03+VtdoN)O)YLi-xtoUbRmr~i^xzx5gRM0R zu^k`0x5J#>8#yPfS6+I#8;v(u?*HgE<=I_h=6hzOWZI&=vs!|aqN_Yo8);2-%(PZ` zw;F9X8u43c+o*Y;{Y^CD=**?(KniS&7F;%|SjQSFaE|UY4I_>ZTIR&8a+>b*Y0iLG z=b7h5*lb@Yr^oW0jew3Yfiz8x6%!IfOT^f17#+=%kc#O>4A)H$=jDu`TCj<@^n=eV zN%9Iun6a5t7h^`i9(|3-wk)a(lf;O&tg1`@V2eKbD+ravD0(ibOXsoB7oSAKJ?a>d z`0M~kb&L=*p2$rE(mwP&*NAxB-O$R{*>{`8oZ`nd@)Qh6udo>`SKSo|ZZID2zFN7q zcUGAJlC4R4_>Zedw#jMk$!Y4gjsZvHCzLkO9tpf+j#E$AN7N^;rC-dqBxpNXOKAZb zNZW%QB)K0ZxSLt}@hPum)d{Rz20mZ{>dAPzSmE0t`$tFwk ze-)&`MqB}w5H_r?3#vvKSIp-YZ4FvGU>feX05`#;6|JO&EJ3)pqQ03kw}3awdgNvh zRnm{t8S302;BEURVciKWL4T;QRkoD1;zl7idCfIYw!DEDUa^2iQqC`}=T+7YHhW;^ zOu<^PLruZjm>)9-mGNZ&%XLZ02wx;7#HrAMRD8E)?1EW2QWpu|oAOMHY7M@QL9LgxMNzax57&DwI4e;9z# zAGa96|GBl6HE=dEH*pj*FmkqY^dM#W4`UaTpe2nX_>&Yxu_o(`qhqI_RMWCA+`UA| zmlBSE6e6$yp#?l#Hf|~*b`UM2TCpRQ2O8q*?@M`>5uvUOiZPS>Za0(t`fmRZq7Pn` zI9Pq^Kq(kD_5LM$l$ofls#)qE4rq*VD(XQEqicm?BUb1S( zFC#_?FG~T+rIu9JUIuWG@oS+$fbG$cxr#+3>zSk%W#ST`YWa$qAYGkG(e_LAOV5q8 z>)!1tqb|A@fA##SMU6Eyc!dp-T$ecA&WFL^9xe8LU9AF#$w`}Jj#E0vj@~5<@skmQ zJt1sD$NKGcSBqj_@m3Yyd4U6@q)RsAS*FY%_dfWw%*j&54aPdMcofF@l_7W`>w<8q zCxIk+rz00V73p@elVNaxB!F>1HH59<3oF03IXeBE6-oNzv-H^OY zD+;4$R^kirs4cs9<@ad0(L?- zg^2c+9i+&JsmaOy62Y}N4Q4cS(I6ap2|GRa_dzcie(sqw9k9Xdxn>#c_yx6HaEN6v zZP_#<*6(%OQP)mihe4?LTY^k+<&;cW`Sa(lP!Ce^fxF@SfR$EOYq|FB52e*9aV|{~^$aWU~ z6K+T7_#PB<^iQ%((A^Gu#GyP`=NZW?m&Q%THq0cd%l-W}G@FcYQ5t!w5I-BRWuANj zDG65YJNUC`=Rvd8K)JOLMKuJFgnqJd;@^f{#wrP#x$Itl#aPoq49FBCq4J~lf|}D% z+u&J5wgF3VN+q)~lYN*_UF^Z5umuY9P~Y4LI?PJQkI37|uh;uDM>#6t#1YuLV8x)) zZV@4mkYq)1%{3u83q#$tk<5E+xDql8U)XZ(c~o;;4$>!bMMmQtSsDFAN0?;tVyR>z z)YMaQBH2Q%;C7KVDA6%Z6plaM$mNk2WkAL9NOu0|r45nqsAUI0Ipf665xB^>*y5=q zqlf$Hd+BJ@j0vRZ9-P;}#}bw4Wj?`Q4viL&=oD6xF(3bxCH9GLGYI&R6oCK#O1%E} z7s^Fh!45|h@oR+7>*`_6AqjWb0-CB=pMxkCifuP|0TA=E>=nj^CPqFx@^-0pxh~{} zAjaRVvE#WDK~kX#fkq-Nmx2-9kHPo?{{|)+xLlKx_D^v=-dM}&ShF*|Y3sfI2G$3+ zgX}IR4pD?{azJIoFguW@E>c47p&hoMIxeBCatA_-n1Q5)REC=8+-T@3gWR*e<`JxD zr;B2gZ^N^4@N(L^SB-vx*8;z&wQ!!n$)#KMDO%X7_X$*W!kw&ghTUm%=hSxVas5iX z0KAr(xF3(W7cfdA+EjI!TQ_dlv#a$QcUv8Dhc3==bmd+(zX~iN$f1ZeA`r7i*LE0q zG*umG)}&S;nMYArHLPtwDRR4OmYQBULlrDD6A|AbcS-c@HbXi@q`qEc%MLZIufP+1 z5>7QX+sD@*r3Vl8z%AN1lcksU$kON=JS-_^nmCVOR$i#)wS0O zs%v!MdyV#kaoX5m31u-g-L3vMHmcfIFH>7BJ5AcnFyzfM#vWkj4lH7yo13c-rH49U zF4vO|UntTRRTzL7Os_NYE4jy<#`XuwIqY0ho!J<5V8$a(|u)gymHB9?k zlV!n3Szck1E8)Yjvf#rA2(+7G|5b6}uCW~5Rj)M2O#Lyc{rQ6uYi2?+{>m?URI|CE z-7ISaVK-Sj1yxh{x%GP;i44%s9qO9pj899Nn@F1bcwAVu3qSjt6C?={BOeUsTQF`MEm&I9S-vk#xF$coYvBq1rYDcX#h1fvisjYdIo#lKB!lDcT*6Q7}Qijh@=?ygnJka*94Q?K65E%iMr<|QPC#DqF^1RmpLI_ zJSrt5kF*Fd3-Bz{HJ!&VKf^?1Kl{93&SdK-;#{+uTLhdr5BNs9h;506Cp5BWj{n<} z6?Lbw+YoOw?b1=@=XR)O}r3jHoDpxw?m8X{c;~Zw}A|A-rqlV z4!vjjW<6Fsa#^n5_bbHne);!12K0||t-15fK&d_4!NWG+V9D_%%@%q#QKbv3%y7JDQ#7AEP%`B;!ceIT2qLj@ z?LhV38A^HPSkviAJfSP}6GzgO0t_QlidlIr%Xau^fqinuP|{s#QTP^wR; z)G@r3u6SWi(v!IFvPYJX^wdQ!al1m?TldoUg z?UM0@INGtW&qLwP5l`=k3hbh453_e>PyyK7zGur%+;F^rz<*p5Ne~q4Uc3EZ-Gp0% zq??jXxa36%fh&^RXPgftiluw;ig6$c>%%yOwF6Wh!Tuyv+~U+f3TKPKO=hrP)#@9Y zn=%i6vDCPQe{;(KFv?Gi3Hzc!y&^ijGHZ46A!=05nf-cheQ+Oe(A&kkbV0pW{<0r< z6yP`5AG}iCH^Ex35UlG+(0tDNe+U%h#rsF)e3Siz!15G}X3eu_Ee;tdpULj#)mV$_ zEC6?ST~2j=@ApNQ{0*vaYaO zihf0PD)7<~ZHQOV7#1i8k3_LgB|#{`#l34bA7U7xyq*$hyHv=1^pu}pM&!xapsIG> z&5=TeRfwP>Qz`-tRuK*|pXPrp4oH_7|3Zb$*C$lL66x1JRALG~wnuMFk|;tKP8iv@ zmU7HImIJcB#m-v@Ob?R(0^z&H9o;0tnb4d0&Qw?8ZkXF#xPcZGDGBLce9*H_sA$Bmz%<7 zVW4o6K@Z9WJ9uckA3c#P{`jc&FrpF@j+veww55ofD99}bNfI2Ls-E(w?C;L5NIH(0 z!RKILuyS0X#Lff>qNM(ZAf5k}DLhG`35SKDmym(mY_nUk$P}@16fL^!-mv)B z5n|%;ksLkYi&H~T1LVdME?7dSKP&?kO$C1c?q+esQA*Ss0~G_!S>B1xp$;c)`b-^N z6}>j6_4DcFrT+2bz(nKJz`_Dph$sf^1xrl86fMIuu`ESuvWJspD*df0Ix0QoaCUmc zk!VQCA~cOOrH$Fd`7oJEc(s05(FC-#RaJM&Af|Z=D3D?in+&9V3NX0F9_vf}R^YlN z!}Ek$oY+XUK4G^>ID`|}fTm(Aq%>Ey0dV+L;e81j8EB@2;$j6YL!B*Dtr0(ryYAh~xx@Kq9G67{A<2GCBWr5*Sg%^I>Uk`~{W3yL>|0}BmDDbg@i z3b<)rG*wa)lZ~qA9yFCqLN$@7`Q3*2;3_bf?s6Ai&a#pgOo@H^Y`;Sq@3RL=wwcIO zKuLk4a%O4hDk||+BEu!+EJ0YBY{2^yAa_0~)YLS)6-q<~0qnrsZD1RX*vf)rFw*5}e_=N$nyvZCk-^@w8RZ(CKdFCW2B|H&FRH#W1j9NedB%^y=B zjH#lns~DrLF0ZW+VI^-_v&o_~B9q97bWA2!(9|`q$H8n5Vy(?Q)X~({$kJ)8|B&e; z&TBY=w4Xog7D=>2Adyzam>+{mlA0h#Q^lamJ*Cr9?n!T6T0pj*l;5e>+}D$;hzz08 zQX?%HlAc6Ot82D2p{K8IwnSC-bhyS_4`j~jOI|J+BEa?mCo-Z}gL7EYAgwA(+D2CM z0@kc>>u5`^7m*#1u5_HJYD#FajO-a(_F2bnrn8oaJ3Gp3|xoik24HODgH_& z<~}1+S)8Q#5e;iOWBX@Fp}cwcnII_?qyk4bm@I`pK1#thYn~HmAR@7EYpGXTLrRym zLcLYDW(-rRdB$=**3!}n6_^G`6C0Xh_Z9k=$wKF64v%LotJ^3VpxyhX(>Rh*omdSF>5_3gKDRMY6&7c5@a7Jp`q|q`^J7e@jLVb$)=f34G= z-#0>khxdoVzLDi9l(fj2if6c)xbV3=`0ZM222`S9lC!m?S82(LIvBKYP)cTmsBAa1 zBOV%cE^%YaLTQ^N&QQ8FiC6hnp)b*rBGKvzPQnWh4wlpBnU}bu39UWJ9LQ8s)zCMD zM({r{vWDya%?<`$6Ng*5li?-iCelJpMS}>X?C#4t(K+X!;%SwfM>ph7Resfam1XO7 zyvX=TYCd8E+(c?(@Z@XZ?UsbO!j1ma@g1kpy2UTsqobuxmR*%`5sXQU;b<+I%j`BCDRtv$RXbDp z%WrQ;ZD9xwKL92Rd4KA@M9NMbI>Nrh(-EDHzQ6%GqH21;&`-Il@h|)`U}4xM@&>D2 zDS2Un28v4tb%A*@ev1qVm8DW*EyA+#wa^?-U9(Y&jtHd(rs4NR-V-R96HVoKJmmOr zc6H+sS;~=#bdSk$E7}E}*0y1Zm5L-*C)#o(|N1#zfNlst?7iTh#*3&#Tk~R zcVLkVFk4X18lo#Oim9xot)6cF=#s*|(4!|E${7m`pcZ|G7gPC8WNyh!c~;|FKfI5O zFxKf9ssZ&2V{w;hzvZHcqoy32n3Vi;`A2xEL!_sD8Zk@95C*7C#acK*0=K^L#Gi;} z-XjkBIau+Mu9AJoHLYFe(mo=`Fim=s2=VXX_f~%qIv@14V?>ulb@@s@vhqJdm}j>L zuVGtdZyPQ(dIy58v0+z6&=22%BM@tpTAJ@&i4JwVRz$Dz`=EVtaNaMds--~GQfVGi zd@*{yB;i9t+2Gsl@1-=It#ez3yIjLnaM21D02;k3T-VC5ZNV;kHtB{~LyonYmAa5N zcA7cryS8C3z+YN3KXEng?Movi#T?(WsuCI_;Wxr9w^BrNoBWv$fB++EVJNY3sPX<> zB)ZT=ev^TzqI4olJ+xJYAkAH5DdF7mNUC$FXow49$cX-~-F<*8SA-D&V*STz|MiM1 z?Y9Ku^BYAm8f9J@DmapDl{Am&Z?DYacPvX>Gn{tcU6h)&M+ym@>Hy<=4a+;+eJyKF zyk)_rV9Yym46D-hFvyRSig6gql6^)nhQtYvWG?RrDLwM-2&l&r?}ilfp!Ok}a>=2p zr5BU)3pUGtpk51Px@CJse>Q{)19t2qI4Xvy++8kjb@v3 z<>nF`BK{3S&^rXjqbe5`Nsr;WL?8@{)88=xc_u$@SD`95VPj|sp5LORy(oJhBj-gi zXzxqkrAT|rUcT`S!uJv}_LijXB;fk|ae5Pnj)ev+)8By@ycoGI4gb~G>l}((TJ44E z;IE)cE4Z$dc}zu;CR5e?0zQX+#xwXdtNaHu{f^1@o&qjcPDS%fPfI0yOcqE1f1|+; zj6*NtN>4Lz=S!mf85Sr$bVGj!;nE=fafa*{K{2Nd->NI3>vwT{3GrMcjVs<9PJYJ` zbS*s&UQ78@E2DfRC6O%zPTt`Vfx@~esmM@9J3;d8_UvRKYQR=N)=*5_fQlFO7be+k z4|%#gfDAFwZ5^2#+O6R|K#W7V9#Gt?^GQ`WRDRgI9@n?lSiJ!JaknjYUyen|q1) zYvW`G#ymj)_UPYfGVwV&o8yB*oa=UQ?Zz0OG2(aT7&jr=3@A{4Yf+tx^0~oy?PD() zTsMcg7n8mAMNAk13pl_el}ix%-yq%>$&#oTL`yr3_0|}Y&$QNA&9j?LCfbetIQxdf zZkyy+%98>b^Q7SugDUjHrE|#^wH?cOHsVj(jXQCV69+90FHAy-#M=)$97&0_Vjail zL5)jsgSHU8HAG4q9J7f=jq=P<#;iTqpCU|7G#Vo4IVE?YpMEdT3N|EkER7m-4iDoO zbn`&pSL6$5mp*2Yag0%?sF1=H*PtZ*Os(^SM5PGXQiZ4nRGBh;a4;6C^pKp1HOE-# z+&>31DG%C?eEo_NjmXNtNh-7E*trgi9Lh~#9~Lc(I-=abNOT;X^MztH+!4{v5MuY; zXxl>7M+5G1vKAFKE@5hwA3WOo^Eh@H_ZVOn^HYUfRm$ye4 zXsIpDPTaW_(c0Fa$Y$!ek@?I#!yZFk@aTG_}p|9 zid-1Ve~8t(;-C3sQhw?PW5*IJ8_E;rjA`f_$k7%J?*vB6LtSgom17ED3CSB3Ku}XW zVQ4;&ds;><=tXbV9WnPcIbrEI5`{U0LCUD1B~=Q@>6rS?%3zccu<|MEjn37SeuqZF zJ>U@3z{IPir6#{}z~M?`prR#f`NkStanE%J9+(uV(-RjkEgg$p3juczdxYr(Nwmsm z^uW$ofb6fKXk{%7uJf?X!_ZJKdC2dymimk|A+G0G9AJ_+|9;4ed{V?AVMj0hp&)mY z%XAd8>Mfr`<07iLrz0oM2ND%0gXrty=)!Sou3DbWZB|e{oVrz(xA&=tP6#7v+`E^t zAO#PoE1=Otdlsy0Kr+7$KtL(RxybF+Rpx2M6bmt_=78xTft&NGlQ1y~L|to3Lszyd ztprtU*UHa75=+nylPawZA-)lps(M0@RTWcCIF##6;gDsY)Fhy3Te}VGOK=*QDPkrV zDrt$z0Qo{z-v!0cS0fE%G?JepXle0h%7;0|8dxpOqAF|^_4k1R=%!cYN>Euj`EX16 z7zSVT@_vYaXo8d#SR(sKU7`jgL!(x)yX{MQOU`%l992CPG?F#;cXv{FWg8*Met*i~ z4(`-a+6Vhf6!&cDXQ&!qSwuEEwrpssC@U5^^BY=KtW&}&?6EddF)eiDRw8&NH(D+)fssP5fI390mH)`!yVmAt1 zOJs&L!`KZJ6r{&Qod64>RSvT+2nv@Kvu+rGtl^=qjMlaqO^RL_Z)U6*?or1B&L#(> zzHndidY%&#olRwG+k9#U3Uf;Xm}>DJsVE7|5TXl}L}8aL^*Gv%{zxYrjUn3=1;}fv zALi%^T^?4`=V1a6VgxN((a#VaVj1W)%4PmpMuCZ^sD{~YUqn&&Y#Sz5+OMk+5QuOy z#n7GEW?T8Xcnq6sJ%5(Msy58rXxb_-6@C#HmBqVSM^4aKE(< zMQw3~^%%#S2PJhg0Y*1-S^-am;5jEGn67qyJ zS*P}cVEk2UdH_U-&edSe4ur}5XUjP|{7jPQ3|HnPw3x!kQ%ZshVez$Q0!C;-iHVnv zloxN2CD5WBbdg1?C2zU%dyVLfGo7zj<+G#aeAY_E&zHs>T6h75Q3o}Vex#X$vT3U}bMonSe@5m&1c03B^X-I}-@2!92jZe0%yycy8A_eRn8iPJpuXUWF2NtRViB3I>d<)eGO8-qiA{Y?CcZo-GRqg#xRiX?4WX``hvj%~OolmlSCqHMw72>cMRMdq-xD8>z zZhc4fPGq3y7-=3nv#5kqAPt!v0XN5%e!lW+E2sh=ZjR-bT^(0=;gIiX%o^XRgJ(~M z*XL7LZBr9AQH1`5FdCB9I0T`I={=vsaQ9zTl^*pm9P>kpR*LbiyMtD!clVTxu*Z|z$5ROa~ z1n9y*O9RS)UyFOpzX@#pI{?1;n=m1_gsA;|w*xTskh)X_B~cm`w_P*nhZ^`9C!S!-l#A*?ryEHIa`_qGO=`V1Xltu>eWnB~DMYlutJ_g%i> z$q4k>wQg^Ctx0-g3?hbJ5WRXfYY?fv;q;xKW-|RCpx*IbgJK6@XxLVEhx(?RfFqm+ zyW##z>_c-DD?9#QAZ8=5>kvVU5n{sFd$b)e=)+|ewsZy%Q>ERg(dOJp`Y_#vK-2MZ@31ket?t-6*mAMF&jLPhy6ng2R{Jq4z1e1SdX3?aIvca0G*|o zIwqng4;rU8Nh|m(5ps9wnCy%9o;z7v|J3*F55HFX2&TlefT2Asp$8dkiPDv*6N3Dw z`4nzM@)naZo{hvh6i5x{(sG0{2*@|IYw7@TkekS&)?js=`dSk=7W^{R5pkqgI!?s< zCZu}l@4LP=Np#WBOUBv#>#<#sHEvPziZtXsO?a|e0Zn%)Is4E#)h|yD*BnEvNS#?* z`FuAcj>arRXT1HjY3n4oPN+-JQ}9U8G8Sc=);4=w#d0i2E%yFa4Dw!AjUTY(jE~m$s1*J3|FKLNTB0A|wo>{a)$cd=p0y5)TN% z&F*6Q*jND;#-ODMNa-W;&kU|Kz}WC0r$g8Zh;S9v_(q+XnxOScjGO+}sK_5-DBUqO ztrP%j5;U(!k=IY5j{$fJo_J2+x39Lu^_su0S1tM{wdd_>dDC=mf4Nt&N=p zjb+;6nGWQCJ!7$7vIIRw%U7K;U4E&Z!uE#vFO&UJP5Y&;1FY`?<$q+bv36BJ3s@7d znLNu3gj;fw&@g-+Z)cY27I%R{IZXih;=HXR_{xd#%XnE0`l79#y%)rwVc&qTrD2Dl z+G{R62}8_JJ3m2?2t1f0$c!hXu!s8{u?c`RLcDc|7KUG3x=f@~2X4y3P2W1~yCm0Y zQgULRbFlxN%_V0+v0*}U@UXlD=0AhIp zl~7ifoul6;twcIJIoNe{6_~t&cP)!KH!g;BakGJ}tb-JMdY!=jrF{oPEv&#x#fhd6 z)2d2s;JNTH-TSu7!(Ym@0fCh~A?jSI>^ER4w3?L6sy!w)$VN*;XanLf z5-bG|LlpT6&ghf;@=0jy>-26Nc-6*v2U*sML^oc0m#d< zztd6RhL=EgbEuyCg%qvQMbHySj5B5GtFD4`E1*7G3!f?$#%(tcW#llEdledEfYsjJ zY~CF~ef|v=f=dkHZ!%X-%AMxyig7zS;H}rIo2$vVO!~eTfL<72{5}2`B#H!=8i6T6 zRfOx|DH-nmr*9c~4$EmT5HHMDOpSE_yzqc6`Dg&t*`C~hD-VtEpPcA*4*ZcdIJON7 z((vNEJ~u&!D?Lx&@gQF-Vf}BH(UN0blV6X4f34dbiP424CrFa{kp*5!TIY|2ie?lM zn-cQ>DQJm?!sq7&>VkLWHRz5Caz`lZ^JXIc%f1F#TlyV2En)CM$qelMQ8GMLK2_s> z(YyTO7KQhx?fV!!WsI-gKOVmq#<^|kwkpZa+a7F%iY(VAxWpy@tP5>5)#wwJAQ}A1 zKay*SXM(UkvXru?$a(D0%b_}|4>F(iKws+~oW{n^r|7imN|np3ayjK11gV!> zpijem|Cd%UCRIQ}deZO&;g1)o{Pb+q$JUWF3d=KHH}Af=F;NzL_rHkmhQ5q=~;G z$ZCGA#?LS4lPoEtQ2y@<|1xD2tPBeICg%g#a;(@h|$$P}cyL zia1uf?HZ&k3oI#Lg8POuI(J$*Cd>volIn602!{bF;~;zflV#%I+tAT^Ed1{_zTlHE0FR!{gLljH!!rA9 z-9JprPWp5IQZITFZDokkz9B-XYRS^Z3RXt4RnO=baCOOf7rw_1kPu3GIWX z1i?m^ROY6CSY~n!=v~7_8waPRbq#gaCTUZ82Hu)h*EB9=*|U3wN9xSKMza!!iIAJwOtFM(z%CWs1A7oz#9Dr6Y*KiQ;CGc7f%i@D9+2M$jv<_}xO{ zOpzU_w(V4MsXMDeTVL73I-YQSW_hSfc`1Do#fDcPf{%P(IX4v_; zTSIw_-Nb+CdKlHS;dMdpD%Za4s9GZ%4vKJX<*BP}iilPl>PR#;SMnBCVNzP$)nrt? zQ!DUkMrI^7SNXT|QoPj&3J7URkCBK^^K7F-8fSR zTLwTkU{M~(%6EMBMD)~Ycc|@&|AKHl`~X7`{pfs{tq%qE82mWbM}xb9e7N{~Shtu2 zK!5HPZkY+-#68Gy4>YEBjWkdRhSwjgkN1+)F>(hzAGFzn{}>2+07;)Lu1W9(#hkEc z;O7mO-mO)~&l;F`(^nnqwnj1-d$~hx%%;_sxl?gZr8Ta)b9!Z|)fahVy$7l_-ngT^ zN7U($zJy%b`65wA!e!slBufDx_bAE1x%FuRL7&q#H>>1japf%ynVf}{GKO~QA7I_F zp_9+&_5{_dmBT{+%7~XRIx+=87Glx|&NWEB znJebv|Lkn?yfBHw+ZQF|1dYBYwsv=HS0g-LU7(w;YN&xo#%^abYwb7APiR|2!7tNd zvLlej3xR5(%L@>Mm*x~?P7ZcZ-=$4PZ@EFfx7(HxV+Y0)TVs?Pf}c30$y zV&th>iOLertha6rQ5tYA_zRV~^#?6Wom(kwdbUg4^4bZvX! zdF~v!xrh|X?1lKyv!<3grfi~bnPO12JI|QtQe3AY2|g;F!v_xp4gvxrujWWHh*5+L zJl1T=vCD<)r%_bP=E_l%7Y~$w>NwX9M8HI+#pW#hRZhg52N*q46o1QA8fcNG5K)`e z*EmMnq$pWeWgBW8DK8+dCQkG}uNt_4EUPOmtD^_&@XQ2*x5rZJ-ZU9xSPlkqkxwBg z2+6PF2C(8jlOy7$$@{|meyw55T@{Akfo*z0Ut-ZRK-&SwxWlt&+JQ>D=a!${gz9QX zc)sn@C+Nk=-Tybx^ugyIv4c?e0I`er7vgDB_?9j9iG=@G@BQd5s2^_Tt6=F}nL4ar zrpxhceg6liE4yDV+yO&_!iP!fw4TA@tCcmpU()o!O@8jHKiVCMHPLr^%6*YF#&`79 zab6Sn7a8|hui@-N-5SjY&NKXXh|fe^LG5dh&vabTU(SHHNtz|(#I%} zoX_7SPTAp;DpHH_Ft<^9$Bd>oG5VMB>zONa#h!e-I_&-@pq{i80>ZKf7J;tQbM*Oe zm=y%D1qA;vi&>5He;GR-4=&fy`kO^@=Jo)CQJqXlcx#Gx6Ziojygtd$$4&FuQ6f^Z;`xyN3J)tPao ztb8)^1Nq@SY5dQZDpn9Dx@zDJhi&~VS>DbJ|A~RnWttt?HfTM0hTjK%%JSAku`ZU$ z%~jJc$h2u7_*e@V3W?j9J(-hTfCz8VxxE8sD}o_-f6qMXtDHB&4=AU(Ac}q>w4zXf z%1&x})~mMX+{PU?%^%)Sr)nClSB4?Z7u)P-f6R@VQo&VQcd9%cewc1JW1|gV-0bey z0C7>#$j(<(g5|)5Gy?^bV>`ouX;A@M30jltBGGKuYX&^|dz%$HkZk#dO$aVkDOvy6 zwJf(roGcn-4{H9|j1>bQnP*EqI9Ga48u!x*vZ1E zeU^!~>s;6Wq*pVywGTp6-EAQSwINAybOJ`~TbY2NZVOr{g1$urnwoHtX$peqWlo8* z85M&E)scWuL`jz-)z#_N`$Y%ftVAIIg!}qM;bGFEz}oa&gDQnI+BBa1)5K8E;i%@Q z6}OG25Oz^twvi{WQ%OS`j1&4p!;vnvnG$1AiU7(9 zdFW~P7(+)NIu3B(0-HnpNE{EQ4U$8VS|Q>~5h4l<;E@|clntWBkv4{{0D9_M zuL1zoN+kC%xI`SC}C-LAGt z5jHIX)jf4B4S5yAYsw>Cn<%S6QO3npS=uqv z!q&TTqdCoHkadO}_Udc3mPR&Ds=o#Fc8FM!&!UF^QC4{bvVmKxqL*tv(!w;e4*klp zvf37G1>#y|7dTl5H?QFBZVV%Pa!>=o%IGvPzMd$sZVT}Ei@qks;-Vx@Cl#}UM`ysj z-1h?O7xT9tBtT^js|cYeZ^d8g0%;62u3%rNZ@7t3oCo4z2xb>8tU#wjHpwuVapQGsv<}iHn}cjF`s~_7d1JoK{}`*U)EZl~(1WFEo-sqx1I& z^N^o<=}XQu5=HX(ZwOrT0$63!yx{3MEi5l=CjmE4qd0Fz%*vF8vL>1L;3fHwJ&yNd z@TtEYm%^y#`(>P$B*?mCjGu(aIg7z%L%X{2(YWek&2wO5F;Eq1ji=f#^Ce<$WtTA zi!l!mnHT738vNE$ZUOvcK~oQyd|WcACej~%9Q&v|I9xrxNxlZVIG#y9l`wJCcNwaF zNOR*n5;8W?Uftavq!_u>xRI4_btxIFhi5OAS9m}RQu+;sU%Y{FDII0o4heIFdl-QP zM7PgRK|!Zjmx@usR`2IeMw*;zhHLMAQ>4Rg!>!-W-Ct9O6EM+lld|C2=`77mBE&wY zciWGFK79n4b-o0H9aM<{;>ENQ4Y}}Dj)1TFHYDFn*5a@e4*FQqChzFNYmH1&9mB$( zk%G=Sx$rYi3D*>{A7dJOBhIZ@em$KANe&s5q?XB?!4B)325<~~PM{V7L|qW^?QoPb zCp-i^j+9hLq;3S+p&d*wpq!Yobdr@NQa%mhaUn?#2{9=k21PhQ$tRoiTV;a4?yV0? zo#L}XNjOaUq&(=YlS%flIiY=?=IcdG2V6PPuaggU1v&AtP1t!zoObJ{LVAsXP#n1y zk7&_p%$lAZ>7&vf)DbxIo)SZ<^R)YBQgu^_FdFY1k+Mjo0md4ozn#!DYnmLe{6y}S zAW!@MDrTt%>4VZ&9|qcrs6Ek?7^Mm~PWQVB1uh5_yD`(ko8Gl=qNpueDC!E_9D+T{ z;lHo1a3`&C0J%Al3}yQ(o8DOG2nZKIaZ$M#`SX`$&@+Jb^w>HpO(30PE`TB0w>mhVH{O0W0`D=M6H#UAoLxdf@vXs@w^^IW8XqDH6w9g#R z&Hnzc{W~TatNRyX+FsC8|G{V16-s_HqMU3CC)@Jzl5&=k(&xWl<#Djz4HhIk>JVF} zT_apDqP(tpVmyh2oW})Xl%gp>>hZPtrrGu-9XRdI10mCpkasP?mFARcH`3l8`wS$ zSob?CmZ0MjPOg8Ll*PA>|3)VEYaSX;elC(XC1_4iB6fKXhdb%*Tgs_n@1dxk?@ zxn6z!#cK}S*y{iv9HFj1!mR7&UTm3$R;+JblJgAPeC6)$I=jL9W(1qpW%%fT6F0hY zjzhmiW)beHuyISP8O6MxJA3ZFH!$|$ zqP+lL5Z950yBr@x-I(xgrZ>=bYS>=6H`3pDhQZbQ={}dxfVqD1n^#62f$e9@3&|jm zQ)No4U~?qG$2K4#KRlsRr?V+;Hi6S;iBlq9q0t1`HbAvlg%hjrd+NsA&O4SrMLbwc zG@_$Bm|qyAUF!5NjApX#9PM1NFe;`Fw!^n6+vR3RnUkyTqDI5KIj$AS7_R*P8Qu-E3$Lx ze3ZaD{QD6I%5#E(a)OY8dz7*Gyn&8;n8P@RJ)T!MnS`Cfc0UNwdoOizzfiP$jCScS zc!Yv%wz1v>emO$F?BKLRD%5|bzXR1jg^X@%$oJIXd?=^U+VPlB)q?AmG8Zsv@S>DT z^KneJBGe74K=+dyeB}%R4iM3Q!wZg5j!}^i(Uv0@W)W7OPzf>LMRL8JdSO=)#^Y(_ zI(_x|Hvgf$Zn8ZUZvFAMH)1>^WG27ybOJHO>F+CiaL+-;m9P&SP+{^Qb&D*;oL`4g z;4qpVIa~V&_0wn?vjm}o?P;<)&l~1c77h~r?DY`` zf-rEq=Cs%6>kQVkzwiR(AYnQR#j?VI*f?Om(T%o6>TAp9$ye^@Xe@Jg(b!yd%OTxA zqT|4V0;SVNM?FDrY7HuTzPZ4O3*k#E>@;r^gba5RguG~OsGcPH4YnMetOASxfW!2% zin}6I#8!o==YAGGbI4;`wbfnaYxbjKgX5-xm|T($FZ{4bk77|hzSBPoE)ok4c2f^E z6NYD1=6WZtO0+MUVPL_|HZRtm<8jKU+@3Wbq>y% z23_8s*tU&{GqG)RV%twJv2EMV#J2ThV%xUOFID?()$Uuhbyxoh_c`6a(|uhD5DXCY z(=z@?BF@*!+fptsp5uUaLdnvwb_x%xNTLHIKIu7c&{w>3Y;m%$dPFj?WICQ|9FPNl zI{BUzsM87qU3X8g`oSn4Hp z;o@&#Y14v3{vQ;Z`NiJo)z=>==G&uhnFm_~6Ce+OhAL*ZR(X`DLekcR4~ds3rCJo* ztH?O^Yy*rp-3`|(#IgCsY?rMrILp!azOK@f@znrjR_tR3GMvwE{c=QNl-sPXiliy& zUQd>ggm(%qu3XQdJ-u(^a6G=Cj~^p?2>Rvh)u=DkG9nbl2K>rA9yOrcr9e?_)L1X zWR7pB9pY!9hT^lj|9X}InKgtBFAC1bxE`xa2%-lK8uwL`dk;S2lu4bx z&a=6Xy?!{FV$bQiFLpoTDT4vT@Y%NZ@{sw+O>*yASF+I zI5a%|n78&c;DMdkSmk#UTtj+ml-LGbC~=nYK~7mfVO++KI%N7+s>>zxh0Fifelk`$9Fl7}vHWG9k9HbikC{JyRYi zQduE59yX(3+eoE0qKQ#qwQDOZgTSerOw4RsSm?2&u@k6T;YG>iaSz3& zpOi=_&l|(G6JGmUpa)%_19iZ1szMl9u%QAv-gIQ z%83sVvs)H_Au~VIc+Va0>>*o^Jr>UIgDV4xN^t@v?~W4|npIma*^iJOE$q-N9VzPH zY1&Xd0Yx+koI%>ZO@!OYJ6!OGFTGa<9@pOEwLS2^&-y0Ly!o$AM!yM5d&wX70kf2` z+IC5@2s*VhqNLq%!UOq!1n!E(M;*m$X}Of%6JP=RRY7j#S19CHq0~l1LQ#**txbi< zrQQ(*-;eHR_(M@vQ>m@=`9-;7u9`&t&J5W_HKC_?d=ZgLozQ_fN{!4k+82w@q%=i{Z7pkSS zlv-2@PI9*UQGRbpu;gYhT)lJxYvTodPZ7)(ZO@}-m>l>@bfhGRn}^&fTG~+`|L!6h zQqQ!`(s4U*x6$uKSw6twhg4HHndP=EK*5*&JB^;@)LFxW>I+d%Bn=Z>WZhXy8TkNt zK(^dzzPNesYfI#|?2*9*c@oD=68yp$?m+o=KL(HEj*P+HBvde3gRBgE2^DU2seq=r z{Q|H|dCYxOLzcFI5ZkUVlsS;H>~z%F=3evBtu?6J#E6f807gDXq~|Nvrqa`P7={fP zW)E!VX?|j?CE{WKiI)0K2rc&qd z4M~(ajQ2-qXA-PYsC6sR!=9c(Bt^A&O4C91*k-{#kS*d`M+{DcI+ymUR2!E65`a-*g?u|St1$$q6x62fXwUQ}s?7+$ub?E--CzzSq?I4pf@ z{ZWIsHEC&7xtk;1h_~~GBByvN9^rpx=8JIGdE427c1WXwC7a_zfps9NenWx9&XN)( zd*2V2bbao~iS!SAAqn)mGE z1(SGiewHUf1m44QR>vCT<&FjMCvZK?&}mJX*m=XBm6_KuylO1U5CIb&{B8XBg>J^z z%3z$GH^a^G??^ZqEC! z(Kkv5P4B@oXyvBw$Yt~36g|*_ID}Xi4{nOkE!M()Eav!sbA<^`gZHSnGpOnQb=Wmu zz?@co%p0qxph~7g4c}>Il`A=++b}pe1bN2Md`@+Sl5s^XyfO$B!DN5XhKzQg%OP^WDg_6?L??dbC!U{KrI+7MMf&4Dx&!q8=%}{+_(spB`Mt>w)B+jBVp}q58~QE5@Z3{#YuQt~TPkU$DvZLE-tW z54^oc82=VRMn1@Bw)x;x%-0yu-qWs#y{g#+`p|a>_rz>eZuQzN*_$ApWG?f6U_K`K z(DGE;n-QI9uVB44_d*PvR2HHRF|_P zs_llhLZa>FSr_r z2fss8#Hg-A-P-)(-#1`&*R?sH>R%`2Z|>(%Fpbb9DTDTB>Zzd>UhL+2tP0?C>j3bQ zy)K0Aorv4rM&RKA|CX1G$R~$k?+0sreUV3|akGm1aPG&^tIyv$iDX0|I;4|u=$z?D zpb4r(qu<0htYgj^x&|@nS)_n&+mJsoQiRwyIKPIyvEJ)Co=-v4%m*u-%3sKjVInO^kf?UjBM6cHta(T zD=LcM*hYp`6a9I^zIFtXQz(@JCi&n`)3nph)Cokp50b+Nzs@$1 zpU|sFoWE*rn4Mg8H&MxHtZ=^156sip9nvq()3Cr=bzfNaV}${VS0{%qAL!G2EQ8EX z)b*+!_~=(!2Sr~D#Iu?{p4YSM@K4D1zdir@A6n8RzMx%(fOJw{K?sWirXmkh%aR{( z>{4GD6N^2j3$IV-!XHrcNCNe8uRSZ-uL?FbpLjfFU!i=ZUz2*%Uq&^jz?Ib3t#ghK zaO*_{KZUPX8^2&}GgPMf{Mx8w(hI{m-giGC?8 zS1|pv8tW+dC!Cqekg(DV7Rmhi0nQ&nMazeC4b1faPo-QbEkS z-?;2&eEy_^q*W zrEW;_kD80`>dLM(>uD`|j@1d11k#y!BPK68m~GichBJ1y`P@fs=tYmjydLcJmg3h= zYW3%|G3-OVfh?lPRas4O6Su;X(ZWX?#>sMebG`eAr5XC>*~N~gJ42>n)~Y>^ad6vwqJ@*F<5VdC^EXVLy2}YE+JYC z@pXBp>I#kOV`~ct=gxu96(#t8 z>uFX01Oxx_3fKf!qa+?v5CaolkB3UhIl z7!AA-w(mHxL-_gUjP)@JvbB;~CVi8E>Mu5gSuZg=B6;#2*au=eExo?L>A#4%_@6u> zh%#TU>H^8ZssR>6i8o3BNqYrqW5X`c%nJO|Ak1*A;C<(^Gd#l^rEq6Gym0-YpJ`o; zMNUNLFj9ZhfiQp z^$}&twFI$eNL@q;3jR`wog!bDa(*D&mU)MYo{UvFH{LW5 zj!k21$w5J#j`-1eo5_+_VVc^A^z2_%H)1M0J(;Gy5z|fwKW?>KaN{2LgZAo^Iq>>N zBH((9!$z^b3a88<4da0kPhmsPMGGlf!2630YbqKR2_*v%weknHm5n*q4NQ6`h9#d< z<6)lgj16*`K?vC>`}T%S+=kOYYw+B!+v1UW@KiK|n4=%q&1ye~W!X2=2F&nOH1e5a zG4SA)Q47Q9Svt>!jZr!_HOB4Oq?a*`Vb&~@>OG^2ZE}@{5V04|F^su9m&!~fqSel6 zjlcbzt#N0=V!WdoKpyNfcXMMfhDEHqo978;h6Ax-)6VtQEPX4Tz8bdb{miI}XUxFQ zt^JxE{ylD=SOAOf{PJKfv)v9O?$@q8Zp&?K6!&Kv0PkybdHjp@&u!u`1M^_3iU~G< zyzM##Y*fe4%P^l&Hy~HTWSx=W7a{s@T%>Tk=uok)y5H+|tYJLSAG<<(D0NG2vb>hO z40^wEkgu>6B8-Ps5^$y@Ejx+da6=Ca_Ds1p-NX*@YDO)G@#?4Dv@!9n{!t9S-Ky_} zty_9gU$MrFhDIxx6yCIXO*{*CTYLQ!;OI^ez|$WSh_c@Y?0M1;KMUPq3s~_*`&x@c zSIHpjyMdMK95>;D6HsX|lW_rhYE{>(dX4 z@v8LzHU;S#r}Nn0bf|tvCjb0(e%392gIHAVVfaq2ZKB(eD6@^=axWoa?oZS|3n~y) zY^o80l+HtkIT_%jF#AWqL%hdDHC6QEQJ!iu*oixsO~hVhyzsZauZW&3S~mJM=9Cx@ zc=evlBs|S@B>8 z=|KNiNO-4yhl9EGG$d3`97I&{$&a0Q0^?QJC`(A!$TgCCUn3(;*`2Pc1_WatD>4?9 zw@cG9)@-4(f7nDud|f7y{|J(%o?B5x(}Q7_0bH%5$<`A&~+a5ZhFnZ4FZiEdrVL~QBK6ISP@G+LGU z>f@X4{8`ix_7QRQu3qoQ-do-*FP4rQ8VGMyp6VZ+^IFAppId4^3%Sfdru`#k9FC6{ zn`h}!4`CJwY}8JI+Ggw~s@Uo|i7H8;ch8Q2o9Do)(`tS`Wk(J%}k6!0Ij^74S+d z*`4V+YH>7`GEzCpIa<6(;ZfC{h%_sJ8qGj82Ni#g$c1N>wgL zB=`i>YTp;yr&|7^xPHGf)5$3~q2h7IXP$uWgl_aX9{XC91q{f!I5cygDA!U{VCk25 zY#$ZP)vVbHj{hKb&Uk1>dWDSHXb)|)thklnHyx)wmkdU?MEPx|G|Et4T6p`G<1_X^ zudNRK$c5}>{_~>7(zo#3zTiPkeE_0)feF}*d$_DVpv~#^n@y7J>@W}xRM~W+_1+?d zSVN~4!>HE7HQC05&ucoofKN@TsHcc3MG>EiH-0v!t1@+Ax-cQSl7o)`1udDjK-3&( zHhY@bh#|i%(tjjU>KM0dX)nM>;Sd>~IKSD41n9wfsStlr(;``;z(S4^;yB&+uW4+Z zl8qn*KS9+;WGw38nC;jO$iTFYXd-t{@W)_2-He)hv(zGV1)R$MrBE(k#ZQkjnBP)M z|3RDED@r>$A3zXd>7fd*yZ zN>eZI$Fn@ugE)RxLbCU+Ls*WaF{cunOFvi(%UjiYyiFaY@sB>%J!83U@BAej1=}aHLoj_-wk~M`J@3!e$iPbek zG+4?2Td{M3UNbJK13Tn8cW24&vWzjg$}C)IF{9)$i!qcl!(1A#TW1B{XgKj+8JXQV zjl+21mr$iAKC`lrOmzka-!U_nB2{r;POg!=lAW+8p~xrx>;iW z^w%8hVTyd2DoM>{jSOO9L~hrlA)WX&^N$V-#w;1zL_M-$JlQBsla@UbZ&3GeXjkt} zxo)Xb7N3<7i!uFo7};U+F6|u+V7yZtpQ9$Z?vQe2voi7K(6&CbP4khZWyJsRPrBV@ z9L}LU*KDWAVY=%mM2UiW#?wgCVb?9LQ_H&5CKVCWRcdSo(#R3h7sVaPOZ7|bd+$1< z05ehiR$A=nS6b{p$~%A@NA7gN1XUB_;hYxLUEJb^m)@CicV4zB;i7m3qm|P{YU9x1 zm{#;ldGn%|O2@dDOvkX7cE^I3#F}MyDW6q$O;^~~(gfKm%ALrC(;eD{`JKvz!W~Q1 z%DXVf1mgqs9Zy&0OW@|xyV4Y^?`&yC&+*-au}Az%hn~@AzCFj+>=kS58B&_uYvJM6 ztI%E0XVgk%&%uumU8uQO&eqRtkz-%3A`<+Jd>&`ARYUA-f)eK59j0ISGsA8YQGlEQ zTUi%pRx{4sX!n@O)BKCKX`*5PzQUe}66#Suv=6%g)PXY$ys~^CqN`xWXrcond~FtF zN-Sc(#Oca8@BSTd!8?-=*=%T=h10C(5sU9a1e~n z5AR}{%818?B+}w|Jy1W7^_d$bA@X}X4YkXvhb+-F9&vNiX%kW|8DQtnGM}DsU#|36 zJdi9?;lrzkL4AhC74ZQz*T#}*;xTM}aN>HE#A6Iu%#LonE`2aOS%j15!i%bZohv0B zFVFFzdUR!YDD8pszL+I*t}c?6**1SO!_m6(;ea-7#xof|A_Krz8x_W-Sbe1;1m8^u zb3(vC!m((yItD@Jh#rXz@tgop{M>Nc=y!C#LTuVmXTT@-oNxEp4OFl^_$qT?Dhdq| zq)MxYupI_0#-ErxG}gnVITvK##~cgJD{5Gw;lRvveQe{U~SMjp5QcquJXQyho&;i$8!3iK_SW~;?VYsqUB$!rVFJCOo)RdU&?3hNj=CFO( zeM$U&Ahr)6j_%M~g4Y!1;PmSonfr8uc0P8Y1g(aL9lG6bPPRh%RbkT7AVn(*uqA<& z%}jE4uN-5JB$XE^R|SlPLNY%T*7nRLR)=B~n?hBsQExVe3NX!e2Kn-mnWH+G@Ne34 z;p3a)&)P>KF&)d^1f5_8)?+%OziISpSNTTN+s>Xw>gr=kGAZOmm)i`|-6;-An4Q-a z+{qj`IhL7=oj3&v_)|f6yNYCn50gO|_`=Iy9~8Pd4MfH1y2p6tOlMqzPO zYw1T7?y8b=PlImuPe-gO)4eBqWnIOzu;0|ZDD`g1{rJV$K#RmB>M=mMLqJAW5!z+} zV(D=X3+pyrmqU!WPSJ0M8NAe!z>50`Ht;sYP&|zz%4T;W3jSUcqTMX*);;5|KbWtH zD!bkD`ahPGeK8q6UdgoY@?1Mxs%(6f=<(%#3hHsxcKU0B5&7W-&wDmrgZ*zR;z0qb z_wR2;s_g%vUH$dn=-(-OwBN{|Ilfg(nrku!BFY@Ww=5(iC9N)&3CfZgg2X~7APnez zW3PrhoE|j9 zbKIRj%=v<-IxvUg)3AqJw?!vD3rCh?>RSOQLs7hnhsuJP;r2k&Z_K8nreMjTzDcS@ zlmi*4)RXLBE~YN-N@7d{!=8CuNb#Eb1xNY=_P^SD4CE zQ~UEY^%Q^I;z`KIGApea_<#Bnd}T#_ghUM6$&aV8aFP+LKQD1()~4`)P<~y;I{P$D zmJLq8_%{yUfpTeTYuN&qqJXo*fAc5}tQ(QXB!MmV4LOpKE@E*ps=8Hhtvoo@R&ZMi z<-J(TTYzW7DxCSXgTHx!&I(>N)v||41vwXihhiABwIu+vyBs;6y~+sSPCKJT(BNfJ!_DTvuVL zr2TOKnFICQ+|$o7)fqS38@f;=w7Dl3)BW zAm=Kx5j~ZuB*$*ztR$uT&rcJ)3u02bXmQiS0h#?tD;NB0AH*c3OqRZEj_T9j&14;7 zG>UmsIDYm7yjP5)DY9#M=|!V6&jraAPb4-TyXoy5C>e9uC>{OBGP#;t%e35`QJ3Bg zg7J#0DMKh7!K7=PGQzvfkWozJ6^8EOKCDe#paMc%IMinM|%a^=O-DJ_pMZ(D*qG!^%QT)a; zb^dTyYou}69y)H6W4 zQxd&={jkk@nPrAEy37mC;HfedFEF#mjmDMZEc`0{()zFe;1y3VWL{H!Gq^3k#qAjX z6Ra*`Z)av{{$GEhZt~inIdSxm7U*q!5(rR);$kQ*NfE$LzC=)COB)5!X!MB@sn+xZ z@Wg}4!Ar-i>c?_d@0f1kooXy^KYpp)f(rq%-~(BPf|tk5hN**9QFĊXjRl(E&_OWQQ=rlZvoI5{Ilxbm3eEissKtQRd+iWIjKw1ji zP_%4x906wJhz+K!)eJgs=p$DYHME6Pu&m<>GmL@>F5sY3>wq_w=tlF#h1Ratf$T`Gfx>xhuyY{4Oj|5rl+{qVb~?zG&~96~Bocon zm{mud`S<8P@187F<7xf2c3s>$lkEegEpD+BiFV0E(vDP#Yt#ai^OlxO+mI)2qfCC8ALN$VP}y@ zRY=w=v*tqEa7{K%|4sjO>KQc?r9>`e>EbFIOuYEo3y#1PG0>ZNfn{1+e)?s4h2r;z z9zO<6Q#M#C1fMs8H>+YP6l*2Qol&KQrjE!3;nMFR#{#>h-C`s;i&tiFJB@`3htoOf zR_}f@i4Lmrv6Y@Q%UZZqTkcMFxbk1!i*V0aowfyKOB>a3*57LCoBN{ymAPvm8+07c z_hxw7>&<8APD=&2A^KXZ5oU85_G+k8wOA^l1K#^MM9#jai*ExS?59Y>R=lS!v4kRP zc+sF4;ckT%I8R!-4o7~NGMXW#JK{&{hgXr)z4Y28XrYz~;n-#^lMX8<$c+4y8?tp^ z#jnoBhtkgU@D?7nSG5AivAM)ep0wG1lc57xeCLAeMECpuX6)>XIyyq*#>;p9S=20@ zYo`q?otXN5`O~8gAxgYG1n%VNEBNBy<#u=)GrMsGC34)(c8YuCz-ncd0w1@K8bj)J za}hfNKRnt!r`PZb+b&l(uf=?8eRXvCjLUqu2%lo&Zmvzdn0s3qL%J2_ytPVjGKSm{ zRk$VYwjtW@Ll^_GsP66kYusKd2=(vW{_UL+Ze2gy#-{RhbM;;M*?-pu^RFCW3!l%{ z9uluFk;i+yxi4_emv^Q{q1Tn_nb6HNKmejfzBU_Zj`sdT=V{mb@@4?$jj=bj)2sXb zyeFgf3-^5j+!yZCE}#d>_{Kr6x#K8Df%i*+&*zZ&ZkL1C`xvm#EHLoLI&;3i0pTBP z&ZGSfhFn+4UCnX7b^CMZTOG>dSQM@3nR7flv8F2n`zO@@?($MCXNsrrKYm!_{)f0( z*xlJw#NNbI(b3Y*`M(j!RT}Qjss|Wf8!wwF|Hx%gAwkgm1tmw~g4iTM|AK3hqM(x^ z7w(d$2f-w!GpFa(*;%arXfhHL6&f^E%=r>3^5SP0bO(~51?UTXH8UR^y!q3GK3 zw5LRaMzJ-Y{Mhu~+PHGH*~-?fw|i*)dSqGMbk$m;XEPD8AN7wL=@TD*8 zK?ZDcm&oGR4$wg-|A4tB&f&6tiCDQar`J>BGvDdVcsZ|< z<%GH@JEA1BoClqu_$(WTTY_n+^7$hUCsE+fbfz5mx$sFG+gwvu7yb7Ff#fe~zsRn& zb@fTq$Su66bC%o)|LR4zNJU7c)gg^3&m_f8Of%%yx}WU(cA<2s#_)&`c~%wyA{#`8 zE++<_%lb|~xU91wDrE-~go-Zp5G&UEHn?&+T&4q6>iUdjLVu?FAABlr<#PtC%M@u* zO}TWFt^U_jXB(FtLK~+YJz4U73NI_@(AC0j#m26|d#-)BlyNKTON$35EUMy4zhYn; z6JBXYEpnu@jq48odMoQ&dt%b(7_YgFEmr`qob zN|Vz5l?(UXEa@^sSm9}8TFy3>DMUQ!o=5pwiobudnPI6S44R3eVH7n4u{}6K;RcJD zYr<)s7KDjnzG|6nm@hoE)D~&;HdJbvu`BdMQib9)rs}Q1^dZjVCIIrXzs|60^woc<`_ zW&gy0-(CD#1qy&8d(<4YrM0sy5chi-K_cH3YtWAR_U~l~W$vpT_HBAS-Xt)6#^2E{ zRAi4mbs{nil`1Xb0`T8;x! zDn(-o>emlLEvX|a87FpW#X+1*!&O!`$}EOq{Bbru>S5l=;(@_K7D`3a!`1vFz!i>$ zf#(CACk0vqF^{?F-_gld>yCIskF+kRbjo@t%~`zI)#7?!;hV>~QhO3VL(kHgW68;; zi98T}@?Di(+p1mHFkQB_i+JZTAZQIv(YBqQ8ON_*>u^_AMLSs&J?1K2=4E_*EP-Ic zsZ!&}yf{i+MwF$s$D)xTx)8_iI~R-Zi=Rb^#TYb~fMU*`NC6-p=peF;6CY})pbDu{ z29(KyE2TphpqlU4sHjk2W(tkq#_w4C+sXQ-mMAs!KXu6aVHjNJqb%{b2* z@BdY1uUm(z4cDH5zbroeECtv9C9@6GJpAMwJ0>y&4BnGAq_#y8)hPo8vvLH%j?B>p zz~Fgsatz&qcL*puutS)mOw;p#V(~*pL5_9wS8?%P^R-{-z9lVl(dTI%run}o%w!R>SJjUf zDzQ*hK7#c&Jd})1Z-r|NyULhd{MjxsDhK+dv%4(HMZ36QdvFPl$Q7(O9F0z=O<4X) zWh9dY>$TXbM*jTb1X-{mS{R+9A})Bq(6m;WLyJ=81}1jbtDfjf%~(9by*atmH(&6{ml!G506#EH)b-Gqq3+G>((& zU3B~k`|WY*fanC*(hOCq>LB>baD@wNGAjH-z@2HZ-5a~FFN#ivc_pOyyq|i9JxB1e zHi-{gx7?X4ivMoC@P6_pt?YAaa4rV092b9|%#^@_kLA({08LR4?Lb}f!RMiGF3aG( zrR>QVXJ5Ql+4v8m>DPUu>=u>A_KgF{{UOU zxDg8n0N|<67}@>3#iSUik+M1@ysgUcLkmXW)hKPpsP3(LQ9y(OaO)w~N;FdqMjAk3 zT43f7SF0QyP`nP*HO#{X)n}a|pjA7lPOQ-|vlaa*VysSACm3q*!A-GpNW=(?5VPfb z?gzm$$j(bcIIy?dvP|)4)Z&J_u?xXVqSv3e>vE1^ZZRvZY*Pl?*zF~8*qQC6?V&sunJLG;vy`~o|w=F);9@{&O}%wu?IUgIpS8SO=H^<9#}?NR5qvG zHo=t%-Z^d2(98>~7FCrPRV7L{BCrar$)YvUvr4UrBsP^=Mm+M$E$9^~U$|tH5EQ92 zJz2CrQY2f3wq99h)WG!mB26R>K#&YpPSPRx8$Nxgq%=cmqrb_J9_+#Sny`D32S zHA*5)8}SLt-2W+`S(@Q`ooLkAl5Bd-cCPM@KD~cC=Kc7QUDG4Y|3P2Ag!H{#U}ihb zP1uqwrX>_T8hditv)1~?4?caaHb=MeHH5%T5}`oN^eOtuDwI_+r-6C6SfQGz{-0HXn&iYGtG%z$1xYI|ar773%e2baDN zJzanb9ltkTjR9se%ACz95T?7uO|B!3c>^1D$vi6JERmz`*(H|wtsR&))p?15qgG}< z9t<mQwC?CmzqF z0c~ZRaxrk`gZ9+0A^ihcQi9CYEA-u-*-KeWY{if@_CiQKAU&a}cRndww5Tw=I>`If zdJDh{JY{P2)i%+_TkmOd)6fLQ6ZTrX%rj$z0<_#2Sf2NC?Kv@S$v_?a*MIC~8ss;@ zWUN&#t(tW(cds(5sE%AJQveHXB&yd98lp$cu+ulORo_hZ4x+ouNEh$&my&dcRN94fPF#y?^9AN z9NRGWcmCr4fBB+V{wsoUQQK0%Q$zo}oS@9KVP65)u*^fJQB4$vkz7e3QYWFnCHDij zOoq~6U#qoUc4m+K#s7T#ydAkG!!rl91_*)TiJ4?tP?9)U@E!2&52eZJFtiZcNcWs_ zo#H!Mcj|V!I=A=zxMuNVt{h8K&)Zp`t{!s0sTnfZb_t%25^OM{2|H;|J4Bbwr=G@x zt=^Wyp}@I=kGBN6yj#QP+t@`5(Xf`Y2R3iFKJH#lrd(8IXuHfd(zDVvbenm^Xb{m- z_^w(0Dx+9x>Jr|tVYk)#L&w^w_4#MO(Mc$)Cq zaQ@!=Uvb$*!;?<*X5`bp(Fw2ISJ|#*YUR==OShqd*(-yK3tDXgE>Z7)-ph~CNZvJ; zO3rPP(RTBXA!E9w>jY&vRlqa*t5c&z;60vabOGZ$FwMj)s3k}K(1%PehAfmRPfomN ztqB|XT0dbfY-bWK{M>~y&>TckbV%9Hl-DI!YT1|}ru>NmNGW?RaVfRgL`X}nBQDez z*BmAdRJJ_#NYQl$Ke)jx9taRPMWax(XZ;yie__v2{wqb&J;5`7XVcM&Mp=@@d1@o; zXQkbE3I}GYI*0n0^ms*0pNNFA0&HAX3Ju!Oz?C41#{k^UjG@tLrij~ zQh&jzyo2Z8*L_ZN-6Ir;gnGyC-tBr0f7-z!l}3J{&8|g6GoKM*-5mHai6XrR!q%J` zcRakqJOTQ!<0be(q9-cACY}dU4+n7!O7c^X5d~Id%m*DQ$^;Z@H(99Uu6vmHMf|Vj z8#XC=VVb_;lxJStg*QA}#N0cVZULdy11J9wbUrxc^|zUdLMbHnH?-xw$d77a{(fFo z94VYs(?Nyqvioq~nY&Qgv1 z(T(;}Gd=&2_paJ@&HelqX_kL4g8!NKs+bx&8e5Qy+dH}%I-30dqNCU+Js^ney;dS8 zS6J1gg#nI4h>LW%UANmOOoDtyG8NwOb*}spjU=aT($t;h z8PvElgRluI#a$QK6MQsb|veocI@zt zvQgOLUvz!bThZRIDk#bKw*p3cs0gn$r>c@Uc?;Bz;W&V^SFrQ!07%*XKf0ZQq0^ht zwGt>UMnq6-Pt!FIp=^lL6wQ)ry~rsuFaJ@~S(J6gaKH2PIHdoueu>!II#}BLcjV>$ z+twLh4adjKHE|_de%8x2;SdaLF~e?F+#*U#nnV)}JTZyVvd%JDHsPPy?1T+>hg2da zGKhAb20DsVF)_rtmTDQfwnbf@W6Y7;`xy}*(AOiT=UmCxqH6wVGkZghUAw;Rsmp0= z>TUDL+x*FuNWT-_0FPh!Mh@Y^jjlHo2<8U5g-Rp}u|;*G_} z-62f5EING+PGn@YZqxuF#&ay{s>6R{ikB+7aBf7k1-y&8xau^Fl6_L-K5&3p%=o9CnZXV> z;DNCUG}JB#uHtAPzgF9M-@4R!;~$g`q>(7`56ycyvlcB!=A;@Lv~pUj3+hVRQTb{3g{@Gb6xT<(Q?CNT`;vSxD)J+$7> zZF>2ah3?uAY@<;(H`mgPu%Huf9UdMYAz~xx(EU4QD6v@lrZH3snkh;+T4~I4xDPM5 zI4P=SBSo8f&1INTjWFL_<=Rj51f@x|c!1FZlowW=zL!q$FgP6DY z1k6TdsiE1Q{qq;OeLO!a|W@8R&Z-O4olAZuP zf~P_beWu?A+~U1XYFO2j1clgh%rTx}7kDK465xq1DCSmDq2VyXZ)mkOd&DKT7d1a3 zW46K?M477whMhk(9TgW)z}D1MQf$ranyS_SM)LZ&h~QdX2b-Q~+8p{cawXdwY_XH# z>}PJ^5*X{sz0!oYg9j>(#vuPdTWR#~9u3XM`W%;zlekheelDha52RH4h}}|rUv!m{ z9d$)~Yqt6}5YT5%4Ww6$_?{@sKN{vMb(c(zM5n<3Zs@kT$hc|svqCTq3Neo0!mqq& zbL{xLDSg;1LIc#@lqjaBYWUSa9}?8rHsoWNktOv^rR*U|SrEEw3v+>Yz zDJ}BzS%m&4cQ_nQiLs*m212UAPsb<~()`X|L1kfDL$|JJ!~%lVG!~tFe&@hcuy0YIiiF^K zcAs|zL}MQ2eGh080EMDYP!aD0ntTSiKu~F#2%hzpTu5I+NwKh-azbe^wX?fZn%s4{ z3)=D0=-tp_{K&(sE(NDEoNIjq-fr)2^Ia{E`@CHa0J`Ib7}5a17Rtvd3>Ui%!aMx= zg8rRzJsP7xnarA{1(R%U+KpP160O{4_vgvxLNShtdK^E2n?5m>YpojL9e(`2!+QnO z!C=k^6=gKjuUgS zKyxUqe+7BX7fUL++@Cax z<{ncVi!d5O_DOfp@9VCkHj2r1ibhR>)e<3Cen+^xqiX62v2DDkuib&8{SMoxtB*}O zy+`~b?5jqWdm9)Z^l=X;#Nbi-G}=$$&Zsn29B{?}*;V@oluoN=JE3L4OvU?bel zT4R>UTE)xV;h88~pN?Z@J_lYLL`wYqk&@n`B7-yuYPr+U@GGjSiVA)&Rnd2T0sb#! z-lNHL%9AXi)hnK-$+jcct2Xn=b^Q;E+m@Oov#k75`GxT=aj#DYYVM6*Qc!^Kf2$V-&+aLQ0nl~4hwP2{*ztcijw zdFlG3H+ZOw!0i?Qr$pEB#S!HE8c^O{sq0<+p&0v}0kWqigzXv@=fl7Al`LFf$dIb3 zW>~27aSAX}hLMV|CxuiqL=uVg0CsxMIw*OU%DF#(Oc4&^;l_t3tY#;*UTlQz$LbqB z5LezANvp603nzKk!UY@g`C^7o4{6a}N@CzUrDA|!uV>RzoQh2>%A58y%XtCMUn||D)?IfZ}+D2x~6*0^!e(X zWNBemTc6!35Yf+Nt%_Q;hJsVXdD6?D&bti~yP=T+IA6Yqx0VmOGZQ&Fs%fpHsFvea zUA3c(Ti2R$v~-mO*cEz2WMc~=GJTu)#d29Wf_diIH^TBe#)2~@r`5%F^8tmvQG%9t zmsG&WzonKo-xIhkds!W6-&M)%a`(-gLi6GD-J!}JMo->QaOY2n>Ily6*lj$6tn|;e z7QY|~Z=m1rbPexOir@sPk1xa~xu3sLN{f8;SL*fis#EF=TmiH8B4p~WwKlk5=xt!> zT5UOIY+I@>VF1=zj8FueaK^omCKR)!QCONUeoOHceQM!1V|mDu5@Sozb?5zH@H>NT zHyPo_@v$A3S(H9=PdI|Ac(GL$uf1nT3(DhCjWDaP9$P%%M9#RPRnI#-o6Tml%*4=U zpkaM`vOdR#VXF^-6SO-herm)}6C4v^T!9;tp?W}RT;zMeou4r+tv6Z93CKYJ9I zbkX6M0e;rHu0QqadSIdd%$e?!5ZjhOoOWMQQ$I(**H^EBlJ+`O z?;G>8o`pW?;Ae-jvTkxN(u8KPq8COtJJN$9ki zr|s4v_n9Wl3<*R;#6F(r%V%TMfy1ijV|cC;WrchByO=WBv-~5m-?7|PplItt;27|w zA6Up}bTe%!RVxSLX@b5ABG0omQ zzvAU%ki2^DyO4;NX*1;5Ei321h0<`MJcW?mx=r)lNU-SFePoYI^Z*;7-SS6ZmtV!} zYND&C>GyWy9hP}DDb3&0b}QRIJz0zduF~)$w9;;yK4-k)f>b7>gaFkxYm{M+8TMM~tG3scwv@}A&i1yl(WFwrPt9sL zXEXY`^YG8RN4e94X$~kPnnbrI=lQwxT&?`mAx;l1E5dj9nT4kXzt%n#w+BR2XCsTa z{A}%V=RB|A2p@Z=Y!a+~VY!6>)-97A%Sy;W!S zqqhH4^^2YoVE+hVyei~Td0pje^o72l3$q)54h{gh#QEMN99C&v2}&qF1&~VpGGJfu zpM723QLjsi^T54tu&^p)qLbaK)P@KL+hIK{wCy-GGdnL%?XyOD zDoP2_Wua(*7!R(OKg`5Z=N@E{_3}P z!PhBhNf2=^3M!n$<@})HfuO~&C!~B>X>A{8p*l9R4MmQ=AUtl&%NbCc?#I7sMpa{8s80zcAH0tLk{BG_G_SrV zeBE#%W^J=K0!etzmhjAd4c^_ zwygS4HLgpu8EkUIoPLuuCf#dyqO^M$Gxkzo6LjG2t)EfLZJKCdxKK0H1ZVFmJ~D2RW8dFTc(V>Wt=`IX%E+5T&y+v_t+Fz3XC;K1aazraAoQKkMH)>r4_ zCsczsE0X=$Tm077a^)90USJSou2`n)lN4YuY>fT%22AkEg!e8G#cp}?#o!eM{Zwq{ zr@<>WiRlECzvU^Nq=EBkj^#}O-E0=x+5DtKG7t{Aw!W??p=TikvT2w(*7FB}#g z-hhAunPZJ7H(x(#$v_yS(DH^MJs*RG zf@v5v+IBA())n4NqE2M7)pkqi)ja?fv#8MOocI}zN@8$mx$q++1>Dojg>W}xSqKue zvFQn43MCrmjVW%QL{kFcX2ak$&H_;;BpBQu;)Kjh0rzUe68uFU78CkDch?z#ivjy4 z&JyhZe>cqBd57a-e7K7pzB5DlH#7ioW}i@30^x}%W03j3*-^J1x`qF{@nm^BNrIya z*=T(drNothaW=ng4A+K%4WNzNC)R{TxEaxZ9Y{i<2qA|YK1TiP=!+Q}B>JzzO8@oC ze@~b#9GZRX9*28EW*OlBZ%X>sCwNLk85r?|F>>I)n0!#<#Bu(MzzeSs`M-K>Jnxuj{j5Mh?L`u|F`rl(ZObQPGvkg-8h z-7SQt-HW-W{HAHTp=*oh>qs3w*f*|>V5Va)6sTUy_PgoiCC*Tz#qD*}jw=U4Dn3wBvL+6{Nn@n9z}0r!Z`G!8(SiD|=DfXU zOw-E}Gj=#@bfdJmTFIFwHtZ*g8#*F6_1V$*?1*)AgbUgQBn|Vb0@Z6Z+Q)XN=oR8p z+dm$VRJs5v6~QZQD@#z|e31cB+dlzM&9!eoa*pCvdfNoC!CRrNt8R3;WeO-N^P25* zbqbX{=fmke%x!%0nFak^glCS0NT|*J_;tDkQQ>!R)@hmMiFbHAm@y+-$vQWN#~!p~ zTg5!G4&}^l?Ur&^It_6m;O;x@Y)zhMP2jk5 zC!1E+d6o~e0QkXtoc@KY~ZV1jS@{2c;B${pfX{``;%2Ea7H{ddd08D!I2kn743_Xgu$uO znj0UYUr<}_z|TvT-UfD;@?$@v2*-_P)O(u|XW#W$TLX~yN)Pp-sH1R)ICT*y&Z-vY z{sHwN-C=^Mv%pDzFSc8wl3v5@i%sC#gM)pP>KuKF#4AQg`PsW^PINkYA85GG z{i&E_`cnE>vsc}%TJMEzwPVo~!9W};D9^$XHO|6mb7uRM#yuXvTN2%Pf&s&h9FRw& z$tUAR(5PtxN25Yz-}u1GtCMUOn$wUMDj+rbQ-)*=rqvWA7L#Rv`h&uT1CK({F)K$Z ze+J9)eOfu?U>LS%-7Q#ROU^q+Q|JCJ>Dy0n%;MEDxl}UN2bp&%XVYoXQ7_Cnaa*!q zNP{B4fYE{YBY?LDdIUA80n#&J*BpPTHMc4=$}PYh^Al?K8s$W0o!0upG0e+1F+auU z@a8Dg#I@e@kbUQ@nJB#&Q`54?#muuxD(4mK<=9TvdPiEj%Y%~HTV>3_LD9(-A?rel zg4aZhF`5?_>@Qtw=ME$v^;Nj44ixmIacXyZ)P{+G4DXa=p=@tsnn|`?b)^`y`MHe# zzx%jnuZ9G1B?vA*Z!SN^u{q%1t$2;7ST^Q^^u0QcLkJbq%Q{J4FC_vrs~ z;~?AA_SE`E8yusQoVJ2D_Bm+Ic@hlHYcv14aMfXg5mvde7&w2$&uu zrRKYVA4D54NXW&j)weTe65I3VeX~2>;y14Ie!BPPqhuVFFL(Dz1-J&Amoyo<`}b=J zPKVz$q$)o8td^iN%WzqlvR!)#r#6HM`VBx;nGn8uXc(;j8b`5@uzQqve@iZSOK#W& ziynSrg7i8JFLofhM^#X(p>QAzIg3Cw|4V+%p)Ys3C+Xg@{0ZGWbKPgtPsu(u z-%;!{TXdOD%k#p9zn_!^dNFx(9VMuA{PGbiPp?|>h;VW7=+~aQue4?qECwO$0IP?e z!V}z4EcRc_LksHc#g^B${hyR(4Yn*v!hEC7G2L1sg80S9b322(?@=9`g;E!Mj~etA zU(OcWr2e*WwF#Wt?BXmTFXJ7F_ZvjAqIfa!iya)>3%!-ue;S#{im4gLwN$!_#nX#) zC63p&=HO3P>-Oiy8v8N9-gMi>eJQgPsWO{g=`I{=dxIO%Q{E~RYujAF#)7PZqtGU^ z6kEYiFj2w4S0osFYW)nimv#`A&{^_C#}>P~t#L72&M-g=w?FRfFe}qcY@+dS5GH>e zf7t6oAM1VF&oGckm(lpNm*Lsh+!4C8LNvaa0@2ZLMvzyo{9Zn7K-Jmf+bxx`I|2My zP{`5+l-`^=&A$&ap~?O8w%?lHuhirxn_1tgS<>xjkUMi5hz5F|)$f_K+3mKi$h&Cq zw$f=drXw}D#_pa{rcAx}I5LtssJ2{sTgTJ#Q2Uevnr0=dFvGJe6KJLKF=5qp)yA4}vYxXKfSXqc| z%41PV@F(*pvM_J+BpwArZ*%(E!(ilH$)^t8rU)xE;Q14YUMUtDPjjR*KE^K{3+4{{ z4?<1-b~Yc?rcFV2)G{@P{1(LS9AV@sxT{R{hfA`&>9V}SPu!Rc!3J3inIz(dtDEu( z<0fgYE!R{zW%nmjL!{bBxCRftxGG56e2^LnZDu5`JPBH)m6E0Llyv~M|;tJ){8D6%7K_^15s)1cI`NKtaE*>mJrsNkh(M4ecOtMFzvMxv?*L0Di^ zb~It@nIrC_{GO~z6fU>bdQ8oev-w;x>!!uTMHX+Ir(ug^0|vLPa=F?pg3ccZq0!u2 zun>PRJ0Z943Jqd#J-acRBrV?9u`i^i6EBI&?lU6(i5_M{CxbS#@Gm^fK9lJ%_^LI@ z4&-1o_#|jM@h#TAzwm5 zllMhGmp4E|1~A#^jM*;fICt>S(C7nIW=)ZFm71t=P{%F|cw$}pzozqARcAzIhafPG zO8oVAdJE#R!L5aS@aykzkER%$e<8IL1>O@yozHMkiYPXHbv^Y#?$hNXgJqXFXC)Gu zIw;2Sk$w{TqF}E`fok{ppCDhA9&&LpW9T}K-3Oj{F&|zIatIaG&)A{*^!vaw_QN~m z1;r*ZMJh9kVb`8m^*c7pPW-qQr_ix@{1^jkkM9e^n8sL_LZRE@7*K$r_^{#}t^#C@ zLr8fYmOH5a`@}5v8!Y8RHpdrpr#G_!j17?TAMAYh`@y8q!7$u!n<_1VN0fuOv{!b) zg)EEdQYKc{1Z;ReXzfYL3$Px4$~^K^r;T+bwAjL;3vV)LC^g6BTUwDHX(ibxx5~KZ zCEpOVa_>wXQJoShAIN3d92SiI5l9q2go`_34Vb--4OTz=XaA@6EP6|>_?AhIaoMx4 zzuIgf_iYI2=ru*vZ@dWSKB_#-cQTLAd^WebR&F97>Z&Up_tP9TL;G*{pv>A&+^>We zLZwc!qTY|0FZ!sg(cfpnj4DGmEk@&O9ZZma$6C*rtnRC3buJQe3tZW)iMIC>-Q!*o4{4z}aVEh5l^9wlM@I0ksSaJ7w}kd$1b@AVv1>|4ba7^1=!= z>C8g8UPEfhOLFYSZ>;vN=>y(_6nFNmq@M+y-^84MDUm>QEQ8TfyXI5*c?yjF5@$5^ z&Z68m_ZmC!(Itx)H8Wd@0C=y$ECnwXH0rf|zR+MLB)eklGl(g7GEm93C-B>Kp>y9@ zr1PxF8#?)q1Y6EMG<<$FL1;m}){`Qd`Y~3y5j^MIJRLk^^GA3fd2mCFKJbLLu(R2$ zPjw|he@ZBWXn#nAgl()B4|4NGvByNBvuA__6cmE}(f9f5+sFTjMeH33Kwj7|Ff;Tp zFnIqb7E!VAu(JE#84Tru$UfR@Yo~p_+|D+4NLys#vosepKyw&ZZLC#{FoY2*Nk06n zS>Tj;N(?vlP`QLo-J7msZ9SGYMNu`;MoLkM?qA$j+4^rU%!BJajV2DPo~5b_-PiLo z*3y52p56Al9}E2FyKM)LTKC0X31CPPK|~ksBLO~(h}}0ysAQ3UfiVY|WMn4?oMb_@ zkfYbYe|Chs(8zb2Ge)w4?*}2dkzgW`Qph{UQyp;-Y!rdtS7h;p6?~s3QZ+M=5v3b0 z>A}->agGO+)MqpNsrwp0;}#!%s=}V|?9BTFQe*D{+7oqS|I~_j_W`R;;M?JE)apJ<;8*ltqcrn|w;Lk3j zDyhNUFbAk;10K?dB9kL}s!utC`vM15*l%;tPA7RPyJ)1Z-MDMKI_?-vL>BU(Ho*cU z9{LPKBBK$$9-?B9HoLK5yY-YoT&C{aLAf*LMYBtw54Du83XiT?58F2qMw4M?5K@PW zJBCG9H)eb!)!eV!vSDJ9BL+ppo*rEDx5EW=ihD><4 zq{~ux^a=uHFTS`T6L+$0)KN^1ORGXSeLG{5m{ct~Ty0iVJ!cQBq+|3de-cfyxyet% zZ>)(ta#)oVX=xArs^VU@3k?kgUGehTpQJ6qi+Pj3-wdx;^td?K7d0g7x_vHzNF23D zunfC*SJ4qsxi)7~by6fD@r7H_3{cZuN3vQc)0s9>;M&oyt*zD4rKs%a5Q7iWxZEa% zVq8Gd0zPjS>+N4^6E+K11!~PBO?o=dk?H!A-dVvDTn)Xgpqp)c? z3IsZ#FD@(*eBsL2BEgbHvZhlCNSeJeg`*xf$m`9Yruj}5Ye~`3x>j zbzq%U0fUH`%C?1;4a6&)rrL6XurlMGKdn z?!2CX-dbhdd^!Xg`}+( z4O@LphVt>|eEcZ>DkAeCMBdt$=Tlv*B0vF!sw#T*M!l<{J?IL?E9GJ`GZp};c0>b= zxN>PlN>rtPp2lz8g3qQLq?z0QjLn%L!=;f6uR@jahcYPw`ye4^j0P(>0>uPa?qEdh zn1DFqPCZP-HJxb1mBv!XQOeTGr`aftbSRXEti;oHu8ykYDS(=B-bC`*Lmx7-<)Zo` z$W7p>Kj;6&2MLnsp+B~$NH%|RKrd0jF670c@#88t&Z8?lx;WO0G^fZw?gOSYTE0-v zV!ai>=5tp02;b~FXVjw`r&;n>9-=!%R>(6P$+z=Il#{MMR$Q@E*IiM1Fvox0 zEt0LLqlM~I$X_68iJ&Wa=Ebf|+WzU8yjVv%g(Iyzy2ZicmTUH&B^kRXJjO~L3*a4F zn$^Iec4Oj#q0SEpLQ`A4r4b>t*c`G4KnOU#MjKz>$zBK$H(%Tj!=ig}-@EkH6eH&K z{*v#@_{tY)tEGciop-pnMBvn*#^bUXvqh+S;9b_AU-SLUG5P~ zIB5SX(5u4bp0g=jhs^Bbz@9&5Gz^*i_RqVpq@$&$X96*Q4fRW=E=ygV6oJ{jsA`%k zSP$Qrh?lq~UOq2W5uJNWq7KWEIGJzOgCr({twKUcy(OJ$ik+VH-Vx9IR>;SdSyKD+|nl(+a$1j7s`?G>}trPb+$%1%|j_z>=* zNTDZ09xZdqIsEcDd}*=`)Uf+5(`fc|;B9#gl-CrZMb<)3 z3M)~$0{7SmerWYj)K0VrO1;}Ior7q8xe+L4nCFzvx@XX~ny22_Me<>nB_$a_CsGz@ zJ@!=hl?x|~?6yB_<#VsqISV5Wq>9kVF|li@i$>|rM*#0Y-+92QHj6LiF4;-6D~H+0 znMwuOO*%K$(I-vFpj7l4-jaMYy(F60q+{ihacyIknCX-U4Fh$KU)l0_%$Z};pk_A( z-3;z!@gK`HrL{4b!v4*Tiz{fp)}$Rt;5VL+X!A}SuU>^4R-0(;#F4+EEq)Xgpz~|J zj;;byCb_SyvsS>#FGhYY)gJek+)x41wDnjcVa>jR<<{@v8zT!c zrERq5ZHfu``i5I!;UXT#A6$8nwWNKKtxcqnF=&5iay&+m##IKsSmHhTEK#_T4X(H_ z3EyxE**Q-H;?*Y=cSwgG&@jGe_^yuLI)V9+cWHTUxQp5E7pPy8-Et2eu0paDq_n(3 zRu+XMexbNU?t`4V>@+v|2nG>JIT9*_Axo0Ji{D6ILpE?~tI+0e2FioN_oJC?^O4AnGKRFb7E$)^%tps&7@IzW=+k5A8A zAUW7XEltbkXe7t(l~KFR9(pSMkVK0%vtd=nMo{VXO{iYx5k|S@~}<>-od{9iLu-AJt#n}d)j8Vx`Y z8uegkje-KlP`P9SKwR!c4g4HkWOsvVDDM_@-fPSK=+bgX!Y`_TLXKqh#)(w5&Syh& zZaE>6I3XfVqk#DK4%rt?)5PrGo7E0)Oop9Aa2ahfLXLc0Ys_xFO_RBZEL|)T8LPI2 zlcf^AkYpBiI8P^?Joj4$>s3VgMt(ZC=yvgLERM;8Uf>=&q2GQzZqI{nGZmCb6&%VF zJhsQPv~_E*=VrC6`~zeawbbIql;Cm@JRZl4I2_~85u+BTtmO<8r+Nuy>=q?h*-kz77PP9alEdhiJgQb+l zc?HZfP_mcfmkcL*8(_0%Iu6;bgIA0gn8>p^C$u%Dz#Pp9J$)Vt(VwHKV~*_z6xjc2 z%Sp(vY{_W>IBO5=C@ZOoYRfK4LA*N*c39N~mRTyu_Dy(W-gS70l_98!rRr>d=kY-I zj}98&0FD{~frdDFobquk&;IQU+ghx#Ul6vGE61CLk2d;(D(#fKqyfS0UQNu)_4JM- zw|%4Am--a=?JC<83qQBuof3O&bUzea6>>m<$$aUr}4jb|21n^|rL9z2UkDYM2tUzZ?kPS6IxR}cL^gbutGtV;jrbX!(koMZNsNKTg0r*4Ptz_a;U5Q$PU`U^9r z$|@>3WIiqHsCc_zj>q%GFq9E(sa}70dGd7&+o!~vxC9I?5S%SXnv`UHN_i~lnBGek zvD@tLP1(qndH}`S$CvB0sKIm1fW*@@et3vEd@?mUIwpi$%WU{XEm==rGTsiZRpq)anIr_4(;)

K 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%0A={eF~}Q&Lb@ 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 ArvLx| diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.2.0.jar b/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.3.0.jar similarity index 91% rename from src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.2.0.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.3.0.jar index 3f93fbc8644169fa72ec4a95c295187d1f6fbd82..b870ca615308061e25e8cb3dad9601ef5ac26609 100644 GIT binary patch delta 2560 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 diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties index 9c61a39de..dffbd1fbb 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Lucene expressions integration for Elasticsearch # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=lang-expression @@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy b/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy index 292c8614c..4835ab053 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy @@ -7,7 +7,7 @@ * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.4.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.1.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.4.1.jar rename to src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.1.jar index 7043e427340afef2df578787a4de0c1a10b74bf6..09a604504e588791b2ab7a4680aef3509b20f787 100644 GIT binary patch delta 1338 zcmex=hOzN1BX58=GYc030|y6#@Qw)+dDS?9lz;1G>B_>1Hj4Ed^KKgm++}?s&ry;Y zIKgbG*R&f;JAy@gg)24)vfS0X5~<`ck;#+w?fvgb$2*(1IJ5KBynlE1vGu(MUSWni`dgiQu!O6$Xy=4Kr;mw`q?_%eic|LVTOU>n< zI=@}w&m2?Rr&`w6B{_Wqe|`HY;nI)M8`%{uEEV2zQ>!fZ&Y#yDC4Yp3c4|)B^mNmM zP4`4wSB0&L>0G9#9r^#v=6pu0ZvDsFf!#{yuQ9INZtXMi=gqO$0drS07>f3(C zW!SG;E+M}D@e-y_784{or#I-n5W5w${c7#@D|6$*=HK#qRU2LE+booNd8_HprCYvy zu$L{bd3*fig#EHDa>Dy}{rR}#*RwfR`#!C|a=rL={Dd`BKY#4~r@E!o z;OIg1qu&ygpGD65%ZP}M8`~!MZ@$4eho5QNgvn)syO>qBPnc{hqzIP)cd?9(B&m z(awINU?W;>XF(kD!=ejfXpg!nD_G}^#0rZDpn->ZkaSMAPv+UIu9O7P)M{kM%FDua18I<*{5PHlY%5QK zG}BIykm6*o1c=b?WND@!LX$r#YEAyD!#$Zdg+~G8h7DZeN3H>l3S(qoFoPS(z_6up zrvzC4KXdWPFOwi<@TN&KJ(dKU@iano@|;wNa3s*SE_tA89Sj!-rr0;8GBYqdU}IqL zLNWddSi|H8i8^2xZv>jLP#I{3-DI9bA+QjCk~CA8D#+N$+A{K!k{}MA9(B<_73kPZ zV92?knAoTZR{J1PWb)%Ah!Kj3(o7!OKw&SScCewVQ>B?Q^(GrSn@#?g3NbP1!P{C_ zU`m(*ObJ#fCVqAX`*okK5Xi6K@S5BGLf4Unf#E(dP3WO0p5O^qtd|P0Itm!xvVLHp zg~{Szy(mczMQ>;@P@&mm?_`K0Wm2S>{zpLUHWCyI@MZ-D9|MCp5Gr#3^FSPk2LL5r B&7S}O delta 1300 zcmZoX%lQ8cBX58=GYc030|y5~NmtlJUNuf2<=?1Tua-a2MzP-4|FMC<-tbrT9b3c& zHc4B1+V2r}am@G`z`r)Ej2x}dn~%#Ie{`WvBg3%c#Ks@c4Dm3XYZrnTERui~b9RvBmKl@l>KGfvE$ zB5fF)w5qGCyLHCNPlYzS_yVH;$i#otoc{Qtk;2z&yEUEWiMp0;;##1a<}F{fe|k~X zjAG{V1t~mV@Bgk+xV2TjNsV)Ip7`-j*6SPOdKN4Ao#^Yo6l(Bf!YQfA=U&!tJv=S@ z{>pM`_4?bMtV=ek8Y$IZvV2t56?8gFaaC2+mCrL*bZJWS8dUkLD!~F%z#zcz*HKM~fg!&rT|dAZ#bOj4KqXKB(&06EVZ5R|x~bAI zC16u)CO?eV0{Lk&UxGB_b|6n~vPXgdSfo2qn(-T0q+gYvAI;v$(Mi%w4#JZ!CfiNk zmL#MAvgV+7gV%1L>n{NV-UDt81H+cauOdK&VPHjpDfW%2%nS?<*cceRP!x$t02S#> z)=AO~rVYoj4C{?cxl+v0!Jyjg6Iyym`X}bB#7dv5m&T}PlP_kn3f55<(%7Lx^2A!)rQ zMVhI?7Hp`ci_qknL>{oiw1C2*&S2s7dOVYBQy{_$iPB8-Bf!F%Qler3-mJhdWnd5o NLS+sH2Ddm64*;nbu#Er! diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.4.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.4.1.jar deleted file mode 100644 index ecfdfefffe86bc30195c0117a1d6a32478cb467f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 542811 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%0D0QmBE%nPyDCu3M5pMC_y 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'eO4@+quO7p;c*>lu-tb}+H=rB1C z%f#Dr2>dU$u}##NoYF6&cD^_{2Y_3%u@3OGU#<2$iit^tux2jm%*d$O&AlEMb;LvP z!_KorIhTO1A(NXt1Un)JMkpsY?=hk>F#kiV3}JA~Au+<#&{=JKw_M8H%0<>=(Z-+| z-rFjCJ$A&i+T41;(xc1)MpcD{9o_PrUT8Kwk~sJlN!3cPsBeJzDFiiwNOc}FMw?tC z0Dp;~aUS=Jy0gkgeXm345FKiv37bcEp>&Yco0SrRNffDAa*C;O|M#aLk@el9HsUG` zB!)JV06}OY#%2~e7%Qkp0DR*XxM%30d+M|r$cbIlWNt7paV!X9zc2o3 zRxhj*!Y6fibA_4fZfr2e z@N;WW`GE))s9CfO<@s3Ec|R}v8$2>rmv*V?b|$2>%bvPSYb&hqkH}p(jNgAS5$5y` zX2}+r<0UrWFyKY$%@1nPmYT7$i_L&*l$bL~__IfJ(YAHq25Iq-weS3{9FR9^vkaU! zdU+~*8i+jS0`MD+kOrDL#$s_byop*1_Yqlj2j=yWOni5(k(Qc!(aP2>-_0<~AcN}T zcTX(}z|I1Ls{arIe}J5vezExuawOI;tr&L=ZiM(=HmO72VG(>2{`U!t#A^_!K@(4f3eGQcr^e@DTPD6JPVk9Z6%;#J@a~_TG1_Ez1c`A3V7%x8ZAx^67xcvhH zZ;+hC<&vLF_>WtgMag?P;Np=ue_hDbk9s1d8IV3zFJyaj_4p*s@ zXo#ceMtlCPxv`sM$PN7Jg$KarOH}JiS?gQ4J3?SRC@%si`T@YKK!4FLgd$AHDVg^c|2CE2%I zF#>%%jwL`?Mt0P?XkkOH=WcGfhrpM8%6M*SYJNoGxq8CqY3wR1NZ2*XYbXn-eg4=W zK){M?B?x=RjT#l;NroB}j_YpzTsik|En^y9zvmM6L8i+NJqt8uFs7lvQlvwJz5oUF zjVj47({e1hbosqKngEF-6h~yYgm=bvu2sE+VEI*xarWSbooBG+*@w9ZYDhP%3^jy} z%5^YL;VjzdJDiOlAr5t&S`EHIyhkGA%ff=OWW{ih%wl~U?%}+=9m}!+*`zRtE-!RD{dA{hq}l3ypncU8 z>}Q=DZL0dMwEv5;cM8rlYP)qi9lK-O<{R6#ZQJf79ox2T+kRu)?ATtt*8cad`d00e zuj;9qN6+c3dyadIYoPG|GFptr2v8T2Tm(Tid^7

73yKmpr^O#B%}}mD#fVN#;nQ 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�T}20`Cb!44 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

*zIPfMp;IVLe(6`g`Rj-r-QqwQ3Lj1 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�TOJu{LNu7D|Kp6)+`*c?xX14ZH)%UJnQ&kstJTl|d#|;*;7O9-!D|wuG z0p-(5j0@S%QFb--xQKhDUaWG<_0exgjA${>>f2lG(&O9JV-2Gp62k=y#M@gDjCG8S zVYcJ4KRxMmDZtO7pQM+neoxZE=8#oOd9)-?bg~ytw@cQZ3R{wM^`yFM&L+eEeUINs z49VR&LJ^1&t(+of#Gkw9lakJ#s@O1#a&YZV^s(HWs~OAZf!o$+?%FMDX-KRvrfM%7 zJkdHYIpv@Eju5~wR~Ah8EAJF7_M4aBtXt}w*SB}fR&+wLDSNTvNX+fVb%QVK9#H|a z(UOMFKLo_4i6VvH@EuB>eYKIC@4j3dBix~UDBy6CAQh|=OLkWh?ElszrhNPP`bYS$ zD7woWVp|WvzMuv%;uA6AQt(?T&Hj79i0D1hM;k2nLAYNY!G4b#G2xx4!gBE2GR?lR z;C_P7&kv1IzIK5dEQACs$pB;$O$kRg{R^Hk>eaiy_!PWjC>UU4M?7V&rY1 z@r265SruH8^ure|c0!-95l7Te&-RlM0_MDrg9 zDu5j)laqk_{OaJpBH^7hf^vfGIKK4}vzfM^4>tjw*7V8%{;JkXk+P(J8lH3lea7Mo zMq?G-zT%#AL}0YJf3;V>mLCB^;!w-BS|DdClrrY=yUuIdwe6dne=@(mvksJI5j{g1 z*Yl%L6eAb_XjQ`J?kM-X*pT6R!;v4_` zxr!(KMSC6zO~FOKgK~vmI@V9At7x+y;W#KegZY4t;9unP41GO&(ToCCBsPBAP)~(1 zo-)iMD5&-<=M!y5IXPRtuX{(2-##VZ81kT6qUw|uJ9LmqvFPV&9P*9(>Y0XqrtOrh zm>NX`LiGvM+Em`?gX=Gt?pglrN>M%h{Wuf1P>m#r)I7t^>An;L7hJ$E( z&M%y>AxYvkhfOMdqNLni!uo7(y|mBB0c}2}vH8ogtsg#-mw3<6^G1eUvm1vU8}ME$ zE?pi)C^8ox-}F~kFuKFwa_mC+PN>ELXXLrWcp?ECq@s=byRJp5cLi}bgR14RS^2eC z%XBn5Ni&EAT4B}X2~CCaxO-0aS)ulYn4b1%N=;7FL*NwlfL&P7!bfs=zTX_5d*ymp zD0Nt5VBk0ZCYlPxID0h5X+Vv%K@Y_9nA4aK-S*-N?kJ-+=+@J$d6UxQ0> zDj<``+vD6=tnYX6#ATa&r2v!E+@`NaQ<_)`4uoxr;Mi32U1cB%cnDMQqZ2z-l3C?G zaUT}Fej$qcnDo!eP=Hi28ox8xygMBDDrCi=emV;|6DTudwlV)#U^nF zOKS)7f6w7k)NB?1r*khx>QahEFO+~#u@&`5&{IDO%AApjN^()yfFr{CD2v&uy+x^5 zPtubo8?xNnHsX~e_T`xaJO-IPXLgtG!xpROR1VOvC-4pY3f$H^#%Ks|0Ctnk4hjY% zC{XFetAOxfb~NtmCxwd!JP<#QJ9y2cb}IoIW0kz)uDpwiabapU_)90vx1*_C{#fh8 z8f#sSmURx)`6>5#;IQeFululGnGwldX8?)}EWHe|Tia{@9(rK8+}Dv~MZs72%yX}x z|H1!#4})zR!tm(Xns~?!;cCHOG;~UYRH1N}kT;wnyiUtFf74Kbs^w&r9s9E-rXo6} zE#QTL@>z^o7~=I)(Ov+N@96xZ+ljsJx#SM4hBu1muM-EcFv*Tb@cMQF@NZIP9^PV9CTYCS~)Bq#}xs^KOYdqec7;Dbg?2KK=!O+*N zJP;-S;AgV~j6L!)HeMW(U9i&|mcN01LFr~^6m}h`hZdZyarOgC zqJw{5i|5J&c;r}h7|F=n8tWuxMrx?9|V@*f9 zhAy1XW8MPn;coR@^uj!eNb#c^{JK1O-abtO zEMAH$i-6L#>wcmolOj<4b#C1lVLxj=MYF<5$($tHP$a*K2;vSIJ#IentvJ( zyIGsMnj5>AS}{6(PA~1uU0oUFjO|U#jQ`iN!oSY1K^-_hwS$z8Tr(C=7gtJ{A73HC z!~hwkJLU`DrKG^bh{aIqcTSjGVMvpJTtM*aYV_F(e=C1whyhK1(mzPz*Rwi=ww~3^ z&Fc<^YaX5*_AMPt7d7_9M}Ch}W{GkXUp-rT44*FAe)Io+o_fu?#NB$idnWyIIG>3V zP_y$5|KLe!IOQocPUB4lBxw7DiJu{NG1vopXZz_}7LMAJkoJ4*iud{9lBeRz7hm<7 zkmq4r5aLBDOmO7NnE^4-&A7wpJuU2GX=gAT=kIW+;{I!{*;6ARFkwd(JMKnkguH+* zwn2Y?yNhaATmiqh$a;T{N>dWz1m|FMe%pVvTDhAK&TT;{AFyXeg%WbjBTp3XmrVsC zi={Z_%I=&HkWT=X7k6Ap-$wjN2=)+ShRAGh1`Y;>wS!S|dQCE=8a$d*H5R_gnN>E+$9zGv zcnF!ZVLxk2htG(u;JYuh92dys?Co@Bo2t6I%AHk3Un>?frwsLfudOxtsLH;NQHab& z!TI}lXZ&Q`(4NPLh6H89L0^PPwNf6!4KF>3bjg{FMZKiR;+%5QS7XBBXKHZ#Vl-T| zQpGZ)(UmY2HkijcyS7IFeg&&0=fZ>p^{tSIcxXT41Qima7@0uO1{pUNx7apf+hdyT z5br*QE)N*a_c@K6os?_uoUY+r(MO7z z@Yk2sW^yw^!{^LJaC+24h&A7Ppl;F1CU9U~MBB02YGl+`C-k})a`lqQ(oaBuQds8t zAMiI1(*@U>GU5~bT%WI|;k%W}=&@L}Ei6YcF87&bhB@HEOfB4^ryX^m>AM*;p1E=& z#0z*KnF=mMWaTvYL6kn3UW|M*Aq6)MzKvBb9R>h|(~MQqZ4W_vH+cA^Yl* z_b?hsq-4_*70!S5#O=YvtU5Nvh+OipwdJf!OG)UXBZqMEfp#5jZ9~iR>ZX-Ob#)j% zse!!45*h5UM{iWR3LYNM)l}w^g6^BlUOwgcn{p(Kq3Va^gL*bm%oGR+jEB<*^)R9d zm>P76$Bxm@Z|fQ_?dTa2N49s|@SZ4lCDHE|EwFAwe{MsAzNYFx-@F1zhn9|sNmlcn z8dtFawNmIM^>n6rS~n^26=v({)C5T#tIMWqnfo5%V14w$tTax#b*yKNbB7Jgb__2# z{(*|6qd@I95X;(J9yaWi1HXA8-DFkc-d$Q1y?;m|8!v7161ZHPTQDyXC z-DC2IiUA6YE^@Y4BlP~WDtXPAkOQ!|OsYwsSB^S7Jwu5A3I}e!m+-uaVt@fp-v4B5 z_}WS>dGGG|y(FaXNhm0If$nT;YVC~UoLhmB+Jy3ut-}V1f_&eGKo2znFL!itm}oP- z;tu-LEDf)g-$8TYI@~W!ub*Zw#;k)(G*$8dym})!w~Rt#Hucb!>-Q3;N3kC(9#%4| zWn78%j%k*l4Z=Xpue#bZt*Aq12`}%Ao1#|;tp-vGbu!ycl>WFL7+Q_%OtbP5a+7uX zSxe+8Y}X&MXeDy;x;4PE;t;j|%1L@+3-%Sunm?&pCLv~v2j=v{Lm}#UEY~~r`}h?0 zcU(FL(^bh^A4&3(nj#IsvSIW)sUJs;LHKh(>};l1T7{wr>_VgiGLw6uVh~u58%O?L z<4~r0URqJK!?H-=hycVN`-H8s+;zgrN4zXb#f0JwO#o$g#rpJ-#1uR_c6w6~zw;*& zT!)W|yC7@}uOoTNzV_4m83~&k9>D%5amy&82dgQ81KaH@b8XF>iY#<6N0K4MH%MU9 zV4lL7jnYpBwmQN`?55b&-gmFw-a@a5URAD7T{wTp(6VSnjBmP&ln8V3vt>{k?9ELWah>%EUx-9J39@MHTS#p^O#unxIL<7(o4cNgwN zshT^>20B|a;TKd<*txAkWKHb;Cb}1Vu`nG9t4N&es!ycf;Dm%Uy%P`m0dI%X9ybZs(GbkQe5``aP&m%s-k(Q1 z7+q6P3Ev*p?6l6OvrH8t;5hTEX+H1t*k(P*)D{50CcX^!0~hcTbmm(K;GCU=^iOy? zO*CIbduP)<>y_UMMZoO5=#6{C60yf z7vEQ@$r!2b={#R@w+Fc2k2~I18y9p^QrnOjvzy9R@&5;DZxs|*^ep@acXx;2?ry;ccXxLmG!TLf?rs5s zySux)JA-?02$st^=Y9|W@8O<@TeYitPxqRd>AiOCUbR>Euhrl{5tb+@wqCPU2lfeG znRpK`;tp)eXCk;zNaHK@W3W~$F288_)&=#lKy=K3xnge00{jP$X*e`8c_MA5@zTxw zcWw5A86Kyn$6l|$FL29|RCsZ(4nm3o5rUahU6w%gN2U!UZrxc0o-0-Ez|-utO=aep zRpl7(ZwmGjSyu-66^vVD-wFGh>-QIp1>9qOiMWJ0VFf$)s$}~sXM0j2vMSU&ojs3K z6us(%_;KsD5A%poJnvW{!Ug#6mJA}*ZHO&!;Zjcd@Y&n%tCJPdOC;qDynrM%+Y5gk z2~jKkVYzyupNJmn?KA{_M;lOwJy1r=UrlZ-u`=y5U81%33vzBT_XE=CB)nC9@opdH zrXk>d(V}j;We2kV&N0~Pitx4}%s6B>PD42N(OPZ{_&a{spHS;Znig!Oc}RV!MB*x% zpGXpqcwWEMtLIrqyPl0|QT}4H*dn1B?qSQZ0PRHo%r~2vIh;PfS$_mxEs#=IB_}*3 zl{uN$V%&ncmvTZMGxLuiqJmG=^r_(Shu@^ z&El^Oyv@!r(#`TU&K_|3LExVrYs%M_2X0K-fPyGCX3C((!N)(zQ5-w8vE4}tC-+sq zHsRBmD*XGByVXj1XfyHIz6Ys#P7mUQmsYgMG;P>(zod%QED*tdAc$H)#kg4aRsKyB zl|Jw&>h5~y{WuiOxsBDl8~grkvQHx!YIGReAcPKH_$@Wm>_=QtCo5w%6P_Y6-u0%Z z!Q?*bj|wpD4QI(7dVQ{1Y1;LPMiTFy8Yv1AL>k!b$I%|5!IVxX-?`yIe*CdWY4`w! z%=CoI@*yc`*%h88<4neh*jJSl%?K3Dx9NJYa%$8?2IJvlBm<@o<#xp$&r-cydSRcg z&>m7Qxg+w$d_(jN37->YNz=j@IlHQ@e28x+n(jPN^J4DLw(2kAHU2y1`j^s6n*dRuy0 zb-Vi8Knh_w*M(|;rbXBFKv`bbS&jIBh{?RFf=DV%+gY28q7KsI`l`%O!H5!oECKzU zfRnp%&&bkNoZj9>^r}H9#{;Z_%a^m&enPI~_oac6`9v%mh+jm~yn;7nW{j83r^FzT zVfy$aLHGTX9_RO-C{{|<$DrOn&hPWaY)H9#Ts(J0XIbkKx&(-rf{F8PJSUA}lUs3c z4o9R%ycBwd8q*jpZU*3NsW8Ujd|qBB21<|Yp9%`hi_e>aw&@w88vbW>TZX5f&YYKX?3i4&u*w@WZ#+? zbo29a#`XC5;NYGsPAtkI^BpY3c#-iIP3I(`?c+OZu=j{F^0yEjzw|--evawvWZ5Ls!o?T|;v=kC(#`*aq?Lp$ zZz)sIui99d$a&ugv9ld6%Yx%ODNilaE~{hHv{j2J>q^c^DY_opSkL3hHePiWCbC~BpQ=&$`~pE!o3 z?EUEw`J%Wk2G-?H7p6c<;X&ML!-3xc}tJQF0xp`^+xOz=m3^=vOXSZ`*vj;9TIV9OMv4RQqgzDYZuE_mIyUBce6?s8b<(0aEi@i>7;gLTqmB(#UKrDe% zo{&>d$x~DVaj!kZ_9%02-jP2du{+;gMK6z6yW-5BFo^SIZU}`zEvK$do4LI+C$i(e zOHL&PBvTfZ-B0=T0AaQWUEdVn45nx9{&{Dz$)JvoW6*i1(&9WSpLq@zF(E(oQOM(h>=dr0+F4bnIHYJZ4 z031PRqM~eoE-Ra>IWXgmm;z%k%tott1;oYF8UMcbO#$CiIv0 zX@664@WRKdZ7*C^+?`#WRa4b`7drM;ipw&RJ`be0-`?kV?f$K8TBRC8i%pd*E0)Uc zrgPxD|0kn;3I7dh!8_ z(HXjcvD#vZtGxMob=5laOT5nu49$(Zz->t}6v~5f#cW6hq zln3)*zBUyG%Ddd^UdlU!ho;K4>5mml0dbi> z82>ZHrLeq&Jm~9}F9(iazR>-DznuI`tx_}v+WgN;$tFJp6D*I%f8RM5tTI8Q^t?rl z*+ulbk+d=?YKVt)fWQ>DjAmORKvH5coi_#DZ*m5=(Xvr+U?r1XRr^`wPw#VIckc_g zR-=oLO&Bkn_ntqKEn^lO3kc7~bxC7S-aAj-fA0QHX34Iv1o&J@eQ5=Z)(>D4r(ZMv zn*rgCdDoFpbxID)TXs%@(l#g%;OYiUh*0Z-p~C7V0#RyeB^Zos2TVNyBjQA;EfTP} zYc3%q>)>w$QETUb=3Y8MF0+W}0^JFGf{}HXY?AugWRl?xmmm_iYX;ABI`fR^B#UgO zeQctSZPYdg4VLpMOQ(Z96@r@7PlE6vhfV0mG_O(bH4y|z=>H?Wz zI|6%)%9J_AeFuW$(US(#91_I28B_>Cp~!~|HtpfOXcP{Rg+sFIujrL=@0{p6O9S%# z2aau%5mIkT!OcNb-iBJ-_3KnBL_bx`OIVWmwZ1;o(2MvXRQ`+jLDaZCv*!7#3m1J3 zjXg}FZKr`Ej%|wl91a$9k_pSssIF?0unyfx?fRVG+2yn7N|)ee{ukLrwCwFouvMkZKrc*Yc8 zLBNtPM$Y0gTW-Zjl8#}`5+4==Gj4jU(^ zqbr!Vefh9p#Dh$Cs}biOW;X^iM+QHay_wie4bK<%LvD3r&R=HX)W%b9vn5?AYRy)4 z=c@p-S;?XQ#A)&m-($OeVq^9Vbppao-ev@f{JB4<)7DBvz-D@+Hpb)G?K^VGo)S=M z*%P-Kota@l+|hArsZ#rCNl+JAm3KzGer0QVynf+xTD*QWpI1hpxobPaU!kQ&Mg%cu zMdq$ZO`~;u_LH)Lf{yaYSd^H9z}<|AEr#Q(WOuLeHo^OKS`l8G!d-Lwzv9^4Dg#RP ztG4Z|yEXJTVM5$usdmPcO--EZ?y0q3#4}gOBCWjF3TbQ7CKD$7xum*Aj0Ae!&+Mtlj=&S5|kIl)L{B2wox6@H)fawyfx{>)9q zinHpcH`Dux^7v03=R$K12hD&0yA)k`$|~`Q?>=FK>iOCzc5cMqzl%&zY1Nkv=qVv$ z6c6RZ+^uVJS0<3Qr}{8rz#jdIONlQ3n~dUoIGBo^V1tDmMA{zomp?+vnAws!BThrc zVEv4xnPK=&qawJ{vxJ*cmit${uW)@ga_PR!d`cVc28K+c#1%QSB7U_-Gnj!fscL@N z8$~~*q>t!6UPMVi``p)xh}A{2qD`PyRX_S=x1*HhRV4mo^>Hz zQ!|Zkxj(eP@0n*`<@i*jXBh+S(=uz?i$qej$D->NZD07?csVlGS&p+tDLZ*bdsZYa zSVrL?qvCv2BZmiT5Xmg`47tVG$*B*Ys%>XR>D#4R#P|R(yl6$>gH^OiqFgsqKnH&@;Je)6r*OZ>AWWqhU;I~nwLMdW; zwdT1%vVB^nb>)KJ%vOJ0b}57=Ut$NJZ9A2s1zC{1e1|!OhV6{r#F}kob{{H5)<@Eq5) zGqZL=^GpA4wI7n^7-*k`Sc#n1(s8fd%0_RXbG?lB>=-p?-l%h*!~+B@HK& zeFp<~_UUmyM2Vl3-$aQ%c6$TBJtW?QGkn)F>*(HziXUhnD}kb50=L4@8jUdv^|m1` zx7`_sf75%c%$4e%X2~7-sh+_Z|CS))`pAeOXRi?H;8Ddw;$$oL7|+oKq+wC*ZOC&z zd4VQBgX}S>!s5xP)}gZ`;zOyjOuXR7f`TytjcD8fbQ%yX#wMZ_J9HYOhW77hf=+OpjGg_e9x z8Y*SDw)y%Ol0g+=!g6QUu1`do)9f=RxFMpkqodru$%(_Tt?v*$E%TR*nxs07Q!!1W z3Zal^{2ek{&!nz(;g?nko|$^nb>TSl5y;F|NZ9sa3`1Kch7Pd2tuL#X!tO*{-LOd| zpARH_7S4pB30=GKCh5O0k^FikeZw$Sq7t0#V0njoVe$UO|6;^j;jylst=aeOz1Bq0JZFT=ZWhMEqTztJ zKSC&>9QC=Jt71|hYy|JvD~YwN*R17SGYPWY+5}dCy*bh7@&N;y#xB>VDB=0pUI>fZ z+u^vadi%KQ9<<8bKr=~jOk|b4M&cQZ793MMoO|vz)S$iaBZVGK8h!Id=-@quBK#qS z0*n9mx!mtKKS6u3JgGz*(Zn7HfAAH?x;WGuM42_J?E7`Wm*O({NhG8=0+dvAOB%_p-B;H?<8bf-$%`l{uvO$5 zE8O+DH|iYY%pJ_PA11y1FeXG;w(#Zh9C`k0KjrFb# zPo<()+PVqG^oC{Y0*Si;%l6SoZ?gLp?(Zrf)9(k;z zY^e@)zI160+A&0GD!zYRZK-*Y27uI3RN;84xQpCkS?WljIIHDo{zC-qvRDM_GKVBH z&)f(LXcsgMJh~7MqZvJ550^v6OFaG(Y7z{dC5_BujQ%M^2ioZaL^@!1F$PAk5f=C3 zmx9zf8ZwIb(!^X83~6p>+#!(hZvt zx-q`H3QLMx6D8fhjhkLOMNf*SXBD?bO0HIF)?e3Yf$CfBWpK|L=A}UHpOGWz49-p8 zU>f)}Jk`t^mc9GUV7{b&5afQE@0SqBr0=@`v4HQsE@z{U!co*klU%+ngy(uba=B6ykV(3<4 zQ2F$d)-h~kM}3Y!11Kb}jRy7LN~&5*zLbA9E!(K(jJejjCzWB#ii8s4_M*UaGH#ZF8qcVHli9dO z?VR9!;rR8n%sov{xR6v+p-KA{EDWP|alr}%MW#FrXi>e$`0K7233qy)R$id!ugN=3 zj>GvHw?Cy)Jl|B`DT@edk{94xKM{jof`Fe}dqK58)b7}si*P6Te z!s0y7Y(l9S)h$j$%MszhPUE`+=Asv)At29}juR$h&~f5w1oW&!Fb z0@|oL+`-gQyn-4WRVZBRA_PlKko}>MvEz7+igK=KO%^?CG4Gw)=&MS+CJ>u!!(LPrb=A1tn+2f{E0kRrfRgV$ze z&j7P$Ix}wsc0Vq5KV)`4Cic!`{2w^%eqY%;qwz%|yoEFHMMCjEzMDNS4PLvMJp;|2 zk3xSSb0WhMiofgsTOHRjW93nl_uzU-`mw~h%?6$mPs`kG5@Mp`EPrH zc9a!T6QA90Tv#;58)aNO*ZY=5C~mFnn&!Pu+SEJE)a)Ae5k#!d6^(oTM0-rub?pa`5Dd}_iS)lT#NInac&_E+D_T7bFf|4mCeacTKzRjQ~FkhqOk9N=(YZezTw znxiB2uyD_)VJslScpW@ftsxav+?;lFRLbZPyW9p>@ILB#3MZvIPHEb4f77W=vG!nx z%t00`1c?{K1Ru{3K5G=8*AxE*4=F;0VU$f55Of+uA}-Ehz{+Qm5)VlfqTvky1RsY0 zy>(ssDe{^9=o^D;LLTA8;TjQ0*!54M{XTC5zhXp9$B*eW8SnhjY zLw-HC&JyKfzwEk;vvkwm4=INT2~i*H>*nXqYMrnG@nGT8knj+-;qhcvDWmOG#RQ^C zP1unqX&-?_xumY$o+Y^~Zz=CoRE+n6R)yJU1Pglj#651LoEp;jupPmeG!VTjwdlJWa{VIn%zPYLuiM^^k7|O`XzvPoDrisfO$I!rKH)8a) zPjX3*ki?ADzOmpdOqw(WHcWVQO!nTgfohwOD$taeQDzK@4g)q5?}nb=px?B^xeAU!;38oU5f}o3vcx7@BCf zEH((WkP343ba*@jOBFhWAU9KvMMQOzd>8IYoN?0zHk4+h1+bJU>;;}xzjZ$oABzE0 z4?NDQ(zQvkN{ny_;Ut!wYwPaNT)#sl_R+3GUsx23Xf@uMYZMz^R;aX}VtPs0TsP8+ z&5rHjsoUs;gUqZmmPlh!?k|Jz_S+|xt?x8SA=mrTL5)ixp-6jph5MkO#<9U`#T%q~ zR|zo=&Q7`?VggQd04q@1AS+-*5!yCBkbKLQ0x%MgMD7?VAI~#H4akayv9o;$d@3$g9Z3+OwcfNihq*%f@RZl5fcbHAX_) zawE*^VHSE&0nTOPdE&_(sl?VLgBmlSPa!Z1nW+F9fcWMl@=J0t-*o6x49r3q*?3Y) zv31#?#wh4h1kA!MDu8kVx$t`rP9fH(H&Y>@GsCO^T4Wg8h6pg;r(;;4r&KGDajbE? z68^S+Cc!pY4|xt7Mj-`k(0yhodCoI)5H>p1qi}}VupR!T` z{v?t6e+#nkXNa#~I%))?oXPDE%1ae1qQ*hkp)W}MRt(%xVA3uL;^T{*t zaVb7$$@afysp!8{5#%_7h>3Li@bhCkQ~;t+M^Ic5=3&jn)-iL*9c$4GQE-DSY6Z?$ z-IRhF`#vX42mZgU^X24@fB(?|enUB!5dkpN$<-A?qXxO?uovI6Ij)4DD-{q&CZUD;;1WM3 z4U5}|=I82ks<_e*>wAnN#kliAo8Ln+={p4eAwCUPlnSnq|Me+Uv_Bem#1wW<=d=5b zzp3lyi13SwxxC%dvO-Q3l&L;kt1;P7oeWO<2`Z>Sa8!7Y%%cDOZ6!sHZa?%quR`9( zl&l4Zr_Uwr#Z8?PTPlDfBXtFt(%{~`;g-OR6MG?RFKczgO#oXX33>5btPT>CB&(@M z>~K>eZsxphNO4G5HV^9U?RQF{lK=|&%9h@NCu#55e`cxp^`ECS-uSlh1LsWF*Ifvt z(GFWCfnk4QuF)H0keIKp-`l{Z3H+qE_BXYoU(i}GNu4N#m?(rcmAqRie+XrB^bd&p zS28kPyNtu5wVd44&O@S=C|t9RlZV;=ml7IHx_McD7o3biYW8T;07I&jLqv+3xevx= zCdDP(1yl47X!Q^9^bdIU4-DMwgUPOyuMQ6_)GQ2hI+(kZ$S$x5qYzBLQPGu24o$wA zax#!(*4L*^uTbvE=45mcat4_l{o~Tb9?)fCAKl|D4!8LXN)nRMJhcy<^k4PfUefZ7 z&5<3tEcA{zdlE;Nd)k=Me1;q>E2LBeScBS`b9NG4#w9h{)mOc5a2QMF?hK20#Zt~yC?(yDbg3pn4O1CiyR68c|2f1`(qUwnO5xirf z{Q)-U`fgOEJ!+W>%d|XVx>yR4I@)h(4w+e@7SF72&=)J5jm*{%&pVLMq0#>cdAjiz zjkjk?vXaNnDdzYsy|zi8-#y#y*PyhWOTIkyE?xph8sNsgK9>+3cdKV=2fwMB^0Q3a zDHG=NTMj~m%BqI5-te7o+j!shEdG48BQc*zz#dV$M!H2lS`}zlvwP2KhEg*aNAlr{ zX;PpiE3<5$=g4WARMEGhW9HPEP-wC&p677qjiUa{lv$^aZ~qpVjBu*P159$u3tL3` zLHhuTDiUEc7!OTQGfrnZ?9-q(P8uQzNy|-UnkMgjlVtxOUh?AE^h&knBS=&Wx##)% zS~469&4I0QP$xPi#$$yx`Mc0~0r|>0Uz{9PyZu>qsr5~p!uWg1sVW&S5U5qrl8wi2 z|CKlEZvr4ET6=yeo?bE3p^R9r@Kla#?JSY*#%9Oily%em~cS z5P=giD3{Js)}x+V;u|<7)Shvo;x;s`lMQ(fnn>o8Qv6tbZUEmf|5g9`i!`DYMJhX} z%zy&qD(#UMo};cOK538O>eYA;XyCRu&1)4$GSO=-%pUZKKNI+Z`p6gI>DoLl7Sjzt zA(y4Fp|ll=4AW3Jeo2g+b`b--%!9N>dz;A}ltV1AFZ}}*}nd@>+ z+6MU@Zd6Vex&+Is3R-Km=GWW~=~^qbQYilgm2+}$?%IO{>_*{vpR*{wp_~fR@pz=9 zOsVu_`LKDlFec8cjpi+6(f5Y##ye3&vVcA}JSFEg^3ociS>m0-S#pkzbzqP}q0vJu(8s!?q7+d+~2yCy2vfJ%gv}`OQF?baJvI++t zcM3b2!d;9e0f_<>xD?*6vL;E93EqY~Zi4fpvc(!o#4%shwqPTDDJ=k5TX1 zOT>X2U;r(?l?mAg+4mC}Q^@ZUX&INZ#ks!CP%pOXKAc5y549RB z8Zh>WFGOri1uRy&j=wiLq%aH^mFbIC#8S6^KF$lqQ+COxWuxt?ol3aK=h|7=JLxnZ zF$7W`E=R4UOY}8{*{hv|G(y}k-PcmQiWac$ME$b$d`wHyD1{%Pt2#jZ zaWBMF{L_gfOD4;0qqS2g79KW14N?E~NBrWvVwzeJg((`7ZO{fBb$hn_X`}jYcX}!R zkp`C%_#Q9*v@*wuM#qVz=EL>oj>S)KlI^-ysUu^fqgREam;J_->c-Vv^H#;@;izBM zT(#J|Rq}Z_>K8Rv%{NzRZD@HVa>dv$4s)x<*e?w?sm452#5~DxSF01PNO4zd6Rmj3 z&2l-Z5b;WKJ82N{+7Wrh`IGV}dk90JbqGnX1)ZPkZBU4 zw&>V^;CvlI$isP+Yk8PjKs)3zK)c_3p3Pg8A*2T|01nZB{+A+c5~&frRg~ae#)UW{ zM}3kiy)R^o%#t*`7d+4Br^hg~QgriN%muNNSgqD8lwiWRFLF`vW?7Eyhhd~mo*mJ_ zt{vzi>i6Y!J_8!274q(c2_n)p;_E`hGcNmT=wCS@vN_9&qH2r!g4Lmq#gbT2`Shce zGtTGY7_&6jZxcHmUk_;M)tZV4Nc}KV3#r|xlo_)aRCRTDxC8Tj?Y`o~TB_@c>GEiL zDp906+k(P=1y_C3Y8FP?NRj`}dEt#|l~Ba)L-nggkjzubm8X1D6R%Lu%mysp-u=Q#k-F|NpaGocI5fi>rPj z@UTCeR;rwEd3iM?r54NdRU^X*p)ikKG8wi~6cgIWy5 zBNcbRR}5%{0`u(ad&D4UValR0TqC!f1-+U8*ml6{0BZJ4Xv@5sY11SmB z2>8W}*~@e^`b&Q8zvSNw$bUV1A)=u%&Ei8?7(_2tut?x^85!id%ETXn0cHH7N0R`T z`kXDhKEYby7yo-lxmV?Yz?WW3N2Z%{*d)lzeM`Vp{bO_FYi6m={hPg1)I8uR#Ffwn z$^wc|QCJg&4qJodv~Yp2pFZ-)_9+}cGO2~;vA42jwsMhFEf;=XCGWdZXcJ-mI#zaZ zgKUJP42JdTmv8L_= z;GXPAQ93th;>Mj=+pIC9f)DHaicLV25sw_h%>&YZ-nNvD*j9<3R4c?!+TH)s#p?gy z;ngjHKwBqk_y6~9)iiY9ki-@ynrPl*P)sUDu)PzLwBQVxAq2*;t&`b0dA;1$HzsrC|Tm~Ku=OzdL}tj0d-eBYk`%&w5w zuxK^+{!!9T!U^xlxLfQ@qQz9R@vte^J22}hC|1P2TFDm8a}jF~^3Ub0%oTN8;^XLH zXN*1dWFY!=?6P2}TL4UJE}zjKe)Q}rathG2w-ZE8qBS7O7o`&{_H{zfbZWI1@Mqa) zmuRl8P=2zQWS>0Y?kdxcN!8Y#T>O>$1cr8+d%~K&&#wX4GPVBtwUo-L^-x?p+5_#3WsZB4|3k4(4t#OSF3W~xn`F@K_D--N5 zG`Mm3iEXp^ZEnjCG-5uV3S`b9V&Cc{oYEioT8lh!+~YH#Wt+*;czT9{^%zy+y#BHB zkM?d}Ux=brIc^TW%Z$ScrjFbUK-33)n$)WBqETo};r|jMBJmfF zejb%zL~fi(o5%~WPt2L~ZMqlKv2{D(<|vx92Z&pQj&?`*YSe5nJUR}f?wwY- z=WNH3oA43Tnf5pIhx)&7U~L0$oF(C5kDOb7V$E0RCGTIB;tky*um4wEsxdB-9{*%P zSbR3R<@sOpEB^;wr(o%14Yc`Bbl6{Gq7j^b)n8)J?V*T*9WghksO!k<4vD8tG0Xyc z;gM8y6ux4mG0l@N8(lI~q?o%k$@(7HB$3K)d_q1c9j})A=!ZT1-!_&175})kYT^+e zP0Tr=yqwJP+2Q^3YboGgzz60}I2Y=0$65R%C;%K-qL`p-mw7b?=4O> zG}$zoVlL?TMjXj#P#)3tA&LA)WNt)LE@vn1;JJ4&7!SE8xt5Y2CpSU~Z6*dyIZkQ# zNV)*4Zm?D$Ej?Svk812X6*{25UJ3gS^Ptt%?fd8~B8*Xdt)Q!cU|A^2)FjB`uFxYW zY^1Hh#!{M_)BIXo838Y079%G!viPW2T~@#v=p>Y>FieXoYr`x{C(w>Tx&m$8P;RX_ zMZaz!?(psuu;yBg`tA>vu+AU}3$Qpp*j>Gzy*H2zyHQ2xILo7Qn0BMJ+gMi%%F?w~ z6<4=;v~e~N-;YlLi@R$L%ED`LCo%G@~uKOmi8li{~i=)GRC}=@=rh~g- zBPJ%A^0_J6zg2tK`C6ag&#ocEOD1Y^S=42kD{_zdb62$Jt}wx${W$T(=;#iN)EkJ8 z!R!3!xcKB7>o=)k;~QQCudQ@ADhGY@Xf@8dEys;!2iMUNN`&zQ!tHbjj~CA+J7-4^2cOK}0sU_-)>B@hC^XA#oC3P-A|^f2!;ujN{MbARpE zeI_k}Y1vh;hP7{q8o22pg3hI^awfhMdUoi^C5sdS9F#IV0= zFe^)Xv_Pl_CPcBOEjvXM?UQy7D#R2%r>Z)|D(WtPpitSGUaUG2ebqKmGl&Ge0Z zD5f{LMpDC%trq-h>n(HH0S{cGOW8}yAqxQ^Mzd8qCmM!+gAD(<7?hi0W+avqD`}68 z5a_DnZ>*a;3lN&_!5lW$m(hjz_(n>PMxx9-2Iu-Kh!G6&_WY(WC_qMCB+N&xt`y7_ z2t#>3FZ+C(Vkvd_IB%@8NMDe^uPdgMLnn`I0Q#{j1%OrkABLBUh%-|a)>V$61;KAA zU7od_1D!=ADj|Y$`qm>WoP}x>!P`H*gtp5XEqQraAVZwu~JcFG*yCem_K zUWY-eciCB09zBtr7e6S9g9Th4U68Kh_3C{Z?@}Wwhv+DV#gOEs?{>KOuUdZ;haZ>( zbDhJ}wb!~fPB@P&u|z_eKhcn8G#v;FjM#{?GTak~=@OpZ410|zCQ3TWI#K)(6Ot4} z!)gkXmfd|}@jvAd5m)Z%07Ao^(5E$Hh>6BPzS#JmD8K-FgGIE+UL;}e^Wb8Z!$fo; zNbd6_9`ef&Z6wJ$Yta15Aq9@a&^|2{KWPk3_-MlAzlnY; z=-{1gfjsqhX#Zj?XUi8gJTYN&CJ5Jq_D76u1{Z!hHd+@XTth zwS)SOuER@v|K?D=L?&IA+Bba_APSmaq?SLIC#yN9zxHf-BXdEQGtM}o6Ms(Y&)CH+ z>p7pbl-WQf2Z|Pizd0e$KAXxc8a5YHv`*A*aGSzpQ(5$b%5AMqZr|rQLHC)apD2Ga zBTg`hTk11Ywb?m=gOh!CxMLZtWk;r+M*E^hl3PXQEn`a=ees2gI)r6OrrjN5$H`c- zlP_%Y#**e{T_jny3|eiZ;0%}rBYUd?K1U2IRKD%qu5&t1*ISkWNjdr#WioQu=%p)S zKfI3|wcxRVvq(%A7Xw#E*jp3aM%hNE?89;>nNRmS`%QPW_VroIe=dKWCXW3NKBMF0 zXLMx#U!&vy#YI`t)^{PY#`%b4w$~=&cXgZIYxE~_X?*cpe^q0$JW{g!DO853w;3qEbCuJArpTb=vo^L3IgM6;jSYE#ZE_Y) zAUlA1t-aNgDhgQ13L-pzkRgp&rK^qSL4noDIW|C#YepZcl z)oq;Evy5Dc3}VqibV#=7R0dI|TM|@qgeCmjpH+*I`LT@q(8U8kt}M+z%GCR1#Ng&B@bgec2%)+=vPvr4 z+djy$^_ZY5!Mp)kev;+nLeNylx4gbSPmtfS&qB$$f7<@2@(4eun%(~@v9Fg*epQM6 zw>zl;rSUR1Z4WlREy(ih(9J^4IJ?%d1+*xq4*SIk|}t0$AyC{$N@j<0p&f#YsZ z?XRFo=76uvYOs8FwOZ$yl5Ul$JFvtr-BWNJlL)7m#md4~QJ*-gg^NfivC?E?C*|~% znki11-R8mPEtdXOc4;h43O5Vl>wOj1SG6Z@zob#uerCs^iPuc{KeMsDH$X{Sf=vFh zv`uPIsJUSiiPj1+hWidruUioh9-;niq+-8$CnlEu4F<;)IL0|?m4xkHA!3$?IX1`o zX-ijog0-PdF9NP!dTxF*vH%O_-#+2H^W;rH@nlM+q3i8SGKI_fPV2NXQWN<$s09nQ zMZqCf`+b;1Mq@yBNpDG^0KK{MoyLI`B%e9padf7{-)SQVwwnVHK&#`wQ{|U%^Yvd= zRYpXb;sQNgB)Jv4N;CAW^s8b)!QRBVm^I39Hw1n>;k4Im5nk_1ZtCwfh zj$ztd_RO6otp;lY9)B;z2~p0`((nztc75I<)3`Sb7fH6pqs%V`6`hJ@{F|W2shppI6U+$}mFB7k9SiH(ppPY-7nhd&1 z1;zYScSZb?RM4*`Ze$nPIB6Uv43N?oixMy4D?@iu_tW}FJ7Bs1ckKR*WpY~T57dFL z)n#^L8p`MO$=8m14qDdq z^bRdos%y?Z5R*2)7HCKphnfz15d?&cW zm5cgub2^+&=l*pw@fn@38{#FFmV-hBO6W*;@R_6%(FD`giEIR0Bh~D18i8(gfFXzC zAMeodC}Zgd{af_yo!hGflQLclX{QkRmN)Fy${hR3MjOPAJCxdS#_`+(G6?#Qz?(Z! zyzik0^x&vKvd2Z)gg=_$|HIffMQIXrTXuKZwrv|<8C|ydm2KPAW!tuG+qThVb(vFl z?##nK4>OZ1Gcs4KT=9?@C*qtPC-yG5`w;^+119AEbBDXVN1>sqh1!t>^#h#ia*oMa5`?<5RFlttcpZ1%3=f?aJ3sUusM3uIzZiO5I{kN6 z+nSlk7$k6p-Gg^CAn3XEUh*$ByrV^pVWy3KK(=r|_6V&v0sRM}+KISZkWVDV358p_ zZtu#e=)0e8Kf_7MGu;Pl&HPMRhL6O@Jq`Bvat-81Nb!lQQ<#q&c9+n^Jw*8|!70@% zicSIlLdyw5qo8k5%86~|i!1&|s9HT4{RB;Gkn3(%>@8&d?;C8$SvF~sF@Pv4o#O8Z zi=%DWZL;u8Ppst28xOAK%X<$D#)-PHZIH^1qX&A2nd^t+)tDfNbC{uqN8PI_7E?&T z!CS~zFbT4+Ie{;lx3D*0;Qb3bno%t9O9TP`ZaH&!CSYaaK-T8kC^Xbf3cLU3y@O}a z#v50xx$gA!aDf}buP^ZboGvMx7mr`QY1pv8IWfP<#Qv{LVz!1rD@Ri4|GNFR(8qt{ zMM+9?vj0UaxIv#tPt)k9qC7~guQB9(I~9U~jMA7Z0d>8=Yz~p4!Q4T1tM?8?fQ>@% z{)2zq%|x>fog}rm;b|J+INj#z+WqzX3fC(o@>9}Hd6@Rh#oa1}!exyTSP@i$??pFV z7+SPk){1CP?8IR6SL}3~2Ejk>rT3&D=C6n{1)^uzDD$sz>!pPN%w@IW^C`2G*x<~P z9T?#x?es}u;~<M$+piLkZwb&Joa@pv%O(-I02VM`RsB8GVcX1-Qh6y6PG&7%(d z^{9#|9dncQCH}FN7_Qc?`yhIBEy;<2J`M47k~xV@%7yCR(ZLGr1h%j4dUY@EYB)^p zkWWp?!>3Z{2dWkxbw=qGHsrylj|YxmtSea3ua7|Mt8dmHgWn>6k9NIK~f$ ztI+F7hIID1C)ItP7OQi3EHm*Y$U8O!D1w4gBpof$2P1 zLkvE7K^!tOh2+*;=Ecyk z1;fx#6UETr=fh{LjvZdC){eG%?rhU_M{7wn*FbDno7uT z=j;Em?Ni0c+{)a^{eQuY${UI(f{1{GAgezS0=+o-;GnRS)hTYG3hDxVb_u`HI^i;y zVCg&TS^6esoMtY|MUf3OMDd$VJ&rT4_)fETe7iq>#18-CgpI^% zwc3@$1xAk8sc22~HgQ%Th{1AfoNm)ycH)Ucy0Y%uz&;tY)})}=^Y#vKdNA4O&-apm zFRUF4F6$}z-`~MfC_b8*gkIZE9O-VCw^LveH|L=wrkL3$wk2pHLXumw55#nXn%ke2(z0*Heq)Eujw~$yC#OP%^4z)wZyvHs<`dVD z-J97W>>R{=f<-)0Cbka6&!uKsX4s}&8oSfBeDy|M%2UaQZ;yek2bI%6_N;s={i}R> zdC)M^=!9Q>g1kOoCaA#{PeFeE2~(CWf=egfMi!Jj-GEbyDPt#^IKZsh4 z)t+t-ZiT{7HkG^^#qSRztUu7Yiv z-RxmgT)Oz%LKi{umGVQqs%*@e{o(p&?+=fYwAmiWb^Biwf;yr+5ws*5%TH(*D0D)c zGCO8NTz)L~Y!w)@p$$eGb1{x=H)_NSrdO*B+HcXb!>&Obk4O@YNk}r7#)FO4B{LX< z6&=jcmjmxys$$}Y!XzhdfYJsuN^P+f@oN50IVPouOHf;`j~bz>=i5m%{{^p8rn z!5ZDXAWk>>vz}%aLJ|zw`ZI98?(S9)jN2y+%eIYT*0D@owO!b{%DKq-yuW`B@T|I2 zqvWvyvVz+Q!JzS}H;p6EObScq1dbO9BNzho%Iu3R*p3Hc*`#H5I%^-_fwyc%Ck$Dc5tvdAZ5D%S zxIU37e}Y62o3u}7pl+RCfL*Ubm=#)MNAIoYr&e6m0*cco%gZXXc(k9?$8|kb`b994 zgW?j3>}TI~@Rf)-ivo(#CPdCR?9#eBCeweCb^{k_kDEbHC&;Wntxk>@+aP=#?hD7) zYqf;_Muhw|dp>lR^Y9@pCDKz0=XMtB&yZR%gl=%l?x#Ffbn}l4T8kYe+(SK9P?ne6 zBP(r`N--by9X-#K4PR=lSnJ4acPH*>MBR5eqnLO|9^)xhY_7n4$0>QH(B;Xdx7;7o zs39_J-{MtAbqR#-zy8T@40XQ8^Eo)>Y?E^I)va8H@oq=$Jg|wrZ9k=>e5z~l$(410 z;kxHd*QtlYrbM1xJNvJ<2bM$}98^=_A;X@`d4#sGT|?7R4z+pP#K9k1>q-+SR@(_dBf30sP#xOa7C| zRh&zXlO#`+J^w7kz3+)-4C94u0+eiy^x($=7Eu~0SI9HNf7;=zx2NKaz>gnaU_bv~ zD8hf+p&HQ2@_*|rZ+Sy`p^84{i^-Uqq2hd>#5w+!^4DIVkXYkw?|HR zsUq8_X4~`OY^mbx?2P~Y^~UfA=+?s0&-To zO%PCiUPsBpOi~WdgIXhfUMf^q(pF|{IgyY1Ug7mDw(5Q%@ss;rt={Reg4wScb~Xvu zm@p3^f8Qq&b~%xV8&)Mm5tv#Gy8;Yi4uB?MGgdBU*2F3pFf*l9FeJ~fD&mQys5XO;^!m#izEoRLRAsr?};EQWr@ zC`>h%C`^@8@=x11t~gP#TU}|KQcoz7b}7-ATbcSOT`_L}x=8WwLXv1A?MfmVcO_Fz z<)S;E&a_%Mt8o&%ICX`yPi=ijyl7%&5vT(E0#PomESQLf-@HC^=y&BVocM`+1#a2D zAt!ex9o)@_>)?dwcLMjr1#*)1;tkLiP$n+ zlA$O`Q{1+N85Yi*!8R7fLRs(|Wp=bc+=|8XT4{4acN}M*=KT^-%Wl7TsjxArqyjdw z(t+SnH1gkh5}{IwvBj+Cc4_mu1GnQ$iIaJSze79~6&*2@2FBw8opW{kN~jUYMk z3Q{0C5erfvIWY^CAUaVCmLN4|7a6#49%$wYVr?jcHg*D%Ez zw^Vk^icfL+47>}O_EkkU?ynioNE_E0&q%*(jt+KZJ<^eJmor@pkI(DO$@3D}4Ndea zY}oz{X8WqH^qJq#HBP~eQ}~`#?Ik&8ntsQT1*gQflGt-@1?qx4C;k#3-$3~S;Xde# zd|y=jP9yvh-dn?xXzRqT`{EjMN0-!7aOf%XB50~q$IPVtg0OT?LiV+knB&AQ{Gx%; zHqOwVT6wWF(L~r!;3jGeGm)kY7f9 z#Fs@U&lbQ8IsTna{l}}t;v^r_cZgI8qhjeQ6)_E8`J}7?noSBreEx`JNjH5x!=bZN za%y=9{G!5wAPX-9oy;OEP_wC~_;Eu1&GPI=R+XCL$?JJyXJG{57Lwu{a?p^q)3rbr zUNAsAvk-oM@xw_qRID6+StF2J1mkb1Fq?Dgbb#3lZ7F<-Q4oE#ytu^~WtO#|XD{f3 zJ=nINL|k$7^4jegrVL(11Wsu?&W))H@##O+)2$_Y$g%@AHZ{`{ni}&nP@T=Z%lI2uT^7a1lQHfUhg(2|;lxxxw zbY#wni%RnX5+r2eO2~zUVeyD$Q|%s+?V?I8%#4y}=OBIgn!ZX(xnY7c#pT~Slz%5n zopG=-j?!2|+GOJP!sMlw7yI$6H<>#W^b~iq&n~jI5x-t(zU_DuXwN zVBSNj>8{V#wzb9eec~~x)7YkWvO+^hn8Xl&fD5z1J;?mCNPj=K1X+Sz#Rl(M=2%%& z4Mn03{CRj*Vjp(Gs|%V!6Gq8q|C49IgSa^t6^I2_*I3LazpUNDhgeDKtf0lF{9>v0 z9LT2JOn>J5+r*x*vFzu=X@-uH9!mPe?$XyaYU?jFly&8WMTwrfl~9Yo1hrR74k@i` zqNoZ#`gmjWGj{MT85s;VLLl=^xc%+CM=1$yuc9v^oToCX!YOzqK9_1dvwd_LAJ?ij zL3tUBG(BYnEgeIdtrdKl4u-~u#dc6vBfD^ zhLa#wTv&Ec8rn{c!o}Dgi+={b1*}ps09BQ03U)5ZLy zgdP1_qs$Kasg8*ZOY0BURi7esK_e~YU^~bgY4om3CN>$iJm`rbTS@goOrFzC2Gm5L zWK?5bTlcuK@XQOkS%#fpztv!DFEn$8&}yo)zeiz;3R1`=H8e^JYY6zVz1{d0HA^M9 z6R3tsPm)i5V=)z}c(q;8vuBT)Z(9}91X&va-W4oP%!-KT9M=>`$?W|aqE*L4EBWGtkeymoI&-BW0=I)TpI<~_+WeDf zZEuO9=7pOCs;rk7vTkR_0#GPiu#xS@8gfy%7BZ`UjfYG3Kz_Bb5-L*0DEJTfwtHk>&F(m{>WQpa+&2YXp_#`ij$5V#C>1SD_%|-5SI!1oh0g z_d{}vv%{+b{ib{gp>nJWC8lIb`$qLNAFD(E8u6%JzOfak2}lS%j>?c< zmoEEb;JZXF1Ar?-HmWcX-Y>V?rO1uoqFNIE2g((hnx`q@EfC&-H=>2o3?@nJ5s@G3 z_d5)NZ;mZEBP2va27nh#LYY)-zw2tgz zZJ0dL-uTUWs`e!pkz-Z3#{U+`6jrPnf2=?)usC};RD+TptKo)ps?u{-MNKYj zt!4`9KKYd>5>WPgpLDh;UPNV(a3Z|?!cIwv!Dx2FzAw3)KJA%0S^8J~l$5wLtcL^? z46c7&vF;$@hWk)*9iKgx&Iu`@k-g>_Obdyq>1VDs+|pu19UdNrqWOp$a~Lh%?EE5= zPv+=-s;Lk=O&Cv-8MK5(SOnv0UVEf?HlP|k zTF#&VQo#wRszd*Qs-a?F6$|T~Zdp^bo>EWTvOawt1SYa9*=$t)Y>~f>lMK)t+VboJ z^;|c6KJ|NFp@_ooLM|L^5W#c*snqD&|87{4fAh-=VRCy#=Ib_j|SqB@tO*!;Z8LitQ zw6Q7m8$f_Ihmxi$bVfW`k6qSKXpKN)Wm~eUED0q__ds*0`^}X^k1k#$)uHZX4J&d< z9w{dhtLP|bWR4ixxnlrB96KKH8?;LbqaAN42rx7sLT*)5F{gx>7+zwx>snS~w~UgU z&%0YAhD0eP3JT$q624nWfm@Ys=mye$lMQ4{GTy|*)@hH#(MrK%d>(7A&hzWbNw?;@ z>0sBt;jxygT31%mvKGJJIQwvBQ(;YF&Qo3v$d_~#D~u9pFz0n72(5%%DX;~Db{cLH-G}~) zOXCEjbqMk`+VLhySy*IGqO=)hM-TExWn9--3o+RYF30Or`;BhzL&YNqw@wTj*OJ9Qg!)!QhYso2doAS2S=0+#HPfHnUhIM}s#vJqsx4C@Ue_O-R-FlW=Q4b09i zODQ^1!?O*-oXWEIsT+1!`rV&H(yK%>ZhU0AK){M=mf(=)t}eVd%9P9{sz61~GSE6g zw*po3U6a_;ku~CDt;YCiBZ?7=qc_Q=CW$CD%ZI2hd2jO|B^HTcJ;S7_Im7lSLcp%^9?lZaC4Vm;vXRJeOH6TMcTBJyuvS(t zO3Qh=RhID=16knTT=PdF6P40x{>#W-Jia@AwG_mHPPy;Dxw-dr0qdroa%cw2GaXnD z9{R$&6UuDq6h3Z;vgp1Cb6|%Qjv!!IZvz*SLku{phX%yajHN0UH8IqZpEq(CqcLGx8_wOx33|jxSq$BdmY&N zJ83r|qVO*o^;q&aOv((9jf;n>A@&Uk+PFc7Qyrb-#xBB6JsCrTxWaaluA zDW?tNvK|}nCOxHVaT{sQB-5V?sL1Z<^5-=yuIrDKY&Sc%={DTS&?a2+7K)NDRS5!@P7QePDbWyRM+OBO)2PYBYsr;ikck=N~A z)#)1({>bciHo~lhFNTU@lus-$-FM9D#B~c$7>67fT41zWE^zeO=lQ5(|Ba$QTq$xF z%FgE7`D_n|`A{*}6q7tB59gH5JL-;7OeNWkUIn{hWs3&S;%UwLuo395eqf`>*!N4h_OLMGp z=LE<48OzBy3`3Q@K}gJU#6eVR+^3zHd~yFAJt;O(7L*Alf1l zH>N1CMz$vKyfI3b?qNxnfaLE6DsGR+l$*s}c>*34ZyDSW?|{fT_+NWQOF1j_lqcMew%F8rk^3;eqW; zy(9>bU{&8DeA%k^pS*<9O!#-0wTL9k}>66b< zc*=cUGQ~PTt23Sx7yYx#L${CnacQv#4 zm2K^HjR+&atdb``EkxH&(70dL-M-Ix-ketg9#h;+!?>V-Ye!?Wz^$lsggU#D_GLw?2U7L)9R*W3(ybZW!e{8eu2Zm&m%6KCgd4xfiGk(u6?@Gn@LC9MdL}ADDhL`}eb9DqW@@#VuXH@OEH59xwmoVH0 zoikPif*q4@sKnz`Y!5Td&O2K(fY_Pgm4gCWM2*D_4(qlOH5t0ImRt_(F<%`vDy#;U zLF9;ZJWxfAvoig>Te@6;!)t4n>TW{fwXKZKLOoD=L={~_E%yu#;YxZxwQFJpPX{Ca zfzb=#-Bri&Ru88~(D|JqbHVJXCbf%Eki0|@YQaBBLGnxF)R)=iqs5MumBQU zX4WiV7?Cw3w+=Ll%nVoX01{hn)~&pIp;}E^$`&8Ckh5N2s`41S8%kLMUxgzsS7N)o zU`ZHZSpGu2xA2wRlkw4@?M}*7j>$_YtmHqz6bD2y7OJrlBXqKcr5<+$F{8cY@(jc0 z<5y@{Jt754(kN6UWszClfN-dExmmAy#r|y4Gq;LCPlLrk^g!Pu8i@eO`vpc}+D3>+ zc(x{9tIbf4o4-RR!4{U~7KN%9SO(eZyG0ObGbNBEi--|k5pa5GwrP7bPby~Jzp zsUv_8TP}^ER@oN;Q)Q*U;{UF8rUlVqS4F_}pH-h#vAb0;?Os$pNvzFxZmMpp$OI8s zyh0NIczbYJ9y+}YTW4{)9#nwutf})-aDLHQU*pj;4?VQNpGb4i{dxt7|3ET7L7Un4 zJ6Yucle}|=>ZL!4d>L7-q-4w%7{6)@GH`_af#(^w0X^ocnu;Lay?1s75qyuQ0R*Kr z(ZkJ*9MA07-7?+Sw#R~tusaH*(fA#-x zb(0Hg6Vl%^CZa7g!?Xp)TEMy^RnpcPkG&Sa)@fHt=L?J5N->GFm9lzGbsNIgN#fc( zH$OLH??d{Nw@kTK68+kz9B|E~xNc1(rHbQmg59}2F7*o7~HU!cFvH5S0ZWf z4k2QYsaQ{{iVnDzU$YLhY`GQ_RZCJ+M|w-;I+Aca>Bpm*x`*NPqntaWi)Kcl(C=^= zx#Cr&i*S?${s;u&z1OtVt8OrOVA*L4x#nf{wr^=&L2QZWfVGckokCoR$bhx4YMn+* ziNFhKm3|*aG>!NNYhTPcfk**uRaUjnDa;CW5t<Jp!7@ls1^$sRC?^_@;1z~NA%Tmdd&SBRJu&_x4a5{e;*46ONbU38_k{Zde9i6Z z{j-Jp=5{RV<3Gy5c{ltF>)ZKDfc;MQS>5+Fxx?rN<2$-LbH|VAMbWdh%W#(h*PU^Y zxr_AK+IPM8g!3-u6VX@mmjm-%(hVeP<9W~JQ zU<8MEum!Wz9|EpBS`EvKj=z7G=Gh{U;UEb-XUr6b_giVYGm(Mm*-O{prmeGgci|Z} zFy^m2IKjjSmKP|2^^H$wPoK)wg4bW1ZkWXqtV4>PALIJ6l9r9I^#&u};0e45v}`@v z8ziqsq~Kj77?MJJ1wtr~&i3a!uqNbPn=|?@)H4L}rR%p`og!LpiT|{mphCA5a%`nm z`3$;~lkF}Q^eClPJx6#2rSq5a`TLV;;TtQ;$WIG%1jWBG`Hz(l@v7$N!o1pvfEf|5 zokIQe+ed-mP>zTXOMXEc)IKX3%*8m);6DADc3h5pz@7u%MF0>@46h`+73vvpHEhHE zo@yE@2GhQToC4o;Fh?$Pu-~29Q1xD+2}%v$S-=Vz4$+y`vVT%MM=#y(Z3quM{iYYq z^UkE7b}-8^?Z$BGnS>059LaaxKyiX(ngtH!3W}b>m+V4*3%*7&_0LA06iobV>6^P? zD7j$SR-pYch2>3MpQL@f3xN~`a3X@AkrYUP?3gLsZ=Z4w1wtkfd34#;kyCry_(t#5 zU*FbkxLpB#P<$-kn;Dg|$D7iZYHwd6A%2-xPd^uC%=$J$Rn{gv;hhpt*@aB>pxuUroanVO1Wr=IayC z8DR1+t>Tx#WB63OmrTeG7l3>t%~GpcVx{{A6+2~Y@vrKM>wdFewj~5zArXwt_1)t1a`ev#UKM=FTag5&{F zf|{W~#%<(bXPQJulto(0tVQn`Wkz`&5;c4b4&{P91WGzUy_<@l!ciPp1dJ3qE>}%! zeQRmGkp!0Ns*m%W@<}X&Rk`~7<>^T952%ao^AW40I}`DsSpW30TnJIvkj4@e^PJI@ z-bY{KS%7qDVK;ZJilz=!pbvdlLlEW#VEPiW0NXRJN^kLcZ-|5Y(Ila#OuD{$aiVgD zQ>}+^cG#dZ@B!x`1cIkAC;S^3FL3vfmiPz(=Mdk!;-2g^mD2w(@>R+jdsTc#YrCFp z3Tl}d$|}ZnZD+QqrVR7JeB*{LN6M&}7xitnJtq5ydDv`fUG@y zjWSF~2*q7Tz))=iZQHrvg<zV%-HXANIsEa*0)~6h1*yD>7hn-V!a~EvZ9^ezLF9ND;~^ojPkPY3 zTg3_#8Q(>Zsajt{p{apz=5e9-=#J6csd#V(%Te|PB2QtKII;KbDen>ye1ev>he$O7{Ns}67VMr?zf2VYmCw4)e`Z--3F4NL@>1$*)7_8XlVQz2w z_o*laEEK9@>h5i`I|2)Hq9A*W^q@RN-1p1FhxwpM3z86>fnmr=7s`QlJOaZ|lMz8! zL!qt{k&Uyb5EkZaKVUpR*sZQHVBR5(zC@W$TSLJ0kBZdz?PGsZ;#P8dn0Pn(wliM> zc36sPyn2!uxz|sB7*h34*uH&ZN*IQLdP*Al>kAYei4d6T2qw+Fc(S5mUE{L?X7gkv zho>)MD+!5-lFu40a&j*)G&C}p@mWcj!YLZC`IDqy<`0tote!=^jc>oqPoFc==r~x` zFeUvPofQO5FTX6umMd?UqYA~#<97t_bOP`te2}TgVh#%h>Ue{zH7^wcT% zl-uW*fW3@j5U>cr?E#z&fVb4(X);si13BRrQY1|i0dti`IEvK}7G%arLojB_iYcfn z$WI4da|sjp-QnYR@%3Pki{Rg0F*}i8HIceNMbM~?LL_uQj6Ys!uk)TAm^m>bb^Y&( z1Ih6I70D`(GVVL+BT886Y8-n8HIWo6M&HDUe6lNQS{Xfkaq0WYC?BDb-C0uUmMsM4 z`_c#xn~_{nsIyD&B*L`VoulUuVWkDLds2a#dIB1X7Nes_`w|-*;+eFB49s?)n$nHe z(S*N;qwPNK;#n<)@#rB-_2KTUur?pQ$U@cj)^G-77p&ZTuKZkl%dJo4qNmJMr)}uu z92CwQ}Y=$W`X+V%=+Ntg+k@X4@g zNpO_@1Sz>0ro{1JGPDx_2^?h(Xx>gWJnIrD$kOA4TI2BSX5!!{Y6=A+)PkKxw4B?7 z(mgBR_l%Xwb8F4VWbfGTiL(wjhipQ&&IzPueB}ONBw)*p1D3b#q!~WBV|+dK?)~UL z$!|n3_HIb?1@i_=A~9C<_pAyTXtFSU?`!Yd;AiCVnu|4QAxPID7y_AtcO{}fhO@} zVm~BQ9AkLUZ%h>-(ny5!&vb7~s0IXIq9xopaDbYeS#af$^{l0{?$rln-^Xkfnny~L z;NuzlNdva=$p-YtT@w3APr8j+@XwdCLG;lv1x3J6e&!{)r_y;8#P9d?vS(_+s2@4eSjB&;PcP)J@F0XVFC0NH}Y~TfDkuF zp^l!3X_=&7RVSs#d#f>WB*1^5QPEHH2OWE{12^_Ai@qfMwB zC2Eaur2n`Na9mtu}PtI+oF~E=&2YHZ1cnE{^}={%=sG^ z)+jY@2ri~pG!46*MR3Jc&Fiu4F41z0{qMh(rXdt>bd|4bRtX;a2pd-vU@0P{dzp*% zM^yS|SUIzd^#hIj(JFBonLu=nw)TvdQMOGqZqO!@Wx9T54KklhL)`fPzIHkpgSh=b z6j~w00R%1**f9+T%j5^QD4e9SZ6D-Vr~G9|J!hz@DMRzJ6^Lbw$E~9E9c{MeY_< zRrBqfoplvqZ|L`(ZNq5g6@tNg^S0+S{EYV5-e|tsraZx1n;E&YN1tM$O@{zR(5-_2 z%8t;-OlY=(cMZPj(}dhqnK)iKas1+fKIy}RLeJ{Pwi=Nu ziUNE%_0f`>GDC!vQ|Wx#^`>&m~55hcl_@v!ah}v0HRh81lT;O z3cA~MeVL%6rbYPBOaJY-ipXl0SyW-OQd1WB#=u%ClYV)281lL`yB`^Wfm?lwo!W;+ zl#h`hVb=R&=(b?tuCb`s@=Cl^%H%hC`pD2r7^3N8rdq_-bt2eO?*uk2DloXf35UY5 zhrv!&bquUn5BaJ}O!rI#kX4}!3Q}W7W^}GJ5-u#GZy;)lser?vs?UObTq$@Hqh-RLsg1e_qw%n+bE&3blkpeyfd?gP`e94Y`)22qH-1qB6GU}ja|OMYE$^2 z`T#?W-)WZFq1PZHkDq1$UE|lkHD>k6aUfhp5O*`KkQG>FpXwUOGWKZlouX^&{PILn zX^POIlrLv6#;tp4iiBO_Vypm#!gK_ZqESVZU!+Z_h5Rdw(*SB78M3B<&;cW!UwY=u zH@?z2Fn`!bxk+wmSIz`Mp*W%dL{k7dif}Z|wUAS;! zB5I#6y&F$Sao@+~BdvdBEeY_uphg-sHFF4@vDdJ~t`v<{z`Mr_N5{iAr0W+B5e+Nf z^R*1^5xF6_3kJGDX@0T}+Y(&fB!}pv_&d|3_;`ZpSu4=gzPmiJn=uEQ2g}p88R8zc zZydIhw6Vo+YWj%qwjDFJ85)e?tsV$H)D&t^<#wOZGGitV-@` z>~H=f%&y|gtm;lJyDU5K;{jGW9zIok!HdM#2`cVj1f<7Sl0(rv+ zzBjcY#5Os(aUR{2EL@2uYm?ZV4fj<5siwhD7MG%m=3)7H9_E|h85IJ<)NidfFnKam zW1QeObB@*dJF3>-5;1Jml3^n?!VMnWc6>7y4#YIe_{oP_UdDn3m`w}rscQ2MorTjn zHk}AIogEt)Ekld-;g}YSb;Bj)FtjXS+5%P_m5bebTr=_k?;o1k?{rKt+-9rEa$kWR>70lj*vTLayy;ei8@jCcnSU&Q z!H4?nbK$^wV1m$3`-n(ufFO+J3Ho;|reEwa2p}+1Zz2l~8=}&Too>y>T7WIr*Wi)c@vV3y_Sd3Kkf*M6kSAZys5LF;j5n=Y!B*X_0o5MaJ4Z6nlt{x66D+pI$x8&6&F_-4?8)Ww?Y^aB1k82&(j(z5C03ui%~qbl$BWyN^->t8YSxR~iwfNVJ$?D^acqEff{Z5zmPNsn z@ZX6p#-y`ceOwspNI1t{p}^@UPVJ8$18XtSjHbRFpC5IfQ_PcCrskapuysQ9dz@U* zp>2gUu?syr>;GVe=wsvbx**!OU{(%kc=p_B zb!j426mEgEx(pE<^0)A`+msO;3bz)t+q4la^0!{J+td*}Wp2diwh2Q!3UxmtS|;}K zl(j>Lc#Lo9sp$vyuZ?eQsL>7VQ)st^hs@PG)zGgC_9ufvi8wDfQ9Jrvt zu&d%IPt_aEcQgCxaap`ELChJmO?y$Z!(_!rd=}u)b3N$~w(QAQK;TEVk#;rYBLJj> zo&)wL;c^GwySUpJ^m`xr5Z4GCH$UxgX8d)`daAq-d8eNO0bY#naR~k^FY<0V2%$C4 zlxr4rW;}+qJzIU(gUS58A;)X-!EjYAc?H%dMmX)WA=OQJ9abkuI39f=+jT_D2{*5B zxm%mT8m`aDU%F!OAbTu6EwDp9LO4m7^Ej{}_@2Pd%v6Tcz2|ET>{yq)@2Km##p}$b zA^|`McP&`52f$?N3^gL*!);Dx*YF~>qKg^dHw0R`Yoq5tYE9T^crjbi$&KwVd{>E~ zKLu4CX=r#=>sY#Po74IJQJ3O+RNFn6({z~AB+qY>7P3r>TxJHV3huo4G^1OX)hsS( z!u4Bb2B|s{XiN^A)ilX(IxJ|K{C+QLnHj_87;GN8xuAK$8m!c61B2Jk`qj^BVdH}R zqiU&`L%iwq$7rOrQU{mTvv9JSMSU{WVc}=+==ekgr*?8vpHy7xXAF}Rsuv%3G1zQq z3THB9J_QNFL~RqlZ9?RufA+k}Jn|69yM2WJHJzs>&E=_a37`wNu7rQg#D{G2tY&;a zXT$noC9~?&qj2fyWMZOrDMh~`#jrw6ze3HRf?-5e4=VJI?eXM%IefI3ZdVia25Jr2 z*hLCeozC7&S?V4f$sDTVTf(}84ow?areCbwha-#D36xt<=@1xL$(Y_duS(s6G0oa~ z;YOW}2~sIPg!zj?rmGN>)eA83rO(th#hiE>Kh}~ZtqI1O z;!1pcXH(f`B~)w?TQ&vnh-J&dijU5Yg5YM%PW$P78p_@rQjSO~m27$y82ea;Xk7>m0?F*mTOR}k7J_kGRe zhqm>IA~@!_GEaU0DkX_Zqk8^e+9N&+i?Zf($A~$z7a$RU7}}q4L6wBDJhP_`#C+>A z<0kHt)*(~qTE2wI56J}-JdYs`N-VQy250um1vWgpwEoF~SKFmM;LgO`9G?l;`PVQv zlnD~EPrGLxxuAE5(F^fzux8}C|L&2vg;u;Kp9e?Rkmt<4s4q;hKKsJ%)C9K$6h_#X z{TChm6lG1llUw#Kkv^{XLX%w9Ii{CXeD~9chkM&+_B)t~!dbqce>VLLG2W^v&`_W& zIt2ehvJd>)1bOYcF-n^!Z=V#QJ#94tjoSTObBdY!0HPimpN5Js7wBJ$Ap;tB;n4q`2_}^U%O?Ew6lNR9`@`k zGH9DG^4=nj6ueKqFN=B$k9zxE(xcu!QSN`2-9aK=3`|Jh2zq<)>P~ye>U*Dy@I{Q# zpAV+5!EmSOX5Q^Bk;{%h{oN_luRm3s*poj=r1%X^IcY!Cl5P4G@sfSkNmh)zH{kfM z{fGmy{c_?Owr(ciPf;rGP;R7PF1Fx$uKfC#)SfiX2`skh?}aZ}VL;v_ei_EGr$wy) z`lN(z!Pz*Juu3SYmB}7vcLyi`2RNb47B#)at=yjx25`SFyhPZMd#uAe)7SxgWvI(> ztA?wliq~e_qFp*SR8O`_XM4t7I>#(V&gXK(*Xt0TD_t%=S!f^DqF$)Jc-fiLW&?i0 z$ZpqRr9vXGN!Nv97Z1a;*$RXELXadptw%|J(o;+XUX*FceFn2Fz6XZ36jU}RFTX0i zUBkt&y2DDnX{IrlfW`PmdVCJn1+45;*Yc}AGn7Txywg~MU0dRBQz}L|%zu!`^U92` z4Kw$jE6}3UoITfMNJZror0Q{6-~v}Te_6iEhI7s$$IaDM({BY~U2Pp!xO9y98gsma zT{{;nZ)L5!UMjw+C~i=svUTfyC+NOcnDu{DiYp_G7STL4WIwlL7+?DN$K9dOO1ZGZ zK`4n%3i5g6Ik(hp7h`XzKc1;BoA%(vrcJ$Gf$FiJuk^nzSUXt%*h6Q}O**>hmjZd} zy0TW$h!_FJ=~LwF-AF0hITtYa?Z=sN?=&-kT- zu=Q@-Zf!aq{lU65E~m~Z_a1+A?d2+0AeI53$^o?l<<;XCl#Z80X>V^`Ep z&ntT?0s?h`d=j*gzr!&PpVbT}dY7 zYP5n~bSCU8RKr~xCUng~H#h0SejBEr+34;!m8p;nVPlW1cj%bZuMt1*fEy6a#ry&? ze{+jH_qssp*x}c10#@ZC!jtM*8?y8#9N{)4 z;bHy@(v*hK!S!2D{mHd2fJtP+oh>idaFiBu7a2d1cQ9newR_+1Ir7`xK|dEWVg)tR z=Lz`$Q88}qmUzbc2iK_c4vTw4X$`}nA0V;n z-DRWf>=XD|rX#Rp21FL;@*}aly~TV#$_Oag76&}&r%(J`DzYzCYlQ`Sao?x_85`s9 z!|H!ye^)9Y)+uA1{~=R9P;6Xu5U)f*gZ#5rzx-3RYHe0&GR%XKu;x!2>c?!`Ej=!p z7$-F|S31UCDQ9v)(&!xZp_xnvE}8}|-B}`uY>vAi9E$k0K^pJeCX`vXXRZG~hgzDM z88!0s7>7mNC6B}g0>OLAP`c5lqvPk3?qJS^?I(q3WOr1O654%8L<2mteguttZ1S)l zuRCyzQdaesUdZDO^0?G=KGk$1+F0Xr+jDIOag<5TtZKC6TsL1D`H`yfR$+&>tEzi{ z7dgYm;(26PUm9&e*@>{@)k9?D>8X*u#fZ<=J;jLOlfZT8`!nclnqb>8H|mWLoJ!c~ z1S#AohX^7nVIppR0YHo*s$e2+g)~ZVDhB6DM+hHp$uS9qD3w_}0uA-kSN{iR?;ITI z-gXPmWF|AQZQHhOTOHe)aH7t{wr$(CZDV3%;?w(i-{-5^`>Ru@YIk+@AKghR_ubd^ zTNl?lIYJy@^Bh3)gpjmJK?MKS*HJs1MvG33wAdGNev+ed0^r0dlDy@ShM!YxB~6T% z?)A{H)YYK6pI!-&cc2RO#tQAg9pD2!=Lj#H)54C?&>=YcMMpeh>dX390}FV&bS>cH zW-F0`wOP6v**?pP<|M96^=WXr9(ol-s0Mm6>y^O-&v0Ta(nQ^%)!FHXd+#6}5z{%9 zQ^_@yWm>96L{kzy+|(=z*YGiDJU9;2xEWQS9UN*+7CBtVQW3!ea~dCM!&z!QfH#~wu5u=a5fzkh z*pRSeRXO*dnz(sAxBzI#6W2wqLs!-b{^rVS2`V>|*akZ6nhv9L+k6CWil|8AMl})| zkDL0o4Dbo5mF*Mb{>Ym5f-Lr~wE&YFJ^vD_auHKVL@6~n#IIbJ|8kV2`gK z_2Q+q`YEfyEYE0e%M4chx0w6Nh9xk#uyC>9p~&I3ZiGiJv0On{@PKkCgxWhp0ePz; zth~!I4cQ7!?GGWfuOQ{6&*F{9)x<_k$on9YmTH$LOFgz*qyE;}P4)(ocKL19^z*8y zz+7a;hbke*g+KHLvQHU#s?@D1-x-lSF=(@4p$3Q*=cPJ|; zX{7d4rUzZw<751HQEwxK8IfmDRT)WYDWynFf4gIC3^Oxm@j%}WI8_Vrz?Tg`H*y^c zCssseS40w&8ilR<*R4YdiS_MbxC~RzoFp4wf}~-`j;wedzL`3W&H4{tkf`l-azhS8 zoXKe+{h$uSH3?2gBW6k^9?v2WZih1J&jJA5VNFBXtpo6kM#Kv{x)bd_kGi$%d~j-{ z3t-1sm+Yg)kK%ZHd~)kd^&`rl=xwWJD(CD!td@uzERV1m_iAH2onEbBba+<3jE~0B z2x)0_+KRI&C!BS|HmZ2jMS0;3ALHx3-WLu>;_EGZ!+=B1TAtuW?bsJdTZ z(mBHgrl(3yzt@&zjQTWm&IT;TsyK8vz8fhdhCl_RgxVi@#n7%3p%zS=_EaM4aG1K!%+avmb!GtlqYjV^^h{f)3ux|oIcfM zn~r&rmniQCu0nY13oMI(u2J;l;*SpkeS_SDQ2K*T*#RHFk#f0}S)U zAijahN%XEv`i|)H+U#CebjEKlr;yI;MDrze$F=ikb!j)pj^>eEO~I-KL%#Y5P3_v6 z5V=@W|LzgBJ4dPU++R#9iaiQ#{y7>w6Se-@{Wfag=vt^KL@mnN%NC1ZZxCkQMY#!v zjl4Q*az{&pa#7DM2^olWL%Jz&ya`_nVwt``#UI1@K-u^}#bj-1zR7*zE7AFqt}-Kj zM{}4s=h>VLZ)aqtwXmb%oJiS;1k_qtskxbQoM&IJwBuNO^rZaQ*xigo@siW%`Q2Ew zExf9F<=tHiRSjkpg}NHw0u-%+uDvzfQe`FfbyDrAwd(KG<=F;$ce0;pi-ci6fNxe; z4K>e$zX;haFByuQ`g_N)pN$O&+b*Mf_I1J#TcDpww*#^w7@MIV3O1{!`j0liUzqHc z$qm;p{ok{_s&m307;_DF`nU$E?!zlZVKE-!iX@j;NQ(=9Lk=*tAoF`=KGb^zpi zAv2&KU^lCW!uXp3TSu^-$?iR{FJyMhE4!lXXK5XPM+Ev7z}7A-xAN-@?2DS+a;WuwT{@&L$@E16{<&W-?7U+kJ&1!zs zsy4vZ0ql#>H4yvZvIEdXzv`-q14fO6}KSLjQv0a9D@7tv1v+uLL2EP6JGY#9efc?O`OU!=uy#ugC!ROlN zGmQOkze^ALNzm<8^V$V&9Kya>UaPa8iMIpviTGUleCDwqo_3kp&xSzvo%H<>_}0vR zHrM~#c3IxNk5BP+1J<*N{mf<;n*EHt0}$NLzh0en1Kc2ZKL)+Plvev8h z?|~JeS)dQjK4UZW(-XA^xwO85XRF&S_Ug5bdLVh?JEe=Dkr`J$I_@ES>(wfGSDkiJ zN$@mdJ zm=A{xd}t1b06s{ENvQUNS%MDK42m=*cOWKk7+3`2+EGiNP25wu#aA`|*4D)A#6+T80m3y$_h% zuAO^*h7a;YMPHozA>Zy-{^Ys0uI zC+gWg1IFV;29X|U#b%7ipewB575RKPkUS;sqp+3xb*#(+9r;k)uoKQ{zD%GaRBQb7 zs?#Nz-GDO?bYW`@{AmAqzm{uUzVC)JIVAD<3E?C&X+HlHn?z2oy0o}pkT2WSDrGm1-N6K1J0-mKBB zIi0OHSQ9#=)hi3Z>ht1JblwNjnfI_pq;AhH&zA*Oi&PXktu^H9-4v11SqVipA(>*d z-cGg}U{ItsYLu!k2GZQJhN&5f4s9<|B^9Q=gl$|DO1k!uQl|2maJ%lnYjG-QjM6ic zyeVM)%&^d1v{@>L*hmmMG9jccoTwmmR0CvoDI{-}Tcp`W&fbh3I#wOe)VUAQH6R%y zmBD=O+b|ikjU=Dt~i@Y&6AX z$3WQ(lt>HHB#%x{^#ajW>4S^T6hWf;qL8%7);9v5ZwA5zR`9AsD{^uxD8!8B&& z2_XtDf;s-M%l{beo5?)hLb!0;u-pl2(#e0^HHIRuHxH-=mt{vM>8!1zJ%Ua9g)S%5 zXmuf=bFV*bU+M`xTM~V;;4QhJUUEBW`@?$GRrO{|I?i&-iL}c?>r^R-%}vXsEYO{? zp(YGlLI2bJ>1SR8jBJN!Q)Y zx@Qz+K2ZkFWU|nUy+8D{e+-a)OK|z-;655?eZCs;@rf6;NdV*QX5wUUvmYlIfp&O( z_IvSD+4W=1LN74t4iOJ1>I1*AWW56)u-;09%}3lITmk%|Od_$aZM+xNTqWM(GA}c| z{Hy!;11?hBeG`R`mIr7Sd-=-ajO!0L9l{@NnP}o&ZZf1KKluWOB|iO@6qAS~y88!F z{{WnP@-4`da6m-;;{VQ*j7*G8Y>ocuP&OckLhxy%)!A}aN4e6Se+W${BAC@;ge4&X z$2PyZbu2g8@mR91`sx$<0oG-37tm7$5}H_dNCZpJFrQ6Z*+?4>%SgR}u@30VNwN_UP z+Myy0uT@aBaI#uhLDB?D_>lqIG+8oy}5bHL-ZFk??fZMTJdweaCaXx>=Wz&-wylu5b21P7afd ztH%(7Z;jx4LzgVm!e==;WjeFlz{R=?M<=(SC9vq_*7D_b8;V(V$AhP^`P+&|I|H#7upfMm|3=iMzSLW5lTfkl{E|poP`j4)tmV z_7TX3LH04s*!!Ds9PO6~@~$g4)Ql^Nh&B{42K4K#F)k72Qdh3@6i&{|7-yh7U+-0j zDu}wr%|2-o^J0fDrfoAj~8dD@V-dx?UG92{Y)bbtRtm zC(m8L#LRu(`0|{G%qHD=^ap~xSFZf=$M}*G#?3_US2=t@|LZJFoJ=&1=o$RqxqI%B za!=(!0vMAZzY_fyekBXAceb-KvHcrNRs1hZ6%NqFgV#_{x%WXo^tX@9OrW+^eq z-@R2JGciuFF>U%4@{aHk0RQYi^F8k`ze+iuMWFzGOFK(vX8!H|=7K4YY}W*a~$KHA0I9^Hjzv)#^TVI}LuhAZ!5N}vjtvQHm-^BhF} zX?y|xKBhpI@DuH@Qp>4O$#QW(K5~KkZK&#_PxruIi?8@axjZvBy{S2#|qn~hRgA4=< zz$P+P8^-O=8BMy#el-*&s5K)9@@5oaU#rwaGk%&q3c}Sv>`>>^O6q^hoD^@`cT{yk zOWgWZ3TbY`;zrqKTa6*+nt0Im>}nzB>Zd%cO0^>kuh6-`TG|1z|0Czdo_^!l_9mj5 znMLV?)&o`-bt?Ze{-!1)y9~~^qA{VoLoR2FRrg=*5ny;L$%Ek$bsR(XP15TW0PH$< z>z$AYqD-c7oZ4GVGB~xyI~Y+_EZXTdC&~?1&mF7y%d11!i#sEVGZ*Ufxsr_5qNFP- zGVr;wf;S%SdyqKpw>9$aD=P1!;5wr=6L`I@wfxYsS=|}n{F`q=7iS1V3Y-HY-0hOF z59D;7|L1-Ni8^f(OiAjrP#ePclzEIuG1KZ(45AI&)NPE&I3C2+bQpl#jJbg+LJ@0r zmcd}-^euADhJp_S>nuxHcDO56Ui}mUkQs5A#4qJ%$4XAgAGF9bG0XZGP<1-lB7L|^ z^^Vm3-~GVHz)p(b@sbKkj!vx6v_EReT-LB{9Dd>znC_OIHO-# zV5Y4o3pM6!Exq@TP3@%#?2E<&4j=fg1k?)WrFsh9Ii9awDs33LDrFh1{x-1uxQO`4x zUCbV$rFk>#NcKkI6?Q`g({3=T&4<#LNuxu)>1r=&>gCCGe(BrRx;CNj`|l_^JD%JYd1X~z;49XtKFyCZE=eXPtM+4nGGHI!Hr_Fijq7eP^vFje#&R>-L+ z8`f!wFuvO}o6y*KI$~*?SrR2I_npYK15D>SV~b8^1f&Es&kNv&9&Nf?){y&k!aF&= zJE4cLI9n%D6OZ}xT(hTIk$|Qnjrr>%kA_kiPcz+=Lpk9TOKKXRGQzoHVajXs)#wPM9g@Bkw~Usdg3ZnJ{{bK5GAW8 zcG#WXHqs{KK%%6KP4aLSy=dh1szrg_pube06xgNXD{kbL>C+=e=lHcvqHoroI%j9! z4Zi&=*3f13t4ZV%r%%#BmHjK%(3aU#8IJzWpYJrj5qo7gAGBk>!`Ik2AGl+_{nxCK zADIXIhks-vKl~2rhJ(CP+Eo)sZo7yQ>2ZkP$0&pFhb$>MOAAPDD84q-2g>(8UjVhj zg7{a;vWHcyBb_dbQ3jGT-7jiTKSpEH2 zQ2C#Xvv6$|daOc6r9HR!98FV{WRNXFgOm`BWcsQ&g)XiZ)Ic{a`cH_g&+u$;w}5ZL z)20gvL1=5AmfQHVE?IzS zi8pZ7SAckMy;dZ6xr0V$`WYcxaI^4yZ8Yw{&>KX3JGWyy=C!nrsP;2q^V9^>bk~4U zCY`S)U@}WNEzD1uk`?QKDhJk@!uGuKO73gyMzuDbx~}BARKfKw&AnxMhqy~93)4PZ zdu4rpEG`Nb@5bdyHe3MaZL%{@Z+WC*G8djvI)IQ&pkH|idA#6Sr6}xAc#b2c1v8DF zmNiUDq5`a)dNWCM?~P-4TO}&kh8azjQ#DBk+dXf*mP8DI_kDoN#cm3qBG~k@KOG4pPS3K~AtB9`fh&V;`$~@a9H%lxdw}s&w)8JLIYhXX&6C}*^GWxjH zC8I>=rgi|~{zxnlBi>t=R2j0d)1aBT*fGS2yf2{_1R|M78Bt(&S~uz_v(5nPD7eNs zgjMa`my#$98gKE@KmMIx;iQe{j49J#YMgqcDni;#GrF^Q2D9?FT!gwD#`%(4BsVMc z;BT67kvfDgRgN|WAXa#OU}~|+oR7xh3O}&_9Shw`QZmCp_U;I>cj13w@5;`OASt)M z8GM0??q4Mq-nmPgBrs8hYh=;$@3o;4;R8~$U+3}(avcN1fIE9EA&S;uO6#0gIl zaDn*;_{`V#nKzZy{SOP z&V3=EX{h@xqEL+8lkup}pr3~rSH7m$2nrZ!mTamK0*P=ve~lxp**<*?)oJYRL@LS5 zQc1=N)KULa=t+SSE8emY>M#&@AaKJucAiyE-87^C5yVC^JRRbjCsuVDWLWv$MI_-! zm~+@!|EN;kt)2vF>1hyVZ-Ra|fb+&{36V)6p+_-YtXz*WC{W2YBbQ0&AmsyQ#A53I z!v;q5<{kh$s7NFo+V6bl9Z-sFe7hhop=MjNTq1m@H2ksL@3sPvrSMegMkY%qCO3@1LHaKQTAk0akmbG{X%BVbp1L z>g;);vDs-}nfzfuWH4x?&`mVsjK+&Wr{G=eU;CDY@)NyLe-(WW&{dQ=svSy`oiV2P zeIwmj$?1;0PSB)LIn*IL{Zu}u^67GO%?63 z^HmF?h{{=)>VlVK);Pw-e&Un}AyoobBa)o4!n18y5gvvUOY7FlEv|CAGKTT>T({ee z2*I(HBmw5=gns{dXoJmj{bpCXY+rpOQV2bi<7_z`kfoyiUZ~QL@bkNKTDcJ7f{1~f z>U^vFX!Q7j1>=OSI!o`TE+@>KFe;0(TFNi_Q-?{JSF{)IIt%IIR`P*X=~~+7x}o+6 zG{BH^a0yjx)SbIe90i6AT-;`cMadfz-`f%WV5){wcLk;6-m_IYR;0acqnC;Ke_)l+ zsJ|w<4&<^#!r69xNDsmXFdM8ej9=C)*^KWsMsPPvZ?yi-G@v*yxUxy_rvzGkF%%hT zR2=jV@?=B1KBZ%tyYH%Lh0HRwoXT)B240oE7b+BfP=A=MTpq8X zH!dtmVEBxkKY?GYbp~ZTcB?BLz#dmvAeu{8B)N(- z*bGJ}S{)*S$dlc1hOpX!nVhu%I&t9l=n+^vAeHd9L3ke##Q%bP3&fcSH_6Dq=FxnG zPvK|K@{+`SNAH8=p^hDo&EHV@J`|Pj3#CZDn#edLxvxlYXLvSKj$w-~S+pLprzFvr z^Kk%bV=~4Tjrc*Dqx8kI0{cjUCFEjR060Te=zj;Ro~h4C=OD0}12qHw4Ol6eIJ-Fh z-F-oHEYS<3O;|A&ld*2AE+f5h7x7N?o8OiIC+^58Uq?Q zRP`L0+a;k6s8bkRQqT!a1*kw7D&2Y$)xAV3DH}7PIM^{(OChHM1TE3wRDgriz$OAG z@BvH`c##VTNf5Kq9fs0pwY(K;DE^>-C@gDt)^8!YlR6R9Yd-$ za2!Ic=ecY{XK{wzK-4)&)5^e3q{JcrWyy+B>39sm>F6)6IM8pa3rd%@VLG5I1jqJ- zqKz=f%^3EJiS0Ci+~RV2+;ncDvKqEyBZgGtO^xJ zCy`T{Hk~cK!~0K2wAiX)%A(Po=~d(Du-NQRsS!V1F7ijD3zC+Yv31im>nZ?PJ zBKYztE@`PHBJt_PvcUD~3zaq2A@B~)`Z?F|G4@ve1g8rF_&9OpbDph@m2r2LJHvr8 z`%|LOOn_5l?enqCQK4Bdd(~N9@STVgyoW;qN#CbR@P{}*Z=SiLXzv%q__<$hLkQPs zh7cp47{%MxBnFwX97yAMMTUx$10VSS)h*Nn?yIot`7S{1W?3t|GPLU0l}m-knFL<{ z)F*!lY`9vIJd!u!qla^gqMOg&qeDio#$j3gxa*|P_S7DBhj~t0tJ7cj@0k-p0flU9=`r^!7Jq1p4`LQV~P8W)fXY6$~-91ZxKu z$IWsr2^e3*T%C1*#99wypHvs9(!bVdj$D<{%ld-ny+L3n{>*fx(xSn?Exzv9yjIV5 zh6lmjKO5Ov2U90mjX_3_wtc5mTLHbgsX6v_U?2)2aRufhW-FXLV@wQZt8I> zcbjQcufFQ_qGC*{w~z?JH59=LM+(O!#s@PR3q(U z=6tykc|h`D4?`8bQJ`0zc7P%%#i3(F^wrNfL0L(E0=KAh29E!hhM-35HEyC3gXoZ4 z&;0>hYZi7QRHGhDrF!e{CJ&GIG3b5`?Lm=~HfF75NeiiV0u<

gm5h`<~$VhWfZc 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%0Dt#$In7ylaA7 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..f6ae23cdfd2fa04811efd39e71202e20f33bde6a GIT binary patch literal 552146 zcma&M1B_-(_x9Vy-L`GpzT38Ko71*!+qP|UTGQ6Fjp?4&dEWDW$sgazn^Q^cWG8D? zDydv+@9VcpNfsOe00II71A^9>s0i}U0Q=YDp8@;NlowYMVUSjkU;+nG`X7N6hscyp zpdcU>|3stz_dt0O1!)O!RW(L=i8Pfahb?C09mq2x7&B|-L{5sC^vtqIRdjhYuSR9` z9mb#9q{2yH(va7Ce@rH#LP|xU5qmxV>>ly$2C@0XMtu(=$9YCevn;eYj#xPhXAmnV z-O4prW+LSY!?EBHpakEHSyjw;!ok%akzrf1jL)Q1hWd`&)89cD%8yg_Q@BM(<770# zMa-kQJxex07Z%G_EL+rU)H$!*niid`Cr)azWFTZfX3Xd-SK5?Kr&VIDnsmLUSsH@3 zVj3RPHKB{=*MTqF`6wlgRWzFsae}srx4#%aNzxH1@^amQSfVU_+2Qt!u9NR*t3Y~w0)2Mwd~eo z`D|W8Ddyom()4i|DT2pmvU8WsPa5^YrNB_rsMEBQERa-2g;NPibmoNsK!Y~;^@z3 zfsDSOQZvuL8uH~F(pQ@;rw@6zxnpqmT?67wGkK`D?p3@M2Kd;DEiT=1Vcnhh`SpL)xjuBIIgxVzJR-a&A;4Y&R}F=H1py?xsH47V9v zHEmv=u2h1x4RFq$em!mg zupKG#WI7alEQ8X}=DJj7no-Mc7!9axO(t&D$QsXUYNkUa5PZ>}p{cpg54U3VKQriZTgAAkMxv z)A%5`fk+*`BLWmbtu=t84nTyf(mlAc-(jjb)V$nUciv0>UAS>+JmKOs(&c4If4-E^ z&V|e}RlRgDB+15PE+OfB2sC_9Y0+#4`J;V@N?XMDlZ#I8>lrC*(iZ8g*f5V9r+wC3PIt>uSSJo^0hY zze9Cf%a@(lrL{5eYkQh;rqB~Zi`hb~+-jUX?@HL78z=5uT1mLez%C=U$wUm`g_J@+ z8lF8`pZGepb?m*5os4xU{rA)Y$a&@zlUojsZc zu)nOpQePd&E@wKykTH}6-VC#tfHj_fH0fxACh|+|OvUEI`8tS8d%mRBYdLcOZk zt0s&>&$UJQhn4jjW|m?RlRMI0(0~Q*bGNDKSwmR-#gS4ZbC&yMNE;cPFWn1vmFw~@zaHNPs1LsE%Be6huLRG;= zE>}U)VGp1e*VTOD^h(%vWFLA%(2gcD2EDH^@u*xA=bXH>bs-Dbk$a$3NfQgyT=%{Y z!i%_R3iNhc`;3#qQd zm>!EnY|uM05If)Cw|axDt4Ntfi!Sg%q(Q;)c*U|ykJ@avp!(3pd~b!3Cy-&437qb6 z{7BJ(HX#0Q0iepU1RE?U(EQ3TwTVWQx$yFXf`Fdse#gcgb^`9a+SrW~bvnGNq1_KV z5AH@%*r_@^=a!HwcLg2!O>JG_g2g3j0vp5pSF9VoS5FH5K|ELP%D=;twjz8;#{Twx#5<@|+^aV|*;3 zszS2Jjg=>1Q>$7@_?3rBkey^Q{RmQbb{|9+zYWt$Vnl8S^urHf)xj+{D%N5H`mHcBB5pBvnpEqxB zQ3og2Lh*848&>rM!6hJK+~Rh~1S=kdmtAeTThb?{*8u!bO-h0VERmGu2;n6V&!4%% zSG{Ir;+0q?icG7A!!W4f@Ka`|u+1Y@Io(Su$UgtHTBQiqcp7m0SX^yco%?*aeuhuJ zbtd*P{q-i0=wkVPyqP94m?g*4ME^#IhM}VfE0~J$oJn)`Q@e$fS~~a9!i2vPh4oJ4 z3}!52g9FWVci8e;W(bNEmx7>O^(}RmNqQ473d8A#_A^yv!tBzlNLsDS(*0Es`cXRZ zX6nozD9c(kB69!=%o)h0Hu0hc(|uyZSq|c< z>moB*lM-t7;yZz-ain2|#r%i-aggpg_i+dzDM!PkQu)Q}Ht8s@oW*04-DLG}fbNy& zL*#5J#A;tyKRFtpy&qii*s|CkFoCCD)@@@4Zl5P62ZDL?9n6=&5(keTj%^g)G9|V` zdzO_6y>ZX|wZW{oqnpd2d_f!8zTB7(JGit@=L!k9Kb=$`Ps){8<2CNG#P-F#&g)_| zVcFDAs#>s8Ep4r;(&p!1iauWH%9J5T>XffC2753HZbP!8eugf?w}lg#Y6U*ARR?zE=~zC zw;J6L!Wh?#@g9$*XCIVCi=|ym_w1bd4oOh7l1w$BdX_jpkPCOTx~|o?!EM{;wI@&r z6dele5E+w=P#*_4A4KEnK^7YR2g^pzaF`?9&e;JI2SK4P)o(DX{~Lz)4f}V5=ps~{ zXlW_uYW1GPwPQkKA>SQrx|<6Py8p`IGrJAA2Gp+dFlZm0$x2Yluaq~t$?|OXp3DND5!N~g|ADUT!Os)FNm0V2k186dueLwkp zzXYr8_wLf`>(QC-lJZ9CZ-hH}Id{wCyHb-NViV%x@07=h%sly~GoaUnzN z2jpUb1F?V>l<(?dBbr;N0v}#mXbwG0Aqf$Vo6VM$kzrXk{h_@l3(m>-)Pm*FXK)nQ z{1aXu2~cv{-kA{PmSH#@ygz9F%;Uq?pV?bs8XD0&cm`J!2nOQYR|FYn;!;!Z}` zn`iJDaJ$yBWhq5X-0qte2oY}C?L~4L1{FG6~ zs9i;*Uccp$dm#t+=dOqF=%9l_oFgGVy^v4MM~%B{3EB0N*S?++CP5rS?_5H#7I5x% z^yp=3VXeXfdpjRVF)rw71aA_%6<3~Lo9{L++XsO&c`W>pWzwg|&3P8}gIhM@USLX+ zxYPA&zLEJ8g@m7o=$_TrcdNy6 zK9u@wf~Lc+{VDbrRyi`Oi}iN^qw&?OrLI;65@q7`rD&QwN!u0stO9&+N>R=DIa(y; zn3b;k-}_S%yo;a=iFUYCAA&LCv78e6+<^_6np&C*eNd7EOb(6*Nhd;kg>cq7Ad%j8 z4NS)kHwTWT(}KGcLwlcCjMN{t=quL1!d0l|aUh;xXq7|~@0(6dxeFKof}Ahp3(AoO zL+tlehM^_Os}<`(%?=3!T2b}w-)04GM#g%%KM}9}!s#Ubaar#(ElV!93y15Xp~NmH}EH9(xeFgX#KDqpRIs1T?X7F@Q4Q%Ouu+GDINh@zc4 zb#^MBrU5&NQ1bYUxj`=Mof7c*#&wyyzJD_emE>Xg32u-2PKNtz@fS)-B3e%n9cy{8 zm(35EpkLqBKY-pL`H~&A1ItH(Qq{GV+2M*w1IVC+!G%OqP5mbTw`Ykm8eoxs_mzG_L9Gq)~Fba=fw-t}6E1@@6f4czN@r z_lWfk`d{{Z?H_xN2-;{L`wuud{%4~7cYvaxsP>OR|Cc*Yi(^3?W=4ka890=omXf0_ z6s1OQJqC~P8LhTD0=p=I{;(^boI{ ze}iXfB8Uq_vcP6ApZrJ-jv8Fffr>XfU=cZmnMax9x`8XK=ZA_pOW@S{eNaS8CyHpnY+6FU#VzY7f(0;pr{Wh5D@PFoGNE*Z(?Q)baZrcb#pOx zA{RAwa&vbvXEgn1Z?1W2n<{7`=mL56KzwpBPEbvykw!UGWGv(~V$`@h5b?BxyeTzo z+SyVIN=Cz?TZaK+byWJg2k;N-nXSA)V6eC^kDue7&%%zy-_r(1A&^<4HgL-%6lMk^ zN(m>naK>5MP7G0q7UgZsQvy&=$k{RG1RpR=bbh6~L=v+{f)tXZz28io2ERR|4gcuR zFwP~-1?ZD(3GX_~cB^i1B7B!=FLrg5I3|jFq028AMb7HBpD-~$QMv}8n9poK{vPL? zV!A|+s-kn;{B7f2VbqP+tCaqOAS8pU%NDlJ8RwycK0##aA==RW95}bxelEkC0?*b= zoT9eJ%Ae9Ro^EiEuFol;xbT<3+-N*dvo8ob!S2qPHap|ffpg!e ztT^p_>}?nRBDmC;`uz-m&c?%1FwFsA;xsdiFDoEf^NbGGqz1MI!jGu=z{9gRV4LB| zS43J;ya|co+dgOE-&sK12C*`vu71n89R9)7^{lQpX4HLd!>7nZZL5;n&y6N@tBHg= z6E6s)7yZ8fg;k@`W!3#O=@ zI{zjsw^R2%4UQXsW*%wg6-|^i{7e{>)#e}Ti;zxA-gwCX@c$`lKFdMlW=If_jDK)2 z?SIygqLaCcv75D{!@pG%mwK+NDv3V6mjl5XN~b3wJcfZ~hH_M|Uf3)q4o(fqu9JaG z1|b?OUAU@q-M``Ic-`OOv0|%Vz51)K?eg>s_H$9Fkm&DI?uei76AjU1#E-qbEH+CE zR<=JE16YjUTH!(u`$Hvy{NWRQ+{a^Rf_4)r+x%k!igZ^>UgMH4+P_cHJ!ttCULeEt z0Zh#T^^Lj*6zxoOSIS;t*EIl?u=S1p`o)?%s4XsxVt`|lpRRGkFrVF?dL&Kn#EV~; zAAqP)plGq;j$|tV{V#@~#d{P`??APk3IhsVp{Whyg)Z0PJqrjtfZu8XgaA%A@-?Ms zedk|-fiefATTJNT=!{K$wNAnZvhAAa%K*csPaTqyJA^GqjAp=I)2D&4)&X?85N#~= z$LLEnmJps(hdVTa8ieY(U;sVJl-bde9DQ>9%Xu|mMRvUTS0yJtr!VYKJ>VqZkDjrfGhJj!qfYduh1JbA+adgORedbrVMAW5Yl8e6 zc(R`2-e~CeGHvmGP#T(F0b%M#bqyg^R^&@)(i2^^s#__s@X5z(V=4D`AwknD7FGnN zD!j^y?LrE=vv6bY$w^mE+0&`9ZGtlD?n|L;K|RUfHT5%a z+Mp;OA9Y}9qkL&}UL|5dF+Q!g+@c%m=0#I>MnIr^k?{oI%7icP^)sQBdy3jLFE*St zMssF4p@b?0LQ-5~d1msWElZz3OHx&HC8Z)`D8|i86%{R&CGqXk$JyxwpB%HI(w`b> z1aq`D7(2JMHlcVxa^<56j9HPUm45eiHeYn3U7Zm`inq9N&NK*pTl_s@vmNhl|(7zj0*`ie;urtIhwJG! zxbzuMiBI6her`3rL?VgAo$bMXWVN2;1_xKLXLRVMTo zIHqRGv$0{>&HL)G~ zZBqQk=x5%8=V82B)E(MhWv>+V>X2dk;p;W>9g<#cuNV$(Pe4RyPc2QiZl|PIje2

(^JrYX^ER`YKf|tl>~`xS&?U1m4uaUjC&`e;^9fl*taIh zH8*9MHOC=Oq2mdVn{y5qtuQO-`!HE|zYoHrn^3m3D8;yRPqj3`x}M>&W$eE5dk0}~ zhre;h%j61UFc#u!Du)O)fdni?1~e|-4LPP7Cn?8`joZ+(aGF##5zNGb(sLmihdIO3 z#T{vx=N7){&C_v*M~D->A^p$FPo+rMt_}|ZQicx#!t$RhznHnjfBibiON;*d15l<3 z>!r4e@ug_-gDoXPn35bh6d8q?4mKw}lvH{{g3=C_kC7=Q<9Nty_h}BkS#7Lcrm0P% z49*=?ywJTWl2y7ax?MxZ_Rs1~&gxB_zIbZ>`|gZcb0X~DIj%qXKDS+``JcIe4!0Bq zz>PRDWL{H|5MEoco;R4n7a|WFShmT+ef*T13qm=G>c>HwxT(Y6{d`{nk<7V|M?$#i z(9!Kj85{;fR^!XTzt|qU^#Bb(A`4gJty~GEtAOp1F4N(W; zL^q@B0vp$3vajKtf90DV8IWGQoN}OZM%OyV);!65HSazJVD~caz=7?UONZI0YaZ41 z5Wl3HBvKjE_K_Tv+i6yfDVCLY@VQ#0BngIg2sPTzp~#?M7!BM;VRpyMVsJC`(e!@F zWu|(_#@MZNRIke0^r|}QR*U@_w$TUpv<<#!JB>uAmq9EX{xxbW>UYKwVpDYDC}6H| zW5zo5DKeK-tAm38Gq=?am*|T#$Hw?cdhsBpS!2^mU1zLHD^MD`P8&|S_EOHaTh)Xg zUoK20f+$8>y@ah{!ji^S6WqO|T=&3QA7)Z*63Sas5{(I4)1>tbZ0i$QKWgeM605ko z<`s$AB$mTZm-Qdhcn5Oe-kNQ0r8#w~!`f3EvrqhRP${N#MfImXkgQE=tap?bgKd%J zDoZk0>J~>ByPRgV*-49}9!D%+sn!luWeL50h$y5yn6S$h-x8h8DVH=sHLz%>hf1%k z#b*%f>|}o|x#1Qn9*51aF!{AhDn-zT#QpP{AG4ICjN63Ygg_JC!YHpulJ_rqp8trg zO`&+)SXk2RlqJo`FV~3S>G?d4&|dcDa=f3iKHOuS6X&B({H0-{R;VxJ_xw7q;SsT+8x9hy3RqJpZ0=t zoZ+76f-QmOjfthxHWf>yAft9$Cr?MTLgg`cNy@QZ1yO(<^W&RAJGhh4j~P`b8|#xp z{bBZyobU|XWSy$@m`g3XdxvdVgxWGeK{8c!@32{8MbL{$c@Scjwb4NV@p$%>4b zU7t*=(~hb6Y&D_DY1v~|PmVcjWL!{Q@!VauK3mt0^0(T(D`FfQ_6lAgoO{RAVUu9KNvUiyGnF}s;CvFRPF zUrAYzot40nxo57vE_(aS4%{{2`QbHT&03?#2aU9jZPeC|HWi>O!h}$g#1rmJLVeOor*ThWzRLTX)l*uXAD@7#A`|bTLe< zz&6lGTta3}p5$oXuyUC9EFoDe8#ih?d|RT-G3=+I4mI^&_Sg;jDk^p-?5n7EE3aZI z15L&%F{FfFd!3QCOdF@!3Kb_qI_|HT<vBZoxhfrKCs1nWLi9zq-UAd=@I5( z4brNC3%0{m+a8mM=Oe5lmi&2O23J!EjD?jYk0H~b2IoE$l@R%(@7#>RMkxUbgwQNX zB8z0;tY9un*UA+!^U-SwCEIl|Kj-R47mv^D02p0YmfqMRos;n44}%}(T+P#T3WLf9 z`~0AmKY}hH^w4fYDsnS!juNL+?q2)Sq+gRKe@oZ9XJB=uO#aBd9{~$% zokvN2>~4&>w>O&H)s*E4Cw$5b>j3+VTA%F1(J|heM}g~0sBQLZG!!D}=7H+KchVOP z>Cv$9;N%mIBZV?L`wJ7{N8$Rh7SBKkP<1YBCJLKPujkIXSFQa;gEzicFG=GsfFBI06 z8J2@>V=iUY!)Ko65V|<7v1#X>+;L1_E~E6g5ZIjOSOjKr4^`0d*p+gMSUzfK)}C>F zkk)7#NAb2{B=Z2!eIks7BNR7iIL?nIM2Dn{FEbm!#*7`f%E{kUx7OD=$S6)a4c zGhq5K=eVPaNiESB+fV8c@9^3^Ib5Ich60S%VYuzz=UpV47 zgtLdXq~DpqQ?)EiOeSvAoyH^hH9``h6-I{H;w1zv) z?hxss=56Lx2UijxU#?MIh&*TX%Bo_`=)Q=0QL0|L#GB8hnkkv*p_2Nd9E-Tf>7CfV zBHB9Q_RBH}DGSYW1HM;7AzwezNhT+*YZ1l#yql+}FF}!_chta^`FPZpy8VSa>6Z_C z{2vp_T>|b{ZdADwXsQks=i4{oM*hS=#LMwwNf)R1=Od;pk?~}bN_*G;jDqi{H9U-ck@x_wxKCiD60a@t+dGv8g++)?VM_dyUt4Q&=fVEp0!sRrhz_X zFD;y7{=n?*^^i|W<~KxX$s}yF%nWS6P}M}1B$ciwQ+?y*qRBDK!aEPljReY02rR#1 zxsS5qA7hdQ&1Fz4H)P{{gl?ks74VI@M+P@+pL68(eQ0Ma0%@M@I{Lo&gq+*$dE?dv z4<@1J`TG`p8qes1XtwfnLF0?t6fIk0Cq*f(5a-xO{s{f0|IW+*g_GHRzL*>SA-r<` z5MIvz>`_#$?Vaq*MXk(DZCypo{=vKEF61o#HY#aq`ilSJyDJX5+Uwkzq*6v+EwCS@ZjkSv~&}tf2OHxI7BK~P|Zo8C(p^8>vPL?z96OPrR!7}Eh6S%DZ z5kud6ci?*xE2GFgI&%++XiC&Y@45c#&^xk7{e-8t3M%p`#eGku-0|aQ`ya7w0B(fC z@p#a7HNicagQv-Q%O9`KHm^w|wcv0g?E0>LuRZJaF#dh_1Puw>ppiaNM*ZhJdfaMO zsG5s+pvI&Q`I&2-Vg;Nz?a%#YX$F&3MtZhc!^;6#eN_)8jbUd0r5kH6hqqPn3y%bH z4g)NMW&DJ9`JRi3VrhaMl7o*ZnXmd4#2Wu&wpn!V=PtS;+-wA(WC#0E6-W3K-T6;5 z27h8jI(`qG9)o>+HeY(Z>!xp^FO4=L*>y*olq~AstQJym14D_n&I1RqRljB9R9gnn z$Bb^E3C<%s>Mt(D5}N9(iL>YM_U?ltgS$s&4zk22EJlVI;I){WtPgm`UA&AB1k34X zP2%Ha26Q8h?_K7+r?WTa@)~h8-cu~Gf2N#QGq+lwW$3u1q#+6X4G6LC-*rvV_sLYf zMhoAx1!Ixy(1@>RBGJGeSIy14!O z{omTU=7;stQ(ryZmis;5+gmE#Z7yT2DkZz7z|}1$W8L0PBdwF{=19}P#x%7!HS1=v z4B1!+77f=)OiW7*=q%I-J*Py+sy2aCL-!o>GgMN>ybieWb4(|9q)ef_p7;*<{_~vU zx##zf{$5;fk_DglOcTHdNnbGIv3MGr(LqjKa!&^#0eTT|c}~b!Q3Wxwpw9JRL_=kV zBdn0^C6Ytldi8@TUQxkxcPfyYCLtgWYK^ct7~D||U}kA&x^vEP!F8SKN9Ooj=uXBx z;C!R5dEo0Yrze0^O=?48YAO z9ghv*=RPBqx3ek@^A!g6-&`$9gU7~>(E={!Jtn7ePPso4YnF{sBydxx>oo# zJ{f)qfPNwq?3tUG_=UC;=}*iWC}hL9EqX8J9&slxwSWDQS0DIZfQBgyh`Ii9oS9}x);Wte&FrUAD7-b5QE`AQTbbA`&*Da z9j?8iL3LhK6Mx_wZcv4Y_FqLv;*esX``|Q3_Lyvc=0DoK|vY)O}z5eM(BLJ~ReWUl>*B@d-k}UK0 zPM}vKWRTq83AE&gNHGPb0K$m{x>sz$`Fn^7Dr7*(Zlnm1{L}3+*$(gqrp%tC0du2L{Nr%v zs&(w|N9ii8^gRwxL`gS9L|_>m89*MW0Y^HVErd->Lw?-7>+87L-~(;a9aLokW6=zt zNdHL#RG+_)q>e{WW*y#M!hz%oNw0Sg{ZZ0}7W(*+H3wpRqJ;okG|4v!f{YovYlW_(hx99x(XM_NTPib8|7*7p6E6}uB7PJdW<3{Y_{7q# zD5~mG6UL*@uiMkJqTff;yvdzQf< z4jWV>+#u9~E-F5LfVSEccRV%>SfvIje)4+BUn&L!X94b~AC=VoEE@x&Pc?mg&ppnT zL5nA^yBjZ&*fvCrJLIf!l=SbV)|3{lT1wwihY9DO$geOrnPOI44qG&_1eld|AmW-Z z@;`l6T}Y)iXj=PlcnYJD#)?ZNgU#Xryve-fxKM~w9cL!HpL|jDR-mGkm|aIvs(t0t zO1zJU8J-ADnT`b*F;niJ zCPVL?*qFB@lS;=R6AejUX!|>2bt0%DwXDR*-3wmB2VQh?wPHZ)4U@HY=Umy*fad!k zVfrp5M}V^0Cee&>kpmDlJ{w;oL$iSx&nKEcf}gHd{7Ip1&n@J1AsQje-6y58+TE}u zU{!cg3p!tv&jlNN%w}v~8P4|U0ukQpnYauWypE>) zC#!KPZ#7BVildh(ObWf75o35>OQVh<6*&4}-3}>Y?IOjP{_q)|ZpTs`8AV|@$+y@5 z9R=lSQFY6Uyi#%_alcjd=L|)FdL+5qPz5d4T~<#+)(CCLzX9}YHp zdf6t$KEk@aUu+1cn(5+MHWHJIg^6J3s=)|ltR-Y6tP<~n!`+OJz^n~r^Evkw=@1^r zqwykK;O1#5>Vv8Z%7cPcf-SsjX7nG>}`Fr#UM1{E*bBM#6rq#kUr(*FV~c`2ds~vQ#u~qy za>yg~czkHoB%8rJrIC|FXw2I=RiPZksbS&Gg_MCOlysM|89#aExNDQ?kyYzu&|CM4 zUtZZ2bH0p4G|t@n zz`(iUvu9GZQC;Ue4^M$bRX(KqfR7iU9;-*EBwBts+H*#xpq0duj#vH8w%{?Um%@UP zop%y!CUxbwUGn|>Dx|rzvT1b)Btz#42R2#J7l&;r)B zz^ZxRMmgh#JDJi<=j=!>LEF*9mwBVWFK0Ny#@mkjuzBA zk#02av0mxo2Q==veufN;?Kyw+0R{$zoIXmT1BQiaoS?U-?wM%$0|V6W9bb#111170 z?*u#Zyl}cZ2JZ`KeF+VLoy5;o9LS44ZNj3ZnrnqqZn4bnXRqU+0fC2Mh3`O@PJ7xf zxbHZnrjl)}<&u*jrP}T71p0)q={A=USL!gtB=`ax>+_t*+8 z_-p-iB1_r{3m)+FmC1)^Ml&nVIgKY%)f_;#FGo?VMKV0y^o!+wESftsO8ta^LwkLaujcGZUFlPlD;I-`tgI|^6VwZdkJwN!D;k%w|6_onIWFhx1Jsw|+e zRRQ;zk~W-fnA16SNgbddNR*Zz;4I5xp|C=$JGWL@n^vd3XR1ytY z8*wp*euNOUg~E^|MP1x%utxP^&t(ak_S{lvel?ry3Asul;;vP=Iif9A808|7Ol0JP ztdX!nBRHIWKV6r5U8ZsXkLZiSSx~2ntW$E@I?tSEbL@&#T`187?J!=Gq~QfCgxf19 zrp4!PJ(Mh6(4{4tL@u`i+|kCefq9hB z{Z6ROD2>y~Tz1-qVQX$!L$-)-B%gs=GG|=e|o3rcrtK(r* zqHrSfRd6P5lVquBo4Y4hSs4JnmZBjat-9*6m5XE(5JFLQ1rR+k#-oc!^T>-m_3oDr z`!o}>PL-;EC^;CsYa96y*i9CBTmH)QzNAkyhXB@uRh+OkpgchY)j1rKUiH>(ez#QEz@0Jb12Ug>OUW$P*s^$sS8R=p=E`Jv33LZl1Zd z1%wtKcHaVJOUd*>q+Un(50HAsuRucP)|bIGV;KZVwprsljKU{PbHd!?eV2w9X)}qd z3g?%**{-xB>sqxY&x$$PR~O@8($Z6O^<*Td6$S*B%AS?hZRnKC&>YQK(>3W)J(`s^ zrfyo$sM&J69?RVcb{KMcRK@5~#a`z@QJx==yM^evz&vBUzL*bB;(y`{Hbzg?o;Slw zIH^39^J-sKn9E9&4k&8@I=48I=mEih``3)v%coHNBu|h7*%TGh|Im23#JD)s%d@H_ zXYZboHJ_>>Mzq4CrPP6N>C|I0TxELf$ zMf{X4Y64L#Px_(Vm}C3=@`UnCc3aerlwU;cTs3}H(RMMZ%87)lBJ|)7d`#p)?K173 zBv_C0DPpU>PHFY^ZX!PY>nf>Go+II@!w}?pjze%%LLrywMN~;qP%=Up$TrHOzOa*mpYY|@|C~Q+Z3$eC zn)`fMdXuXahAmPkuxAV^(A|xT2r6+aQ7^|Ar6`&`aT{)jt+f)LpuM)$qT7EdZ8O`o zrk38(5xW3d{@8_p0 z>j@Xuh*B>a1^R%*6`7ZrztMAxm-JI_v3`13@!?QIx%jt2X>LsOr0bpdS^N^8{)>+> z;y{-r<%@JPJaK{DbJ9queUo;suO$fO3OuUFPliVYy0PiX$h7gS$z1wmEM|+qlPiSO zDV>)Hny2X=WLsc(iuTuMn)oX&XKVjI^`YAi5dk~Ewo4NZ{_N6Q%)?4y0TBwMiIB(k zo^xiW@x~d@De4fP1Z=1DfF#d|D?+A_rwuAsbC5sXy~66~R?T~GJcj*QAz8J1PqFYc zrm-jd(*-5@Z9BLngtjNXPkMXUt0j7cMNyp69|XntKFj*YA_ZlDlcQC~jYGlT!!s^>I&Vn%v@b;umYBCc^7DnAG&NOi7^0F#pMLp~b;JLBgx z5M_>}Oln0_9~a_+ntGA_YedNj25D;3A$_>`_SJ9y6`XpQNV@lAJd?a&><)yV`jj?2 zVQ2#O4^?tYOnyY=sj3QvmRa(>HSimU6psQ2@0=!-t?f5VB~_6a|Dlo>YUi~`!S~jgHZ#rrd{+r+SJ&;yI=_+PTYF&+^L@YQebD5MVmpvoOewegZPp$CpK#W&KtD%fS=x+p2U!0diIwugrFxxvJ6$ydDLG}&A2x(T% zOxT=#7<>wKH6S#8$Wdu8MkBf)QUb~)Xs{o?LgL6(Syn+HlhoU8X6kKRIji_(%pC>l zFAnzMKs1*=><5LFP((y%9=p>!^Wiu0h!p&Cr&qwBwaaqvPf0I?#1YK{Ta_so#idch z2-R}Ni>ic`j1EnrAUNI&!f-gEKnjj06_GjaS%0wKUUrN*XOSb~l10fuRC{Se5!GZ$ z*G)tb*$j;D#+3qMqL+k$hZorwrp#D{FEE|rd%a?NzAd-h^itKfBs5hwC|cy`9?n4H z7)A0rXGZkI=f&hC7A0*$IZMt;^S8##O=F6q#%!L#oU}ns4S-**jExCG6B_~TKHi=D zunJttzV4m<@~BDjfvXDIXl*Le@u*jhGP{UdaA4!L(c2 z$dO;%dhMHO0T93VFPyFR4popuBPtfvBb~K8A=a2^s^?rW6li#%GSGsY&z{iNJEQfF z{q%oGN~e;CAV?aQG*06xM#bc=kO(@U0`{(&$BbiYj*$;akW!8#phce1y8!y)&KtjJ z`45_8rIuzOyNcKSgW)CMG5VhLUr#wT`y0PQ*cTofG5o;>0u5JMg2~@V1qvz*??0e> z<<@#IWcG2~BK_SWsc5-DWzTmSll9Tv1LvTjbzvy%P}CY@isBi<&Fx^>o6DSVbfGkv zks!1Lu1seRh(%JZQGZHHQ0YL2oSM?jUS~E40}7M|AdiyaV!$49#Mc_A%1k zi6EbHrV0XJgo>q{@z{qFq8>wDq2@~{+5xD!=R*kk2qBJeaD#%FP4$PGvH;m+Lt!nMywG!7;a1VRwe!-$;TH2ujURF~qk5xo zZt#z<7i3uEiz0d`AEE(8Bb3>5;;Pc2L0g33pl$5pUldICI6R$$xf=zMDX0;`rnWr; zh+VKma`dnq-e-Y+hcNlFsGPh#L0-nx?0}^{Cb|U~OnzW5(Gp3rOEE`IedPQ!KtQ-P z6XzF7+GNQ9(QyE(HI{Sz!=4ly?#HF~+N5b8Z57V7apN9B=P$U%b^Czn`1?-(t#)W{ z^FeRNMQQ`&jqzboPg?<5pi#+=av^f6qEha18VUgw60(VWv3Od|@FX9p5a9f3CH1g^ zEUJ>GZ`dq>jIuwm28^;KqdCxSha_1tnmmF|{NmS>CXO1gmn@=?$%o1oZAXFF9G6Gx z1NBjbkvxfqEHNkfw=&$X!Kix(!WlUXzui;D5KZ2&7IDstI4`kH;ocLE?FlU4)FRt_ zrVYy@#)~4X04f;A9KtAwQ<4?(5~wJHX;KvwBq}I^yqR$=BI-X8$c&=76_Vf^pPUe-D~yo% zEYzkds#8oz`d~9Dvz)iGp1QEe6g9+Mfm3^dFJLcm+ma55`?{Xr5Y;VwQim;z@8oBn z7M^@YP6IfWywdjElIV{^NHl|rp1YyCuY4fg_uC=1S#mC}yw;<7ieL9en4M5rm!7U5 zUc_y6Qa`z%<+xB*^+*>}D@M9_TKw}hqm~cTi)?r3o(I4Gjezo>Z455YT`R>;RKE77 zsv`E^+NB8F**crJJO5mM8YnJC&UTKHwx)Lf-x8%--Aw@d1ohiT!k!?86eQ(p&mBPv zqR!fSRI(4m_!0rcwV#npb^~t#D72XS)tQK+JhSD@cCm!mW|1u$6W11-9&^*>yrv28 zb9=VqRqI@0vE$}u-lqYc!2fu4)4l7pt5qtV!}X5v2iDpFQa1?Q>lSJ2x?lQ^iOw_innl<=wsbcQAFzF6$YA{|1W%{-iB`$i+{gOU05qHKWi4ibC@phLJhLgem_ z7rS0z?D(kn41jWtDAso{&uwom&bP0`6sK8_c?RS! zaK*DEnb&DaVl?S3)JByh#4nkIyjg78FhknrQ;UM;^)|-lUmb*z4`f)5RUpDxSPsl3 z8U)(j;9(^WhEPVyI$wK(uV$-{l8Q!8gp0@*9G0w9d4w%yFf0_YbW7u|Xf_6ImQo^0 zH?fJTMA5>mzC197S#InBFk=vXVRXuu<~giJ4ao)YbfDME@yc-7Ee&otGub8uCjD8`5uK0wN_3x43OG+vjDk0naTa~uHVGjbb=%^IbZ30dZK2=q< z8#nOVtEla&W4KV!a4Eu=&QBPf79(SLI-rR+(PP5AgPeNSy_CSzEJKAEjXpt-szA}2 zf@ql>CLBejH^rdOuTQYVY;b6u0}Sx{fW$_N!;%~XDfeT2v6l27L$N_kR`M%l?LH`& zx57~2OTr)e$QLL)*^8adUng=p)@=lUb$tPjA=@^%q$IstwWC z3?`qyU)b7IsoY*J(bursH>^&dpU4NgT*M1L96Ay<;ZNr%0Af5qb>iLU}?3oB)>QV@fSO_tHJKev( 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

B&WfgKtR<04|R`-u&wofFOF$Ic_}ZqfB8Pi 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

wvbA8gr1#5D^@%`Hn93%6i>H~ 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 gB!nNw=RUz~tQ@2F!V|3B$cZ@wxAs>i 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 Owc8d3EB^rm1N%Q=$zGuV literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties index a603ccf38..e2ff62e8a 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=An easy, safe and fast scripting language for Elasticsearch # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=lang-painless @@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-security.policy b/src/test/resources/test-home-dir/modules/lang-painless/plugin-security.policy index f4d757447..b383c6da3 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-security.policy +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-security.policy @@ -7,7 +7,7 @@ * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an diff --git a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties index bd5a7ecea..1e5e098c2 100644 --- a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds advanced field mappers # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=mapper-extras @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties index e49908e3f..a1503106d 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=The Reindex module adds APIs to reindex from one index to another or update documents in place. # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=reindex @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-security.policy b/src/test/resources/test-home-dir/modules/reindex/plugin-security.policy index e59570988..a2482eaf4 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-security.policy +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-security.policy @@ -7,7 +7,7 @@ * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties index 19742f641..6507a11e2 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for URL repository # # 'version': plugin's version -version=7.4.1 +version=7.5.1 # # 'name': the plugin name name=repository-url @@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.4.1 +elasticsearch.version=7.5.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-security.policy b/src/test/resources/test-home-dir/modules/repository-url/plugin-security.policy index 1959e8a14..b878c4857 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-security.policy +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-security.policy @@ -7,7 +7,7 @@ * 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.4.1.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.5.1.jar similarity index 81% rename from src/test/resources/test-home-dir/modules/repository-url/repository-url-7.4.1.jar rename to src/test/resources/test-home-dir/modules/repository-url/repository-url-7.5.1.jar index 973eba00564f56a12a67ab0f7623d6205dcdc956..07ab80290e9bf6b5febca6435255ea878062d53d 100644 GIT binary patch delta 1185 zcmaD-__B~Uz?+$ci-CcIgF$@9go(UroIuK7<;L@_!ihGD^{4Z08wl*-zF;r#VyUa+ zttn2CN&2pH7G=yjz%K22@pfC3H;YEl1Lcf=`+8*6`7X&-J!rJvY<)QLUencTo{9e) ziR0~ZxpeW8l7EeA`F3k( zB>Xu$A-z@ohf${ROSAgLnjVXCj~tYrq5k5Nzj(dwGd2{!i)&huiJ%NAI@$hz9OyKZIGRuS>J53=re?#rF1od0{>$*|&(tUvSn z=9j!(7MWge{eju7s`l&OkK9|HU-;Nr-@0$k?Yhkm#qaqBWt=a&u<6&w*?+SyTstJ= zCa!w3nKMEx^&>kXI&N&6;J^7Q;~ajbZ4)LJ3+`eDM$BXbAw@79BBT$d_sW}r>2LCm zVA@K-RS*<`Pn!z9JF_q_aPcxQI8JVq5S{!$o_(@{0{7(g=CYfwDEP8~m8+=Qfa(20 z%9D94c!f)ga`c%Q5N-e(wRxH9TwZRZG%|Uwyz=DtChU_p2=PEQJAmzE00Jfu0R-wm zJGCZT34>K^_7qlU1u5NJEMd>i%g7|c3{P>B1B^`&Np5nlu_ZImLyBH>wHY4#WjQ&81jqK^#i<74XXpH^qH(^Dmr<+3B+;xfFgBZ5nupl zqp9}?IThw)6%Ypu1Q`B0Zinds1sYy`8Zd1PAbr1)^-Yd67XZ6C$6T7pS$Oh91?S0U z%pnfD4HSARK3Py$1Q_y?3ZO^>83c2UGK#4x5>SP_lhZ69Mpjx#Go>Shw_8Y}1uW3# zO#Es%k=VWF&<;t^eMUujL>RW%AfzR&1AC{XZVg7cr8{m;|yd#;|Z;8MhImyzyz zEW=JFrhIQBU(OW4=9Hz287Era4=^xtS{jH zpH6;YoUfj%6sa_;=|ugO-U~l`pYd7Mi{9LPWI^xl3rU)rc5Zu_D!t-lYmY|H^EWLU z<`nEp5(*df9UIXa$e!-1Wy*Pspe+Pw5I<`ORLGKjqo3 zxW)UXe&KZ~DlYt8$8@OtatO){(WIr$6^oR zfae7t*bp&st24}h%a%uNxts4ZPUmOp44YgbxQiJWF_TS&6v1?)kUp4}Q8NS6h7!t? z?bX;P*Q<$v`7_j9K=kJOYU-?D2B(faJ2z5HPnJ Date: Thu, 2 Jan 2020 13:27:32 +0100 Subject: [PATCH 0030/1191] DATAES-278 - Fix documentation for created queries from repository method names. Original PR: #371 --- .../elasticsearch-repository-queries.adoc | 213 +++++-- .../core/ElasticsearchPartQueryTests.java | 589 ++++++++++++++++++ 2 files changed, 758 insertions(+), 44 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index ae0a126d6..4e578ce9c 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -8,7 +8,7 @@ The Elasticsearch module supports all basic query building feature as string que === Declared queries -Deriving the query from the method name is not always sufficient and/or may result in unreadable method names. In this case one might make either use of `@Query` annotation (see <> ). +Deriving the query from the method name is not always sufficient and/or may result in unreadable method names. In this case one might make use of the `@Query` annotation (see <> ). [[elasticsearch.query-methods.criterions]] == Query creation @@ -29,12 +29,14 @@ The method name above will be translated into the following Elasticsearch json q [source] ---- -{ "bool" : - { "must" : - [ - { "field" : {"name" : "?"} }, - { "field" : {"price" : "?"} } - ] +{ + "query": { + "bool" : { + "must" : [ + { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, + { "query_string" : { "query" : "?", "fields" : [ "price" ] } } + ] + } } } ---- @@ -48,80 +50,184 @@ A list of supported keywords for Elasticsearch is shown below. | Sample | Elasticsearch Query String| `And` | `findByNameAndPrice` -| `{"bool" : {"must" : [ {"field" : {"name" : "?"}}, - {"field" : {"price" : "?"}} ]}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, + { "query_string" : { "query" : "?", "fields" : [ "price" ] } } + ] + } +}}` | `Or` | `findByNameOrPrice` -| `{"bool" : {"should" : [ {"field" : {"name" : "?"}}, - {"field" : {"price" : "?"}} ]}}` +| `{ "query" : { +"bool" : { +"should" : [ + { "query_string" : { "query" : "?", "fields" : [ "name" ] } }, + { "query_string" : { "query" : "?", "fields" : [ "price" ] } } + ] + } +}}` | `Is` | `findByName` -| `{"bool" : {"must" : {"field" : {"name" : "?"}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "?", "fields" : [ "name" ] } } + ] + } +}}` | `Not` | `findByNameNot` -| `{"bool" : {"must_not" : {"field" : {"name" : "?"}}}}` +| `{ "query" : { +"bool" : { +"must_not" : [ + { "query_string" : { "query" : "?", "fields" : [ "name" ] } } + ] + } +}}` | `Between` | `findByPriceBetween` -| `{"bool" : {"must" : {"range" : {"price" : {"from" : - ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : ?, "to" : ?, "include_lower" : true, "include_upper" : true } } } + ] + } +}}` -| `LessThanEqual` +| `LessThan` | `findByPriceLessThan` -| `{"bool" : {"must" : {"range" : {"price" : {"from" : - null,"to" : ?,"include_lower" : true,"include_upper" : - true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : false } } } + ] + } +}}` + +| `LessThanEqual` +| `findByPriceLessThanEqual` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } + ] + } +}}` + +| `GreaterThan` +| `findByPriceGreaterThan` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : false, "include_upper" : true } } } + ] + } +}}` + | `GreaterThanEqual` | `findByPriceGreaterThan` -| `{"bool" : {"must" : {"range" : {"price" : {"from" : - ?,"to" : null,"include_lower" : true,"include_upper" : - true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } + ] + } +}}` | `Before` | `findByPriceBefore` -| `{"bool" : {"must" : {"range" : {"price" : {"from" : - null,"to" : ?,"include_lower" : true,"include_upper" : - true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : null, "to" : ?, "include_lower" : true, "include_upper" : true } } } + ] + } +}}` | `After` | `findByPriceAfter` -| `{"bool" : {"must" : {"range" : {"price" : {"from" : - ?,"to" : null,"include_lower" : true,"include_upper" : - true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"range" : {"price" : {"from" : ?, "to" : null, "include_lower" : true, "include_upper" : true } } } + ] + } +}}` | `Like` | `findByNameLike` -| `{"bool" : {"must" : {"field" : {"name" : {"query" : - "?*","analyze_wildcard" : true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } + ] + } +}}` | `StartingWith` | `findByNameStartingWith` -| `{"bool" : {"must" : {"field" : {"name" : {"query" : - "?*","analyze_wildcard" : true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "?*", "fields" : [ "name" ] }, "analyze_wildcard": true } + ] + } +}}` | `EndingWith` | `findByNameEndingWith` -| `{"bool" : {"must" : {"field" : {"name" : {"query" : - "*?","analyze_wildcard" : true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "*?", "fields" : [ "name" ] }, "analyze_wildcard": true } + ] + } +}}` | `Contains/Containing` | `findByNameContaining` -| `{"bool" : {"must" : {"field" : {"name" : {"query" : - "*?*","analyze_wildcard" : true}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "\*?*", "fields" : [ "name" ] }, "analyze_wildcard": true } + ] + } +}}` | `In` | `findByNameIn(Collectionnames)` -| `{"bool" : {"must" : {"bool" : {"should" : [ {"field" : - {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"bool" : {"must" : [ + {"terms" : {"name" : ["?","?"]}} + ] + } + } + ] + } +}}` | `NotIn` | `findByNameNotIn(Collectionnames)` -| `{"bool" : {"must_not" : {"bool" : {"should" : {"field" : - {"name" : "?"}}}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + {"bool" : {"must_not" : [ + {"terms" : {"name" : ["?","?"]}} + ] + } + } + ] + } +}}` | `Near` | `findByStoreNear` @@ -129,16 +235,35 @@ A list of supported keywords for Elasticsearch is shown below. | `True` | `findByAvailableTrue` -| `{"bool" : {"must" : {"field" : {"available" : true}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "true", "fields" : [ "available" ] } } + ] + } +}}` | `False` | `findByAvailableFalse` -| `{"bool" : {"must" : {"field" : {"available" : false}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "false", "fields" : [ "available" ] } } + ] + } +}}` | `OrderBy` | `findByAvailableTrueOrderByNameDesc` -| `{"sort" : [{ "name" : {"order" : "desc"} }],"bool" : - {"must" : {"field" : {"available" : true}}}}` +| `{ "query" : { +"bool" : { +"must" : [ + { "query_string" : { "query" : "true", "fields" : [ "available" ] } } + ] + } +}, "sort":[{"name":{"order":"desc"}}] +}` + |=== [[elasticsearch.query-methods.at-query]] diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java new file mode 100644 index 000000000..7e631c3a1 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -0,0 +1,589 @@ +/* + * Copyright 2020 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; + +import static org.mockito.Mockito.*; +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.json.JSONException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.elasticsearch.repository.query.ElasticsearchPartQuery; +import org.springframework.data.elasticsearch.repository.query.ElasticsearchQueryMethod; +import org.springframework.data.projection.SpelAwareProxyProjectionFactory; +import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; +import org.springframework.data.repository.query.ParametersParameterAccessor; + +/** + * Tests for {@link ElasticsearchPartQuery}. Resides in the core package, as we need an instance of the + * {@link RequestFactory} class for the tests. The tests make sure that queries are built according to the method + * naming. + * + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +class ElasticsearchPartQueryTests { + + public static final String BOOK_TITLE = "Title"; + public static final int BOOK_PRICE = 42; + + private @Mock ElasticsearchOperations operations; + private ElasticsearchConverter converter; + + @BeforeEach + public void setUp() { + converter = new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext()); + when(operations.getElasticsearchConverter()).thenReturn(converter); + } + + @Test + void findByName() throws NoSuchMethodException, JSONException { + String methodName = "findByName"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameNot() throws NoSuchMethodException, JSONException { + String methodName = "findByNameNot"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must_not\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameLike() throws NoSuchMethodException, JSONException { + String methodName = "findByNameLike"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + + "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameStartingWith() throws NoSuchMethodException, JSONException { + String methodName = "findByNameStartingWith"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + + "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameEndingWith() throws NoSuchMethodException, JSONException { + String methodName = "findByNameEndingWith"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"*" + BOOK_TITLE + + "\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameContaining() throws NoSuchMethodException, JSONException { + String methodName = "findByNameContaining"; + Class[] parameterClasses = new Class[] { String.class }; + Object[] parameters = new Object[] { BOOK_TITLE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"*" + BOOK_TITLE + + "*\", \"fields\" : [\"name^1.0\"], \"analyze_wildcard\": true }}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameIn() throws NoSuchMethodException, JSONException { + String methodName = "findByNameIn"; + Class[] parameterClasses = new Class[] { Collection.class }; + List names = new ArrayList<>(); + names.add(BOOK_TITLE); + names.add(BOOK_TITLE + "2"); + Object[] parameters = new Object[] { names }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"bool\" : {\"must\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) + + "\"]}}]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameNotIn() throws NoSuchMethodException, JSONException { + String methodName = "findByNameNotIn"; + Class[] parameterClasses = new Class[] { Collection.class }; + List names = new ArrayList<>(); + names.add(BOOK_TITLE); + names.add(BOOK_TITLE + "2"); + Object[] parameters = new Object[] { names }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"bool\" : {\"must_not\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) + + "\"]}}]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPrice() throws NoSuchMethodException, JSONException { + String methodName = "findByPrice"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { 42 }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameAndPrice() throws NoSuchMethodException, JSONException { + String methodName = "findByNameAndPrice"; + Class[] parameterClasses = new Class[] { String.class, Integer.class }; + Object[] parameters = new Object[] { BOOK_TITLE, BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}," + // + " {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByNameOrPrice() throws NoSuchMethodException, JSONException { + String methodName = "findByNameOrPrice"; + Class[] parameterClasses = new Class[] { String.class, Integer.class }; + Object[] parameters = new Object[] { BOOK_TITLE, BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"should\" : [" + // + " {\"query_string\" : {\"query\" : \"" + BOOK_TITLE + "\", \"fields\" : [\"name^1.0\"]}}," + // + " {\"query_string\" : {\"query\" : \"" + BOOK_PRICE + "\", \"fields\" : [\"price^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceBetween() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceBetween"; + Class[] parameterClasses = new Class[] { Integer.class, Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE - 10, BOOK_PRICE + 10 }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : 32, \"to\" : 52, \"include_lower\" : true, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceLessThan() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceLessThan"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : false } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceLessThanEqual() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceLessThanEqual"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceGreaterThan() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceGreaterThan"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : false, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceGreaterThanEqual() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceGreaterThanEqual"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : true, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceBefore() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceBefore"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : null, \"to\" : 42, \"include_lower\" : true, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByPriceAfter() throws NoSuchMethodException, JSONException { + String methodName = "findByPriceAfter"; + Class[] parameterClasses = new Class[] { Integer.class }; + Object[] parameters = new Object[] { BOOK_PRICE }; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"range\" : {\"price\" : {\"from\" : 42, \"to\" : null, \"include_lower\" : true, \"include_upper\" : true } } }" + + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByAvailableTrue() throws NoSuchMethodException, JSONException { + String methodName = "findByAvailableTrue"; + Class[] parameterClasses = new Class[] {}; + Object[] parameters = new Object[] {}; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"true\", \"fields\" : [\"available^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByAvailableFalse() throws NoSuchMethodException, JSONException { + String methodName = "findByAvailableFalse"; + Class[] parameterClasses = new Class[] {}; + Object[] parameters = new Object[] {}; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"false\", \"fields\" : [\"available^1.0\"]}}" + // + " ]" + // + " }" + // + "}}"; // + + assertEquals(expected, query, false); + } + + @Test + void findByAvailableTrueOrderByNameDesc() throws NoSuchMethodException, JSONException { + String methodName = "findByAvailableTrueOrderByNameDesc"; + Class[] parameterClasses = new Class[] {}; + Object[] parameters = new Object[] {}; + + String query = getQueryBuilder(methodName, parameterClasses, parameters); + + String expected = "{\"query\": {" + // + " \"bool\" : {" + // + " \"must\" : [" + // + " {\"query_string\" : {\"query\" : \"true\", \"fields\" : [\"available^1.0\"]}}" + // + " ]" + // + " }" + // + "}," + // + "\"sort\":[{\"name\":{\"order\":\"desc\"}}]" + // + '}'; // + + assertEquals(expected, query, false); + } + + private String getQueryBuilder(String methodName, Class[] parameterClasses, Object[] parameters) + throws NoSuchMethodException { + Method method = SampleRepository.class.getMethod(methodName, parameterClasses); + ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method, + new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(), + converter.getMappingContext()); + ElasticsearchPartQuery partQuery = new ElasticsearchPartQuery(queryMethod, operations); + CriteriaQuery criteriaQuery = partQuery + .createQuery(new ParametersParameterAccessor(queryMethod.getParameters(), parameters)); + SearchSourceBuilder source = new RequestFactory(converter) + .searchRequest(criteriaQuery, Book.class, IndexCoordinates.of("dummy")).source(); + return source.toString(); + } + + private interface SampleRepository extends ElasticsearchRepository { + List findByName(String name); + + List findByNameNot(String name); + + List findByNameLike(String name); + + List findByNameStartingWith(String name); + + List findByNameEndingWith(String name); + + List findByNameContaining(String name); + + List findByNameIn(Collection names); + + List findByNameNotIn(Collection names); + + List findByNameAndPrice(String name, Integer price); + + List findByNameOrPrice(String name, Integer price); + + List findByPrice(Integer price); + + List findByPriceBetween(Integer lower, Integer upper); + + List findByPriceLessThan(Integer price); + + List findByPriceLessThanEqual(Integer price); + + List findByPriceGreaterThan(Integer price); + + List findByPriceGreaterThanEqual(Integer price); + + List findByPriceBefore(Integer price); + + List findByPriceAfter(Integer price); + + List findByAvailableTrue(); + + List findByAvailableFalse(); + + List findByAvailableTrueOrderByNameDesc(); + + } + + static class Book { + @Id private String id; + private String name; + private Integer price; + @Field(type = FieldType.Boolean) private boolean available; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getPrice() { + return price; + } + + public void setPrice(Integer price) { + this.price = price; + } + + public Boolean getAvailable() { + return available; + } + + public void setAvailable(Boolean available) { + this.available = available; + } + } +} From 0d272fe9bfed391571273a16318d3a3e9f2f7468 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 3 Jan 2020 23:20:17 +0100 Subject: [PATCH 0031/1191] DATAES-717 - Enable Repositories to return a SearchHits instance instead of a list. Original PR: #372 --- .../reference/elasticsearch-operations.adoc | 5 +- .../elasticsearch-repository-queries.adoc | 10 +++ .../core/ReactiveElasticsearchTemplate.java | 9 ++- .../data/elasticsearch/core/SearchHits.java | 2 +- ...tReactiveElasticsearchRepositoryQuery.java | 5 +- .../query/ElasticsearchPartQuery.java | 5 +- .../query/ElasticsearchQueryMethod.java | 64 +++++++++++++++++-- .../query/ElasticsearchStringQuery.java | 3 +- .../ReactiveElasticsearchQueryMethod.java | 12 +++- .../ElasticsearchRepositoryFactory.java | 5 ++ .../ElasticsearchRepositoryMetadata.java | 59 +++++++++++++++++ ...eactiveElasticsearchRepositoryFactory.java | 7 +- ...activeElasticsearchRepositoryMetadata.java | 37 +++++++++++ .../CustomMethodRepositoryBaseTests.java | 64 ++++++++++++++++++- ...eReactiveElasticsearchRepositoryTests.java | 39 ++++++++++- 15 files changed, 304 insertions(+), 22 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index 7b1cc3ef1..1e80e865e 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -133,12 +133,15 @@ Contains the following information: * Id * Score * Sort Values -* the retrieved entity of type +* Highligth fields +* The retrieved entity of type .SearchHits Contains the following information: * Number of total hits +* Total hits relation * Maximum score * A list of `SearchHit` objects +* Returned aggregations diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index 4e578ce9c..7dd13bb88 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -266,6 +266,16 @@ A list of supported keywords for Elasticsearch is shown below. |=== +== Method return types + +Repository methods can be defined to have the following return types for returning multiple Elements: + +* `List` +* `Stream` +* `SearchHits` +* `List>` +* `Stream<>>SearchHit>` + [[elasticsearch.query-methods.at-query]] == Using @Query Annotation diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index fc71a7af2..8d36358c3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. @@ -429,6 +429,10 @@ public Flux> search(Query query, Class entityType, Class private Flux doFind(Query query, Class clazz, IndexCoordinates index) { + if (query instanceof CriteriaQuery) { + converter.updateQuery((CriteriaQuery) query, clazz); + } + return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, clazz, index); @@ -561,11 +565,10 @@ private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntit private QueryBuilder mappedQuery(Query query, ElasticsearchPersistentEntity entity) { - // TODO: we need to actually map the fields to the according field names! - QueryBuilder elasticsearchQuery = null; if (query instanceof CriteriaQuery) { + converter.updateQuery((CriteriaQuery) query, entity.getType()); elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(((CriteriaQuery) query).getCriteria()); } else if (query instanceof StringQuery) { elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java index c5a2e4317..876daa5e5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -35,11 +35,11 @@ public class SearchHits implements Streamable> { private final long totalHits; + private final TotalHitsRelation totalHitsRelation; private final float maxScore; private final String scrollId; private final List> searchHits; private final Aggregations aggregations; - private final TotalHitsRelation totalHitsRelation; /** * @param totalHits the number of total hits for the search diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index f2a044b57..eb4808bd7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -62,7 +62,7 @@ public Object execute(Object[] parameters) { Object result = queryMethod.hasReactiveWrapperParameter() ? executeDeferred(parameters) : execute(new ReactiveElasticsearchParametersParameterAccessor(queryMethod, parameters)); - return SearchHitSupport.unwrapSearchHits(result); + return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result; } private Object executeDeferred(Object[] parameters) { @@ -122,7 +122,8 @@ private ReactiveElasticsearchQueryExecution getExecutionToWrap(ElasticsearchPara return (query, type, targetType, indexCoordinates) -> operations.search(query.setPageable(accessor.getPageable()), type, targetType, indexCoordinates); } else { - return (query, type, targetType, indexCoordinates) -> operations.search(query, type, targetType, indexCoordinates); + return (query, type, targetType, indexCoordinates) -> operations.search(query, type, targetType, + indexCoordinates); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index b529bf8b3..546b6e49d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -86,7 +86,7 @@ public Object execute(Object[] parameters) { } else { query.setPageable(accessor.getPageable()); } - result = StreamUtils.createStreamFromIterator(elasticsearchOperations.stream(query, clazz, index)); + result = StreamUtils.createStreamFromIterator(elasticsearchOperations.searchForStream(query, clazz, index)); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isUnpaged()) { @@ -97,13 +97,14 @@ public Object execute(Object[] parameters) { } result = elasticsearchOperations.search(query, clazz, index); + } else if (tree.isCountProjection()) { result = elasticsearchOperations.count(query, clazz, index); } else { result = elasticsearchOperations.searchOne(query, clazz, index); } - return SearchHitSupport.unwrapSearchHits(result); + return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result; } private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java index 8fd8a97d9..2705e7b69 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -16,9 +16,14 @@ package org.springframework.data.elasticsearch.repository.query; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.Collection; +import java.util.stream.Stream; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.data.elasticsearch.annotations.Query; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.mapping.context.MappingContext; @@ -37,22 +42,25 @@ * @author Oliver Gierke * @author Mark Paluch * @author Christoph Strobl + * @author Peter-Josef Meisch */ public class ElasticsearchQueryMethod extends QueryMethod { + private final Method method; // private in base class, but needed here as well private final Query queryAnnotation; private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private @Nullable ElasticsearchEntityMetadata metadata; - public ElasticsearchQueryMethod(Method method, RepositoryMetadata metadata, ProjectionFactory factory, + public ElasticsearchQueryMethod(Method method, RepositoryMetadata repositoryMetadata, ProjectionFactory factory, MappingContext, ElasticsearchPersistentProperty> mappingContext) { - super(method, metadata, factory); + super(method, repositoryMetadata, factory); Assert.notNull(mappingContext, "MappingContext must not be null!"); - this.queryAnnotation = method.getAnnotation(Query.class); + this.method = method; this.mappingContext = mappingContext; + this.queryAnnotation = method.getAnnotation(Query.class); } public boolean hasAnnotatedQuery() { @@ -101,4 +109,52 @@ public ElasticsearchEntityMetadata getEntityInformation() { protected MappingContext, ElasticsearchPersistentProperty> getMappingContext() { return mappingContext; } + + /** + * checks whether the return type of the underlying method is a + * {@link org.springframework.data.elasticsearch.core.SearchHits} or a collection of + * {@link org.springframework.data.elasticsearch.core.SearchHit}. + * + * @return true if the method has a {@link org.springframework.data.elasticsearch.core.SearchHit}t related return type + * @since 4.0 + */ + public boolean isSearchHitMethod() { + Class methodReturnType = method.getReturnType(); + + if (SearchHits.class.isAssignableFrom(methodReturnType)) { + return true; + } + + try { + // dealing with Collection>, getting to T + ParameterizedType methodGenericReturnType = ((ParameterizedType) method.getGenericReturnType()); + if (isAllowedGenericType(methodGenericReturnType)) { + ParameterizedType collectionTypeArgument = (ParameterizedType) methodGenericReturnType + .getActualTypeArguments()[0]; + if (SearchHit.class.isAssignableFrom((Class) collectionTypeArgument.getRawType())) { + return true; + } + } + } catch (Exception ignored) {} + + return false; + } + + protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { + return Collection.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()) + || Stream.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()); + } + + /** + * checks whether the return type of the underlying method is a + * {@link org.springframework.data.elasticsearch.core.SearchHits} or a collection of + * {@link org.springframework.data.elasticsearch.core.SearchHit}. + * + * @return true if the method has not a {@link org.springframework.data.elasticsearch.core.SearchHit}t related return + * type + * @since 4.0 + */ + public boolean isNotSearchHitMethod() { + return !isSearchHitMethod(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 79348e9c0..567a4696f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -89,8 +89,7 @@ public Object execute(Object[] parameters) { result = elasticsearchOperations.searchOne(stringQuery, clazz, index); } - return SearchHitSupport.unwrapSearchHits(result); - + return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result; } protected StringQuery createQuery(ParametersParameterAccessor parameterAccessor) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java index da6b7dba0..eecad7b69 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. @@ -17,7 +17,10 @@ import static org.springframework.data.repository.util.ClassUtils.*; +import reactor.core.publisher.Flux; + import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.domain.Page; @@ -115,4 +118,11 @@ public boolean isStreamQuery() { public ElasticsearchParameters getParameters() { return (ElasticsearchParameters) super.getParameters(); } + + @Override + protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { + return super.isAllowedGenericType(methodGenericReturnType) + || Flux.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()); + } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java index 0d8443667..e37bf8011 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java @@ -115,4 +115,9 @@ public RepositoryQuery resolveQuery(Method method, RepositoryMetadata metadata, return new ElasticsearchPartQuery(queryMethod, elasticsearchOperations); } } + + @Override + protected RepositoryMetadata getRepositoryMetadata(Class repositoryInterface) { + return new ElasticsearchRepositoryMetadata(repositoryInterface); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java new file mode 100644 index 000000000..9ad08e572 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java @@ -0,0 +1,59 @@ +/* + * Copyright 2020 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.repository.support; + +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.util.Collection; +import java.util.stream.Stream; + +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class ElasticsearchRepositoryMetadata extends DefaultRepositoryMetadata { + + public ElasticsearchRepositoryMetadata(Class repositoryInterface) { + super(repositoryInterface); + } + + @Override + public Class getReturnedDomainClass(Method method) { + Class returnedDomainClass = super.getReturnedDomainClass(method); + if (SearchHit.class.isAssignableFrom(returnedDomainClass)) { + try { + // dealing with Collection> or Flux>, getting to T + ParameterizedType methodGenericReturnType = ((ParameterizedType) method.getGenericReturnType()); + if (isAllowedGenericType(methodGenericReturnType)) { + ParameterizedType collectionTypeArgument = (ParameterizedType) methodGenericReturnType + .getActualTypeArguments()[0]; + if (SearchHit.class.isAssignableFrom((Class) collectionTypeArgument.getRawType())) { + returnedDomainClass = (Class) collectionTypeArgument.getActualTypeArguments()[0]; + } + } + } catch (Exception ignored) {} + } + return returnedDomainClass; + } + + protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { + return Collection.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()) + || Stream.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java index b9c64c871..72025e88f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. @@ -120,6 +120,11 @@ private ElasticsearchEntityInformation getEntityInformation(Class entity.getIndexCoordinates(), entity.getVersionType()); } + @Override + protected RepositoryMetadata getRepositoryMetadata(Class repositoryInterface) { + return new ReactiveElasticsearchRepositoryMetadata(repositoryInterface); + } + /** * @author Christoph Strobl */ diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java new file mode 100644 index 000000000..18dc491d1 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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.repository.support; + +import reactor.core.publisher.Flux; + +import java.lang.reflect.ParameterizedType; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class ReactiveElasticsearchRepositoryMetadata extends ElasticsearchRepositoryMetadata { + + public ReactiveElasticsearchRepositoryMetadata(Class repositoryInterface) { + super(repositoryInterface); + } + + @Override + protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { + return super.isAllowedGenericType(methodGenericReturnType) + || Flux.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index a7c0ebd12..943127887 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; @@ -48,6 +49,8 @@ import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -379,7 +382,7 @@ public void shouldHandleManyValuesQueryingIn() { List list = repository.findByKeywordIn(keywords); // then - assertThat(list).hasSize(1); + assertThat(list).hasSize(1); assertThat(list.get(0).getId()).isEqualTo(documentId1); } @@ -1366,6 +1369,53 @@ void streamMethodShouldNotReturnSearchHits() { stream.forEach(o -> assertThat(o).isInstanceOf(SampleEntity.class)); } + @Test // DATAES-717 + void shouldReturnSearchHits() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + // when + SearchHits searchHits = repository.queryByType("abc"); + + assertThat(searchHits.getTotalHits()).isEqualTo(20); + } + + @Test // DATAES-717 + void shouldReturnSearchHitList() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + // when + List> searchHitList = repository.queryByMessage("Message"); + + assertThat(searchHitList).hasSize(20); + } + + @Test // DATAES-717 + void shouldReturnSearchHitStream() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + // when + Stream> searchHitStream = repository.readByMessage("Message"); + + List> searchHitList = searchHitStream // + .peek(searchHit -> assertThat(searchHit.getContent().getType()).isEqualTo("abc")) // + .collect(Collectors.toList()); + assertThat(searchHitList).hasSize(20); + } + + @Test // DATAES-717 + void shouldReturnSearchHitsForStringQuery() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + // when + SearchHits searchHits = repository.queryByString("abc"); + + assertThat(searchHits.getTotalHits()).isEqualTo(20); + } + private List createSampleEntities(String type, int numberOfEntities) { List entities = new ArrayList<>(); @@ -1386,8 +1436,7 @@ private List createSampleEntities(String type, int numberOfEntitie @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-repositories-custo-method", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-repositories-custom-method", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; @@ -1502,6 +1551,15 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository queryByType(String type); + + @Query("{\"bool\": {\"must\": [{\"term\": {\"type\": \"?0\"}}]}}") + SearchHits queryByString(String type); + + List> queryByMessage(String type); + + Stream> readByMessage(String type); } /** diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index 8738e6c15..c1c933eed 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -23,7 +23,6 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.junit.jupiter.api.AfterEach; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -43,6 +42,7 @@ import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; @@ -62,6 +62,7 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration; +import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; @@ -181,7 +182,8 @@ public void findAllByIdShouldRetrieveMatchingDocuments() throws IOException { repository.findAllById(Arrays.asList("id-one", "id-two")) // .as(StepVerifier::create)// - .expectNextCount(2) // + .expectNextMatches(entity -> entity.getId().equals("id-one") || entity.getId().equals("id-two")) // + .expectNextMatches(entity -> entity.getId().equals("id-one") || entity.getId().equals("id-two")) // .verifyComplete(); } @@ -197,6 +199,34 @@ public void findAllByIdShouldCompleteWhenNothingFound() throws IOException { .verifyComplete(); } + @Test // DATAES-717 + void shouldReturnFluxOfSearchHit() throws IOException { + + bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // + SampleEntity.builder().id("id-two").message("message").build(), // + SampleEntity.builder().id("id-three").message("message").build()); + + repository.queryByMessageWithString("message") // + .as(StepVerifier::create) // + .expectNextMatches(searchHit -> SearchHit.class.isAssignableFrom(searchHit.getClass()))// + .expectNextCount(2) // + .verifyComplete(); + } + + @Test // DATAES-717 + void shouldReturnFluxOfSearchHitForStringQuery() throws IOException { + + bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // + SampleEntity.builder().id("id-two").message("message").build(), // + SampleEntity.builder().id("id-three").message("message").build()); + + repository.queryAllByMessage("message") // + .as(StepVerifier::create) // + .expectNextMatches(searchHit -> SearchHit.class.isAssignableFrom(searchHit.getClass()))// + .expectNextCount(2) // + .verifyComplete(); + } + @Test // DATAES-519 public void countShouldReturnZeroWhenIndexDoesNotExist() { repository.count().as(StepVerifier::create).expectNext(0L).verifyComplete(); @@ -505,6 +535,11 @@ interface ReactiveSampleEntityRepository extends ReactiveCrudRepository findAllByMessage(Publisher message); + Flux> queryAllByMessage(String message); + + @Query("{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}") + Flux> queryByMessageWithString(String message); + @Query("{ \"bool\" : { \"must\" : { \"term\" : { \"message\" : \"?0\" } } } }") Flux findAllViaAnnotatedQueryByMessageLike(String message); From 16e0f566cd4d56b757f43b656d88c4f46030c557 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 4 Jan 2020 17:44:19 +0100 Subject: [PATCH 0032/1191] DATAES-723 - Cleanup ElasticsearchRepository interface. Original PR: #373 --- .../elasticsearch/core/RequestFactory.java | 10 +++- .../ElasticsearchCrudRepository.java | 9 ++-- .../repository/ElasticsearchRepository.java | 42 +++++++++++++++-- ...lasticsearchRepositoryConfigExtension.java | 3 +- .../repository/package-info.java | 5 ++ .../query/ElasticsearchPartQuery.java | 1 + .../AbstractElasticsearchRepository.java | 47 +++++++++++++------ .../repository/support/package-info.java | 5 ++ ...ettingAndMappingEntityRepositoryTests.java | 4 +- ...ldDynamicMappingEntityRepositoryTests.java | 5 +- .../synonym/SynonymRepositoryTests.java | 5 +- .../UUIDElasticsearchRepositoryTests.java | 7 +-- .../SimpleElasticsearchRepositoryTests.java | 13 ++--- 13 files changed, 106 insertions(+), 50 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 02558c058..96bf8a49e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -327,8 +327,13 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) { MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), query.getId()); - MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders - .moreLikeThisQuery(new MoreLikeThisQueryBuilder.Item[] { item }); + String[] fields = null; + if (query.getFields() != null) { + fields = query.getFields().toArray(new String[] {}); + } + + MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery(fields, null, + new MoreLikeThisQueryBuilder.Item[] { item }); if (query.getMinTermFreq() != null) { moreLikeThisQueryBuilder.minTermFreq(query.getMinTermFreq()); @@ -361,6 +366,7 @@ public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query if (query.getBoostTerms() != null) { moreLikeThisQueryBuilder.boostTerms(query.getBoostTerms()); } + return moreLikeThisQueryBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java index 9e29de536..2730a6afb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchCrudRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -25,8 +25,9 @@ * @author Mohsin Husen * @author Oliver Gierke * @author Sascha Woo + * @author Peter-Josef Meisch + * @deprecated since 4.0, use {@link ElasticsearchRepository} instead */ +@Deprecated @NoRepositoryBean -public interface ElasticsearchCrudRepository extends PagingAndSortingRepository { - -} +public interface ElasticsearchCrudRepository extends PagingAndSortingRepository {} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index 9e7ad0bd8..8d63042d3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -18,8 +18,11 @@ import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.PagingAndSortingRepository; +import org.springframework.lang.Nullable; /** * @param @@ -31,9 +34,15 @@ * @author Peter-Josef Meisch */ @NoRepositoryBean -public interface ElasticsearchRepository extends ElasticsearchCrudRepository { +public interface ElasticsearchRepository extends PagingAndSortingRepository { - S index(S entity); + /** + * @deprecated since 4.0, use {@link #save(Object)} instead + */ + @Deprecated + default S index(S entity) { + return save(entity); + } /** * This method is intended to be used when many single inserts must be made that cannot be aggregated to be inserted @@ -42,15 +51,38 @@ public interface ElasticsearchRepository extends ElasticsearchCrudReposit */ S indexWithoutRefresh(S entity); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Iterable search(QueryBuilder query); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Page search(QueryBuilder query, Pageable pageable); + /** + * @deprecated since 4.0, use standard repository method naming or @{@link Query} annotated methods, or + * {@link org.springframework.data.elasticsearch.core.ElasticsearchOperations}. + */ Page search(Query searchQuery); - Page searchSimilar(T entity, String[] fields, Pageable pageable); + /** + * Search for similar entities using a morelikethis query + * + * @param entity the entity for which similar documents should be searched, must not be {@literal null} + * @param fields + * @param pageable , must not be {@literal null} + * @return + */ + Page searchSimilar(T entity, @Nullable String[] fields, Pageable pageable); + /** + * @deprecated since 4.0, use {@link IndexOperations#refresh(Class)} instead. Repository methods should call refresh + * in their implementation. + */ + @Deprecated void refresh(); - - Class getEntityClass(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java index b50543b86..a03d68705 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java @@ -23,7 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean; import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource; @@ -99,7 +98,7 @@ protected Collection> getIdentifyingAnnotations() { */ @Override protected Collection> getIdentifyingTypes() { - return Arrays.asList(ElasticsearchRepository.class, ElasticsearchCrudRepository.class); + return Arrays.asList(ElasticsearchRepository.class, ElasticsearchRepository.class); } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java new file mode 100644 index 000000000..9d9e57ab2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/package-info.java @@ -0,0 +1,5 @@ +/** + * infrastructure to define the Elasticsearch mapping for an index. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.repository; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 546b6e49d..b6be9d570 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -76,6 +76,7 @@ public Object execute(Object[] parameters) { if (tree.isDelete()) { result = countOrGetDocumentsForDelete(query, accessor); elasticsearchOperations.delete(query, clazz, index); + elasticsearchOperations.getIndexOperations().refresh(index); } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 5977febef..87f707fda 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -52,6 +52,7 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.util.Streamable; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -132,11 +133,12 @@ public Iterable findAll() { int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); } + @SuppressWarnings("unchecked") @Override public Page findAll(Pageable pageable) { NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); @@ -145,12 +147,13 @@ public Page findAll(Pageable pageable) { return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Iterable findAll(Sort sort) { int itemCount = (int) this.count(); if (itemCount == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, itemCount, sort)).build(); @@ -185,11 +188,6 @@ public List save(List entities) { return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); } - @Override - public S index(S entity) { - return save(entity); - } - @Override public S indexWithoutRefresh(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); @@ -216,13 +214,14 @@ public boolean existsById(ID id) { return findById(id).isPresent(); } + @SuppressWarnings("unchecked") @Override public Iterable search(QueryBuilder query) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); int count = (int) operations.count(searchQuery, getEntityClass(), getIndexCoordinates()); if (count == 0) { - return new PageImpl<>(Collections. emptyList()); + return new PageImpl<>(Collections.emptyList()); } searchQuery.setPageable(PageRequest.of(0, count)); SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); @@ -230,6 +229,7 @@ public Iterable search(QueryBuilder query) { return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page search(QueryBuilder query, Pageable pageable) { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); @@ -238,6 +238,7 @@ public Page search(QueryBuilder query, Pageable pageable) { return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page search(Query query) { SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); @@ -245,6 +246,7 @@ public Page search(Query query) { return (Page) SearchHitSupport.unwrapSearchHits(page); } + @SuppressWarnings("unchecked") @Override public Page searchSimilar(T entity, String[] fields, Pageable pageable) { Assert.notNull(entity, "Cannot search similar records for 'null'."); @@ -264,24 +266,39 @@ public Page searchSimilar(T entity, String[] fields, Pageable pageable) { @Override public void deleteById(ID id) { + Assert.notNull(id, "Cannot delete entity with id 'null'."); + IndexCoordinates indexCoordinates = getIndexCoordinates(); - operations.delete(stringIdRepresentation(id), indexCoordinates); + doDelete(id, indexCoordinates); indexOperations.refresh(indexCoordinates); } @Override public void delete(T entity) { + Assert.notNull(entity, "Cannot delete 'null' entity."); - deleteById(extractIdFromBean(entity)); - indexOperations.refresh(getIndexCoordinates()); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); + doDelete(extractIdFromBean(entity), indexCoordinates); + indexOperations.refresh(indexCoordinates); } @Override public void deleteAll(Iterable entities) { + Assert.notNull(entities, "Cannot delete 'null' list."); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); for (T entity : entities) { - delete(entity); + doDelete(extractIdFromBean(entity), indexCoordinates); + } + indexOperations.refresh(indexCoordinates); + } + + private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { + if (id != null) { + operations.delete(stringIdRepresentation(id), indexCoordinates); } } @@ -328,8 +345,7 @@ private ParameterizedType resolveReturnedClassFromGenericType(Class clazz) { return resolveReturnedClassFromGenericType(clazz.getSuperclass()); } - @Override - public Class getEntityClass() { + protected Class getEntityClass() { if (!isEntityClassSet()) { try { @@ -350,6 +366,7 @@ public final void setEntityClass(Class entityClass) { this.entityClass = entityClass; } + @Nullable protected ID extractIdFromBean(T entity) { return entityInformation.getId(entity); } @@ -364,7 +381,7 @@ private List stringIdsRepresentation(Iterable ids) { return stringIds; } - protected abstract String stringIdRepresentation(ID id); + protected abstract String stringIdRepresentation(@Nullable ID id); private Long extractVersionFromBean(T entity) { return entityInformation.getVersion(entity); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java new file mode 100644 index 000000000..3c33bb8e0 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java @@ -0,0 +1,5 @@ +/** + * infrastructure to define the Elasticsearch mapping for an index. + */ +@org.springframework.lang.NonNullApi +package org.springframework.data.elasticsearch.repository.support; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index ab972d8a0..649f09c46 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -39,7 +39,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -229,6 +229,6 @@ public void setEmail(String email) { * @author Mohsin Husen */ public interface DynamicSettingAndMappingEntityRepository - extends ElasticsearchCrudRepository {} + extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index aee8fe076..c673f35c3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -32,7 +32,7 @@ import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -57,6 +57,7 @@ static class Config {} @Autowired private ElasticsearchOperations operations; private IndexOperations indexOperations; + @BeforeEach public void before() { indexOperations = operations.getIndexOperations(); @@ -129,6 +130,6 @@ public void setFile(byte[] file) { * @author Ted Liang */ public interface FieldDynamicMappingEntityRepository - extends ElasticsearchCrudRepository {} + extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index cfd9d7cbe..7950b2f2d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -37,7 +37,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; -import org.springframework.data.elasticsearch.repository.ElasticsearchCrudRepository; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -72,6 +72,7 @@ public void before() { void after() { indexOperations.deleteIndex(SynonymEntity.class); } + @Test public void shouldDo() { @@ -112,5 +113,5 @@ static class SynonymEntity { * * @author Artur Konczak */ - interface SynonymRepository extends ElasticsearchCrudRepository {} + interface SynonymRepository extends ElasticsearchRepository {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 1a9673c6f..fc73c16b3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -389,7 +389,6 @@ public void shouldDeleteByMessageAndReturnList() { // when List result = repository.deleteByAvailable(true); - repository.refresh(); // then assertThat(result).hasSize(2); @@ -423,7 +422,6 @@ public void shouldDeleteByListForMessage() { // when List result = repository.deleteByMessage("hello world 3"); - repository.refresh(); // then assertThat(result).hasSize(1); @@ -457,7 +455,6 @@ public void shouldDeleteByType() { // when repository.deleteByType("article"); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -478,7 +475,6 @@ public void shouldDeleteEntity() { // when repository.delete(sampleEntityUUIDKeyed); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId.toString())) @@ -601,8 +597,7 @@ private static List createSampleEntitiesWithMessage(Strin @AllArgsConstructor @Builder @Data - @Document(indexName = "test-index-uuid-keyed", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-uuid-keyed", replicas = 0, refreshInterval = "-1") static class SampleEntityUUIDKeyed { @Id private UUID id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 080fa30c8..de6eb3558 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -148,9 +148,7 @@ public void throwExceptionWhenTryingToInsertWithVersionButWithoutId() { sampleEntity.setVersion(System.currentTimeMillis()); // when - assertThatThrownBy(() -> { - repository.save(sampleEntity); - }).isInstanceOf(ActionRequestValidationException.class); + assertThatThrownBy(() -> repository.save(sampleEntity)).isInstanceOf(ActionRequestValidationException.class); } @Test @@ -385,7 +383,6 @@ public void shouldDeleteById() { // when long result = repository.deleteSampleEntityById(documentId); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -422,7 +419,6 @@ public void shouldDeleteByMessageAndReturnList() { // when List result = repository.deleteByAvailable(true); - repository.refresh(); // then assertThat(result).hasSize(2); @@ -456,7 +452,6 @@ public void shouldDeleteByListForMessage() { // when List result = repository.deleteByMessage("hello world 3"); - repository.refresh(); // then assertThat(result).hasSize(1); @@ -490,7 +485,6 @@ public void shouldDeleteByType() { // when repository.deleteByType("article"); - repository.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -581,7 +575,7 @@ public void shouldIndexEntity() { sampleEntity.setMessage("some message"); // when - repository.index(sampleEntity); + repository.save(sampleEntity); // then Page entities = repository.search(termQuery("id", documentId), PageRequest.of(0, 50)); @@ -707,8 +701,7 @@ private static List createSampleEntitiesWithMessage(String message @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-simple-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-simple-repository", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; From 9fea1365acb35093ca4f858f307ca2d338f3c85b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 4 Jan 2020 22:19:01 +0100 Subject: [PATCH 0033/1191] DATAES-718 - Deprecate @Score and scoreProperty. original PR: #374 --- .../data/elasticsearch/annotations/Score.java | 7 ++++++- .../core/mapping/ElasticsearchPersistentEntity.java | 4 ++++ .../core/mapping/ElasticsearchPersistentProperty.java | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Score.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Score.java index 1696626c6..f5cd57a21 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Score.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Score.java @@ -8,16 +8,21 @@ import java.lang.annotation.Target; import org.springframework.data.annotation.ReadOnlyProperty; +import org.springframework.data.elasticsearch.core.SearchHit; /** * Specifies that this field is used for storing the document score. * * @author Sascha Woo + * @author Peter-Josef Meisch * @since 3.1 + * @deprecated since 4.0, use {@link SearchHit#getScore()} instead */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @Documented @Inherited @ReadOnlyProperty -public @interface Score {} +@Deprecated +public @interface Score { +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 8b08f321b..6d2ab20cd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -63,7 +63,9 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends PersistentEntity Date: Sun, 5 Jan 2020 12:36:14 +0300 Subject: [PATCH 0034/1191] DATAES-461 - Make deleteAll(entities) more performant. Original PR: #375 --- .../support/AbstractElasticsearchRepository.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 87f707fda..26caa8bdb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. @@ -26,6 +26,7 @@ import java.util.stream.Collectors; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.index.query.IdsQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,6 +70,7 @@ * @author Sascha Woo * @author Murali Chevuri * @author Peter-Josef Meisch + * @author Aleksei Arsenev */ public abstract class AbstractElasticsearchRepository implements ElasticsearchRepository { @@ -290,9 +292,19 @@ public void deleteAll(Iterable entities) { Assert.notNull(entities, "Cannot delete 'null' list."); IndexCoordinates indexCoordinates = getIndexCoordinates(); + IdsQueryBuilder idsQueryBuilder = idsQuery(); for (T entity : entities) { - doDelete(extractIdFromBean(entity), indexCoordinates); + ID id = extractIdFromBean(entity); + if (id != null) { + idsQueryBuilder.addIds(stringIdRepresentation(id)); + } + } + if(idsQueryBuilder.ids().isEmpty()) { + return; } + DeleteQuery deleteQuery = new DeleteQuery(); + deleteQuery.setQuery(idsQueryBuilder); + operations.delete(deleteQuery, indexCoordinates); indexOperations.refresh(indexCoordinates); } From d3c624c28a492efec951a59e44e9f840f3cf884e Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 5 Jan 2020 10:40:59 +0100 Subject: [PATCH 0035/1191] DATAES-461 - Polishing. --- .../repository/support/AbstractElasticsearchRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 26caa8bdb..9df312dbf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -299,11 +299,13 @@ public void deleteAll(Iterable entities) { idsQueryBuilder.addIds(stringIdRepresentation(id)); } } - if(idsQueryBuilder.ids().isEmpty()) { + + if (idsQueryBuilder.ids().isEmpty()) { return; } DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(idsQueryBuilder); + operations.delete(deleteQuery, indexCoordinates); indexOperations.refresh(indexCoordinates); } From 0693923798e3a0e884b104c0d866c5ae1db0b588 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 6 Jan 2020 22:25:54 +0100 Subject: [PATCH 0036/1191] DATAES-372 - Support highlighting via annotation. Original PR: #377 --- .../elasticsearch/annotations/Highlight.java | 36 ++++ .../annotations/HighlightField.java | 37 ++++ .../annotations/HighlightParameters.java | 78 ++++++++ .../elasticsearch/core/RequestFactory.java | 26 +-- .../data/elasticsearch/core/SearchHit.java | 6 + .../MappingElasticsearchConverter.java | 21 +- .../ElasticsearchPersistentEntity.java | 12 ++ .../SimpleElasticsearchPersistentEntity.java | 26 ++- .../core/query/AbstractQuery.java | 13 ++ .../core/query/HighlightQuery.java | 37 ++++ .../core/query/HighlightQueryBuilder.java | 180 ++++++++++++++++++ .../data/elasticsearch/core/query/Query.java | 17 ++ ...tReactiveElasticsearchRepositoryQuery.java | 4 + .../query/ElasticsearchPartQuery.java | 8 +- .../query/ElasticsearchQueryMethod.java | 35 +++- .../query/ElasticsearchStringQuery.java | 10 +- .../ReactivePartTreeElasticsearchQuery.java | 1 + ...pleElasticsearchPersistentEntityTests.java | 24 ++- .../query/HighlightQueryBuilderTests.java | 141 ++++++++++++++ .../CustomMethodRepositoryBaseTests.java | 35 +++- ...eReactiveElasticsearchRepositoryTests.java | 43 ++++- .../highlights-with-parameters.json | 34 ++++ src/test/resources/highlights/highlights.json | 5 + 23 files changed, 806 insertions(+), 23 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java create mode 100644 src/test/resources/highlights/highlights-with-parameters.json create mode 100644 src/test/resources/highlights/highlights.json diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java new file mode 100644 index 000000000..3ac6f60ab --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Highlight { + + HighlightParameters parameters() default @HighlightParameters; + + HighlightField[] fields(); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java new file mode 100644 index 000000000..d65d59d93 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface HighlightField { + + /** + * The name of the field to apply highlighting to. This must be the field name of the entity's property, not the name + * of the field in the index mappings. + */ + String name() default ""; + + HighlightParameters parameters() default @HighlightParameters; +} diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java new file mode 100644 index 000000000..74aad474b --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java @@ -0,0 +1,78 @@ +/* + * Copyright 2020 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface HighlightParameters { + String boundaryChars() default ""; + + int boundaryMaxScan() default -1; + + String boundaryScanner() default ""; + + String boundaryScannerLocale() default ""; + + /** + * only used for {@link Highlight}s. + */ + String encoder() default ""; + + boolean forceSource() default false; + + String fragmenter() default ""; + + /** + * only used for {@link HighlightField}s. + */ + int fragmentOffset() default -1; + + int fragmentSize() default -1; + + /** + * only used for {@link HighlightField}s. + */ + String[] matchedFields() default {}; + + int noMatchSize() default -1; + + int numberOfFragments() default -1; + + String order() default ""; + + int phraseLimit() default -1; + + String[] preTags() default {}; + + String[] postTags() default {}; + + boolean requireFieldMatch() default true; + + /** + * only used for {@link Highlight}s. + */ + String tagsSchema() default ""; + + String type() default ""; +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 96bf8a49e..172964089 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -241,20 +241,24 @@ public GetRequestBuilder getRequestBuilder(Client client, GetQuery query, IndexC } public HighlightBuilder highlightBuilder(Query query) { - HighlightBuilder highlightBuilder = null; - if (query instanceof NativeSearchQuery) { - NativeSearchQuery searchQuery = (NativeSearchQuery) query; + HighlightBuilder highlightBuilder = query.getHighlightQuery().map(HighlightQuery::getHighlightBuilder).orElse(null); - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - highlightBuilder = searchQuery.getHighlightBuilder(); + if (highlightBuilder == null) { - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; + + if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { + highlightBuilder = searchQuery.getHighlightBuilder(); + + if (highlightBuilder == null) { + highlightBuilder = new HighlightBuilder(); + } - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); + if (searchQuery.getHighlightFields() != null) { + for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { + highlightBuilder.field(highlightField); + } } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index 7b947030f..c681a8f79 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -21,6 +21,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -78,6 +79,11 @@ public List getSortValues() { return Collections.unmodifiableList(sortValues); } + public Map> getHighlightFields() { + return Collections.unmodifiableMap(highlightFields.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, entry -> Collections.unmodifiableList(entry.getValue())))); + } + /** * gets the highlight values for a field. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 2b204e9a7..9561d95db 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -184,12 +184,31 @@ public SearchHit read(Class type, SearchDocument searchDocument) { String id = searchDocument.hasId() ? searchDocument.getId() : null; float score = searchDocument.getScore(); Object[] sortValues = searchDocument.getSortValues(); - Map> highlightFields = searchDocument.getHighlightFields(); + Map> highlightFields = getHighlightsAndRemapFieldNames(type, searchDocument); T content = mapDocument(searchDocument, type); return new SearchHit(id, score, sortValues, highlightFields, content); } + @Nullable + private Map> getHighlightsAndRemapFieldNames(Class type, SearchDocument searchDocument) { + Map> highlightFields = searchDocument.getHighlightFields(); + + if (highlightFields == null) { + return null; + } + + ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(type); + if (persistentEntity == null) { + return highlightFields; + } + + return highlightFields.entrySet().stream().collect(Collectors.toMap(entry -> { + ElasticsearchPersistentProperty property = persistentEntity.getPersistentPropertyWithFieldName(entry.getKey()); + return property != null ? property.getName() : entry.getKey(); + }, Entry::getValue)); + } + @Override @Nullable public T mapDocument(@Nullable Document document, Class type) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 6d2ab20cd..8604854d7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.mapping; import org.elasticsearch.index.VersionType; +import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.mapping.PersistentEntity; import org.springframework.lang.Nullable; @@ -80,4 +81,15 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends BasicPersistentEntity implements ElasticsearchPersistentEntity, ApplicationContextAware { @@ -68,6 +73,7 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private @Nullable String settingPath; private VersionType versionType; private boolean createIndexAndMapping; + private final Map fieldNamePropertyCache = new ConcurrentHashMap<>(); public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { @@ -233,4 +239,22 @@ public void setPersistentPropertyAccessorFactory(PersistentPropertyAccessorFacto // DATACMNS-1322 switches to proper immutability behavior which Spring Data Elasticsearch // cannot yet implement } + + @Nullable + @Override + public ElasticsearchPersistentProperty getPersistentPropertyWithFieldName(String fieldName) { + + Assert.notNull(fieldName, "fieldName must not be null"); + + return fieldNamePropertyCache.computeIfAbsent(fieldName, key -> { + AtomicReference propertyRef = new AtomicReference<>(); + doWithProperties((PropertyHandler) property -> { + if (key.equals(property.getFieldName())) { + propertyRef.set(property); + } + }); + + return propertyRef.get(); + }); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 1c2a106d7..8aeba913a 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Optional; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.support.IndicesOptions; @@ -52,6 +53,7 @@ abstract class AbstractQuery implements Query { protected boolean trackScores; protected String preference; protected Integer maxResults; + protected HighlightQuery highlightQuery; @Override public Sort getSort() { @@ -195,4 +197,15 @@ public Integer getMaxResults() { public void setMaxResults(Integer maxResults) { this.maxResults = maxResults; } + + @Override + public void setHighlightQuery(HighlightQuery highlightQuery) { + this.highlightQuery = highlightQuery; + } + + @Override + public Optional getHighlightQuery() { + return Optional.ofNullable(highlightQuery); + } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java new file mode 100644 index 000000000..90396b988 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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.query; + +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; + +/** + * Encapsulates an Elasticsearch {@link org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder} to prevent + * leaking of Elasticsearch classes into the query API. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class HighlightQuery { + private final HighlightBuilder highlightBuilder; + + public HighlightQuery(HighlightBuilder highlightBuilder) { + this.highlightBuilder = highlightBuilder; + } + + public HighlightBuilder getHighlightBuilder() { + return highlightBuilder; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java new file mode 100644 index 000000000..4f68e6e95 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java @@ -0,0 +1,180 @@ +/* + * Copyright 2020 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.query; + +import java.util.Arrays; +import java.util.stream.Collectors; + +import org.elasticsearch.search.fetch.subphase.highlight.AbstractHighlighterBuilder; +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.springframework.data.elasticsearch.annotations.Highlight; +import org.springframework.data.elasticsearch.annotations.HighlightField; +import org.springframework.data.elasticsearch.annotations.HighlightParameters; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.mapping.context.MappingContext; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.StringUtils; + +/** + * Converts the {@link Highlight} annotation from a method to an Elasticsearch {@link HighlightBuilder}. + * + * @author Peter-Josef Meisch + */ +public class HighlightQueryBuilder { + + private final MappingContext, ElasticsearchPersistentProperty> mappingContext; + + public HighlightQueryBuilder( + MappingContext, ElasticsearchPersistentProperty> mappingContext) { + this.mappingContext = mappingContext; + } + + /** + * creates a HighlightBuilder from an annotation + * + * @param highlight, must not be {@literal null} + * @param type the entity type, used to map field names. If null, field names are not mapped. + * @return the builder for the highlight + */ + public HighlightQuery getHighlightQuery(Highlight highlight, @Nullable Class type) { + + Assert.notNull(highlight, "highlight must not be null"); + + HighlightBuilder highlightBuilder = new HighlightBuilder(); + + addParameters(highlight.parameters(), highlightBuilder, type); + + for (HighlightField highlightField : highlight.fields()) { + String mappedName = mapFieldName(highlightField.name(), type); + HighlightBuilder.Field field = new HighlightBuilder.Field(mappedName); + + addParameters(highlightField.parameters(), field, type); + + highlightBuilder.field(field); + } + + return new HighlightQuery(highlightBuilder); + } + + private void addParameters(HighlightParameters parameters, AbstractHighlighterBuilder builder, Class type) { + + if (StringUtils.hasLength(parameters.boundaryChars())) { + builder.boundaryChars(parameters.boundaryChars().toCharArray()); + } + + if (parameters.boundaryMaxScan() > -1) { + builder.boundaryMaxScan(parameters.boundaryMaxScan()); + } + + if (StringUtils.hasLength(parameters.boundaryScanner())) { + builder.boundaryScannerType(parameters.boundaryScanner()); + } + + if (StringUtils.hasLength(parameters.boundaryScannerLocale())) { + builder.boundaryScannerLocale(parameters.boundaryScannerLocale()); + } + + if (parameters.forceSource()) { // default is false + builder.forceSource(parameters.forceSource()); + } + + if (StringUtils.hasLength(parameters.fragmenter())) { + builder.fragmenter(parameters.fragmenter()); + } + + if (parameters.fragmentSize() > -1) { + builder.fragmentSize(parameters.fragmentSize()); + } + + if (parameters.noMatchSize() > -1) { + builder.noMatchSize(parameters.noMatchSize()); + } + + if (parameters.numberOfFragments() > -1) { + builder.numOfFragments(parameters.numberOfFragments()); + } + + if (StringUtils.hasLength(parameters.order())) { + builder.order(parameters.order()); + } + + if (parameters.phraseLimit() > -1) { + builder.phraseLimit(parameters.phraseLimit()); + } + + if (parameters.preTags().length > 0) { + builder.preTags(parameters.preTags()); + } + + if (parameters.postTags().length > 0) { + builder.postTags(parameters.postTags()); + } + + if (!parameters.requireFieldMatch()) { // default is true + builder.requireFieldMatch(parameters.requireFieldMatch()); + } + + if (StringUtils.hasLength(parameters.type())) { + builder.highlighterType(parameters.type()); + } + + if (builder instanceof HighlightBuilder) { + HighlightBuilder highlightBuilder = (HighlightBuilder) builder; + + if (StringUtils.hasLength(parameters.encoder())) { + highlightBuilder.encoder(parameters.encoder()); + } + + if (StringUtils.hasLength(parameters.tagsSchema())) { + highlightBuilder.tagsSchema(parameters.tagsSchema()); + } + } + + if (builder instanceof HighlightBuilder.Field) { + HighlightBuilder.Field field = (HighlightBuilder.Field) builder; + + if (parameters.fragmentOffset() > -1) { + field.fragmentOffset(parameters.fragmentOffset()); + } + + if (parameters.matchedFields().length > 0) { + field.matchedFields(Arrays.stream(parameters.matchedFields()) // + .map(fieldName -> mapFieldName(fieldName, type)) // + .collect(Collectors.toList()) // + .toArray(new String[] {})); // + } + } + } + + private String mapFieldName(String fieldName, @Nullable Class type) { + + if (type != null) { + ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(type); + + if (persistentEntity != null) { + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getPersistentProperty(fieldName); + + if (persistentProperty != null) { + return persistentProperty.getFieldName(); + } + } + } + + return fieldName; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 581b6734e..0dde4e6a1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -17,6 +17,7 @@ import java.util.Collection; import java.util.List; +import java.util.Optional; import org.elasticsearch.action.search.SearchType; import org.elasticsearch.action.support.IndicesOptions; @@ -24,6 +25,7 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.lang.Nullable; /** * Query @@ -185,4 +187,19 @@ default Integer getMaxResults() { return null; } + /** + * Sets the {@link HighlightQuery}.* + * + * @param highlightQuery the query to set + * @since 4.0 + */ + void setHighlightQuery(@Nullable HighlightQuery highlightQuery); + + /** + * @return the optional set {@link HighlightQuery}. + * @since 4.0 + */ + default Optional getHighlightQuery() { + return Optional.empty(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index eb4808bd7..6565c7944 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -84,6 +84,10 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) { Query query = createQuery( new ConvertingParameterAccessor(elasticsearchOperations.getElasticsearchConverter(), parameterAccessor)); + if (queryMethod.hasAnnotatedHighlight()) { + query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery()); + } + Class targetType = processor.getReturnedType().getTypeToRead(); String indexName = queryMethod.getEntityInformation().getIndexName(); String indexTypeName = queryMethod.getEntityInformation().getIndexTypeName(); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index b6be9d570..51c36f5c0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -58,13 +58,19 @@ public ElasticsearchPartQuery(ElasticsearchQueryMethod method, ElasticsearchOper @Override public Object execute(Object[] parameters) { + Class clazz = queryMethod.getEntityInformation().getJavaType(); ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); + CriteriaQuery query = createQuery(accessor); + Assert.notNull(query, "unsupported query"); - Class clazz = queryMethod.getEntityInformation().getJavaType(); elasticsearchConverter.updateQuery(query, clazz); + if (queryMethod.hasAnnotatedHighlight()) { + query.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery()); + } + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); Object result = null; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java index 2705e7b69..3b1d28876 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java @@ -21,15 +21,19 @@ import java.util.stream.Stream; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.data.elasticsearch.annotations.Highlight; import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.query.HighlightQuery; +import org.springframework.data.elasticsearch.core.query.HighlightQueryBuilder; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.query.QueryMethod; +import org.springframework.data.util.Lazy; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -46,10 +50,12 @@ */ public class ElasticsearchQueryMethod extends QueryMethod { - private final Method method; // private in base class, but needed here as well - private final Query queryAnnotation; private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private @Nullable ElasticsearchEntityMetadata metadata; + private final Method method; // private in base class, but needed here as well + private final Query queryAnnotation; + private final Highlight highlightAnnotation; + private final Lazy highlightQueryLazy = Lazy.of(this::createAnnotatedHighlightQuery); public ElasticsearchQueryMethod(Method method, RepositoryMetadata repositoryMetadata, ProjectionFactory factory, MappingContext, ElasticsearchPersistentProperty> mappingContext) { @@ -61,6 +67,7 @@ public ElasticsearchQueryMethod(Method method, RepositoryMetadata repositoryMeta this.method = method; this.mappingContext = mappingContext; this.queryAnnotation = method.getAnnotation(Query.class); + this.highlightAnnotation = method.getAnnotation(Highlight.class); } public boolean hasAnnotatedQuery() { @@ -71,6 +78,30 @@ public String getAnnotatedQuery() { return (String) AnnotationUtils.getValue(queryAnnotation, "value"); } + /** + * @return true if there is a {@link Highlight} annotation present. + * @since 4.0 + */ + public boolean hasAnnotatedHighlight() { + return highlightAnnotation != null; + } + + /** + * @return a {@link HighlightQuery} built from the {@link Highlight} annotation. + * @throws IllegalArgumentException if no {@link Highlight} annotation is present on the method + * @see #hasAnnotatedHighlight() + */ + public HighlightQuery getAnnotatedHighlightQuery() { + + Assert.isTrue(hasAnnotatedHighlight(), "no Highlight annotation present on " + getName()); + + return highlightQueryLazy.get(); + } + + private HighlightQuery createAnnotatedHighlightQuery() { + return new HighlightQueryBuilder(mappingContext).getHighlightQuery(highlightAnnotation, getDomainClass()); + } + /** * @return the {@link ElasticsearchEntityMetadata} for the query methods {@link #getReturnedObjectType() return type}. * @since 3.2 diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 567a4696f..82dfe9425 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -69,9 +69,17 @@ public ElasticsearchStringQuery(ElasticsearchQueryMethod queryMethod, Elasticsea @Override public Object execute(Object[] parameters) { + Class clazz = queryMethod.getEntityInformation().getJavaType(); ParametersParameterAccessor accessor = new ParametersParameterAccessor(queryMethod.getParameters(), parameters); + StringQuery stringQuery = createQuery(accessor); - Class clazz = queryMethod.getEntityInformation().getJavaType(); + + Assert.notNull(stringQuery, "unsupported query"); + + if (queryMethod.hasAnnotatedHighlight()) { + stringQuery.setHighlightQuery(queryMethod.getAnnotatedHighlightQuery()); + } + IndexCoordinates index = elasticsearchOperations.getIndexCoordinatesFor(clazz); Object result = null; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java index ee90dfef0..e723e275c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java @@ -46,6 +46,7 @@ protected Query createQuery(ElasticsearchParameterAccessor accessor) { if (tree.isLimiting()) { query.setMaxResults(tree.getMaxResults()); } + return query; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index 735d9428d..1180009fd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -17,10 +17,10 @@ import static org.assertj.core.api.Assertions.*; -import java.beans.IntrospectionException; - import org.junit.jupiter.api.Test; +import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; +import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.Property; @@ -79,6 +79,21 @@ public void rejectsMultipleScoreProperties() { .withMessageContaining("second"); } + @Test + void shouldFindPropertiesByMappedName() { + + SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); + SimpleElasticsearchPersistentEntity persistentEntity = context + .getRequiredPersistentEntity(FieldNameEntity.class); + + ElasticsearchPersistentProperty persistentProperty = persistentEntity + .getPersistentPropertyWithFieldName("renamed-field"); + + assertThat(persistentProperty).isNotNull(); + assertThat(persistentProperty.getName()).isEqualTo("renamedField"); + assertThat(persistentProperty.getFieldName()).isEqualTo("renamed-field"); + } + private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasticsearchPersistentEntity entity, String field) { @@ -130,4 +145,9 @@ static class TwoScoreProperties { @Score float first; @Score float second; } + + private static class FieldNameEntity { + @Id private String id; + @Field(name = "renamed-field") private String renamedField; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java new file mode 100644 index 000000000..7b1d09f17 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java @@ -0,0 +1,141 @@ +/* + * Copyright 2020 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.query; + +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.Highlight; +import org.springframework.data.elasticsearch.annotations.HighlightField; +import org.springframework.data.elasticsearch.annotations.HighlightParameters; +import org.springframework.data.elasticsearch.core.ResourceUtil; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.util.Assert; + +/** + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +class HighlightQueryBuilderTests { + + private final SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); + + private HighlightQueryBuilder highlightQueryBuilder = new HighlightQueryBuilder(context); + + @Test + void shouldProcessAnnotationWithNoParameters() throws NoSuchMethodException, JSONException { + Highlight highlight = getAnnotation("annotatedMethod"); + String expected = ResourceUtil.readFileFromClasspath("/highlights/highlights.json"); + + HighlightBuilder highlightBuilder = highlightQueryBuilder.getHighlightQuery(highlight, HighlightEntity.class) + .getHighlightBuilder(); + String actualStr = highlightBuilder.toString(); + assertEquals(expected, actualStr, false); + + } + + @Test + void shouldProcessAnnotationWithParameters() throws NoSuchMethodException, JSONException { + Highlight highlight = getAnnotation("annotatedMethodWithManyValue"); + String expected = ResourceUtil.readFileFromClasspath("/highlights/highlights-with-parameters.json"); + + HighlightBuilder highlightBuilder = highlightQueryBuilder.getHighlightQuery(highlight, HighlightEntity.class) + .getHighlightBuilder(); + String actualStr = highlightBuilder.toString(); + + assertEquals(expected, actualStr, true); + } + + private Highlight getAnnotation(String methodName) throws NoSuchMethodException { + Highlight highlight = HighlightQueryBuilderTests.class.getDeclaredMethod(methodName).getAnnotation(Highlight.class); + + Assert.notNull(highlight, "no highlight annotation found"); + + return highlight; + } + + /** + * The annotation values on this method are just random values. The field has just one common parameters and the field + * specific, the whole bunch pf parameters is tested on the top level. tagsSchema cannot be tested together with + * preTags and postTags, ist it sets it's own values for these. + */ + // region test data + @Highlight(fields = { @HighlightField(name = "someField") }) + private void annotatedMethod() {} + + @Highlight( // + parameters = @HighlightParameters( // + boundaryChars = "#+*", // + boundaryMaxScan = 7, // + boundaryScanner = "chars", // + boundaryScannerLocale = "de-DE", // + encoder = "html", // + forceSource = true, // + fragmenter = "span", // + noMatchSize = 2, // + numberOfFragments = 3, // + fragmentSize = 5, // + order = "score", // + phraseLimit = 42, // + preTags = { "", "" }, // + postTags = { "", "" }, // + requireFieldMatch = false, // + type = "plain" // + ), // + fields = { // + @HighlightField( // + name = "someField", // + parameters = @HighlightParameters( // + fragmentOffset = 3, // + matchedFields = { "someField", "otherField" }, // + numberOfFragments = 4) // + // + ) // + } // + ) // + private void annotatedMethodWithManyValue() {} + + @Document(indexName = "dont-care") + private static class HighlightEntity { + @Id private String id; + @Field(name = "some-field") private String someField; + @Field(name = "other-field") private String otherField; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSomeField() { + return someField; + } + + public void setSomeField(String someField) { + this.someField = someField; + } + } + // endregion +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 943127887..50ea5f11a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -46,6 +46,8 @@ import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.Highlight; +import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; @@ -1416,6 +1418,32 @@ void shouldReturnSearchHitsForStringQuery() { assertThat(searchHits.getTotalHits()).isEqualTo(20); } + @Test // DATAES-372 + void shouldReturnHighlightsOnAnnotatedMethod() { + List entities = createSampleEntities("abc", 2); + repository.saveAll(entities); + + // when + SearchHits searchHits = repository.queryByType("abc"); + + assertThat(searchHits.getTotalHits()).isEqualTo(2); + SearchHit searchHit = searchHits.getSearchHit(0); + assertThat(searchHit.getHighlightField("type")).hasSize(1).contains("abc"); + } + + @Test // DATAES-372 + void shouldReturnHighlightsOnAnnotatedStringQueryMethod() { + List entities = createSampleEntities("abc", 2); + repository.saveAll(entities); + + // when + SearchHits searchHits = repository.queryByString("abc"); + + assertThat(searchHits.getTotalHits()).isEqualTo(2); + SearchHit searchHit = searchHits.getSearchHit(0); + assertThat(searchHit.getHighlightField("type")).hasSize(1).contains("abc"); + } + private List createSampleEntities(String type, int numberOfEntities) { List entities = new ArrayList<>(); @@ -1552,14 +1580,17 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository queryByType(String type); @Query("{\"bool\": {\"must\": [{\"term\": {\"type\": \"?0\"}}]}}") + @Highlight(fields = { @HighlightField(name = "type") }) SearchHits queryByString(String type); - List> queryByMessage(String type); + List> queryByMessage(String message); + + Stream> readByMessage(String message); - Stream> readByMessage(String type); } /** diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index c1c933eed..9534fc00d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -33,6 +33,7 @@ import java.lang.Object; import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.stream.IntStream; @@ -58,6 +59,8 @@ import org.springframework.data.elasticsearch.TestUtils; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.Highlight; +import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; @@ -206,7 +209,7 @@ void shouldReturnFluxOfSearchHit() throws IOException { SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-three").message("message").build()); - repository.queryByMessageWithString("message") // + repository.queryAllByMessage("message") // .as(StepVerifier::create) // .expectNextMatches(searchHit -> SearchHit.class.isAssignableFrom(searchHit.getClass()))// .expectNextCount(2) // @@ -220,13 +223,47 @@ void shouldReturnFluxOfSearchHitForStringQuery() throws IOException { SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-three").message("message").build()); - repository.queryAllByMessage("message") // + repository.queryByMessageWithString("message") // .as(StepVerifier::create) // .expectNextMatches(searchHit -> SearchHit.class.isAssignableFrom(searchHit.getClass()))// .expectNextCount(2) // .verifyComplete(); } + @Test // DATAES-372 + void shouldReturnHighlightsOnAnnotatedMethod() throws IOException { + + bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // + SampleEntity.builder().id("id-two").message("message").build(), // + SampleEntity.builder().id("id-three").message("message").build()); + + repository.queryAllByMessage("message") // + .as(StepVerifier::create) // + .expectNextMatches(searchHit -> { + List hitHighlightField = searchHit.getHighlightField("message"); + return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("message"); + }) // + .expectNextCount(2) // + .verifyComplete(); + } + + @Test // DATAES-372 + void shouldReturnHighlightsOnAnnotatedStringQueryMethod() throws IOException { + + bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // + SampleEntity.builder().id("id-two").message("message").build(), // + SampleEntity.builder().id("id-three").message("message").build()); + + repository.queryByMessageWithString("message") // + .as(StepVerifier::create) // + .expectNextMatches(searchHit -> { + List hitHighlightField = searchHit.getHighlightField("message"); + return hitHighlightField.size() == 1 && hitHighlightField.get(0).equals("message"); + }) // + .expectNextCount(2) // + .verifyComplete(); + } + @Test // DATAES-519 public void countShouldReturnZeroWhenIndexDoesNotExist() { repository.count().as(StepVerifier::create).expectNext(0L).verifyComplete(); @@ -535,9 +572,11 @@ interface ReactiveSampleEntityRepository extends ReactiveCrudRepository findAllByMessage(Publisher message); + @Highlight(fields = { @HighlightField(name = "message") }) Flux> queryAllByMessage(String message); @Query("{\"bool\": {\"must\": [{\"term\": {\"message\": \"?0\"}}]}}") + @Highlight(fields = { @HighlightField(name = "message") }) Flux> queryByMessageWithString(String message); @Query("{ \"bool\" : { \"must\" : { \"term\" : { \"message\" : \"?0\" } } } }") diff --git a/src/test/resources/highlights/highlights-with-parameters.json b/src/test/resources/highlights/highlights-with-parameters.json new file mode 100644 index 000000000..566d2996f --- /dev/null +++ b/src/test/resources/highlights/highlights-with-parameters.json @@ -0,0 +1,34 @@ +{ + "boundary_chars": "#+*", + "boundary_max_scan": 7, + "boundary_scanner": "CHARS", + "boundary_scanner_locale": "de-DE", + "encoder": "html", + "force_source": true, + "fragmenter": "span", + "fragment_size": 5, + "no_match_size": 2, + "number_of_fragments": 3, + "order": "score", + "phrase_limit": 42, + "pre_tags": [ + "", + "" + ], + "post_tags": [ + "", + "" + ], + "require_field_match": false, + "type": "plain", + "fields": { + "some-field": { + "fragment_offset": 3, + "number_of_fragments": 4, + "matched_fields": [ + "some-field", + "other-field" + ] + } + } +} diff --git a/src/test/resources/highlights/highlights.json b/src/test/resources/highlights/highlights.json new file mode 100644 index 000000000..0a2c7eeca --- /dev/null +++ b/src/test/resources/highlights/highlights.json @@ -0,0 +1,5 @@ +{ + "fields": { + "some-field": {} + } +} From 8472c296f640f133280f9d1d8dc259b018595ed8 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 7 Jan 2020 09:08:10 +0100 Subject: [PATCH 0037/1191] DATAES-725 - Update copyright years to 2020. --- .../data/elasticsearch/ElasticsearchException.java | 2 +- .../data/elasticsearch/NoSuchIndexException.java | 2 +- .../data/elasticsearch/annotations/CompletionField.java | 2 +- .../data/elasticsearch/annotations/DateFormat.java | 2 +- .../data/elasticsearch/annotations/Document.java | 2 +- .../data/elasticsearch/annotations/DynamicMapping.java | 2 +- .../data/elasticsearch/annotations/DynamicMappingValue.java | 2 +- .../springframework/data/elasticsearch/annotations/Field.java | 2 +- .../data/elasticsearch/annotations/FieldType.java | 2 +- .../data/elasticsearch/annotations/GeoPointField.java | 2 +- .../data/elasticsearch/annotations/Highlight.java | 2 +- .../data/elasticsearch/annotations/HighlightField.java | 2 +- .../data/elasticsearch/annotations/HighlightParameters.java | 2 +- .../data/elasticsearch/annotations/IndexOptions.java | 2 +- .../data/elasticsearch/annotations/IndexPrefixes.java | 2 +- .../data/elasticsearch/annotations/InnerField.java | 2 +- .../springframework/data/elasticsearch/annotations/Mapping.java | 2 +- .../data/elasticsearch/annotations/MultiField.java | 2 +- .../springframework/data/elasticsearch/annotations/Parent.java | 2 +- .../springframework/data/elasticsearch/annotations/Query.java | 2 +- .../springframework/data/elasticsearch/annotations/Setting.java | 2 +- .../data/elasticsearch/annotations/Similarity.java | 2 +- .../data/elasticsearch/annotations/TermVector.java | 2 +- .../data/elasticsearch/client/ClientConfiguration.java | 2 +- .../data/elasticsearch/client/ClientConfigurationBuilder.java | 2 +- .../springframework/data/elasticsearch/client/ClientLogger.java | 2 +- .../springframework/data/elasticsearch/client/ClusterNodes.java | 2 +- .../data/elasticsearch/client/DefaultClientConfiguration.java | 2 +- .../data/elasticsearch/client/ElasticsearchHost.java | 2 +- .../data/elasticsearch/client/InetSocketAddressParser.java | 2 +- .../data/elasticsearch/client/NoReachableHostException.java | 2 +- .../data/elasticsearch/client/NodeClientFactoryBean.java | 2 +- .../data/elasticsearch/client/RestClientFactoryBean.java | 2 +- .../springframework/data/elasticsearch/client/RestClients.java | 2 +- .../data/elasticsearch/client/TransportClientFactoryBean.java | 2 +- .../client/reactive/DefaultReactiveElasticsearchClient.java | 2 +- .../elasticsearch/client/reactive/DefaultWebClientProvider.java | 2 +- .../data/elasticsearch/client/reactive/HostProvider.java | 2 +- .../elasticsearch/client/reactive/MultiNodeHostProvider.java | 2 +- .../data/elasticsearch/client/reactive/RawActionResponse.java | 2 +- .../client/reactive/ReactiveElasticsearchClient.java | 2 +- .../data/elasticsearch/client/reactive/ReactiveRestClients.java | 2 +- .../client/reactive/RequestBodyEncodingException.java | 2 +- .../elasticsearch/client/reactive/SingleNodeHostProvider.java | 2 +- .../data/elasticsearch/client/reactive/WebClientProvider.java | 2 +- .../data/elasticsearch/client/util/RequestConverters.java | 2 +- .../config/AbstractElasticsearchConfiguration.java | 2 +- .../config/AbstractReactiveElasticsearchConfiguration.java | 2 +- .../elasticsearch/config/ElasticsearchConfigurationSupport.java | 2 +- .../elasticsearch/config/ElasticsearchNamespaceHandler.java | 2 +- .../elasticsearch/config/NodeClientBeanDefinitionParser.java | 2 +- .../elasticsearch/config/RestClientBeanDefinitionParser.java | 2 +- .../config/TransportClientBeanDefinitionParser.java | 2 +- .../data/elasticsearch/core/AbstractDefaultIndexOperations.java | 2 +- .../data/elasticsearch/core/CriteriaFilterProcessor.java | 2 +- .../data/elasticsearch/core/CriteriaQueryProcessor.java | 2 +- .../data/elasticsearch/core/DefaultIndexOperations.java | 2 +- .../elasticsearch/core/DefaultTransportIndexOperations.java | 2 +- .../data/elasticsearch/core/DocumentOperations.java | 2 +- .../elasticsearch/core/ElasticsearchExceptionTranslator.java | 2 +- .../data/elasticsearch/core/ElasticsearchOperations.java | 2 +- .../data/elasticsearch/core/ElasticsearchRestTemplate.java | 2 +- .../data/elasticsearch/core/ElasticsearchTemplate.java | 2 +- .../data/elasticsearch/core/EntityOperations.java | 2 +- .../data/elasticsearch/core/IndexOperations.java | 2 +- .../data/elasticsearch/core/ReactiveDocumentOperations.java | 2 +- .../elasticsearch/core/ReactiveElasticsearchOperations.java | 2 +- .../data/elasticsearch/core/ReactiveSearchOperations.java | 2 +- .../springframework/data/elasticsearch/core/RequestFactory.java | 2 +- .../springframework/data/elasticsearch/core/ResourceUtil.java | 2 +- .../org/springframework/data/elasticsearch/core/ScoredPage.java | 2 +- .../org/springframework/data/elasticsearch/core/SearchHit.java | 2 +- .../data/elasticsearch/core/SearchHitSupport.java | 2 +- .../org/springframework/data/elasticsearch/core/SearchHits.java | 2 +- .../data/elasticsearch/core/SearchOperations.java | 2 +- .../springframework/data/elasticsearch/core/StreamQueries.java | 2 +- .../elasticsearch/core/aggregation/impl/AggregatedPageImpl.java | 2 +- .../data/elasticsearch/core/client/support/AliasData.java | 2 +- .../data/elasticsearch/core/convert/ConversionException.java | 2 +- .../data/elasticsearch/core/convert/DateTimeConverters.java | 2 +- .../core/convert/DefaultElasticsearchTypeMapper.java | 2 +- .../data/elasticsearch/core/convert/ElasticsearchConverter.java | 2 +- .../core/convert/ElasticsearchCustomConversions.java | 2 +- .../elasticsearch/core/convert/ElasticsearchDateConverter.java | 2 +- .../elasticsearch/core/convert/ElasticsearchTypeMapper.java | 2 +- .../data/elasticsearch/core/convert/GeoConverters.java | 2 +- .../core/convert/MappingElasticsearchConverter.java | 2 +- .../data/elasticsearch/core/document/Document.java | 2 +- .../data/elasticsearch/core/document/DocumentAdapters.java | 2 +- .../data/elasticsearch/core/document/MapDocument.java | 2 +- .../data/elasticsearch/core/document/SearchDocument.java | 2 +- .../elasticsearch/core/document/SearchDocumentResponse.java | 2 +- .../org/springframework/data/elasticsearch/core/geo/GeoBox.java | 2 +- .../springframework/data/elasticsearch/core/geo/GeoPoint.java | 2 +- .../data/elasticsearch/core/index/MappingBuilder.java | 2 +- .../data/elasticsearch/core/index/MappingParameters.java | 2 +- .../core/mapping/ElasticsearchPersistentEntity.java | 2 +- .../core/mapping/ElasticsearchPersistentProperty.java | 2 +- .../core/mapping/ElasticsearchPersistentPropertyConverter.java | 2 +- .../elasticsearch/core/mapping/ElasticsearchSimpleTypes.java | 2 +- .../data/elasticsearch/core/mapping/IndexCoordinates.java | 2 +- .../core/mapping/SimpleElasticsearchMappingContext.java | 2 +- .../core/mapping/SimpleElasticsearchPersistentProperty.java | 2 +- .../data/elasticsearch/core/query/AbstractQuery.java | 2 +- .../data/elasticsearch/core/query/AliasBuilder.java | 2 +- .../data/elasticsearch/core/query/AliasQuery.java | 2 +- .../data/elasticsearch/core/query/BulkOptions.java | 2 +- .../springframework/data/elasticsearch/core/query/Criteria.java | 2 +- .../data/elasticsearch/core/query/CriteriaQuery.java | 2 +- .../data/elasticsearch/core/query/DeleteQuery.java | 2 +- .../data/elasticsearch/core/query/FetchSourceFilter.java | 2 +- .../data/elasticsearch/core/query/FetchSourceFilterBuilder.java | 2 +- .../springframework/data/elasticsearch/core/query/Field.java | 2 +- .../springframework/data/elasticsearch/core/query/GetQuery.java | 2 +- .../data/elasticsearch/core/query/HighlightQuery.java | 2 +- .../data/elasticsearch/core/query/HighlightQueryBuilder.java | 2 +- .../data/elasticsearch/core/query/IndexBoost.java | 2 +- .../data/elasticsearch/core/query/IndexQuery.java | 2 +- .../data/elasticsearch/core/query/IndexQueryBuilder.java | 2 +- .../data/elasticsearch/core/query/MoreLikeThisQuery.java | 2 +- .../data/elasticsearch/core/query/NativeSearchQuery.java | 2 +- .../data/elasticsearch/core/query/NativeSearchQueryBuilder.java | 2 +- .../springframework/data/elasticsearch/core/query/Query.java | 2 +- .../data/elasticsearch/core/query/SimpleField.java | 2 +- .../data/elasticsearch/core/query/SourceFilter.java | 2 +- .../data/elasticsearch/core/query/StringQuery.java | 2 +- .../data/elasticsearch/core/query/UpdateQuery.java | 2 +- .../data/elasticsearch/core/query/UpdateQueryBuilder.java | 2 +- .../data/elasticsearch/repository/ElasticsearchRepository.java | 2 +- .../repository/ReactiveElasticsearchRepository.java | 2 +- .../repository/cdi/ElasticsearchRepositoryBean.java | 2 +- .../repository/cdi/ElasticsearchRepositoryExtension.java | 2 +- .../repository/config/ElasticsearchRepositoriesRegistrar.java | 2 +- .../config/ElasticsearchRepositoryConfigExtension.java | 2 +- .../repository/config/EnableElasticsearchRepositories.java | 2 +- .../config/EnableReactiveElasticsearchRepositories.java | 2 +- .../config/ReactiveElasticsearchRepositoriesRegistrar.java | 2 +- .../ReactiveElasticsearchRepositoryConfigurationExtension.java | 2 +- .../repository/query/AbstractElasticsearchRepositoryQuery.java | 2 +- .../query/AbstractReactiveElasticsearchRepositoryQuery.java | 2 +- .../repository/query/ConvertingParameterAccessor.java | 2 +- .../repository/query/ElasticsearchEntityMetadata.java | 2 +- .../repository/query/ElasticsearchParameterAccessor.java | 2 +- .../elasticsearch/repository/query/ElasticsearchParameters.java | 2 +- .../query/ElasticsearchParametersParameterAccessor.java | 2 +- .../elasticsearch/repository/query/ElasticsearchPartQuery.java | 2 +- .../repository/query/ElasticsearchStringQuery.java | 2 +- .../query/ReactiveElasticsearchParametersParameterAccessor.java | 2 +- .../repository/query/ReactiveElasticsearchQueryExecution.java | 2 +- .../repository/query/ReactiveElasticsearchStringQuery.java | 2 +- .../repository/query/ReactivePartTreeElasticsearchQuery.java | 2 +- .../repository/query/SimpleElasticsearchEntityMetadata.java | 2 +- .../repository/query/parser/ElasticsearchQueryCreator.java | 2 +- .../repository/support/ElasticsearchEntityInformation.java | 2 +- .../support/ElasticsearchEntityInformationCreator.java | 2 +- .../support/ElasticsearchEntityInformationCreatorImpl.java | 2 +- .../repository/support/ElasticsearchRepositoryFactory.java | 2 +- .../repository/support/ElasticsearchRepositoryFactoryBean.java | 2 +- .../repository/support/ElasticsearchRepositoryMetadata.java | 2 +- .../support/MappingElasticsearchEntityInformation.java | 2 +- .../support/ReactiveElasticsearchRepositoryFactoryBean.java | 2 +- .../support/ReactiveElasticsearchRepositoryMetadata.java | 2 +- .../repository/support/SimpleElasticsearchRepository.java | 2 +- .../support/SimpleReactiveElasticsearchRepository.java | 2 +- .../data/elasticsearch/support/SearchHitsUtil.java | 2 +- .../springframework/data/elasticsearch/DocumentUnitTests.java | 2 +- .../data/elasticsearch/ElasticsearchTestConfiguration.java | 2 +- .../data/elasticsearch/JUnit5ClusterConnectionTests.java | 2 +- .../data/elasticsearch/JUnit5SampleRestClientBasedTests.java | 2 +- .../elasticsearch/JUnit5SampleTransportClientBasedTests.java | 2 +- .../springframework/data/elasticsearch/NestedObjectTests.java | 2 +- .../data/elasticsearch/RestElasticsearchTestConfiguration.java | 2 +- .../java/org/springframework/data/elasticsearch/TestUtils.java | 2 +- src/test/java/org/springframework/data/elasticsearch/Utils.java | 2 +- .../data/elasticsearch/client/ClientConfigurationUnitTests.java | 2 +- .../data/elasticsearch/client/ClusterNodesUnitTests.java | 2 +- .../elasticsearch/client/InetSocketAddressParserUnitTests.java | 2 +- .../client/reactive/DefaultWebClientProviderUnitTests.java | 2 +- .../client/reactive/MultiNodeHostProviderUnitTests.java | 2 +- .../client/reactive/ReactiveElasticsearchClientTests.java | 2 +- .../client/reactive/ReactiveElasticsearchClientUnitTests.java | 2 +- .../client/reactive/ReactiveMockClientTestsUtils.java | 2 +- .../client/reactive/SingleNodeHostProviderUnitTests.java | 2 +- .../data/elasticsearch/client/util/RequestConvertersTest.java | 2 +- .../config/ElasticsearchConfigurationSupportUnitTests.java | 2 +- .../ElasticsearchConfigurationTests.java | 2 +- .../config/namespace/ElasticsearchNamespaceHandlerTests.java | 2 +- .../nested/EnableNestedElasticsearchRepositoriesTests.java | 2 +- .../EnableNestedElasticsearchRepositoriesTransportTests.java | 2 +- .../config/notnested/SampleElasticsearchRepository.java | 2 +- .../notnested/SampleUUIDKeyedElasticsearchRepository.java | 2 +- .../data/elasticsearch/core/CriteriaQueryMappingTests.java | 2 +- .../data/elasticsearch/core/DocumentAdaptersUnitTests.java | 2 +- .../data/elasticsearch/core/ElasticsearchPartQueryTests.java | 2 +- .../data/elasticsearch/core/ElasticsearchRestTemplateTests.java | 2 +- .../data/elasticsearch/core/ElasticsearchTemplateTests.java | 2 +- .../elasticsearch/core/ElasticsearchTransportTemplateTests.java | 2 +- .../data/elasticsearch/core/IndexCoordinatesTest.java | 2 +- .../springframework/data/elasticsearch/core/LogEntityTests.java | 2 +- .../data/elasticsearch/core/LogEntityTransportTests.java | 2 +- .../elasticsearch/core/ReactiveElasticsearchTemplateTests.java | 2 +- .../core/ReactiveElasticsearchTemplateUnitTests.java | 2 +- .../elasticsearch/core/aggregation/AggregatedPageImplTest.java | 2 +- .../core/aggregation/ElasticsearchTemplateAggregationTests.java | 2 +- .../ElasticsearchTemplateAggregationTransportTests.java | 2 +- .../core/completion/ElasticsearchTemplateCompletionTests.java | 2 +- .../ElasticsearchTemplateCompletionTransportTests.java | 2 +- .../ElasticsearchTemplateCompletionWithContextsTests.java | 2 +- ...asticsearchTemplateCompletionWithContextsTransportTests.java | 2 +- .../elasticsearch/core/convert/DateTimeConvertersTests.java | 2 +- .../core/convert/MappingElasticsearchConverterUnitTests.java | 2 +- .../elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java | 2 +- .../core/geo/ElasticsearchTemplateGeoTransportTests.java | 2 +- .../data/elasticsearch/core/index/MappingBuilderTests.java | 2 +- .../data/elasticsearch/core/index/MappingContextBaseTests.java | 2 +- .../core/index/SimpleDynamicTemplatesMappingTests.java | 2 +- .../core/index/SimpleElasticsearchDateMappingTests.java | 2 +- .../core/mapping/SimpleElasticsearchPersistentEntityTests.java | 2 +- .../mapping/SimpleElasticsearchPersistentPropertyUnitTests.java | 2 +- .../data/elasticsearch/core/query/CriteriaQueryTests.java | 2 +- .../elasticsearch/core/query/CriteriaQueryTestsTransport.java | 2 +- .../elasticsearch/core/query/HighlightQueryBuilderTests.java | 2 +- .../immutable/ImmutableElasticsearchRepository.java | 2 +- .../immutable/ImmutableElasticsearchRepositoryTests.java | 2 +- .../data/elasticsearch/immutable/ImmutableEntity.java | 2 +- .../data/elasticsearch/junit/junit4/ElasticsearchVersion.java | 2 +- .../elasticsearch/junit/junit4/ElasticsearchVersionRule.java | 2 +- .../data/elasticsearch/junit/junit4/TestNodeResource.java | 2 +- .../data/elasticsearch/junit/jupiter/ClusterConnection.java | 2 +- .../elasticsearch/junit/jupiter/ClusterConnectionException.java | 2 +- .../data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java | 2 +- .../junit/jupiter/ElasticsearchRestTemplateConfiguration.java | 2 +- .../junit/jupiter/ElasticsearchTemplateConfiguration.java | 2 +- .../data/elasticsearch/junit/jupiter/IntegrationTest.java | 2 +- .../junit/jupiter/SpringDataElasticsearchExtension.java | 2 +- .../data/elasticsearch/junit/jupiter/SpringIntegrationTest.java | 2 +- .../elasticsearch/repositories/cdi/CdiProductRepository.java | 2 +- .../elasticsearch/repositories/cdi/CdiRepositoryClient.java | 2 +- .../data/elasticsearch/repositories/cdi/CdiRepositoryTests.java | 2 +- .../repositories/cdi/ElasticsearchTemplateProducer.java | 2 +- .../data/elasticsearch/repositories/cdi/OtherQualifier.java | 2 +- .../data/elasticsearch/repositories/cdi/PersonDB.java | 2 +- .../repositories/cdi/QualifiedProductRepository.java | 2 +- .../elasticsearch/repositories/cdi/SamplePersonRepository.java | 2 +- .../repositories/cdi/SamplePersonRepositoryCustom.java | 2 +- .../repositories/cdi/SamplePersonRepositoryImpl.java | 2 +- .../autowiring/ComplexCustomMethodRepositoryTests.java | 2 +- .../autowiring/ComplexCustomMethodRepositoryTransportTests.java | 2 +- .../custommethod/autowiring/ComplexElasticsearchRepository.java | 2 +- .../autowiring/ComplexElasticsearchRepositoryCustom.java | 2 +- .../ComplexCustomMethodRepositoryManualWiringTests.java | 2 +- ...ComplexCustomMethodRepositoryManualWiringTransportTests.java | 2 +- .../ComplexElasticsearchRepositoryManualWiring.java | 2 +- .../ComplexElasticsearchRepositoryManualWiringImpl.java | 2 +- .../custommethod/CustomMethodRepositoryBaseTests.java | 2 +- .../custommethod/CustomMethodRepositoryRestTests.java | 2 +- .../repositories/custommethod/CustomMethodRepositoryTests.java | 2 +- .../repositories/doubleid/DoubleIDRepositoryTests.java | 2 +- .../repositories/doubleid/DoubleIDRepositoryTransportTests.java | 2 +- .../repositories/dynamicindex/DynamicIndexEntityTests.java | 2 +- .../dynamicindex/DynamicIndexEntityTransportTests.java | 2 +- .../repositories/geo/SpringDataGeoRepositoryTests.java | 2 +- .../repositories/geo/SpringDataGeoRepositoryTransportTests.java | 2 +- .../repositories/integer/IntegerIDRepositoryTests.java | 2 +- .../repositories/integer/IntegerIDRepositoryTransportTests.java | 2 +- .../repositories/nestedobject/InnerObjectTests.java | 2 +- .../repositories/nestedobject/InnerObjectTransportTests.java | 2 +- .../dynamic/DynamicSettingAndMappingEntityRepositoryTests.java | 2 +- .../DynamicSettingAndMappingEntityRepositoryTransportTests.java | 2 +- .../fielddynamic/FieldDynamicMappingEntityRepositoryTests.java | 2 +- .../FieldDynamicMappingEntityRepositoryTransportTests.java | 2 +- .../data/elasticsearch/repositories/spel/SpELEntityTests.java | 2 +- .../repositories/spel/SpELEntityTransportTests.java | 2 +- .../repositories/synonym/SynonymRepositoryTests.java | 2 +- .../repositories/synonym/SynonymRepositoryTransportTests.java | 2 +- .../uuidkeyed/UUIDElasticsearchRepositoryTests.java | 2 +- .../uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java | 2 +- .../config/ReactiveElasticsearchRepositoriesRegistrarTests.java | 2 +- ...eElasticsearchRepositoryConfigurationExtensionUnitTests.java | 2 +- .../repository/query/ElasticsearchStringQueryUnitTests.java | 2 +- .../query/ReactiveElasticsearchQueryMethodUnitTests.java | 2 +- .../query/ReactiveElasticsearchStringQueryUnitTests.java | 2 +- .../elasticsearch/repository/query/StubParameterAccessor.java | 2 +- .../query/keywords/QueryKeywordsRepositoryTransportTests.java | 2 +- .../repository/query/keywords/QueryKeywordsTests.java | 2 +- .../support/ElasticsearchEntityInformationCreatorImplTests.java | 2 +- .../support/SimpleReactiveElasticsearchRepositoryTests.java | 2 +- .../support/simple/SimpleElasticsearchRepositoryTests.java | 2 +- .../data/elasticsearch/utils/IndexInitializer.java | 2 +- 289 files changed, 289 insertions(+), 289 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java index 1553c6571..2660ad7b7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java b/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java index 4670ddb45..b6369ed8d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java +++ b/src/main/java/org/springframework/data/elasticsearch/NoSuchIndexException.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java index 04bb3b59e..2f4fafb2b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java index 740eb4698..990abfd25 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java index 629d2a433..e72987ed4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java index 3d79732ec..fd14699ef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java index 3cec02048..54061bd6b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicMappingValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java index aecea592a..7adaa7244 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java index 867973dc5..09cc014e4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java index 59ee71aea..f2d5915c0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/GeoPointField.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java index 3ac6f60ab..075327a40 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Highlight.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java index d65d59d93..ec7c0c6c1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightField.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java index 74aad474b..608a78734 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/HighlightParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java index 85141cb06..b72db4c9c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java index 1ad56153e..fa91f37f3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/IndexPrefixes.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java index 54a11dd84..c6fa617d7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java index d9dd1d0ce..9a0647a4f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Mapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java index adb2a6d90..876bd8aa0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/MultiField.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java index 481a21be5..d919f32f0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java index dcae53e00..ab4ef449b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java index 43cf37e1e..8256f466d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Setting.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java index bb4580efa..54c3c8c59 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Similarity.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java index 615760a4d..ba8ec1c14 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index 6b3fe8dc1..755f37071 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index fa1b49a4a..032f5b39f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java index 9a9b41e85..50d7d68ef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java b/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java index 5621c5715..fc5479753 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClusterNodes.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index 72dbdfaa0..6bdc9bea9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java index 852bb2663..5840cddb3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ElasticsearchHost.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java b/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java index 2839ce282..56e0e79ef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/InetSocketAddressParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java b/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java index 3e3d863c1..155d6cdd9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NoReachableHostException.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java index 4a313a1ce..72b41c22f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java index a26a2b6d4..ba972c9d7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java index 6915ca3cf..7500943a6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java index 90b679ebe..a8579aa05 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 961da02d4..db3b3216e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java index 9dd97118e..30be17eca 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java index b51d4270a..b742c2b03 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java index 144c2219c..6930a4a32 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java index a2e79330d..c763ca7b0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index d7ccc4049..6480074a3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java index 17ffc055f..4bd0c921b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestBodyEncodingException.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestBodyEncodingException.java index 50b9cbe40..33cb29709 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestBodyEncodingException.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestBodyEncodingException.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java index 69c4fbd85..428f3daeb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java index a6c3a6d6b..f2e8b45ee 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index ab428764f..5abc0986c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java index 47fbbb00b..97e680d90 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/AbstractReactiveElasticsearchConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/config/AbstractReactiveElasticsearchConfiguration.java index 02273549e..2e9a1882d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/AbstractReactiveElasticsearchConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/AbstractReactiveElasticsearchConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index f78c91612..949822ac5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchNamespaceHandler.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchNamespaceHandler.java index 719521dc4..774b1df0e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchNamespaceHandler.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchNamespaceHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/NodeClientBeanDefinitionParser.java b/src/main/java/org/springframework/data/elasticsearch/config/NodeClientBeanDefinitionParser.java index 86a2166a5..b9878bfe1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/NodeClientBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/NodeClientBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/RestClientBeanDefinitionParser.java b/src/main/java/org/springframework/data/elasticsearch/config/RestClientBeanDefinitionParser.java index bb4802081..cfb32e6fe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/RestClientBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/RestClientBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/TransportClientBeanDefinitionParser.java b/src/main/java/org/springframework/data/elasticsearch/config/TransportClientBeanDefinitionParser.java index b8fbea302..c5a6497fe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/TransportClientBeanDefinitionParser.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/TransportClientBeanDefinitionParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index cc49fb7cb..2032624c8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java index ef73dc50a..eb91dd597 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java index a337baac2..bffb1c0f3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 5ea59998f..87aab6cd5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 39a910269..cbc485c48 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 58b5ee836..a38d4afc0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index a453dda4b..512238103 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 66d0ae503..456c91def 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 2fe6da806..dd4ade833 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index a452f7806..f6793032e 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 9c09fbad7..160f89941 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 1fba70566..31f79f2c5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index bba9582ea..8a7e73be7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java index 880a6d133..9132dea67 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java index 2177ae8c9..1006b833b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 172964089..5ecf31d6d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java index 627ab09a0..f7a4e10ee 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java b/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java index a444f2d6c..de1ddfe71 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ScoredPage.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index c681a8f79..83b9d3c77 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 590b6c984..51552a8a6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java index 876daa5e5..57c18c9ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 7dc92f6f4..4c173264b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index 2a685525b..784d1eeb8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java index 01da64509..1bdff8c87 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 the original author or authors. + * Copyright 2017-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java index f8b326a9d..14cbda75d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java index 33a504610..cd249f2ec 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ConversionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/DateTimeConverters.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/DateTimeConverters.java index 399f3f3f8..47942f48f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/DateTimeConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/DateTimeConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java index a6a5306ac..7bf5e65a6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/DefaultElasticsearchTypeMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index ed3d27af9..d1666ee70 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java index 14b62aee3..c42078491 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java index 0d6d25240..a09c95ab7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java index f8cbc9e73..5d21afa29 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchTypeMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java index e1f348a5a..4ebb27ab4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 9561d95db..0f5716ede 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index e1aaa0594..1c5c856cc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 4e2af31bc..c309143ce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java index 439aeb3b9..665629197 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java index 6ea162475..3caafc554 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java index 89cf9ea74..489c5cd43 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java index 476a3a3df..68ad3d395 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoBox.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java index a0779f0e1..248ec12cf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 082c7ecfd..9846e8f6c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java index 2028749ae..39bc8d760 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 8604854d7..330a5bf04 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java index b65115784..a3b7b5ed2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java index 24da65fe5..698fea732 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentPropertyConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchSimpleTypes.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchSimpleTypes.java index 04d90ad8b..05b8a482f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchSimpleTypes.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchSimpleTypes.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java index 61ff0f7ea..79fd063f1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java index 43cec5b69..17a5b6e59 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchMappingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index ee0825e52..2b2207262 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 8aeba913a..1bb2419b0 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java index d3df80d0f..2fe6e7509 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java index 459e98c06..e4d710dcd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/BulkOptions.java b/src/main/java/org/springframework/data/elasticsearch/core/query/BulkOptions.java index c7a1b57cb..b5b96dcce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/BulkOptions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/BulkOptions.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index 91d25e41e..88a9fa158 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java index b348c85bb..885c30b44 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java index d1a5f82a5..ea17d96c9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java index 0197d3ca2..93bc6e495 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java index 317877947..f94d278fa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java index 936445231..aa80c12dc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java index 2713d4240..7fbbb3969 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java index 90396b988..745a38de0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java index 4f68e6e95..b341373cf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java index 8a9ad78a9..38abbd48e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexBoost.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index 4abe51385..529d91886 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 1dcd9a30d..579b703ec 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java index f8b9c3aba..c9b56dfc3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java index dc376232f..78ddddd0d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java index 4c682653e..e8b292504 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 0dde4e6a1..6c0c2e721 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index 42dac159d..9abca6a2d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java index 58d750c4a..cb7d9a33e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/StringQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/StringQuery.java index 61699daec..1b0c30ada 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/StringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/StringQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index 1e4081bdd..bf9b02b90 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java index e7075a56f..a22915192 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index 8d63042d3..e56fdec44 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java index ce30c7730..200a6b95f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ReactiveElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java index c61baef52..1bb38970f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java index e08aae248..a3ce299c1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/ElasticsearchRepositoryExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoriesRegistrar.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoriesRegistrar.java index a97b840b5..ff0845665 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoriesRegistrar.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoriesRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java index a03d68705..9e2bfaa4a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ElasticsearchRepositoryConfigExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableElasticsearchRepositories.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableElasticsearchRepositories.java index 8b0d24fef..ddcf633f6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableElasticsearchRepositories.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableElasticsearchRepositories.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableReactiveElasticsearchRepositories.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableReactiveElasticsearchRepositories.java index 8c012a768..2da87428f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableReactiveElasticsearchRepositories.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/EnableReactiveElasticsearchRepositories.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrar.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrar.java index 6728cbd70..757124629 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrar.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtension.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtension.java index 83d5809bc..d33a5a5e2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtension.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java index 45de5b0d0..88907be50 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index 6565c7944..09f8999b1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java index e56d4c036..f574e1edf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ConvertingParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java index 2e90241f0..bfddab930 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java index 7df958164..b3eccdd57 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java index df9d7b67f..be5cfe1c4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java index 5b25dd3df..6b5016cbe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchParametersParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 51c36f5c0..528701e41 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index 82dfe9425..f6863067d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java index 4ef0b9992..38611e5d0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchParametersParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java index e3fbc76b1..92be9879e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryExecution.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java index d618c4dae..7f7215f97 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java index e723e275c..fec2177e7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ReactivePartTreeElasticsearchQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java index 80aae45b4..6be1bc537 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/SimpleElasticsearchEntityMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java index 4f4d9b707..8eac98132 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java index 83bd22fdd..3f529ba0e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreator.java index 3d6cb5b4b..2acd074c1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImpl.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImpl.java index 0cb1413fe..75f339949 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java index e37bf8011..b0b2a8386 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java index ea709b225..625f9e00d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java index 9ad08e572..4f52f7c37 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java index 69b8983ac..83c55edb5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java index cbdf90eab..fbf33742c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java index 18dc491d1..2c6ac4af4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 45c6b45ec..e178aa949 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index 66919a460..bc88bc301 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/main/java/org/springframework/data/elasticsearch/support/SearchHitsUtil.java b/src/main/java/org/springframework/data/elasticsearch/support/SearchHitsUtil.java index 77758ef2a..c5ae17c93 100644 --- a/src/main/java/org/springframework/data/elasticsearch/support/SearchHitsUtil.java +++ b/src/main/java/org/springframework/data/elasticsearch/support/SearchHitsUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/DocumentUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/DocumentUnitTests.java index c47dc7558..ac2fcc6a3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/DocumentUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/DocumentUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java index b9c9529f0..f0bf2b856 100644 --- a/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java b/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java index a35685425..1f31f5bef 100644 --- a/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/JUnit5ClusterConnectionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleRestClientBasedTests.java b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleRestClientBasedTests.java index d708faa04..f7174ef19 100644 --- a/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleRestClientBasedTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleRestClientBasedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleTransportClientBasedTests.java b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleTransportClientBasedTests.java index fdd6e9234..7fc13416d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleTransportClientBasedTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleTransportClientBasedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index e42b53652..61b2b0342 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java index 2f9ab0343..6bcee8f79 100644 --- a/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java b/src/test/java/org/springframework/data/elasticsearch/TestUtils.java index bd879cb78..5f3bd2094 100644 --- a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/TestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/Utils.java b/src/test/java/org/springframework/data/elasticsearch/Utils.java index c851a2cf6..1c8ffc791 100644 --- a/src/test/java/org/springframework/data/elasticsearch/Utils.java +++ b/src/test/java/org/springframework/data/elasticsearch/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java index 96cb70f32..f37da88a1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/ClientConfigurationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/ClusterNodesUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/ClusterNodesUnitTests.java index 93c34560c..9280fca29 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/ClusterNodesUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/ClusterNodesUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/InetSocketAddressParserUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/InetSocketAddressParserUnitTests.java index 8f53ddf02..2d691d712 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/InetSocketAddressParserUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/InetSocketAddressParserUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java index 64836ccba..ecc3a4a35 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultWebClientProviderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java index 7769e0269..830c69de4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index aa1c0fc0b..0d7d1858c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index 01e4ee615..513c23846 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index 2ff13a387..6b58dc37b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProviderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProviderUnitTests.java index 95b7ddc70..a27e22389 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProviderUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProviderUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/util/RequestConvertersTest.java b/src/test/java/org/springframework/data/elasticsearch/client/util/RequestConvertersTest.java index dc0111792..d73ebf62e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/util/RequestConvertersTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/util/RequestConvertersTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupportUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupportUnitTests.java index c7317151b..0ef81acc4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupportUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupportUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java index f234bc959..b93bb01da 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java index 591fcdc17..e25a9a466 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/namespace/ElasticsearchNamespaceHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java index 72df2ec51..86790a25e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015-2019 the original author or authors. + * Copyright 2015-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java index f21ab286e..ed2790f24 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleElasticsearchRepository.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleElasticsearchRepository.java index a6c6b9e4a..a705f5cb4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleElasticsearchRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleUUIDKeyedElasticsearchRepository.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleUUIDKeyedElasticsearchRepository.java index 51eaf9474..3985ab518 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleUUIDKeyedElasticsearchRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/SampleUUIDKeyedElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java index ee82bef3b..0a39f55a6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java index 1e03dfa21..852e8f0da 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java index 7e631c3a1..a1909435b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 01271dd76..781f427c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 3b8205f94..f824f88d3 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 683e2571c..02c3c55ba 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java index 0f1a6a14c..ee33e4b4f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index ff16c14a2..3acaab94c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java index 76e2e4d8c..9e7cf811d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 4d74cb592..1d855e3c6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index dd917e301..7e0b30e3a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPageImplTest.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPageImplTest.java index ef9f435a9..fd488f679 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPageImplTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPageImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index 71c8cf285..91108c41e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java index b0f158f2d..067801571 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 3f4296f85..302c76b92 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java index 239f19e24..165d79901 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index 470962714..1219a11fe 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java index 8f88d1d56..fa3e7867f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/DateTimeConvertersTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/DateTimeConvertersTests.java index 3a98c068e..c93944242 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/DateTimeConvertersTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/DateTimeConvertersTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index daa24cfcc..79a8a950e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index adeefe32e..daa4dac42 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java index b4067334c..602d006fc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 921c8cbe1..db105f987 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java index 069c5297c..11e975921 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java @@ -1,4 +1,4 @@ -/* Copyright 2019 the original author or authors. +/* Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java index 0d56d60e6..7ffcdd987 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java index 1c3230b27..eec5b4c5c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index 1180009fd..d5ee992c8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 083d4743b..f6b08b2f8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 04c737a87..33a367965 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java index 1a18d17ed..58d1a5d90 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java index 7b1d09f17..a1241cac9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2020-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepository.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepository.java index e10afd8e0..0362c59d9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index 3a20fe679..b4d4a949a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableEntity.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableEntity.java index 1edf59e3c..75302f935 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableEntity.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java index 85ebfd6da..8d936c268 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java index aa68dc142..d71c1f8b7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java index b6c1c07aa..007704d6c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java index 87cea98a4..825636d00 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionException.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionException.java index 83661b25d..96c84d289 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionException.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java index 26d67d06d..33884dbc6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java index aaf800ab1..e06f60bfd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java index 2298024fb..b781630fb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java index 17e3032bb..4af516887 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/IntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java index 4f5a17940..916747fca 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringDataElasticsearchExtension.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringIntegrationTest.java index 387507aeb..e23605523 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringIntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/SpringIntegrationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java index f4d36723c..8102e9873 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiProductRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java index 228bb41b7..167288026 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index 913ffc76e..d42f2b308 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java index 05a821c79..2a4a07b16 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java index 28062174b..0a6237f7d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/OtherQualifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java index 74a7ef51e..ba31ca617 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/PersonDB.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java index ec3124fdb..34da07334 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/QualifiedProductRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java index f82bd24b0..62356a2b6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java index 1d44c249e..ba447902b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryCustom.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java index d7219d5af..a95d57970 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/SamplePersonRepositoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index 268ec79c0..9a25b5ae4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java index 15885237f..cf668e3c8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepository.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepository.java index 1ba357257..42f85297b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepository.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java index 9e1f4e93d..9edcb5543 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexElasticsearchRepositoryCustom.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java index aa61d0e14..e38055272 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java index 7236ed774..e1d3c9262 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiring.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiring.java index 87f7739d4..dbd88f734 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiring.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiring.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java index 825a7aa6d..329b09328 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexElasticsearchRepositoryManualWiringImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 50ea5f11a..20fc5752d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java index 84f1fd07e..79743aecd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryRestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java index 7a0541b8b..7f82c31cb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2018-2019 the original author or authors. + * Copyright 2018-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index 620180dd1..2e8705f6d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java index 2e42afb0a..a25a6bd9c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 75b1cf813..1b2527678 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java index 7dadae7c2..1d3b4f7b7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 47ba36cc8..008efcbe5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java index 81c3d3a3e..5773f02d5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index da84a2ea6..8a9c20e8f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java index 451ef33b9..8b1678828 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index a51f1ad7c..18ad8941d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java index 62d5ff43e..0efd7b2b6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 649f09c46..ed97872ac 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java index c4e0c0b8c..2baeaabf9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index c673f35c3..77931653f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java index 03a68bcf9..8ed73bae6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index bb304f0ac..243e2e09d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java index 3e4dd6c70..f94a88a77 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 7950b2f2d..46aff078e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java index b0e52a913..634c330f4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index fc73c16b3..4a632268e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java index abbc32a43..4d7de8d27 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java index 84f554c87..3745c3efb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java index aea0b777c..9a2bb94f2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoryConfigurationExtensionUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java index 299e3ed53..996e064aa 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java index e57f9c6ba..bc8aebba2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java index 1d68dd1ba..a20b391f9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java index 98613b757..f94bee97b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java index 59f31af29..734f802b7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsRepositoryTransportTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index 2636a00ba..4cd0fb8be 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2019 the original author or authors. + * Copyright 2016-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java index dcb8b9cfd..dd674ec20 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformationCreatorImplTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2019 the original author or authors. + * Copyright 2014-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index 9534fc00d..ac9668faf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index de6eb3558..894719fc6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2019 the original author or authors. + * Copyright 2013-2020 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. diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java index d0281942a..cb3513d21 100644 --- a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2019 the original author or authors. + * Copyright 2019-2020 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. From 0843481cc5c4cb1d53df327487827f3ba59e8508 Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Wed, 13 Nov 2019 08:29:51 -0600 Subject: [PATCH 0038/1191] DATAES-690 - Enable JDK 11+ builds. --- .travis.yml | 5 +- Jenkinsfile | 45 +++++++++- pom.xml | 2 +- .../org/elasticsearch/bootstrap/JarHell.java | 85 +++++++++++++++++++ 4 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 src/test/java/org/elasticsearch/bootstrap/JarHell.java diff --git a/.travis.yml b/.travis.yml index 0b2b94275..c15c7007c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ dist: xenial language: java -jdk: - - openjdk8 +sudo: true -script: "mvn clean dependency:list test -Dsort -U -B" +script: "./mvnw -Pjava11 clean dependency:list test -Dsort -U -B" diff --git a/Jenkinsfile b/Jenkinsfile index 6a62bb691..a1f7efeb9 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -12,7 +12,28 @@ pipeline { } stages { - stage("Test") { + stage("test: baseline (jdk8)") { + when { + anyOf { + branch 'master' + not { triggeredBy 'UpstreamCause' } + } + } + agent { + docker { + image 'adoptopenjdk/openjdk8:latest' + label 'data' + args '-v $HOME:/tmp/jenkins-home' + } + } + options { timeout(time: 30, unit: 'MINUTES') } + steps { + sh 'rm -rf ?' + sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B' + } + } + + stage("Test other configurations") { when { anyOf { branch 'master' @@ -20,10 +41,10 @@ pipeline { } } parallel { - stage("test: baseline") { + stage("test: baseline (jdk11)") { agent { docker { - image 'adoptopenjdk/openjdk8:latest' + image 'adoptopenjdk/openjdk11:latest' label 'data' args '-v $HOME:/tmp/jenkins-home' } @@ -31,11 +52,27 @@ pipeline { options { timeout(time: 30, unit: 'MINUTES') } steps { sh 'rm -rf ?' - sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B' + sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' + } + } + + stage("test: baseline (jdk12)") { + agent { + docker { + image 'adoptopenjdk/openjdk12:latest' + label 'data' + args '-v $HOME:/tmp/jenkins-home' + } + } + options { timeout(time: 30, unit: 'MINUTES') } + steps { + sh 'rm -rf ?' + sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' } } } } + stage('Release to artifactory') { when { anyOf { diff --git a/pom.xml b/pom.xml index d790d6756..7d8a6880b 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.JDK11-SNAPSHOT Spring Data Elasticsearch diff --git a/src/test/java/org/elasticsearch/bootstrap/JarHell.java b/src/test/java/org/elasticsearch/bootstrap/JarHell.java new file mode 100644 index 000000000..3b939ddfb --- /dev/null +++ b/src/test/java/org/elasticsearch/bootstrap/JarHell.java @@ -0,0 +1,85 @@ +/* + * Copyright 2018-2019 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.elasticsearch.bootstrap; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.Set; +import java.util.function.Consumer; + +/** + * No words – No words can describe this piece of code and why we cannot opt-in/opt-out from JarHell check. + *

+ * Elasticsearch wants to raise awareness if there are two classes with the exact same name (class name and package + * name) to avoid downstream issues. Turns out, in some case, such as Java 9 module descriptors, it's perfectly fine to + * have exactly same class names (such as {@code module-info.class}) yet JarHell goes awry and prevents startup. + *

+ * This class is here to be loaded before ES's JarHell class and to anyone that wants to survive JarHell, leave it here + * or you will die a slow and painful death. + *

+ * Oh, by the way: If Elasticsearch decides to upgrade JarHell with new method signatures, we should adapt to these. + * + * @author Mark Paluch + */ +public class JarHell { + + private JarHell() {} + + /** + * Empty stub. Leave it here or you will die a slow and painful death. + * + * @param output + * @throws IOException + * @throws URISyntaxException + */ + public static void checkJarHell(Consumer output) throws IOException, URISyntaxException {} + + /** + * Empty stub. Leave it here or you will die a slow and painful death. + * + * @return + */ + public static Set parseClassPath() { + return Collections.emptySet(); + } + + /** + * Empty stub. Leave it here or you will die a slow and painful death. + * + * @param urls + * @param output + * @throws URISyntaxException + * @throws IOException + */ + public static void checkJarHell(Set urls, Consumer output) throws URISyntaxException, IOException {} + + /** + * Empty stub. Leave it here or you will die a slow and painful death. + * + * @param targetVersion + */ + public static void checkVersionFormat(String targetVersion) {} + + /** + * Empty stub. Leave it here or you will die a slow and painful death. + * + * @param resource + * @param targetVersion + */ + public static void checkJavaVersion(String resource, String targetVersion) {} +} From 7294accaca6babbd926e598d55fbbc0c25c6c229 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 9 Jan 2020 23:29:34 +0100 Subject: [PATCH 0039/1191] DATAES-661 - Added track_total_hits request parameter to Query. Original PR: #378 --- .../elasticsearch/core/RequestFactory.java | 8 ++++++++ .../core/query/AbstractQuery.java | 10 ++++++++++ .../data/elasticsearch/core/query/Query.java | 20 +++++++++++++++++++ 3 files changed, 38 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 5ecf31d6d..e2ffaa038 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -552,6 +552,10 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz } + if (query.getTrackTotalHits()) { + sourceBuilder.trackTotalHits(query.getTrackTotalHits()); + } + request.source(sourceBuilder); return request; } @@ -714,6 +718,10 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli prepareNativeSearch(searchRequestBuilder, (NativeSearchQuery) query); } + if (query.getTrackTotalHits()) { + searchRequestBuilder.setTrackTotalHits(query.getTrackTotalHits()); + } + return searchRequestBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 1bb2419b0..2a98092d8 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -54,6 +54,7 @@ abstract class AbstractQuery implements Query { protected String preference; protected Integer maxResults; protected HighlightQuery highlightQuery; + private boolean trackTotalHits = false; @Override public Sort getSort() { @@ -208,4 +209,13 @@ public Optional getHighlightQuery() { return Optional.ofNullable(highlightQuery); } + @Override + public void setTrackTotalHits(boolean trackTotalHits) { + this.trackTotalHits = trackTotalHits; + } + + @Override + public boolean getTrackTotalHits() { + return trackTotalHits; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 6c0c2e721..34155b080 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -202,4 +202,24 @@ default Integer getMaxResults() { default Optional getHighlightQuery() { return Optional.empty(); } + + /** + * Sets the flag whether to set the Track_total_hits parameter on queries {@see Elasticseacrh + * documentation} + * + * @param trackTotalHits the value to set. + * @since 4.0 + */ + void setTrackTotalHits(boolean trackTotalHits); + + /** + * Sets the flag whether to set the Track_total_hits parameter on queries {@see Elasticseacrh + * documentation} + * + * @return the set value. + * @since 4.0 + */ + boolean getTrackTotalHits(); } From d55cb00d4576e1c7b95f121438dfeb1371ea7232 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 10 Jan 2020 15:52:03 +0100 Subject: [PATCH 0040/1191] DATAES-727 - Use track_total_hits parameter for count queries. Original PR: #379 --- .../DefaultReactiveElasticsearchClient.java | 8 ++-- .../reactive/ReactiveElasticsearchClient.java | 23 ++++++----- .../core/ElasticsearchRestTemplate.java | 5 +++ .../core/ElasticsearchTemplate.java | 4 ++ .../core/ReactiveElasticsearchTemplate.java | 38 +++++-------------- 5 files changed, 34 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index db3b3216e..8c1466cc4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -79,7 +79,6 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Request; import org.elasticsearch.client.core.CountRequest; -import org.elasticsearch.client.core.CountResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -336,9 +335,10 @@ public Mono delete(HttpHeaders headers, DeleteRequest deleteRequ * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#count(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest) */ @Override - public Mono count(HttpHeaders headers, CountRequest countRequest) { - return sendRequest(countRequest, RequestCreator.count(), CountResponse.class, headers) // - .map(CountResponse::getCount) // + public Mono count(HttpHeaders headers, SearchRequest searchRequest) { + return sendRequest(searchRequest, RequestCreator.search(), SearchResponse.class, headers) // + .map(SearchResponse::getHits) // + .map(searchHits -> searchHits.getTotalHits().value) // .next(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 6480074a3..914a43395 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -43,7 +43,6 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; -import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; @@ -342,37 +341,37 @@ default Mono delete(DeleteRequest deleteRequest) { * @return the {@link Mono} emitting the count result. * @since 4.0 */ - default Mono count(Consumer consumer) { + default Mono count(Consumer consumer) { - CountRequest countRequest = new CountRequest(); - consumer.accept(countRequest); - return count(countRequest); + SearchRequest searchRequest = new SearchRequest(); + consumer.accept(searchRequest); + return count(searchRequest); } /** - * Execute a {@link SearchRequest} against the {@literal count} API. + * Execute a {@link SearchRequest} against the {@literal search} API. * - * @param countRequest must not be {@literal null}. + * @param searchRequest must not be {@literal null}. * @see Count API on * elastic.co * @return the {@link Mono} emitting the count result. * @since 4.0 */ - default Mono count(CountRequest countRequest) { - return count(HttpHeaders.EMPTY, countRequest); + default Mono count(SearchRequest searchRequest) { + return count(HttpHeaders.EMPTY, searchRequest); } /** - * Execute a {@link SearchRequest} against the {@literal count} API. + * Execute a {@link SearchRequest} against the {@literal search} API. * * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. - * @param countRequest must not be {@literal null}. + * @param searchRequest must not be {@literal null}. * @see Count API on * elastic.co * @return the {@link Mono} emitting the count result. * @since 4.0 */ - Mono count(HttpHeaders headers, CountRequest countRequest); + Mono count(HttpHeaders headers, SearchRequest searchRequest); /** * Execute a {@link SearchRequest} against the {@literal search} API. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index dd4ade833..314680272 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -212,8 +212,13 @@ private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoor @Override public long count(Query query, Class clazz, IndexCoordinates index) { + Assert.notNull(query, "query must not be null"); Assert.notNull(index, "index must not be null"); + + final boolean trackTotalHits = query.getTrackTotalHits(); + query.setTrackTotalHits(true); SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); + query.setTrackTotalHits(trackTotalHits); searchRequest.source().size(0); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index f6793032e..24ce4df8e 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -185,9 +185,13 @@ private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoor @Override public long count(Query query, @Nullable Class clazz, IndexCoordinates index) { + Assert.notNull(query, "query must not be null"); Assert.notNull(index, "index must not be null"); + final boolean trackTotalHits = query.getTrackTotalHits(); + query.setTrackTotalHits(true); SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); + query.setTrackTotalHits(trackTotalHits); searchRequestBuilder.setSize(0); return SearchHitsUtil.getTotalCount(getSearchResponse(searchRequestBuilder).getHits()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8d36358c3..ae2357c78 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -435,10 +435,7 @@ private Flux doFind(Query query, Class clazz, IndexCoordinate return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, clazz, index); - - if (indicesOptions != null) { - request.indicesOptions(indicesOptions); - } + request = prepareSearchRequest(request); if (query.getPageable().isPaged() || query.isLimiting()) { return doFind(request); @@ -455,17 +452,18 @@ public Mono count(Query query, Class entityType) { @Override public Mono count(Query query, Class entityType, IndexCoordinates index) { - return doCount(query, getPersistentEntityFor(entityType), index); + return doCount(query, entityType, index); } - private Mono doCount(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { + private Mono doCount(Query query, Class entityType, IndexCoordinates index) { return Mono.defer(() -> { - CountRequest countRequest = buildCountRequest(query, entity, index); - CountRequest request = prepareCountRequest(countRequest); + SearchRequest request = requestFactory.searchRequest(query, entityType, index); + request = prepareSearchRequest(request); + request.source().size(0); + request.source().trackTotalHits(true); return doCount(request); }); - } private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { @@ -524,17 +522,17 @@ protected Flux doFind(SearchRequest request) { /** * Customization hook on the actual execution result {@link Publisher}.
* - * @param request the already prepared {@link CountRequest} ready to be executed. + * @param request the already prepared {@link SearchRequest} ready to be executed. * @return a {@link Mono} emitting the result of the operation. */ - protected Mono doCount(CountRequest request) { + protected Mono doCount(SearchRequest request) { if (QUERY_LOGGER.isDebugEnabled()) { QUERY_LOGGER.debug("Executing doCount: {}", request); } return Mono.from(execute(client -> client.count(request))) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); + .onErrorResume(NoSuchIndexException.class, it -> Mono.just(0L)); } /** @@ -608,22 +606,6 @@ private static List sort(Query query, ElasticsearchPersistentE return mappedSort; } - /** - * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the - * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. - * - * @param request the generated {@link CountRequest}. - * @return never {@literal null}. - */ - protected CountRequest prepareCountRequest(CountRequest request) { - - if (indicesOptions == null) { - return request; - } - - return request.indicesOptions(indicesOptions); - } - /** * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. From 513741bcf6499f715035705157112591be787258 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 11 Jan 2020 21:13:42 +0100 Subject: [PATCH 0041/1191] DATAES-701 - Enable proxy support for the reactive rest client. Original PR: #380 --- .../DefaultReactiveElasticsearchClient.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 8c1466cc4..a6835f66b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -25,6 +25,7 @@ import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; +import reactor.netty.tcp.ProxyProvider; import reactor.netty.tcp.TcpClient; import java.io.IOException; @@ -198,12 +199,22 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client } if (!soTimeout.isNegative()) { - tcpClient = tcpClient.doOnConnected(connection -> connection // .addHandlerLast(new ReadTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS)) .addHandlerLast(new WriteTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS))); } + if (clientConfiguration.getProxy().isPresent()) { + String proxy = clientConfiguration.getProxy().get(); + String[] hostPort = proxy.split(":"); + + if (hostPort.length != 2) { + throw new IllegalArgumentException("invalid proxy configuration " + proxy + ", should be \"host:port\""); + } + tcpClient = tcpClient.proxy(proxyOptions -> proxyOptions.type(ProxyProvider.Proxy.HTTP).host(hostPort[0]) + .port(Integer.parseInt(hostPort[1]))); + } + String scheme = "http"; HttpClient httpClient = HttpClient.from(tcpClient); From e670a8877289eee6959e0c54ebbc360bf6eb2007 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 12 Jan 2020 18:11:40 +0100 Subject: [PATCH 0042/1191] DATAES-724 - Provide IndexOperations bean. Original PR: #381 --- .../AbstractElasticsearchConfiguration.java | 6 ++++ .../data/elasticsearch/NestedObjectTests.java | 9 ++--- .../EnableElasticsearchRepositoriesTests.java | 6 ++-- .../core/ElasticsearchTemplateTests.java | 6 +--- .../elasticsearch/core/LogEntityTests.java | 3 +- ...ElasticsearchTemplateAggregationTests.java | 9 +++-- .../ElasticsearchTemplateCompletionTests.java | 11 ++----- ...chTemplateCompletionWithContextsTests.java | 7 ++-- .../geo/ElasticsearchTemplateGeoTests.java | 12 ++----- .../core/index/MappingBuilderTests.java | 33 +++++++------------ .../core/query/CriteriaQueryTests.java | 7 ++-- .../ElasticsearchTemplateConfiguration.java | 6 ++++ .../ComplexCustomMethodRepositoryTests.java | 9 ++--- ...stomMethodRepositoryManualWiringTests.java | 8 ++--- .../CustomMethodRepositoryBaseTests.java | 5 +-- .../doubleid/DoubleIDRepositoryTests.java | 8 ++--- .../dynamicindex/DynamicIndexEntityTests.java | 7 +--- .../geo/SpringDataGeoRepositoryTests.java | 9 ++--- .../integer/IntegerIDRepositoryTests.java | 8 ++--- .../nestedobject/InnerObjectTests.java | 5 +-- ...ettingAndMappingEntityRepositoryTests.java | 3 +- ...ldDynamicMappingEntityRepositoryTests.java | 6 +--- .../repositories/spel/SpELEntityTests.java | 6 ++-- .../synonym/SynonymRepositoryTests.java | 3 +- .../UUIDElasticsearchRepositoryTests.java | 5 +-- .../query/keywords/QueryKeywordsTests.java | 9 ++--- .../SimpleElasticsearchRepositoryTests.java | 3 +- .../elasticsearch/utils/IndexInitializer.java | 11 +++---- 28 files changed, 73 insertions(+), 147 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java index 97e680d90..c81ade77c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java @@ -19,6 +19,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; /** @@ -47,4 +48,9 @@ public abstract class AbstractElasticsearchConfiguration extends ElasticsearchCo public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) { return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter); } + + @Bean + public IndexOperations indexOperations(ElasticsearchOperations elasticsearchOperations) { + return elasticsearchOperations.getIndexOperations(); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 61b2b0342..d5e2baaf0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -68,11 +68,10 @@ public class NestedObjectTests { @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, Book.class); IndexInitializer.init(indexOperations, Person.class); IndexInitializer.init(indexOperations, PersonMultipleLevelNested.class); @@ -388,8 +387,7 @@ public void shouldIndexAndSearchMapAsNestedType() { @Setter @Getter - @Document(indexName = "test-index-book-nested-objects", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-nested-objects", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -427,8 +425,7 @@ static class Car { * @author Artur Konczak */ @Data - @Document(indexName = "test-index-person-multiple-level-nested", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-person-multiple-level-nested", replicas = 0, refreshInterval = "-1") static class PersonMultipleLevelNested { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index fb6107bac..e285c3c13 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -39,7 +39,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -73,7 +73,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @EnableElasticsearchRepositories static class Config {} - @Autowired ElasticsearchOperations operations; + @Autowired private IndexOperations indexOperations; @Autowired private SampleElasticsearchRepository repository; @@ -83,7 +83,7 @@ interface SampleRepository extends Repository searchHits = operations.search(searchQuery, ArticleEntity.class, IndexCoordinates.of(INDEX_NAME)); + SearchHits searchHits = operations.search(searchQuery, ArticleEntity.class, + IndexCoordinates.of(INDEX_NAME)); Aggregations aggregations = searchHits.getAggregations(); // then @@ -135,8 +135,7 @@ public void shouldReturnAggregatedResponseForGivenSearchQuery() { * @author Mohsin Husen */ @Data - @Document(indexName = "test-index-articles-core-aggregation", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-articles-core-aggregation", replicas = 0, refreshInterval = "-1") static class ArticleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 302c76b92..19812e941 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -62,13 +62,10 @@ public class ElasticsearchTemplateCompletionTests { static class Config {} @Autowired private ElasticsearchOperations operations; - - IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach private void setup() { - indexOperations = operations.getIndexOperations(); - IndexInitializer.init(indexOperations, CompletionEntity.class); IndexInitializer.init(indexOperations, AnnotatedCompletionEntity.class); } @@ -244,8 +241,7 @@ public void setSomeField2(String someField2) { /** * @author Mewes Kochheim */ - @Document(indexName = "test-index-core-completion", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-core-completion", replicas = 0, refreshInterval = "-1") static class CompletionEntity { @Id private String id; @@ -328,8 +324,7 @@ public IndexQuery buildIndex() { /** * @author Mewes Kochheim */ - @Document(indexName = "test-index-annotated-completion", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-annotated-completion", replicas = 0, refreshInterval = "-1") static class AnnotatedCompletionEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index 1219a11fe..b5ed2c959 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -66,12 +66,10 @@ public class ElasticsearchTemplateCompletionWithContextsTests { static class Config {} @Autowired private ElasticsearchOperations operations; - - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach void setup() { - indexOperations = operations.getIndexOperations(); indexOperations.deleteIndex(ContextCompletionEntity.class); } @@ -243,8 +241,7 @@ public void setSomeField2(String someField2) { * @author Mewes Kochheim * @author Robert Gruendler */ - @Document(indexName = "test-index-context-completion", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-context-completion", replicas = 0, refreshInterval = "-1") static class ContextCompletionEntity { public static final String LANGUAGE_CATEGORY = "language"; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index daa4dac42..573c356d6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -78,14 +78,10 @@ static class Config {} .withTypes("geo-class-point-type"); @Autowired private ElasticsearchOperations operations; - - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - - indexOperations = operations.getIndexOperations(); - IndexInitializer.init(indexOperations, AuthorMarkerEntity.class); IndexInitializer.init(indexOperations, LocationMarkerEntity.class); } @@ -375,8 +371,7 @@ private IndexQuery buildIndex(LocationMarkerEntity result) { * @author Mohsin Husen */ @Data - @Document(indexName = "test-index-author-marker-core-geo", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-author-marker-core-geo", replicas = 0, refreshInterval = "-1") static class AuthorMarkerEntity { @Id private String id; @@ -434,8 +429,7 @@ public IndexQuery buildIndex() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-location-marker-core-geo", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-location-marker-core-geo", replicas = 0, refreshInterval = "-1") static class LocationMarkerEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index db105f987..8ac57c73a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -28,7 +28,6 @@ import lombok.NoArgsConstructor; import lombok.Setter; -import java.io.IOException; import java.lang.Boolean; import java.lang.Double; import java.lang.Integer; @@ -84,13 +83,11 @@ public class MappingBuilderTests extends MappingContextBaseTests { @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); - indexOperations.deleteIndex(StockPrice.class); indexOperations.deleteIndex(SimpleRecursiveEntity.class); indexOperations.deleteIndex(StockPrice.class); @@ -113,8 +110,8 @@ public void shouldNotFailOnCircularReference() { @Test // DATAES-568 public void testInfiniteLoopAvoidance() throws JSONException { - String expected = "{\"properties\":{\"message\":{\"store\":true,\"" - + "type\":\"text\",\"index\":false," + "\"analyzer\":\"standard\"}}}"; + String expected = "{\"properties\":{\"message\":{\"store\":true,\"" + "type\":\"text\",\"index\":false," + + "\"analyzer\":\"standard\"}}}"; String mapping = getMappingBuilder().buildPropertyMapping(SampleTransientEntity.class); @@ -319,8 +316,7 @@ public void shouldUseCopyTo() { public void shouldUseFieldNameOnId() throws JSONException { // given - String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" - + "}}"; + String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.IdEntity.class); @@ -648,8 +644,7 @@ static class MinimalChildEntity { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-mapping-builder", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -665,8 +660,7 @@ static class Book { * @author Stuart Stevenson * @author Mohsin Husen */ - @Document(indexName = "test-index-simple-recursive-mapping-builder", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-simple-recursive-mapping-builder", replicas = 0, refreshInterval = "-1") static class SimpleRecursiveEntity { @Id private String id; @@ -701,8 +695,7 @@ static class CopyToEntity { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-normalizer-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-normalizer-mapping-builder", replicas = 0, refreshInterval = "-1") @Setting(settingPath = "/settings/test-normalizer.json") static class NormalizerEntity { @@ -743,8 +736,7 @@ public void setName(String name) { /** * @author Kevin Leturc */ - @Document(indexName = "test-index-sample-inherited-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-inherited-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleInheritedEntity extends AbstractInheritedEntity { @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; @@ -801,8 +793,7 @@ public IndexQuery buildIndex() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-stock-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-stock-mapping-builder", replicas = 0, refreshInterval = "-1") static class StockPrice { @Id private String id; @@ -841,8 +832,7 @@ public void setCreatedDate(Date createdDate) { /** * @author Jakub Vavrik */ - @Document(indexName = "test-index-recursive-mapping-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-recursive-mapping-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleTransientEntity { @Id private String id; @@ -898,8 +888,7 @@ public void setSomething(Boolean something) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-geo-mapping-builder", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-geo-mapping-builder", replicas = 0, refreshInterval = "-1") static class GeoEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 33a367965..a0a34b3ec 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -67,12 +67,10 @@ static class Config {} private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes("test-type"); @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); - indexOperations.deleteIndex(SampleEntity.class); indexOperations.createIndex(SampleEntity.class); indexOperations.putMapping(SampleEntity.class); @@ -846,8 +844,7 @@ public void shouldEscapeValue() { @Getter @NoArgsConstructor @AllArgsConstructor - @Document(indexName = "test-index-sample-core-query", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-core-query", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java index b781630fb..a7f88efb7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java @@ -19,7 +19,9 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; /** @@ -42,4 +44,8 @@ public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient, return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter); } + @Bean + IndexOperations indexOperations(ElasticsearchOperations elasticsearchOperations) { + return elasticsearchOperations.getIndexOperations(); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index 9a25b5ae4..8b0633828 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -29,7 +29,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -53,12 +52,10 @@ static class Config {} @Autowired private ComplexElasticsearchRepository complexRepository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SampleEntity.class); } @@ -80,8 +77,8 @@ public void shouldExecuteComplexCustomMethod() { } @Data - @Document(indexName = "test-index-sample-repositories-complex-custommethod-autowiring", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-sample-repositories-complex-custommethod-autowiring", replicas = 0, + refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java index e38055272..86944a0f1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java @@ -29,7 +29,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -52,12 +51,10 @@ static class Config {} @Autowired private ComplexElasticsearchRepositoryManualWiring complexRepository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SampleEntity.class); } @@ -79,8 +76,7 @@ public void shouldExecuteComplexCustomMethod() { } @Data - @Document(indexName = "test-index-sample-repository-manual-wiring", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-repository-manual-wiring", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 20fc5752d..0c514d5fa 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -49,7 +49,6 @@ import org.springframework.data.elasticsearch.annotations.Highlight; import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.Query; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; @@ -80,12 +79,10 @@ public abstract class CustomMethodRepositoryBaseTests { @Autowired private SampleStreamingCustomMethodRepository streamingRepository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index 2e8705f6d..544fe2e27 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -30,7 +30,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -57,12 +56,10 @@ static class Config {} @Autowired private DoubleIDRepository repository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, DoubleIDEntity.class); } @@ -121,8 +118,7 @@ public void shouldSaveDocument() { * @author Mohsin Husen */ - @Document(indexName = "test-index-double-keyed-entity", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-double-keyed-entity", replicas = 0, refreshInterval = "-1") static class DoubleIDEntity { @Id private Double id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 1b2527678..469b25186 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -26,7 +26,6 @@ import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -57,16 +56,12 @@ public IndexNameProvider indexNameProvider() { @Autowired private DynamicIndexRepository repository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @Autowired private IndexNameProvider indexNameProvider; @BeforeEach public void init() { - - indexOperations = operations.getIndexOperations(); - deleteIndexes(); indexOperations.createIndex("index1"); indexOperations.createIndex("index2"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 008efcbe5..5f20dbb99 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -35,7 +35,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -63,15 +62,12 @@ public class SpringDataGeoRepositoryTests { @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} - @Autowired ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @Autowired SpringDataGeoRepository repository; @BeforeEach public void init() { - - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, GeoEntity.class); } @@ -121,8 +117,7 @@ private double[] toGeoArray(Point point) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-geo-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-geo-repository", replicas = 0, refreshInterval = "-1") static class GeoEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index 8a9c20e8f..8a3f5ae88 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -30,7 +30,6 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -57,12 +56,10 @@ static class Config {} @Autowired private IntegerIDRepository repository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, IntegerIDEntity.class); } @@ -121,8 +118,7 @@ public void shouldSaveDocument() { * @author Mohsin Husen */ - @Document(indexName = "test-index-integer-keyed-entity", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-integer-keyed-entity", replicas = 0, refreshInterval = "-1") static class IntegerIDEntity { @Id private Integer id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index 18ad8941d..0118ba8dd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -41,7 +41,6 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -66,12 +65,10 @@ static class Config {} @Autowired private SampleElasticSearchBookRepository bookRepository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, Book.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index ed97872ac..0d8e38bc4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -61,13 +61,12 @@ public class DynamicSettingAndMappingEntityRepositoryTests { static class Config {} @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @Autowired private DynamicSettingAndMappingEntityRepository repository; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, DynamicSettingAndMappingEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index 77931653f..267b6ce0d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -52,15 +52,11 @@ public class FieldDynamicMappingEntityRepositoryTests { @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} - @Autowired private FieldDynamicMappingEntityRepository repository; - @Autowired private ElasticsearchOperations operations; - - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, FieldDynamicMappingEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 243e2e09d..8ac6c018b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -55,11 +55,10 @@ static class Config {} @Autowired private SpELRepository repository; @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SpELEntity.class); } @@ -103,8 +102,7 @@ public void shouldSupportSpelInType() { * * @author Artur Konczak */ - @Document(indexName = "#{'test-index-abz'+'-'+'entity'}", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "#{'test-index-abz'+'-'+'entity'}", replicas = 0, refreshInterval = "-1") static class SpELEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 46aff078e..1da59ef11 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -60,11 +60,10 @@ static class Config {} @Autowired private SynonymRepository repository; @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SynonymEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index 4a632268e..f70facbf6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -45,7 +45,6 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -77,12 +76,10 @@ static class Config {} @Autowired private SampleUUIDKeyedElasticsearchRepository repository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SampleEntityUUIDKeyed.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index 4cd0fb8be..cac633f21 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -37,7 +37,6 @@ 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.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -66,13 +65,10 @@ static class Config {} @Autowired private ProductRepository repository; - @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); - IndexInitializer.init(indexOperations, Product.class); Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false) @@ -275,8 +271,7 @@ void shouldDeleteWithNullValues() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-product-query-keywords", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-product-query-keywords", replicas = 0, refreshInterval = "-1") static class Product { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 894719fc6..ef31e8434 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -81,11 +81,10 @@ static class Config {} @Autowired private SampleElasticsearchRepository repository; @Autowired private ElasticsearchOperations operations; - private IndexOperations indexOperations; + @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations = operations.getIndexOperations(); IndexInitializer.init(indexOperations, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java index cb3513d21..9cd564bcb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java @@ -36,11 +36,11 @@ private IndexInitializer() {} */ @Deprecated public static void init(ElasticsearchOperations operations, Class clazz) { - - operations.getIndexOperations().deleteIndex(clazz); - operations.getIndexOperations().createIndex(clazz); - operations.getIndexOperations().putMapping(clazz); - operations.getIndexOperations().refresh(clazz); + IndexOperations indexOperations = operations.getIndexOperations(); + indexOperations.deleteIndex(clazz); + indexOperations.createIndex(clazz); + indexOperations.putMapping(clazz); + indexOperations.refresh(clazz); } /** @@ -50,7 +50,6 @@ public static void init(ElasticsearchOperations operations, Class clazz) { * @param clazz */ public static void init(IndexOperations operations, Class clazz) { - operations.deleteIndex(clazz); operations.createIndex(clazz); operations.putMapping(clazz); From d7262e43701b499d9880b51ebeb767963be60cab Mon Sep 17 00:00:00 2001 From: alesharik Date: Mon, 13 Jan 2020 22:26:19 +0300 Subject: [PATCH 0043/1191] DATAES-623 - Add bulk operations for ReactiveElasticsearchRepository. Original PR:#376 --- .../core/ReactiveDocumentOperations.java | 67 +++++++- .../core/ReactiveElasticsearchTemplate.java | 156 +++++++++++++++--- .../ElasticsearchEntityInformation.java | 4 + ...SimpleReactiveElasticsearchRepository.java | 49 +++++- .../ReactiveElasticsearchTemplateTests.java | 145 ++++++++++++---- 5 files changed, 354 insertions(+), 67 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 8a7e73be7..41df2a9f0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -16,16 +16,23 @@ package org.springframework.data.elasticsearch.core; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.util.Assert; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; -import org.springframework.util.Assert; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; /** * The reactive operations for the * Elasticsearch Document APIs. * * @author Peter-Josef Meisch + * @author Aleksei Arsenev * @since 4.0 */ public interface ReactiveDocumentOperations { @@ -78,6 +85,64 @@ default Mono save(Mono entityPublisher, IndexCoordinates ind */ Mono save(T entity, IndexCoordinates index); + /** + * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is + * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. + * + * @param entities must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Flux} emitting saved entities. + * @since 4.0 + */ + default Flux saveAll(Iterable entities, IndexCoordinates index) { + List entityList = new ArrayList<>(); + entities.forEach(entityList::add); + return saveAll(Mono.just(entityList), index); + } + + /** + * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is + * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. + * + * @param entities must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return a {@link Flux} emitting saved entities. + * @since 4.0 + */ + Flux saveAll(Mono> entities, IndexCoordinates index); + + /** + * Execute a multiGet against elasticsearch for the given ids. + * + * @param query the query defining the ids of the objects to get + * @param clazz the type of the object to be returned + * @param index the index(es) from which the objects are read. + * @return flux with list of nullable objects + * @since 4.0 + */ + Flux multiGet(Query query, Class clazz, IndexCoordinates index); + + /** + * Bulk update all objects. Will do update. + * + * @param queries the queries to execute in bulk + * @since 4.0 + */ + default Mono bulkUpdate(List queries, IndexCoordinates index) { + return bulkUpdate(queries, BulkOptions.defaultOptions(), index); + } + + /** + * Bulk update all objects. Will do update. + * + * @param queries the queries to execute in bulk + * @param bulkOptions options to be added to the bulk request + * @since 4.0 + */ + Mono bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index); + /** * Find the document with the given {@literal id} mapped onto the given {@literal entityType}. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index ae2357c78..e36c1a473 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -15,17 +15,12 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.index.VersionType.*; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.SearchRequest; @@ -48,26 +43,32 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.NoSuchIndexException; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity; import org.springframework.data.elasticsearch.core.EntityOperations.Entity; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; -import org.springframework.data.elasticsearch.core.query.CriteriaQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.elasticsearch.index.VersionType.EXTERNAL; /** * @author Christoph Strobl @@ -76,6 +77,7 @@ * @author Martin Choraine * @author Peter-Josef Meisch * @author Mathias Teier + * @author Aleksei Arsenev * @since 3.2 */ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations { @@ -135,6 +137,60 @@ public Mono save(T entity) { return save(entity, getIndexCoordinatesFor(entity.getClass())); } + @Override + public Flux saveAll(Mono> entities, IndexCoordinates index) { + + Assert.notNull(entities, "Entities must not be null!"); + + return entities.flatMapMany(entityList -> { + + List> adaptibleEntities = entityList.stream() // + .map(e -> operations.forEntity(e, converter.getConversionService())) // + .collect(Collectors.toList()); + Iterator> iterator = adaptibleEntities.iterator(); + List indexRequests = adaptibleEntities.stream() // + .map(e -> getIndexQuery(e.getBean(), e)) // + .collect(Collectors.toList()); + return doBulkOperation(indexRequests, BulkOptions.defaultOptions(), index) // + .map(bulkItemResponse -> { + + AdaptibleEntity mappedEntity = iterator.next(); + mappedEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); + return mappedEntity.getBean(); + }); + }); + } + + @Override + public Flux multiGet(Query query, Class clazz, IndexCoordinates index) { + + Assert.notNull(index, "Index must not be null"); + Assert.notNull(clazz, "Class must not be null"); + Assert.notNull(query, "Query must not be null"); + Assert.notEmpty(query.getIds(), "No Id define for Query"); + + MultiGetRequest request = requestFactory.multiGetRequest(query, index); + return Flux.from(execute(client -> client.multiGet(request))) // + .handle((result, sink) -> { + + Document document = DocumentAdapters.from(result); + T entity = converter.mapDocument(document, clazz); + if (entity != null) { + sink.next(entity); + } + }); + } + + @Override + public Mono bulkUpdate(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + + Assert.notNull(queries, "List of UpdateQuery must not be null"); + Assert.notNull(bulkOptions, "BulkOptions must not be null"); + Assert.notNull(index, "Index must not be null"); + + return doBulkOperation(queries, bulkOptions, index).then(); + } + /** * Customization hook on the actual execution result {@link Publisher}.
* You know what you're doing here? Well fair enough, go ahead on your own risk. @@ -146,6 +202,33 @@ protected Mono doIndex(IndexRequest request) { return Mono.from(execute(client -> client.index(request))); } + protected Flux doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + BulkRequest bulkRequest = prepareWriteRequest(requestFactory.bulkRequest(queries, bulkOptions, index)); + return client.bulk(bulkRequest) // + .onErrorMap(e -> new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e)) // + .flatMap(this::checkForBulkOperationFailure) // + .flatMapMany(response -> Flux.fromArray(response.getItems())); + } + + protected Mono checkForBulkOperationFailure(BulkResponse bulkResponse) { + + if (bulkResponse.hasFailures()) { + Map failedDocuments = new HashMap<>(); + for (BulkItemResponse item : bulkResponse.getItems()) { + if (item.isFailed()) { + failedDocuments.put(item.getId(), item.getFailureMessage()); + } + } + ElasticsearchException exception = new ElasticsearchException( + "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + + failedDocuments + ']', + failedDocuments); + return Mono.error(exception); + } else { + return Mono.just(bulkResponse); + } + } + /** * Customization hook on the actual execution result {@link Publisher}.
* @@ -178,27 +261,46 @@ protected Mono doExists(GetRequest request) { private Mono doIndex(Object value, AdaptibleEntity entity, IndexCoordinates index) { return Mono.defer(() -> { + IndexRequest request = getIndexRequest(value, entity, index); + request = prepareIndexRequest(value, request); + return doIndex(request); + }); + } - Object id = entity.getId(); + private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, IndexCoordinates index) { + Object id = entity.getId(); - IndexRequest request = id != null - ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) - : new IndexRequest(index.getIndexName()); + IndexRequest request = id != null + ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) + : new IndexRequest(index.getIndexName()); - request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); + request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); - if (entity.isVersionedEntity()) { + if (entity.isVersionedEntity()) { - Object version = entity.getVersion(); - if (version != null) { - request.version(((Number) version).longValue()); - request.versionType(EXTERNAL); - } + Number version = entity.getVersion(); + if (version != null) { + request.version(version.longValue()); + request.versionType(EXTERNAL); } + } + return request; + } - request = prepareIndexRequest(value, request); - return doIndex(request); - }); + private IndexQuery getIndexQuery(Object value, AdaptibleEntity entity) { + Object id = entity.getId(); + IndexQuery query = new IndexQuery(); + if (id != null) { + query.setId(id.toString()); + } + query.setObject(value); + if (entity.isVersionedEntity()) { + Number version = entity.getVersion(); + if (version != null) { + query.setVersion(version.longValue()); + } + } + return query; } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java index 3f529ba0e..e2f57275c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java @@ -18,6 +18,7 @@ import org.elasticsearch.index.VersionType; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.core.EntityInformation; +import org.springframework.lang.Nullable; /** * @param @@ -27,6 +28,7 @@ * @author Christoph Strobl * @author Ivan Greene * @author Peter-Josef Meisch + * @author Aleksei Arsenev */ public interface ElasticsearchEntityInformation extends EntityInformation { @@ -34,9 +36,11 @@ public interface ElasticsearchEntityInformation extends EntityInformation IndexCoordinates getIndexCoordinates(); + @Nullable Long getVersion(T entity); VersionType getVersionType(); + @Nullable String getParentId(T entity); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index bc88bc301..1b4d8f4dd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -15,21 +15,25 @@ */ package org.springframework.data.elasticsearch.repository.support; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - +import org.elasticsearch.index.query.QueryBuilders; import org.reactivestreams.Publisher; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.util.Assert; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; /** * @author Christoph Strobl * @author Peter-Josef Meisch + * @author Aleksei Arsenev * @since 3.2 */ public class SimpleReactiveElasticsearchRepository implements ReactiveElasticsearchRepository { @@ -65,7 +69,9 @@ public Flux saveAll(Iterable entities) { public Flux saveAll(Publisher entityStream) { Assert.notNull(entityStream, "EntityStream must not be null!"); - return Flux.from(entityStream).flatMap(this::save); + + return elasticsearchOperations + .saveAll(Flux.from(entityStream).collectList(), entityInformation.getIndexCoordinates()); } @Override @@ -117,14 +123,22 @@ public Flux findAllById(Iterable ids) { Assert.notNull(ids, "Ids must not be null!"); - return Flux.fromIterable(ids).flatMap(this::findById); + return findAllById(Flux.fromIterable(ids)); } @Override public Flux findAllById(Publisher idStream) { Assert.notNull(idStream, "IdStream must not be null!"); - return Flux.from(idStream).buffer().flatMap(this::findAllById); + return Flux.from(idStream) // + .map(ID::toString) // + .collectList() // + .map(ids -> new NativeSearchQueryBuilder().withIds(ids).build()) // + .flatMapMany(query -> { + + IndexCoordinates index = entityInformation.getIndexCoordinates(); + return elasticsearchOperations.multiGet(query, entityInformation.getJavaType(), index); + }); } @Override @@ -169,7 +183,28 @@ public Mono deleteAll(Iterable entities) { public Mono deleteAll(Publisher entityStream) { Assert.notNull(entityStream, "EntityStream must not be null!"); - return Flux.from(entityStream).flatMap(this::delete).then(); + return Flux.from(entityStream) // + .map(entity -> { + + ID id = entityInformation.getId(entity); + if (id == null) { + throw new IllegalStateException("Entity id must not be null!"); + } + return convertId(id); + }) + .collectList() + .map(objects -> { + + return new StringQuery(QueryBuilders.idsQuery() // + .addIds(objects.toArray(new String[0])) // + .toString()); + }) // + .flatMap(query -> { + + return elasticsearchOperations + .deleteBy(query, entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + }) // + .then(); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 1d855e3c6..60a0a37dd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -15,32 +15,9 @@ */ package org.springframework.data.elasticsearch.core; -import static org.assertj.core.api.Assertions.*; -import static org.elasticsearch.index.query.QueryBuilders.*; -import static org.springframework.data.elasticsearch.annotations.FieldType.*; - -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.lang.Long; -import java.lang.Object; -import java.net.ConnectException; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - +import lombok.*; import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.junit.jupiter.api.AfterEach; @@ -56,17 +33,26 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; 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.IndexQuery; -import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.net.ConnectException; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; +import static org.elasticsearch.index.query.QueryBuilders.termQuery; +import static org.springframework.data.elasticsearch.annotations.FieldType.Text; /** * Integration tests for {@link ReactiveElasticsearchTemplate}. @@ -76,6 +62,7 @@ * @author Peter-Josef Meisch * @author Farid Azaza * @author Martin Choraine + * @author Aleksei Arsenev */ @SpringIntegrationTest public class ReactiveElasticsearchTemplateTests { @@ -711,6 +698,100 @@ void shouldReturnSortFields() { .verifyComplete(); } + @Test // DATAES-623 + public void shouldReturnObjectsForGivenIdsUsingMultiGet() { + SampleEntity entity1 = randomEntity("test message 1"); + entity1.rate = 1; + index(entity1); + SampleEntity entity2 = randomEntity("test message 2"); + entity2.rate = 2; + index(entity2); + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withIds(Arrays.asList(entity1.getId(), entity2.getId())) // + .build(); + + template.multiGet(query, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNext(entity1, entity2) // + .verifyComplete(); + } + + @Test // DATAES-623 + public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { + SampleEntity entity1 = randomEntity("test message 1"); + entity1.rate = 1; + index(entity1); + SampleEntity entity2 = randomEntity("test message 2"); + entity2.rate = 2; + index(entity2); + + NativeSearchQuery query = new NativeSearchQueryBuilder() // + .withIds(Arrays.asList(entity1.getId(), entity2.getId())) // + .withFields("message") // + .build(); + + template.multiGet(query, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNextCount(2) // + .verifyComplete(); + } + + @Test // DATAES-623 + public void shouldDoBulkUpdate() { + SampleEntity entity1 = randomEntity("test message 1"); + entity1.rate = 1; + index(entity1); + SampleEntity entity2 = randomEntity("test message 2"); + entity2.rate = 2; + index(entity2); + + IndexRequest indexRequest1 = new IndexRequest(); + indexRequest1.source("message", "updated 1"); + UpdateQuery updateQuery1 = new UpdateQueryBuilder() // + .withId(entity1.getId()) // + .withIndexRequest(indexRequest1).build(); + + IndexRequest indexRequest2 = new IndexRequest(); + indexRequest2.source("message", "updated 2"); + UpdateQuery updateQuery2 = new UpdateQueryBuilder() // + .withId(entity2.getId()) // + .withIndexRequest(indexRequest2).build(); + + List queries = Arrays.asList(updateQuery1, updateQuery2); + template.bulkUpdate(queries, IndexCoordinates.of(DEFAULT_INDEX)).block(); + + NativeSearchQuery getQuery = new NativeSearchQueryBuilder() // + .withIds(Arrays.asList(entity1.getId(), entity2.getId())) // + .build(); + template.multiGet(getQuery, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNextMatches(entity -> entity.getMessage().equals("updated 1")) // + .expectNextMatches(entity -> entity.getMessage().equals("updated 2")) // + .verifyComplete(); + } + + @Test // DATAES-623 + void shouldSaveAll() { + SampleEntity entity1 = randomEntity("test message 1"); + entity1.rate = 1; + SampleEntity entity2 = randomEntity("test message 2"); + entity2.rate = 2; + + template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNext(entity1) // + .expectNext(entity2) // + .verifyComplete(); + + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + template.search(searchQuery, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNextMatches(hit -> entity1.equals(hit.getContent()) || entity2.equals(hit.getContent())) // + .expectNextMatches(hit -> entity1.equals(hit.getContent()) || entity2.equals(hit.getContent())) // + .verifyComplete(); + } + @Data @Document(indexName = "marvel") static class Person { From e5ec8fdab392ee892dd226399155b82b486ec40a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 13 Jan 2020 20:35:03 +0100 Subject: [PATCH 0044/1191] DATAES-623 - Polishing. --- .../core/ReactiveDocumentOperations.java | 12 +++-- .../core/ReactiveElasticsearchTemplate.java | 46 +++++++++++------ ...SimpleReactiveElasticsearchRepository.java | 17 +++---- .../ReactiveElasticsearchTemplateTests.java | 49 +++++++++++++------ 4 files changed, 79 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 41df2a9f0..d0c8b353e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -15,11 +15,6 @@ */ package org.springframework.data.elasticsearch.core; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.UpdateQuery; -import org.springframework.util.Assert; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -27,6 +22,12 @@ import java.util.Collection; import java.util.List; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.util.Assert; + /** * The reactive operations for the * Elasticsearch Document APIs. @@ -230,6 +231,7 @@ default Mono deleteById(String id, IndexCoordinates index) { * @return a {@link Mono} emitting the {@literal id} of the removed document. */ Mono deleteById(String id, Class entityType, IndexCoordinates index); + /** * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index e36c1a473..8c5826362 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -15,6 +15,20 @@ */ package org.springframework.data.elasticsearch.core; +import static org.elasticsearch.index.VersionType.*; + +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; @@ -57,18 +71,17 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import java.util.*; -import java.util.stream.Collectors; - -import static org.elasticsearch.index.VersionType.EXTERNAL; /** * @author Christoph Strobl @@ -165,8 +178,8 @@ public Flux saveAll(Mono> entities, Ind public Flux multiGet(Query query, Class clazz, IndexCoordinates index) { Assert.notNull(index, "Index must not be null"); - Assert.notNull(clazz, "Class must not be null"); - Assert.notNull(query, "Query must not be null"); + Assert.notNull(clazz, "Class must not be null"); + Assert.notNull(query, "Query must not be null"); Assert.notEmpty(query.getIds(), "No Id define for Query"); MultiGetRequest request = requestFactory.multiGetRequest(query, index); @@ -186,7 +199,7 @@ public Mono bulkUpdate(List queries, BulkOptions bulkOptions, Assert.notNull(queries, "List of UpdateQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - Assert.notNull(index, "Index must not be null"); + Assert.notNull(index, "Index must not be null"); return doBulkOperation(queries, bulkOptions, index).then(); } @@ -215,9 +228,10 @@ protected Mono checkForBulkOperationFailure(BulkResponse bulkRespo if (bulkResponse.hasFailures()) { Map failedDocuments = new HashMap<>(); for (BulkItemResponse item : bulkResponse.getItems()) { + if (item.isFailed()) { - failedDocuments.put(item.getId(), item.getFailureMessage()); - } + failedDocuments.put(item.getId(), item.getFailureMessage()); + } } ElasticsearchException exception = new ElasticsearchException( "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" @@ -270,8 +284,7 @@ private Mono doIndex(Object value, AdaptibleEntity entity, Ind private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, IndexCoordinates index) { Object id = entity.getId(); - IndexRequest request = id != null - ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) + IndexRequest request = id != null ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) : new IndexRequest(index.getIndexName()); request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); @@ -279,6 +292,7 @@ private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, In if (entity.isVersionedEntity()) { Number version = entity.getVersion(); + if (version != null) { request.version(version.longValue()); request.versionType(EXTERNAL); @@ -294,8 +308,10 @@ private IndexQuery getIndexQuery(Object value, AdaptibleEntity entity) { query.setId(id.toString()); } query.setObject(value); + if (entity.isVersionedEntity()) { Number version = entity.getVersion(); + if (version != null) { query.setVersion(version.longValue()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index 1b4d8f4dd..9de865e0a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -15,6 +15,9 @@ */ package org.springframework.data.elasticsearch.repository.support; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + import org.elasticsearch.index.query.QueryBuilders; import org.reactivestreams.Publisher; import org.springframework.data.domain.Pageable; @@ -27,8 +30,6 @@ import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.util.Assert; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; /** * @author Christoph Strobl @@ -70,8 +71,8 @@ public Flux saveAll(Publisher entityStream) { Assert.notNull(entityStream, "EntityStream must not be null!"); - return elasticsearchOperations - .saveAll(Flux.from(entityStream).collectList(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations.saveAll(Flux.from(entityStream).collectList(), + entityInformation.getIndexCoordinates()); } @Override @@ -191,9 +192,7 @@ public Mono deleteAll(Publisher entityStream) { throw new IllegalStateException("Entity id must not be null!"); } return convertId(id); - }) - .collectList() - .map(objects -> { + }).collectList().map(objects -> { return new StringQuery(QueryBuilders.idsQuery() // .addIds(objects.toArray(new String[0])) // @@ -201,8 +200,8 @@ public Mono deleteAll(Publisher entityStream) { }) // .flatMap(query -> { - return elasticsearchOperations - .deleteBy(query, entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); + return elasticsearchOperations.deleteBy(query, entityInformation.getJavaType(), + entityInformation.getIndexCoordinates()); }) // .then(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 60a0a37dd..f560315c6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -15,7 +15,30 @@ */ package org.springframework.data.elasticsearch.core; -import lombok.*; +import static org.assertj.core.api.Assertions.*; +import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.springframework.data.elasticsearch.annotations.FieldType.*; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import java.lang.Long; +import java.lang.Object; +import java.net.ConnectException; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.search.sort.FieldSortBuilder; @@ -35,24 +58,18 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import java.net.ConnectException; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery; -import static org.elasticsearch.index.query.QueryBuilders.termQuery; -import static org.springframework.data.elasticsearch.annotations.FieldType.Text; /** * Integration tests for {@link ReactiveElasticsearchTemplate}. From 9e5a828342cc5ba46d7cfa7bc3bbda72464c378c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 14 Jan 2020 14:50:04 +0100 Subject: [PATCH 0045/1191] DATAES-690 - Polishing. Revert parent pom version to 2.3.0.BUILD-SNAPSHOT. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7d8a6880b..d790d6756 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.JDK11-SNAPSHOT + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch From 28d31fbb07a82f968085963e8885c7e1c5c92a8f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 15 Jan 2020 10:24:58 +0100 Subject: [PATCH 0046/1191] DATAES-703 - Updated changelog. --- src/main/resources/changelog.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 7488d2037..70d8b80b4 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,12 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.15.RELEASE (2020-01-15) +---------------------------------------------- +* DATAES-725 - Update copyright years to 2020. +* DATAES-703 - Release 3.1.15 (Lovelace SR15). + + Changes in version 3.2.3.RELEASE (2019-12-04) --------------------------------------------- * DATAES-700 - Enable proxy support for RestClient. @@ -924,3 +930,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) * #6 - spirng-data-elasticsearch with elasticsearch-river-mongodb + From fe0359f40bd175728613d2bca8c317d5db8e614e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 15 Jan 2020 12:37:16 +0100 Subject: [PATCH 0047/1191] DATAES-704 - Updated changelog. --- src/main/resources/changelog.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 70d8b80b4..ba6dd7f9f 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,15 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.4.RELEASE (2020-01-15) +--------------------------------------------- +* DATAES-725 - Update copyright years to 2020. +* DATAES-720 - SimpleReactiveElasticsearchRepository findAll() returns only 10 elements. +* DATAES-719 - Add customization hook for reactive WebClient. +* DATAES-705 - Add support for PathPrefix to clients in 3.2.x. +* DATAES-704 - Release 3.2.4 (Moore SR4). + + Changes in version 3.1.15.RELEASE (2020-01-15) ---------------------------------------------- * DATAES-725 - Update copyright years to 2020. @@ -931,3 +940,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 2677e39bb1da54d7657fcd44cb4e20578b3f8deb Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 16 Jan 2020 16:05:02 +0100 Subject: [PATCH 0048/1191] DATAES-663 - Updated changelog. --- src/main/resources/changelog.txt | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index ba6dd7f9f..c713197e9 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,60 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.M1 (2020-01-16) +---------------------------------------- +* DATAES-727 - Use track_total_hits parameter for count queries. +* DATAES-725 - Update copyright years to 2020. +* DATAES-724 - Provide IndexOperations bean. +* DATAES-723 - Cleanup ElasticsearchRepository interface. +* DATAES-722 - Return total count relation in the SearchHits object. +* DATAES-721 - Deprecation and Warnings cleanup. +* DATAES-720 - SimpleReactiveElasticsearchRepository findAll() returns only 10 elements. +* DATAES-719 - Add customization hook for reactive WebClient. +* DATAES-718 - Deprecate @Score and scoreProperty. +* DATAES-717 - Enable Repositories to return a SearchHits instance instead of a list. +* DATAES-716 - Add Value mapping to the ElasticsearchMappingConverter. +* DATAES-715 - Highlight results should be returned in the SearchHits. +* DATAES-714 - Sort results should be returned in the SearchHits. +* DATAES-713 - Transfer returned aggregations from the AggregatedPage to the SearchHits. +* DATAES-711 - Update to Elasticsearch 7.5. +* DATAES-709 - Add parameter to include default settings on setting request. +* DATAES-702 - Travis CI builds currently broken. +* DATAES-701 - Enable proxy support for the reactive rest template. +* DATAES-700 - Enable proxy support for RestClient. +* DATAES-697 - Query refactoring cleanup. +* DATAES-693 - Support for source fetching in update operations. +* DATAES-690 - Enable builds on JDK 11+. +* DATAES-688 - Remove unneeded SearchQuery subinterface. +* DATAES-684 - Implement Bulk Request for Reactive. +* DATAES-680 - ReactiveElasticsearchTemplate should use the count API. +* DATAES-677 - Update to Elasticsearch 7.4.1. +* DATAES-676 - fix documentation to reflect the changes in API restructuring. +* DATAES-675 - migrate tests to JUnit 5. +* DATAES-673 - Create a Ssl Rest Client using SslContext and HostnameVerifier. +* DATAES-672 - Introduce SearchHit to enrich an Entity type. +* DATAES-671 - Missing indicesOptions support for scrolling queries. +* DATAES-670 - fix version compatibility matrix in documentation. +* DATAES-666 - Rebase branch 4.0.x onto master and merge it. +* DATAES-665 - Javadoc not deployed. +* DATAES-663 - Release 4.0 M1 (Neumann). +* DATAES-661 - Support track_total_hits request parameter. +* DATAES-659 - Move MappingElasticsearchConverter to correct package. +* DATAES-658 - Update 4.0.x to ES 7.3.2. +* DATAES-654 - Add Junit 5 support. +* DATAES-651 - Fix regression from escaping. +* DATAES-650 - Add support for pathPrefix to ClientConfiguration. +* DATAES-647 - In and NotIn uses should instead of terms-query. +* DATAES-639 - Add ignore_above mapping parameter support. +* DATAES-638 - Remove redundant public modifiers in @MultiField. +* DATAES-637 - Change branch 4.0. to use Elasticsearch 7.3. +* DATAES-635 - Create branch 4.0.x and integrate the changes from the existing 4.x branch. +* DATAES-634 - Rearrange methods in Template API. +* DATAES-633 - Introduce value object to capture index type/index name. +* DATAES-632 - Use single Query type in Template API methods. +* DATAES-631 - Consolidate query objects. + + Changes in version 3.2.4.RELEASE (2020-01-15) --------------------------------------------- * DATAES-725 - Update copyright years to 2020. @@ -941,3 +995,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From fe8d2fe1a27df742925cd4b9003c56be4550740b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 16 Jan 2020 16:05:03 +0100 Subject: [PATCH 0049/1191] DATAES-663 - Prepare 4.0 M1 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index d790d6756..b10fde7ab 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M1 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.1 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M1 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 4cbcc92c9..269e986c5 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 3.2 GA +Spring Data Elasticsearch 4.0 M1 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -8,3 +8,4 @@ This product may include a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. + From 191ce92743dac59dcf5c9575b1377fae5054ca93 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 16 Jan 2020 16:05:23 +0100 Subject: [PATCH 0050/1191] DATAES-663 - Release version 4.0 M1 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b10fde7ab..6c0acfc4d 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.M1 org.springframework.data.build From 86c621de35ccd182132c8e24dbfcc1ce2c62c0ad Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 16 Jan 2020 16:11:54 +0100 Subject: [PATCH 0051/1191] DATAES-663 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6c0acfc4d..b10fde7ab 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.M1 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From bf75f0fab24153de3e2340545b28ceda2005cbfc Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 16 Jan 2020 16:11:55 +0100 Subject: [PATCH 0052/1191] DATAES-663 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index b10fde7ab..d790d6756 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.M1 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.1 2.9.1 - 2.3.0.M1 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 2b5619f17259ff01e736fd07478d82e3f1114126 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 17 Jan 2020 09:38:42 +0100 Subject: [PATCH 0053/1191] DATAES-731 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index c713197e9..fdde3979e 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.M2 (2020-01-17) +---------------------------------------- +* DATAES-731 - Release 4.0 M2 (Neumann). + + Changes in version 4.0.0.M1 (2020-01-16) ---------------------------------------- * DATAES-727 - Use track_total_hits parameter for count queries. @@ -996,3 +1001,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 1f19ac031399ebc077e65e2f26f2c7264bcf4713 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 17 Jan 2020 09:38:43 +0100 Subject: [PATCH 0054/1191] DATAES-731 - Prepare 4.0 M2 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index d790d6756..599297660 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M2 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.1 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M2 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 269e986c5..652d1ee42 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 M1 +Spring Data Elasticsearch 4.0 M2 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -9,3 +9,4 @@ separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. + From 033a6b21dc79b8b3333643fa35c66fb196f9f51c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 17 Jan 2020 09:39:03 +0100 Subject: [PATCH 0055/1191] DATAES-731 - Release version 4.0 M2 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 599297660..9993759fb 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.M2 org.springframework.data.build From 9e3712e41e7bc3613665a4a7e24e7de6836873dc Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 17 Jan 2020 09:47:49 +0100 Subject: [PATCH 0056/1191] DATAES-731 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9993759fb..599297660 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.M2 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From bf13ed919f954aebc6988bc982f5420434bf87a3 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 17 Jan 2020 09:47:50 +0100 Subject: [PATCH 0057/1191] DATAES-731 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 599297660..d790d6756 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.M2 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.1 2.9.1 - 2.3.0.M2 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 37f15853c0ca21382f9dea306f6b3c5336068f36 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 23 Jan 2020 18:03:37 +0100 Subject: [PATCH 0058/1191] DATAES-734 - Add Sort implementation that allows geo distance sorts. Original PR: #382 --- .../reference/elasticsearch-misc.adoc | 14 ++ .../asciidoc/reference/elasticsearch-new.adoc | 1 + .../elasticsearch/core/RequestFactory.java | 34 +++-- .../data/elasticsearch/core/geo/GeoPoint.java | 9 ++ .../core/query/GeoDistanceOrder.java | 126 ++++++++++++++++++ .../core/CriteriaQueryMappingTests.java | 6 +- .../core/RequestFactoryTest.java | 111 +++++++++++++++ .../CustomMethodRepositoryBaseTests.java | 36 +++++ 8 files changed, 325 insertions(+), 12 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/GeoDistanceOrder.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index d35522f75..1cba145e2 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -80,3 +80,17 @@ while (stream.hasNext()) { } ---- ==== + +[[elasticsearch.misc.sorts]] +== Sort options + +In addition to the default sort options described <> Spring Data Elasticsearch has a `GeoDistanceOrder` class which can be used to have the result of a search operation ordered by geographical distance. + +If the class to be retrieved has a `GeoPoint` property named _location_, the following `Sort` would sort the results by distance to the given point: + +[source,java] +---- +Sort.by(new GeoDistanceOrder("location", new GeoPoint(48.137154, 11.5761247))) +---- + + diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 807d3d62d..7f4720779 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -12,6 +12,7 @@ * Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules. * Introduction of `SearchHit` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_). * Introduction of the `SearchHits` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_). +* Introduction of the `GeoDistanceOrder` class to be able to create sorting by geographical distance [[new-features.3-2-0]] == New in Spring Data Elasticsearch 3.2 diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index e2ffaa038..2af47e775 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -41,6 +41,8 @@ import org.elasticsearch.client.Requests; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.PutMappingRequest; +import org.elasticsearch.common.geo.GeoDistance; +import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentType; @@ -56,9 +58,11 @@ import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; +import org.elasticsearch.search.sort.GeoDistanceSortBuilder; import org.elasticsearch.search.sort.ScoreSortBuilder; import org.elasticsearch.search.sort.SortBuilder; import org.elasticsearch.search.sort.SortBuilders; +import org.elasticsearch.search.sort.SortMode; import org.elasticsearch.search.sort.SortOrder; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; @@ -771,17 +775,29 @@ private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchP : null; String fieldName = property != null ? property.getFieldName() : order.getProperty(); - FieldSortBuilder sort = SortBuilders // - .fieldSort(fieldName) // - .order(sortOrder); + if (order instanceof GeoDistanceOrder) { + GeoDistanceOrder geoDistanceOrder = (GeoDistanceOrder) order; - if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { - sort.missing("_first"); - } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { - sort.missing("_last"); - } + GeoDistanceSortBuilder sort = SortBuilders.geoDistanceSort(fieldName, geoDistanceOrder.getGeoPoint().getLat(), + geoDistanceOrder.getGeoPoint().getLon()); - return sort; + sort.geoDistance(GeoDistance.fromString(geoDistanceOrder.getDistanceType().name())); + sort.ignoreUnmapped(geoDistanceOrder.getIgnoreUnmapped()); + sort.sortMode(SortMode.fromString(geoDistanceOrder.getMode().name())); + sort.unit(DistanceUnit.fromString(geoDistanceOrder.getUnit())); + return sort; + } else { + FieldSortBuilder sort = SortBuilders // + .fieldSort(fieldName) // + .order(sortOrder); + + if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { + sort.missing("_first"); + } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { + sort.missing("_last"); + } + return sort; + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java index 248ec12cf..5d2c33a70 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java @@ -22,6 +22,7 @@ * * @author Franck Marchand * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class GeoPoint { @@ -58,6 +59,14 @@ public static GeoPoint fromPoint(Point point) { public static Point toPoint(GeoPoint point) { return new Point(point.getLat(), point.getLon()); } + + @Override + public String toString() { + return "GeoPoint{" + + "lat=" + lat + + ", lon=" + lon + + '}'; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/GeoDistanceOrder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/GeoDistanceOrder.java new file mode 100644 index 000000000..b3c436f2f --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/GeoDistanceOrder.java @@ -0,0 +1,126 @@ +/* + * Copyright 2020 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.query; + +import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.core.geo.GeoPoint; + +/** + * {@link org.springframework.data.domain.Sort.Order} derived class to be able to define a _geo_distance order for a + * search. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class GeoDistanceOrder extends Sort.Order { + + private static final DistanceType DEFAULT_DISTANCE_TYPE = DistanceType.arc; + private static final Mode DEFAULT_MODE = Mode.min; + private static final String DEFAULT_UNIT = "m"; + private static final Boolean DEFAULT_IGNORE_UNMAPPED = false; + + private final GeoPoint geoPoint; + private final DistanceType distanceType; + private final Mode mode; + private final String unit; + private final Boolean ignoreUnmapped; + + public GeoDistanceOrder(String property, GeoPoint geoPoint) { + this(property, geoPoint, Sort.Direction.ASC, DEFAULT_DISTANCE_TYPE, DEFAULT_MODE, DEFAULT_UNIT, + DEFAULT_IGNORE_UNMAPPED); + } + + private GeoDistanceOrder(String property, GeoPoint geoPoint, Sort.Direction direction, DistanceType distanceType, + Mode mode, String unit, Boolean ignoreUnmapped) { + super(direction, property); + this.geoPoint = geoPoint; + this.distanceType = distanceType; + this.mode = mode; + this.unit = unit; + this.ignoreUnmapped = ignoreUnmapped; + } + + public GeoPoint getGeoPoint() { + return geoPoint; + } + + public DistanceType getDistanceType() { + return distanceType; + } + + public Mode getMode() { + return mode; + } + + public String getUnit() { + return unit; + } + + public Boolean getIgnoreUnmapped() { + return ignoreUnmapped; + } + + @Override + public GeoDistanceOrder withProperty(String property) { + return new GeoDistanceOrder(property, getGeoPoint(), getDirection(), getDistanceType(), getMode(), getUnit(), + getIgnoreUnmapped()); + } + + @Override + public GeoDistanceOrder with(Sort.Direction direction) { + return new GeoDistanceOrder(getProperty(), getGeoPoint(), direction, getDistanceType(), getMode(), getUnit(), + getIgnoreUnmapped()); + } + + @Override + public GeoDistanceOrder with(Sort.NullHandling nullHandling) { + throw new UnsupportedOperationException("null handling is not supported for _geo_distance sorts"); + } + + public GeoDistanceOrder with(DistanceType distanceType) { + return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), distanceType, getMode(), getUnit(), + getIgnoreUnmapped()); + } + + public GeoDistanceOrder with(Mode mode) { + return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), mode, getUnit(), + getIgnoreUnmapped()); + } + + public GeoDistanceOrder withUnit(String unit) { + return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), getMode(), unit, + getIgnoreUnmapped()); + } + + public GeoDistanceOrder withIgnoreUnmapped(Boolean ignoreUnmapped) { + return new GeoDistanceOrder(getProperty(), getGeoPoint(), getDirection(), getDistanceType(), getMode(), getUnit(), + ignoreUnmapped); + } + + @Override + public String toString() { + return "GeoDistanceOrder{" + "geoPoint=" + geoPoint + ", distanceType=" + distanceType + ", mode=" + mode + + ", unit='" + unit + '\'' + ", ignoreUnmapped=" + ignoreUnmapped + "} " + super.toString(); + } + + public enum DistanceType { + arc, plane + } + + public enum Mode { + min, max, median, avg + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java index 0a39f55a6..6fe403e81 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -36,7 +36,7 @@ /** * Tests for the mapping of {@link CriteriaQuery} by a * {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. In the same package as - * {@link CriteriaQueryProcessor} as this is needed to get the String represenation to assert. + * {@link CriteriaQueryProcessor} as this is needed to get the String representation to assert. * * @author Peter-Josef Meisch */ @@ -59,8 +59,8 @@ void setUp() { void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException { // use POJO properties and types in the query building - CriteriaQuery criteriaQuery = new CriteriaQuery( - new Criteria("birthDate").between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28))); + CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("birthDate") + .between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28))); // mapped field name and converted parameter String expected = '{' + // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java new file mode 100644 index 000000000..ddd144944 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2020 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; + +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import java.util.Collections; + +import org.json.JSONException; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.annotation.Id; +import org.springframework.data.domain.Sort; +import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; + +/** + * @author Peter-Josef Meisch + */ +class RequestFactoryTest { + + private static RequestFactory requestFactory; + private static MappingElasticsearchConverter converter; + + @BeforeAll + + static void setUpAll() { + SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext(); + mappingContext.setInitialEntitySet(Collections.singleton(Person.class)); + mappingContext.afterPropertiesSet(); + + converter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService()); + converter.afterPropertiesSet(); + + requestFactory = new RequestFactory((converter)); + } + + @Test // FPI-734 + void shouldBuildSearchWithGeoSortSort() throws JSONException { + CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith")); + Sort sort = Sort.by(new GeoDistanceOrder("location", new GeoPoint(49.0, 8.4))); + query.addSort(sort); + + converter.updateQuery(query, Person.class); + + String expected = '{' + // + " \"query\": {" + // + " \"bool\": {" + // + " \"must\": [" + // + " {" + // + " \"query_string\": {" + // + " \"query\": \"Smith\"," + // + " \"fields\": [" + // + " \"first-name^1.0\"" + // + " ]" + // + " }" + // + " }" + // + " ]" + // + " }" + // + " }," + // + " \"sort\": [" + // + " {" + // + " \"_geo_distance\": {" + // + " \"current-location\": [" + // + " {" + // + " \"lat\": 49.0," + // + " \"lon\": 8.4" + // + " }" + // + " ]," + // + " \"unit\": \"m\"," + // + " \"distance_type\": \"arc\"," + // + " \"order\": \"asc\"," + // + " \"mode\": \"min\"," + // + " \"ignore_unmapped\": false" + // + " }" + // + " }" + // + " ]" + // + '}'; + + String searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")).source() + .toString(); + + assertEquals(expected, searchRequest, false); + } + + static class Person { + @Id String id; + @Field(name = "last-name") String lastName; + @Field(name = "current-location") GeoPoint location; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 0c514d5fa..75f0e044b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -54,6 +54,7 @@ import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.utils.IndexInitializer; @@ -1441,6 +1442,40 @@ void shouldReturnHighlightsOnAnnotatedStringQueryMethod() { assertThat(searchHit.getHighlightField("type")).hasSize(1).contains("abc"); } + @Test // DATAES-734 + void shouldUseGeoSortParameter() { + GeoPoint munich = new GeoPoint(48.137154, 11.5761247); + GeoPoint berlin = new GeoPoint(52.520008, 13.404954); + GeoPoint vienna = new GeoPoint(48.20849, 16.37208); + GeoPoint oslo = new GeoPoint(59.9127, 10.7461); + + List entities = new ArrayList<>(); + + SampleEntity entity1 = new SampleEntity(); + entity1.setId("berlin"); + entity1.setLocation(berlin); + entities.add(entity1); + + SampleEntity entity2 = new SampleEntity(); + entity2.setId("vienna"); + entity2.setLocation(vienna); + entities.add(entity2); + + SampleEntity entity3 = new SampleEntity(); + entity3.setId("oslo"); + entity3.setLocation(oslo); + entities.add(entity3); + + repository.saveAll(entities); + + SearchHits searchHits = repository.searchBy(Sort.by(new GeoDistanceOrder("location", munich))); + + assertThat(searchHits.getTotalHits()).isEqualTo(3); + assertThat(searchHits.getSearchHit(0).getId()).isEqualTo("vienna"); + assertThat(searchHits.getSearchHit(1).getId()).isEqualTo("berlin"); + assertThat(searchHits.getSearchHit(2).getId()).isEqualTo("oslo"); + } + private List createSampleEntities(String type, int numberOfEntities) { List entities = new ArrayList<>(); @@ -1588,6 +1623,7 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository> readByMessage(String message); + SearchHits searchBy(Sort sort); } /** From 13761b073a252fb2371ddb883ded2f296587894e Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 25 Jan 2020 18:54:51 +0100 Subject: [PATCH 0059/1191] DATAES-449 - Pass route parameter to created search request. Original PR: #383 --- .../data/elasticsearch/core/RequestFactory.java | 8 ++++++++ .../elasticsearch/core/RequestFactoryTest.java | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 2af47e775..021673938 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -560,6 +560,10 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz sourceBuilder.trackTotalHits(query.getTrackTotalHits()); } + if (StringUtils.hasLength(query.getRoute())) { + request.routing(query.getRoute()); + } + request.source(sourceBuilder); return request; } @@ -726,6 +730,10 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli searchRequestBuilder.setTrackTotalHits(query.getTrackTotalHits()); } + if (StringUtils.hasLength(query.getRoute())) { + searchRequestBuilder.setRouting(query.getRoute()); + } + return searchRequestBuilder; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java index ddd144944..693f8ad0a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java @@ -15,10 +15,12 @@ */ package org.springframework.data.elasticsearch.core; +import static org.assertj.core.api.Assertions.*; import static org.skyscreamer.jsonassert.JSONAssert.*; import java.util.Collections; +import org.elasticsearch.action.search.SearchRequest; import org.json.JSONException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -103,6 +105,18 @@ void shouldBuildSearchWithGeoSortSort() throws JSONException { assertEquals(expected, searchRequest, false); } + @Test // DATAES-449 + void shouldAddRouting() throws JSONException { + String route = "route66"; + CriteriaQuery query = new CriteriaQuery(new Criteria("lastName").is("Smith")); + query.setRoute(route); + converter.updateQuery(query, Person.class); + + SearchRequest searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + + assertThat(searchRequest.routing()).isEqualTo(route); + } + static class Person { @Id String id; @Field(name = "last-name") String lastName; From 4fc4d91b74e00672fb585ac1d7dd7a536ea09475 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 25 Jan 2020 21:36:34 +0100 Subject: [PATCH 0060/1191] DATAES-735 - Update to Elasticsearch 7.5.2. Original PR: #384 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 2 +- .../asciidoc/reference/elasticsearch-new.adoc | 2 +- ...on-7.5.1.jar => analysis-common-7.5.2.jar} | Bin 193639 -> 193638 bytes .../plugin-descriptor.properties | 4 ++-- ....1.jar => elasticsearch-dissect-7.5.2.jar} | Bin 24487 -> 24484 bytes ...7.5.1.jar => elasticsearch-grok-7.5.2.jar} | Bin 32240 -> 32238 bytes ...mmon-7.5.1.jar => ingest-common-7.5.2.jar} | Bin 107326 -> 107807 bytes .../plugin-descriptor.properties | 4 ++-- ...on-7.5.1.jar => lang-expression-7.5.2.jar} | Bin 61186 -> 61184 bytes .../plugin-descriptor.properties | 4 ++-- ...icsearch-scripting-painless-spi-7.5.2.jar} | Bin 26241 -> 26239 bytes ...less-7.5.1.jar => lang-painless-7.5.2.jar} | Bin 552146 -> 552144 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- ...url-7.5.1.jar => repository-url-7.5.2.jar} | Bin 14569 -> 14566 bytes 18 files changed, 17 insertions(+), 17 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.5.1.jar => analysis-common-7.5.2.jar} (88%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.5.1.jar => elasticsearch-dissect-7.5.2.jar} (86%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.5.1.jar => elasticsearch-grok-7.5.2.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.5.1.jar => ingest-common-7.5.2.jar} (82%) rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.5.1.jar => lang-expression-7.5.2.jar} (89%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.5.1.jar => elasticsearch-scripting-painless-spi-7.5.2.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.5.1.jar => lang-painless-7.5.2.jar} (93%) rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.5.1.jar => repository-url-7.5.2.jar} (81%) diff --git a/pom.xml b/pom.xml index d790d6756..e90ef3df0 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.5.1 + 7.5.2 2.9.1 2.3.0.BUILD-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 60ddff34b..5913f6cd3 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,7 +35,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.5.1 |2.3.xfootnote:cdv[] +| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.5.2 |2.3.xfootnote:cdv[] | Moore | 3.2.x |6.8.4 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 7f4720779..f41bf934f 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -5,7 +5,7 @@ == New in Spring Data Elasticsearch 4.0 * Uses Spring 5.2. -* Upgrade to Elasticsearch 7.5.1. +* Upgrade to Elasticsearch 7.5.2. * Deprecation of `TransportClient` usage. * Implements most of the mapping-types available for the index mappings. * Removal of the Jackson `ObjectMapper`, now using the <> diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.1.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.2.jar similarity index 88% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.1.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.2.jar index 8c77e44cea1adb189e53186785f94815384269fb..a2c7da81a6bd9bf9d83aa4da1eed2a474755654a 100644 GIT binary patch delta 8928 zcmZu130O{9``**`wQovF8%k-#WJ#8cEs=)En29Vy)?^xl88pVeR96mTRMtUF;*&45 zXc=2t2q7wCD-wy{TK(@m=X`zLW_Uc^=RNPfo%g(XR-^m0M%N(FUrk+y<76@}W4cFR ztbv2J`181SUm-l!$A0zLaaKKzvPNEAomQZ+t}bO+&jk;3yCfZ7<+Nd#**|?w&ROOb z^)mkD@F!J|x~bo|VbkwJbyWD%fjJFo{mMeeyzRI?EK^t~pW*%SuA%wLNbT|NH{$)w z9UAuk5N7Xqu*=XuYpc3Dmdn%)>ioZo?NRl<^5>k;==j7Vnf{r%!3R%na$nusdxYOs z|2ym5el!fp8udo+Y|V}A)00Op3BUhgWpL?R%kfJmng8Ic8*p}V!}ulc!>{z1nyB6U z)xIyXB)4BK>n_cXP1L%UwIVsMuD!Sed?BTfxmx!FjB~RniBLre)~x8_f4Uva?IA5n`UKYSFDQuWOOg9 zA+fY*|I2YM&D9Tf=sd_ZnKxFZb`5+S#Z!dO;AQM{^C)yh-B_gAsMFEw6320K zc#a#1_v`UKLPb**l~%Ed52Df($Le_}_Ia_C*HDv*v=e=l9=B6s;xYe%L`@yvlt zLHoa_FxW38>(%r{f+wZ!-EV?|pM{9|&hlEX_f+p`{RSM!*W|dL429Q%6HY#bbnuv` z$W$@Q0~KjfBeQ-p)Feh`?yAZvLL4_w3ny*oofJW9(Fdm4l;6<=EsCCG_bnp!>Gb(= z%|t*yq``54!Z+3qigm7N8zZpj%9}AA7nqM@Uwi$SV-*F3d^22TSEQ&-;%r*V8QmN$+B8whIfp#(t zJbf&3!k$IQ6n8F0GDW^K|0~n7-UsbfCla6MY|x}!H=U(iToi0k_mBwCOfkK#tC3pRq**zV3Uj{Ust;W78^9Cal zit`UQ1s?#v+UnzoK;$I6`b`&qlp_nd|JW1_nnH(j`7SaVlIIs*^AuQUiVE3z#9#bJ zW@h0P{vA&mmReksh8pf%!@J36CAl%F+0A`eY@JQgLH}HZpUgOn(_37$W0#d$bpj1 za~QDk1CZ`g$M!Y6lklC3Delz38z^pX;CUu8Z2kzPn^ruh_6n;nHxV!0%+=U?8e&|e zMY1~}2U*L5PGvL7&*MikSA;J^%2-6b;9Z#si52`WR1c>!4ncOnr-ugK|A=?OrMr23 z{I&*JDZU?pdN6kDpAKVRZadP|iTuTV3OdeH=Qz0z%`rPDQ0#I6b(CMoh-7iTBInmo zIz>qtKaI(*nt{Hf%E|pE_ho#GYwCHz_j049Q6u<;XSus98(Cq!cqEhGO@7Bb`~5;R znQDJ%^7MpfQ2H-*NUq@0E2yKw#s)PpSqX`J2@B<)o4^sIUo1GG1qH=%9pbBzGqz1b zn(}~jds<<)%hqS&;uXjpC#NG@s4#80ZHO8b_A$SMWjWAk$>JX(C%Jm6Qp(gA^c5nJ zj`Ueo!s8N=z9|jah!rY#bZTKnHbrOB_R(ULxAtq`v{Q@YhT+&Xyd$=3MD~i{!)Pp( zb=qop%X{huu?Xx<1M#ZtQETb584o_}FMIz1kBH=?X;_wp+lG;kf7z%uCUPBe(g+Nz0I16=Ry zzo8?9|A98g^@9fJh&?NinPNpbZ%;YMZ7Q`HgOmGF0E@@MFup(2WqM=)QSo$~*KT9$(&J!NzyEdK2%4pHw3U#U^#s z!qVjTPN*+U*28(F|7-$(8_4iC0wlTjKgdQgQx6Hu8;+re*q5vA-6i9h_9@YP8I@vsB`^FykjO&FmV7Gy7LJ@j+@N6d8MZ9cFS%OHp^c_&qOE z=tl4#8PB=z9AxCeDLZg1nqD}7r==LM4cXG_8+5tCpIj!2D1lerCbcre#sEdf8h$Fp zJg}#i2X;5(-LY2&WCq-lRENhWJa^DmE0zqsA_ENhFHG5=Kl07g0)=fCRKkL}=1MTF z%Waif(c2+U^q`6Y#k%Z{tBaAVqHHR^n~?>W@OP;5{@Iu4kO~QmAq^aOC zBLg0FP*VXhpMrXm#2`-vJTL|ISMLWc3$I8)mi$#5pMtuQ!4+qUfVsFl1$80yjhg^q z;b_8f;Y;Rt1p2pQe6kT)s5kkJHW6}{cEHpALbNO3@V}5HS|viQ@lk-u!8_ojFx~>6xP&^;vo8|KzQYK|3|`bnypBB~|3*p($GH;?^*4(aoMGru8A094 z0DT7((EthhpPtm%ad(j(u6}?lh|4Y}oeS9kF53zh;r9~!vR-Y>F~ec^kg4i*P<0-e zqx)Wf;UFxt?u-L7lqukQ23*mvKjsZVt>`nT2X)-OTmVN65DD-FUno8O78%aYS5k%K z!*Tf_<*_DCyp2p+afqg^j||XMYT5LmMAKTYPPjQ6>Dh`&r+Rxpp-Jr8jvG#ayOpmI zTdH5|IZz;VEVhq?zFDF`M)*n&vLu34FB6XYTEZ%Kf+!fnQ^lS{fTd3ZuzEF#96|aR z;L&dolTvj8jz&x+X4<8po`k>TDI?*3FqAMUc!Ins>(|$Se)i1PK$_r!bY*HLq{7+i z*@U7p6}b@Je}2;=U91T6e^tbdxg_m`Vm~VqJ%YY{RJHvsD8QT0L;@tLxGkhvdhRaj zOHlLY6iizJNp>DOwXX!#V+qm0)d<4(^Riri?YMHZ0Tj)rciy#LCxg7L~v3XZ`USP`(MJ5W+FNIvI4@`s*_{%ZT%M@ zBoBm0b((WPOpqX=dFsla_$OfKad`Yoqjcs7VY;UXxl(7PiS6R^F%k@6=xWDW{K^=oa6i@E*PDTeYf(Cf{&>^4!w>{ z2>RjRoymKlS2}<}(vGq?t2H}FuhbCSbG5KlE{lxo!a<9|pdZgOfO}pdXI2i0OtUH6 z>8(z?S@Puf-QW%lP;I0Hz4zbL$7x6#8hchJcu+Hl-(iR2Y;nGdW< zHjs)IcLbQf3isNL7QA*U?;uQlMAMOIpjsEScfXq&j<|sWsrFmNHusx`2N@Uph9$ZQ9&mw0ctJA4z6{&#o5&n5eP_v8)=eSxuJS`8I zQke#DQ=x1Vaw0xBoGIA;G=NLY@X0&C8y<&-!oUdzsth@n>Ur(Ihb3z(%Ic?=%8axZ zC!*yx6rB1Bf(PcHXSQmyhlDcQw3oYVvY^YF~6(!B<;Jd+`Sc_ zY)-mTzom$cad~fgR#%RCQSj<}0RG}d!8!Mo4eZl%08i^rz=FrGTG(PHvT38)4lxSZ zgD4riNNG_tbse~B57_7Uuh#Q%2tkdj?Sw-wvVNml$+S1&#Zbx^mNea|n)NS0UjO0v z;SGqoN1ZZ)=N|z$eiX$PmoylbGa0uMiKg_D_3A;)dBZ-1HaF|88xapQPop;Bw< zlalqFAT|wfUyYKe<(fo@guqHI?0lQW;o^~u>2-j<3Es|QCFseAROsHXkSEP^Yw?;u z$Eo;`2IX{M`4GUvQfU6=Xu>rtK8+~JE3tz2r_wWMi1x&N34`XpOas9aV9b&xfPq{o zxb57u@C|UW%AkV(dZSEy`%(ZeJWs%Jwd&Y2ADOjzI9|_yE$aP;MG zsur|CcXA!A3_g*HFQmbB^z&sZ%jJ@CYMy@zC>|72Fg#>v&&(edH>{*5$5kKYI3I}z z``@9ct6X_YyuFx}JXzd90sZ@BIYS5MR-=j3YXM^C$kY=d-AKsdA1RjvpG0TBHzG&k zN{_wu?xh2`vI7Cf)f!`$Gs-tgvG~keZ$SwR3Q%t48>t`o%<_kwnwWn;~n+FV|+|OKBR>Hn45IS=N0kdt0D^5vMR$*Ep9Df*1 zsa_W%Ya)O%LzT_{>AMkQ@Ha1^QH7X6@~ZX>Q!W9U#Br1j)PPx=1x|4loYj0o&kU-S zS7VG=qC+N9Ff2ZM6Uogok@vcy=v3Onpm-tqG!`HD{a_0sVqHtAI?(d(lfsrc&W9%EW{=3 ze|ybfp@{E{y)%@>+9YPqoW+z4+&nBrLPTHX{Yb$lKJslh8SanatY8^EgSynlQ@Vhe z+hAxQHx}nR)9D>vTnRT8UO}+}>tRaB%u`NB3B|zS%_@3US*+Y+%)1KU`ZW{`SxyHg z;yTq*xBaAl^;d!qzvRP{Zz*SAqk2*O-&%#U1?l`s0H57Rz=Bb}Ca!M?&8l>wVxJq(NEwomP}GC;V!n20z3FvTBWCn>m-jUaZKiN s4I-rQDAs?AMzmi&`-^8Yj!{lqU|rln174#XcNG4H!Z`3c8Dw++2V*n6`v3p{ delta 8744 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 Cji5jP delta 1342 zcmZ3opK6lwZXXHC3g6cJ;Jsn3!|BHd4zizr^R6fTFGG~>#mY||*EAPb9?G!q z%L{ug7QVvv2g9VDpL9PRxiKq=`<(Vefi)R^eR(cg&jWsRE9z?eHhdDC=-zL2waSP) z=Xu4VEyr)=X??%)qE}sCpx)u__X{P*CRZ=reO*`KBukCKv~Q8F5neYE<}KSJ@hQjS zw9VPie=Pgf>7EeV|AgCWL8eTvZd=^Wz{Ho8(^QuSb1yoYlJn+P&e}O|OYdc z<##Jfd~>EGjD>q|m~Kq|^aJYFTUUiGTp0GxXwI_efW)vG@#yy&c2ZnTYuQTbWuK)s zh<0$T@(DTW^sQCouhM!hwP~S>r-dXp1%)*y7_g|!`d?x*abx7#&=2P9(Tml$Pu|^s zbb9-hZ;AVZ!ri0)@4LQ!*KfZCb{_kd+&upLSM~*;!?#S2eNN$Ad)T6DaXBLRZ)}_3 zzh%p#wp@M&hBzGt1`!4Z2H(wh8N2vdt^uVcXAACR(bx`TXb34l7(POJ5JsJlnIK4t zCzbv2VnzlAPG$xM+sOqodYf&7fKd#R(r#ZUwE!sfm1*)vCH2Yc>69HQ74+1rIE#fn2m%L!Vg?qG*TEBB(2(B>|+^2gg-Z ztQ6Bvm@M1m`LRM^<2{ysl8peS>?yzyGeB`0LlDp?oyq!9P~&T(rI?ll1I2VFAB&a- rYi@nI{i_yG<2zuE(L>R^E)?vE*D;(TtU#YLFo*$RE-*$^B0xLgsLs21^NkCzveP9 zb{Cl7j5u*~$wV0_G6gdCV`E_*R>6;rxj-09aRD;I7=!J$7oou3=H`8R?(>}U+;h)6 zK1=#zmPF&HI8a;xaCQc_#5}%<7U*Jqmp_*um6&2)sYu;J4)f@MkY#6DUeM>JnP+%AXnwlUJ9X1JPm9TkBO?7|WmA9usZ;lE4d_In zoa}~)UlU9{H?Hw__IoinS2}7VkHX={-Bk>8=fIx@$usUJW9PhM3W|rjLmN`LY*`Fb ze!u-#g_A!!Gd`H;;-u!Yb(T-HPnirKqkEI4M?w$3YuPq*G|Z%|zy3@5M_o6wrfGr` zYi6oTA5JE`Cl<;CtghW3jvAiD30ZDevz}b7`QW^nB~&o@XD^8QC{OBSA5)ppHRfmL zzi0FX&x$W5s4vdRw&uaTQtv^|b#sy;B7#z}C-5x$%v5-_w2~^}|C4D7=%AFF0;!x(< zPElDw2t5FUH2P)?j?lv~2#6TBfffyyAY+u~wTXohBa-b*vu1c4I4p>#0Pu7T{F=VL zrGuAC!HhOK#3~pa8;C=K_{fDsYYVFvXi+)ix$u&6`f3dIZ4(cEsrvHJK-E7 zl1r{O1SPRoa41-OdqF5j(z)Qxv5fEWW|2@$!l)|Y8%K=35-l7E9*^t6AZCv zFQSpi42PvTh9)fm2TFXFh8g}_vW;SGFpMcBNS!dFbOY{dIr{rHtSe>Pvcj%Xf<@2) zC{*V2_$fo2=cjga6%Ido4Bsa(3Yt; z?zB@Y#nQv7mD;Iv-TjOdBtGa20II(DG#Yag?Zo?)g)60!PP+0r2>>@_+-p$>K%?=& zF4(N{Ue&E2S@FmQC-lLfxj>)h;?roHOok@IdfcfO27>(hUg%O55MXUhswm))9#K!D zwQf;jt@3*oEQNo2=u8L=iCnhm}-Qj&g*lk5UOpEm%^Wh6l^ zr0X|g3*&l%Y$<`^8&*wyEQ0>(LmL1+F}t?;*QB z%EkH8!d15bUo#Lfg9glz#sjB&_FaJ1_1v7+O8*R delta 1677 zcmaF&oAJYMM!o=VW)?061`ZAe;T;qFC-SLsf@t=i`U_Gg+9=ka_B(7Ku*dzBy~`se zr?S^ATQ=@g;Bs;Z^vw6*aA**w)a({+( z>Xr@(*|vkZm#^JeQ1+l^;+d(d16__y6UlxtXOe8w)TLb|DXIn zHid6h-s%3^&&A7H=WW~0=6b#RE?b!5ujGZ#da5)_>+b$MZq}Vl&ts1|ALH!ils@}7 zVoCDEp3E|_^qMa+Z02HJQu~iBFL8NnFeBp2-lJ(;-TsqRtmZ{dFm)47j^4brXw&Rs zcI_M7C%)UySoD3<&X;Syh_P*rDrx@u*?!^7(50W=1nuOmUsdP0H1mjiLUZ$j`W5OG z{-Q4~b*nbWsIbrTn5WmZQ0Iw(?PJZ!-t)vF+jt_wK1?isetF{6daHRSj+m_d^zT`M zcgd4?uj=-G%8|dd?^XDVUkUf`Pycmv_BWxgac?Ajuiby8zc9x6cIdIr49?Q_L;<$< zh&Z^hZG!)nEsxrA`574EbQl;m-(c+LXSoIxot!PWlSN}Ykf9-@0ActD=|LEELdIam z=7m<1nINp=qG}Ql)=FV1sF=7}8w*6kR-q3N$&b2991tN3TU7|-d-Mv3T&`OoMB`+> z;xiDTL|ap+S(@30Ss`Lc@l~7<*1h5cMhMHu#T=?`U1m8%Z1RJQQxM4y1yBcV^7dha z2rZ7;4OJfyxR?tpHrc7PkO!7DLH^!6%YF)r5Qvq$PpIfMBLf333j>2F!{m!q;+xq$ z-!k$sGKnxFlJew(rN)S~Jo#^_B?~BYCtHy4TBZyM)*2u;e)9A(C5Wwi%cLY^ zgcum|i_-N2yb&gXL;gKbt;6L0a?#21Qo^)NCctx;H?qi?EhqOQVnpP?I&p(i)&4Y^Gqt4^&7(#1589 zS?bs_Fcc(~l%y8r6=MW|Z-hd2HPFaDAQnb4dP!rb?c|BoiV$O}tE6lg?U0N~D#}N9 zw%mt`HD3u7&YzmIVti&=5y-FU9_sW4; z#Y2^W0cbZIENQ%%JUOr$TE48Ql~QWRLvlz_YDy-CCnhrjgX?eJWZ5c6@Sx^SxX}zt b8mATm^Qxo>E6~Rb4Dvvz&H*gpNv6(}% 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 Bmk0m= diff --git a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties index 008a57f4a..5bffb9554 100644 --- a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources # # 'version': plugin's version -version=7.5.1 +version=7.5.2 # # 'name': the plugin name name=ingest-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.5.1 +elasticsearch.version=7.5.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.5.1.jar b/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.5.2.jar similarity index 89% rename from src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.5.1.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.5.2.jar index 59e466244fc8c17a2a133c76754d0bbf93c96072..e627e68074123e4a16896c86a597d368b6cc7f85 100644 GIT binary patch delta 2560 zcmZWq2~<-@6rKDeY(jt#K|WPvGioddh#-Q1C>0_atoFE5Pyv--T~L(WU7;2_E+}rL zv=%qeAXSkH3VJL{qt&_q(FA0XMXlmS(axVglE!`xhsoo<`|f@3{mDiZH%-MA$fR7J z5da1TpftiomMw5HWd3%qOFI^q?PHf3y28fJtZd%jss2x#X7Luz&h~mKtSUI(5;)=B z@w|r7HQn}Sim0(6ACj-FJ$OEJbz3_3MU*P>l6s;3U4Q47R{5QgvdxNR-f!=l4%uKZ z*=p3SbCMyV9R*7s#XHw6R^C_>`)pCi6|2HPse1jCtX~};*6m-c;a2BXN|HRh!`qBf zZ@Nk}6Vu0bd7CQlteAXwjAh`s-FqdIyXOx&@|rI#j1P#;6AnD(^>|h77R~(Nie)Jk zKP4QTmf|S)y;Ln-Te2tIv3ySHmugM%=^HoPmNuo2iljBF-|ud!`!?m)7k27@l8YT~ zoz~$WU?QX5n!S#%*TQ?8UmExGt%f5Op>d!~ZEQ}N4wQ08{jcZqXs1A9H+ zTf9q&?Y+A5VQ+U3R~=)x`l}Uw527cXIJ&K&DsRe<$y?hOd#~qchv9{WP+Y80G;nfE zd1KKBm|%W^$BYJg2#2zVIYMXlkRkM750yfH0fXtgel|3N0>D-e22=(pisBDa7@#OC z*vMl~QxdO{Q^!#m7iU$&tDleJ0dU3;ezSZGbZHVQ+#@CsRAH?Rm(8qGULmoQxpydY zrrrxbL0=2nqC6V_#=x6GF_erjQpnO?8L=tt1C>O8eE)cI+HyFOoUVtK@vwkedB?t8 zNcK%Wl08zf?sN%3cvg-h#W^LHN%5UC-St>@QPy16z#9{*Yp=KfSQ=s5rltA>8x~_u z^4H0u$*E%Q5RxxTc*)vG;5+>ss}DerDFE)+M!3pUVQI5gpDk22NJs>|9-d8T{PH*O zaSyorS_ZqL?qwPR;D(dCn*|ETmA*v7_8IRvEKTO9vd`Gl?mJF={xY}C)UVq@Oy#^q+ejJb4N9bQqb8f(S^$xboMhZAZ@=O3gGy1hazaO9c z^cZ-k-ad?33?_yKiXYS)@|c0X04E^;D^^9j$fUZp8OX;B1R)QT5e&^5>})?}wf+bJ z3?>oE8iwP(z@!G6Di%UDJq-TVV9dshAJfzuA$RYDo7vNXzIN)A`-*PZ6mNUo!3=|gl&LQ+ zkkTk-i3cF!CO_h20CZ@!WaFJEZa)#nlk+X0v|WUY-bp>eosE=F7yy7&r|9-cn7B7o z442PZA~^FS{e>n3zjOx9tJn@dca!!50(`+XfW zRkNU99=ej?f=N{m};_xB{yo3|NrbT`wiD2bY;oOWRBI`tqnrbN8r4ALNDIQ$W5 zTvj(twH?FxW{sl$?pFnsY(9YmZ$*Nq=m@qxg-N<<&6rihOQ5C_6IP)m_~(Bw%g92s zMLyb>0d+J_tT#zpb>eY5$U$4@;m}h)b>`6*6?U4R#4bJ09JO2 zSbGy5(NtM^zp?|5NIbU{jk5~Ji=YVhwvu(OL${V&HL*=@vZ?4Qu&BeaU0p+1-V`*; uX}58#TqR*+Pf;xDF5xt>b#-)gUKAU#dbLc-NBYsX68iBFp*4TNeEJs(m8Wq4 delta 2793 zcmaJ?2~<>77{2pn7`6e25fC0Cg5l@@%BZB_u#;(sAmTPBO>#raa5)+XGC*o7cpSV% z2?vnWG>yd`VuT8u1dTDZf}mj$g^@+jaLWztzIz`|kIw1M8MyD>|Ns8)e*ZElZNjuR zp><@KP-FpsnHd=MgEk`5+TEP}A6=L{urX8Rs;QpW;ca{Fow|S}ddt|=)8}n;N}TLr z5v;R+blsxhyknQo>CUFi{;^LITe5;v4OP{ql?iccRM)2e)@!wMPh7QW|963(+a^3d z?jm`(;z-7~dm4Rd>E)+cDVeV8?E<$qWL9SsmIY*#dhNbc9ny60MYheXZh6+?y`!Ea z)sMfmFj#YGthUTXU3o_p*cCzfU5+jth*TGe)Uh-D?^;@2&??{Zu&h&hDRYZ-Q6+~? ztU2nx(q!$c`+aq~+NvDYxCK$S|7;1#-mpzk`eNzA?o~ay4c2`(S4pKVN-Qo1#>z(8)i1`GQ3!pI^P`oL7;2{pTC%XZCIv zEo<)nS3%1NZynmYDzUQ?(fiWFT zW!i{Rrb&=JLi7h(!fiI?6WG)M^ib>{^oYLeV9O9D}|jHXTR&*>azqHx2oGzZc0wytG5+ev6$l@#OV7Gl|<+*_knpm64-v% zg1OvykCObmrkLEsOrbUF;FEFc@XFButcih<3I!}tTOcnPvnzeWXacRP+9o2atkCl! zOq}+6wd7*lGrg~96|?w^72Hcr_G_Va2k}B%NT>3 zzX+eXyo?x#M|@|9VP=8?R^4%9CX}af_w)Y1Mo6&ag;o@{7v{{!lL!GQ5yMnk0qYFT zOx9|9&Z=amhM*2!`aV1zp}L4+%$%W1Ntnoyxdi28ZhUzTIuA945z+XZk;avAQ9q$; zxeFVV(=17Rv(llxB(<6dmsI~{a*hcAHCDVB2WkpUh|fU4Ob$^pxnbx=!5?s|AeTrX z7IUgi;sQs6lOh4&9W3TXjcN$OE{&tIcup_pIHULq$-*O(Sx;k;tXt8j@MFsd=65(U z*CIA^F8XCr+^VR;(FCj4))BO`72P|{l+StYJr3OU>U1u9a=85!t3fobiK9xJL>GgTiDmXs@m3|2a4g*#p*L2kYPj*SAPW*zGMe zRmSd(hv!-(W7&Q<_0+5PQxuLtDG7Y-3_xk>GZ~EOpGO>v+i9xV4m;*|jD$J;w%9o} z<=uPVqs9=U3Z2DsE_T4i6$x(A;dJ4zw`r<|#^*0Ljez=Y!erf%UG`@Y6E86UAv~}& zH*Bn}cY%KG#Q1gJBjZq>ake`g=<|b>jpoqIK#b#$KU?u8qBy}6fFPc6&jgHopxpxA zjkSb>UF2TIAu(K(WKV>yf|_(OEa~A?jp?JQfH?@r8y5DxfrV+%vpsIeirqs_rPL=)qX0$?@|xM2md_h!cyG_=_ghRJtmYVB%n-vNHrNkHZceuz4Q zQYJ@P2en_Q~s zHkxWZ%wd?rgPnvWZ|w3|Dvu(7g@k~rm8Ocn#Ue@LERFf!af_yWim)7&w-oqBH>t$< z&8Wm*pjjBm0~~jnGqi^;oiYNvtb?W=oWc9~9qt(5iPfmu$EYjq5dgn<%6`Q86c|W8 z4=&kx`2vchN52^S_LWp}_vG@~k7!Q3h@G`_O<{NkDbvbbNu6D&H);^Tn>?y(E@4WK z`o|EOgGjuBU(g=g%2K%W21h>*iC=Xc+p;B{tZ;Z;DOEi*wYve0N?+)ILTn!yW`ddl PfGOzXV++7pJ^S_#=|S98 diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties index dffbd1fbb..d5ecfbf5e 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Lucene expressions integration for Elasticsearch # # 'version': plugin's version -version=7.5.1 +version=7.5.2 # # 'name': the plugin name name=lang-expression @@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.5.1 +elasticsearch.version=7.5.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.2.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.1.jar rename to src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.2.jar index 09a604504e588791b2ab7a4680aef3509b20f787..d4cf33bdd4f83c1d9520be6308755a0c861cd239 100644 GIT binary patch delta 1375 zcmZoX%lQ8cBVT|wGYc030|y7g_C)=FiF~S@AbPE@G)w+O8^!vAS<;3Ad!_&IH^l{Y zJ-Mp)`o^oJM>th8oA}LCznD!+D`$<$oVZ2t@9)017KNVGCmh+&&aQm_vRCfFZMNWN z_J(TGdy;}gE}zV`w|H|g{Y1!<=-IMbVoBN;98ZO*x2&)>+_7=%zhJ31*S!O~Kiz$z z{g%7NG-~?KwhM-uX|>19>gBBbFI>$(I`p+M4dU$=pN#DpRtoka` zzlKfo@(P{4XjRwGqMzATKjjWu)J$G~v_^k_m&fL33zSalhaT0tCb-3U8&@HRyY_s4 ztMU&l=?5?TaW+uCn0H9RG;+q*_Uc)dA9UppRP94>*7Rid1P$KJfXXE>F$0X zn@^!H*uDR46No#?_~ab+kM@iYv0#hd2#;Q27#;ps{i(9JWlk8 zJ<(BqN>gUVfAYshKiNzwTVK+=6QBPWf@&&Lha;@ zv}NUiB{Gmjn~zJVL3MtVTntsE?We=a$H*kYj7W@=BjSt^sd4g@I7=2#s7$^XC&hSb z@|!qic~HRcF>c81VPIf*0>r{V3j!uv>_*oCR00Jc9bS_c#w*IBtC5B&0h?Mg`C+^kI7BA%CrB}F2Xf^mdn5>ewIL#h zfx!f>je%iH<2SInzFv3KX-Oye&xx zB6bES=BEx;H&0c5vQH8Z*oV`jF8Zf3GB9KUZFfO2v~u!=WZlU!3L=x|CqvE9PLX1A z&;|Q!y&lix+7uqJ!{&Cs&~*gH)qP-k&_glfl+$FvR2zr`dV!k5-NBkIU4$mrBtkS- zZTUUn6HxPfZUzQR6wP0Jz>1^Ngpm>(C?F>91%|L~5KvZe@~;GCi1CWR&`l2p>(G=E k1sM+!4@{L};)?`}Pfz6)VFl(G1_p5;ROVn{aEk-+0AJR>vj6}9 delta 1381 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 I>@sEl4<~5u(*OVf delta 14976 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 WUW64GY77iQK-kO5z~F2Q;sF4UOMC(V delta 1133 zcmaD>__B~Mz?+$ci-CcIgF$@91pkSAs+=HN<;L@_!ihGD^{4Z08wl*-zF;r#VyUa+ zttn2CN&2pH7G=yjz%K22@pfC3H;YEl1Lcf=`+8*6`7X&-J!rJvY<)QLUencTo{9e) ziR0~ZxpeW8l7EeA`F3k( zB>Xu$A-z@ohf${ROSAgLnjVXCj~tYrq5k5Nzj(dwGd2{!i)&huiJ%NAI@$hz9OyKZIGRuS>J53=re?#rF1od0{>$*|&(tUvSn z=9j!(7MWge{eju7s`l&OkK9|HU-;Nr-@0$k?Yhkm#qaqBWt=a&u<6&w*?+SyTstJ= zCa!w3nKMEx^&>kXK5lHA;J^7g<7|GGYe3fIGQpi1pr~O00wxdv1S~+DUzD!T%z)4a zQZqSRNRI`~c%^F!VJPc4Kp5$IE?~yy^?K7-c#tE1@&S2kh?@WM_JSbop%+`@LU)ljCXRhx%lP|g*aY_+E=+4W>3~MQG&R} z-$Y76LkJQo0p4gPHkwE=`3Oxm)DscFkUI#Js{_eNPu^+HqktaLD&X)25dsW<9k+uN zs!is$;DOjGZ6U?<8zL5KApj981d2HegVk-ekVp4igP9c5Q*n?}fI%t=(Qy_irXm3q zuT?2>z?x+1J>ARR(L N*vrbm;ARZs0RW0Yg|7er From 936de20421dadd10292859098deb15a5568dfe3d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 9 Feb 2020 13:00:25 +0100 Subject: [PATCH 0061/1191] DATAES-739 - Introduce nullable annotations for API validation. Original PR: #387 --- .../elasticsearch/ElasticsearchException.java | 6 +- .../annotations/package-info.java | 3 + .../client/ClientConfigurationBuilder.java | 10 +- .../client/NodeClientFactoryBean.java | 19 ++- .../client/RestClientFactoryBean.java | 11 +- .../client/TransportClientFactoryBean.java | 10 +- .../elasticsearch/client/package-info.java | 3 + .../DefaultReactiveElasticsearchClient.java | 3 +- .../client/reactive/WebClientProvider.java | 5 +- .../client/reactive/package-info.java | 3 - .../client/util/package-info.java | 3 + .../elasticsearch/config/package-info.java | 3 + .../core/AbstractElasticsearchTemplate.java | 16 ++- .../core/CriteriaFilterProcessor.java | 3 + .../core/CriteriaQueryProcessor.java | 7 +- .../core/ElasticsearchRestTemplate.java | 4 +- .../core/ElasticsearchTemplate.java | 5 +- .../elasticsearch/core/RequestFactory.java | 1 + .../data/elasticsearch/core/ResourceUtil.java | 2 + .../data/elasticsearch/core/ScrolledPage.java | 4 +- .../core/aggregation/AggregatedPage.java | 5 +- .../aggregation/impl/AggregatedPageImpl.java | 8 +- .../core/aggregation/impl/package-info.java | 3 + .../core/aggregation/package-info.java | 3 + .../core/client/support/package-info.java | 3 + .../core/completion/Completion.java | 16 +-- .../core/completion/package-info.java | 3 + .../MappingElasticsearchConverter.java | 3 +- .../core/convert/package-info.java | 1 + .../core/document/DocumentAdapters.java | 1 + .../core/document/package-info.java | 4 +- .../elasticsearch/core/geo/package-info.java | 3 + .../core/index/package-info.java | 4 +- .../ElasticsearchPersistentEntity.java | 6 +- .../SimpleElasticsearchPersistentEntity.java | 7 +- ...SimpleElasticsearchPersistentProperty.java | 5 +- .../core/mapping/package-info.java | 4 +- .../data/elasticsearch/core/package-info.java | 3 + .../core/query/AbstractQuery.java | 24 ++-- .../core/query/AliasBuilder.java | 20 +-- .../elasticsearch/core/query/AliasQuery.java | 28 ++-- .../elasticsearch/core/query/Criteria.java | 7 +- .../core/query/CriteriaQuery.java | 10 +- .../elasticsearch/core/query/DeleteQuery.java | 10 +- .../core/query/FetchSourceFilterBuilder.java | 13 +- .../elasticsearch/core/query/GetQuery.java | 14 +- .../elasticsearch/core/query/IndexQuery.java | 17 ++- .../core/query/IndexQueryBuilder.java | 12 +- .../core/query/MoreLikeThisQuery.java | 31 ++-- .../core/query/NativeSearchQuery.java | 20 ++- .../core/query/NativeSearchQueryBuilder.java | 27 ++-- .../data/elasticsearch/core/query/Query.java | 11 +- .../elasticsearch/core/query/SimpleField.java | 5 +- .../elasticsearch/core/query/UpdateQuery.java | 7 +- .../core/query/UpdateQueryBuilder.java | 7 +- .../core/query/package-info.java | 3 + .../data/elasticsearch/package-info.java | 3 + .../repository/cdi/package-info.java | 3 + .../repository/config/package-info.java | 3 + .../repository/query/package-info.java | 3 + .../repository/query/parser/package-info.java | 4 +- .../AbstractElasticsearchRepository.java | 15 +- .../ElasticsearchRepositoryFactory.java | 4 +- .../ElasticsearchRepositoryFactoryBean.java | 11 +- .../SimpleElasticsearchRepository.java | 8 +- .../repository/support/package-info.java | 4 +- .../elasticsearch/support/package-info.java | 3 + .../data/elasticsearch/NestedObjectTests.java | 3 +- .../client/reactive/package-info.java | 3 + .../client/util/package-info.java | 3 + .../ElasticsearchConfigurationTests.java | 3 +- .../package-info.java | 3 + .../EnableElasticsearchRepositoriesTests.java | 3 +- .../config/notnested/package-info.java | 3 + .../core/CriteriaQueryMappingTests.java | 9 +- .../core/ElasticsearchPartQueryTests.java | 10 +- .../core/ElasticsearchTemplateTests.java | 18 ++- .../core/RequestFactoryTest.java | 11 +- .../ElasticsearchTemplateCompletionTests.java | 28 ++-- ...chTemplateCompletionWithContextsTests.java | 18 ++- ...appingElasticsearchConverterUnitTests.java | 10 +- .../core/index/MappingBuilderTests.java | 135 ++++++++++-------- .../core/index/MappingParametersTest.java | 9 +- .../SimpleDynamicTemplatesMappingTests.java | 22 ++- ...pleElasticsearchPersistentEntityTests.java | 14 +- ...sticsearchPersistentPropertyUnitTests.java | 13 +- .../query/HighlightQueryBuilderTests.java | 9 +- .../repositories/cdi/CdiRepositoryClient.java | 12 +- .../repositories/cdi/CdiRepositoryTests.java | 12 +- .../repositories/cdi/package-info.java | 3 + .../ElasticsearchStringQueryUnitTests.java | 28 ++-- ...tiveElasticsearchQueryMethodUnitTests.java | 22 +-- ...tiveElasticsearchStringQueryUnitTests.java | 25 ++-- .../query/StubParameterAccessor.java | 10 +- 94 files changed, 612 insertions(+), 357 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/client/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/client/util/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/aggregation/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/completion/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/geo/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/support/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/client/reactive/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java diff --git a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java index 2660ad7b7..8559cab62 100644 --- a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java @@ -17,15 +17,18 @@ import java.util.Map; +import org.springframework.lang.Nullable; + /** * ElasticsearchException * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class ElasticsearchException extends RuntimeException { - private Map failedDocuments; + @Nullable private Map failedDocuments; public ElasticsearchException(String message) { super(message); @@ -45,6 +48,7 @@ public ElasticsearchException(String message, Map failedDocument this.failedDocuments = failedDocuments; } + @Nullable public Map getFailedDocuments() { return failedDocuments; } diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java b/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java new file mode 100644 index 000000000..60fe25267 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.annotations; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index 032f5b39f..61ae39b35 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -54,11 +54,11 @@ class ClientConfigurationBuilder private @Nullable HostnameVerifier hostnameVerifier; private Duration connectTimeout = Duration.ofSeconds(10); private Duration soTimeout = Duration.ofSeconds(5); - private String username; - private String password; - private String pathPrefix; - private String proxy; - private Function webClientConfigurer; + private @Nullable String username; + private @Nullable String password; + private @Nullable String pathPrefix; + private @Nullable String proxy; + private @Nullable Function webClientConfigurer; /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java index 72b41c22f..37a7cc7e5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java @@ -32,7 +32,9 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.FactoryBeanNotInitializedException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -48,12 +50,12 @@ public class NodeClientFactoryBean implements FactoryBean, InitializingB private static final Logger logger = LoggerFactory.getLogger(NodeClientFactoryBean.class); private boolean local; private boolean enableHttp; - private String clusterName; - private Node node; - private NodeClient nodeClient; - private String pathData; - private String pathHome; - private String pathConfiguration; + private @Nullable String clusterName; + private @Nullable Node node; + private @Nullable NodeClient nodeClient; + private @Nullable String pathData; + private @Nullable String pathHome; + private @Nullable String pathConfiguration; public static class TestNode extends Node { @@ -82,6 +84,11 @@ public NodeClientFactoryBean(boolean local) { @Override public NodeClient getObject() { + + if (nodeClient == null) { + throw new FactoryBeanNotInitializedException(); + } + return nodeClient; } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java index ba972c9d7..f32d301cc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java @@ -25,18 +25,21 @@ import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.FactoryBeanNotInitializedException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** * RestClientFactoryBean * * @author Don Wellington + * @author Peter-Josef Meisch */ @Slf4j public class RestClientFactoryBean implements FactoryBean, InitializingBean, DisposableBean { - private RestHighLevelClient client; + private @Nullable RestHighLevelClient client; private String hosts = "http://localhost:9200/"; static final String COMMA = ","; @@ -59,6 +62,11 @@ public void afterPropertiesSet() throws Exception { @Override public RestHighLevelClient getObject() { + + if (client == null) { + throw new FactoryBeanNotInitializedException(); + } + return client; } @@ -75,6 +83,7 @@ public boolean isSingleton() { protected void buildClient() throws Exception { Assert.hasText(hosts, "[Assertion Failed] At least one host must be set."); + ArrayList httpHosts = new ArrayList<>(); for (String host : hosts.split(COMMA)) { URL hostUrl = new URL(host); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java index a8579aa05..d5e0abba0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/TransportClientFactoryBean.java @@ -24,7 +24,9 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.FactoryBeanNotInitializedException; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; /** * TransportClientFactoryBean @@ -48,8 +50,8 @@ public class TransportClientFactoryBean implements FactoryBean, private Boolean clientIgnoreClusterName = Boolean.FALSE; private String clientPingTimeout = "5s"; private String clientNodesSamplerInterval = "5s"; - private TransportClient client; - private Properties properties; + private @Nullable TransportClient client; + private @Nullable Properties properties; @Override public void destroy() { @@ -65,6 +67,10 @@ public void destroy() { @Override public TransportClient getObject() { + + if (clientTransportSniff == null) { + throw new FactoryBeanNotInitializedException(); + } return client; } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/package-info.java b/src/main/java/org/springframework/data/elasticsearch/client/package-info.java new file mode 100644 index 000000000..3594797d6 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.client; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index a6835f66b..67fe9c891 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -865,8 +865,9 @@ private static class ScrollState { private final Object lock = new Object(); private final List pastIds = new ArrayList<>(1); - private String scrollId; + @Nullable private String scrollId; + @Nullable String getScrollId() { return scrollId; } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java index f2e8b45ee..d1a70eb30 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/WebClientProvider.java @@ -105,6 +105,7 @@ static WebClientProvider create(String scheme, @Nullable ClientHttpConnector con * @return the pathPrefix if set. * @since 4.0 */ + @Nullable String getPathPrefix(); /** @@ -133,7 +134,9 @@ static WebClientProvider create(String scheme, @Nullable ClientHttpConnector con WebClientProvider withPathPrefix(String pathPrefix); /** - * Create a new instance of {@link WebClientProvider} calling the given {@link Function} to configure the {@link WebClient}. + * Create a new instance of {@link WebClientProvider} calling the given {@link Function} to configure the + * {@link WebClient}. + * * @param webClientConfigurer configuration function * @return new instance of {@link WebClientProvider} * @since 4.0 diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/package-info.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/package-info.java index 2423de032..3d808c547 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/package-info.java @@ -1,6 +1,3 @@ -/** - * Everything required for a Reactive Elasticsearch client. - */ @org.springframework.lang.NonNullApi @org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.client.reactive; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/package-info.java b/src/main/java/org/springframework/data/elasticsearch/client/util/package-info.java new file mode 100644 index 000000000..79701328c --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.client.util; diff --git a/src/main/java/org/springframework/data/elasticsearch/config/package-info.java b/src/main/java/org/springframework/data/elasticsearch/config/package-info.java new file mode 100644 index 000000000..6461b9824 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.config; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index bd845ea5b..985e388ff 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -31,6 +31,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -41,9 +42,9 @@ */ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { - protected ElasticsearchConverter elasticsearchConverter; - protected RequestFactory requestFactory; - protected IndexOperations indexOperations; + protected @Nullable ElasticsearchConverter elasticsearchConverter; + protected @Nullable RequestFactory requestFactory; + protected @Nullable IndexOperations indexOperations; // region Initialization protected void initialize(ElasticsearchConverter elasticsearchConverter, IndexOperations indexOperations) { @@ -74,6 +75,9 @@ public void setApplicationContext(ApplicationContext context) throws BeansExcept // region getter/setter @Override public IndexOperations getIndexOperations() { + + Assert.notNull("indexOperations are not initialized"); + return indexOperations; } // endregion @@ -159,6 +163,9 @@ public List> multiSearch(List queries, List createFilterFragmentForCriteria(Criteria chainedCrite return filterList; } + @Nullable private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String fieldName) { + if (value == null) { return null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java index bffb1c0f3..a1f9c919c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java @@ -30,6 +30,7 @@ import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -46,8 +47,8 @@ class CriteriaQueryProcessor { QueryBuilder createQueryFromCriteria(Criteria criteria) { - if (criteria == null) - return null; + + Assert.notNull(criteria, "criteria must not be null"); List shouldQueryBuilderList = new LinkedList<>(); List mustNotQueryBuilderList = new LinkedList<>(); @@ -109,6 +110,7 @@ QueryBuilder createQueryFromCriteria(Criteria criteria) { return query; } + @Nullable private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) { if (chainedCriteria.getQueryCriteriaEntries().isEmpty()) return null; @@ -135,6 +137,7 @@ private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) { return query; } + @Nullable private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String fieldName) { OperationKey key = entry.getKey(); Object value = entry.getValue(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 314680272..ad2f94c3b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -93,10 +93,12 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { // region Initialization public ElasticsearchRestTemplate(RestHighLevelClient client) { + this.client = client; initialize(client, createElasticsearchConverter()); } public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { + this.client = client; initialize(client, elasticsearchConverter); } @@ -210,7 +212,7 @@ private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoor // region SearchOperations @Override - public long count(Query query, Class clazz, IndexCoordinates index) { + public long count(Query query,@Nullable Class clazz, IndexCoordinates index) { Assert.notNull(query, "query must not be null"); Assert.notNull(index, "index must not be null"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 24ce4df8e..e8c1c8c93 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -83,14 +83,16 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { .getLogger("org.springframework.data.elasticsearch.core.QUERY"); private Client client; - private String searchTimeout; + @Nullable private String searchTimeout; // region Initialization public ElasticsearchTemplate(Client client) { + this.client = client; initialize(client, createElasticsearchConverter()); } public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter) { + this.client = client; initialize(client, elasticsearchConverter); } @@ -102,6 +104,7 @@ private void initialize(Client client, ElasticsearchConverter elasticsearchConve // endregion // region getter/setter + @Nullable public String getSearchTimeout() { return searchTimeout; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 021673938..95113f373 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -867,6 +867,7 @@ private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null; } + @Nullable private String getPersistentEntityId(Object entity) { Object identifier = elasticsearchConverter.getMappingContext() // diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java index f7a4e10ee..17973223c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.ClassPathResource; +import org.springframework.lang.Nullable; import org.springframework.util.StreamUtils; /** @@ -40,6 +41,7 @@ public abstract class ResourceUtil { * @param url * @return */ + @Nullable public static String readFileFromClasspath(String url) { ClassPathResource classPathResource = new ClassPathResource(url); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java index 65577a757..1445e0e84 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java @@ -2,12 +2,14 @@ package org.springframework.data.elasticsearch.core; import org.springframework.data.domain.Page; +import org.springframework.lang.Nullable; /** * @author Artur Konczak + * @author Peter-Josef Meisch */ public interface ScrolledPage extends Page { + @Nullable String getScrollId(); - } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java index 086845c92..41014fae0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/AggregatedPage.java @@ -4,6 +4,7 @@ import org.elasticsearch.search.aggregations.Aggregations; import org.springframework.data.elasticsearch.core.ScoredPage; import org.springframework.data.elasticsearch.core.ScrolledPage; +import org.springframework.lang.Nullable; /** * @author Petar Tahchiev @@ -16,7 +17,7 @@ public interface AggregatedPage extends ScrolledPage, ScoredPage { boolean hasAggregations(); - Aggregations getAggregations(); + @Nullable Aggregations getAggregations(); - Aggregation getAggregation(String name); + @Nullable Aggregation getAggregation(String name); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java index 1bdff8c87..88fd756d4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java @@ -25,6 +25,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; +import org.springframework.lang.Nullable; /** * @author Petar Tahchiev @@ -35,8 +36,8 @@ */ public class AggregatedPageImpl extends PageImpl implements AggregatedPage { - private Aggregations aggregations; - private String scrollId; + @Nullable private Aggregations aggregations; + @Nullable private String scrollId; private float maxScore; private static Pageable pageableOrUnpaged(Pageable pageable) { @@ -114,15 +115,18 @@ public boolean hasAggregations() { } @Override + @Nullable public Aggregations getAggregations() { return aggregations; } @Override + @Nullable public Aggregation getAggregation(String name) { return aggregations == null ? null : aggregations.get(name); } + @Nullable @Override public String getScrollId() { return scrollId; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/package-info.java new file mode 100644 index 000000000..c7553ddc6 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.aggregation.impl; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/package-info.java new file mode 100644 index 000000000..c15f3e1c4 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.aggregation; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java new file mode 100644 index 000000000..bbd425849 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.client.support; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java index baaa5911d..ee0fc4ace 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java @@ -1,27 +1,23 @@ package org.springframework.data.elasticsearch.core.completion; -import com.fasterxml.jackson.annotation.JsonInclude; - import java.util.List; import java.util.Map; +import org.springframework.lang.Nullable; + /** * Based on the reference doc - * https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-completion.html * * @author Mewes Kochheim * @author Robert Gruendler + * @author Peter-Josef Meisch */ -@JsonInclude(value = JsonInclude.Include.NON_NULL) public class Completion { private String[] input; - private Map> contexts; - private Integer weight; - - private Completion() { - // required by mapper to instantiate object - } + @Nullable private Map> contexts; + @Nullable private Integer weight; public Completion(String[] input) { this.input = input; @@ -35,6 +31,7 @@ public void setInput(String[] input) { this.input = input; } + @Nullable public Integer getWeight() { return weight; } @@ -43,6 +40,7 @@ public void setWeight(Integer weight) { this.weight = weight; } + @Nullable public Map> getContexts() { return contexts; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/completion/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/completion/package-info.java new file mode 100644 index 000000000..6615b6eb1 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/completion/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.completion; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 0f5716ede..ab7cb01e6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -147,7 +147,7 @@ public void afterPropertiesSet() { @Override public AggregatedPage> mapResults(SearchDocumentResponse response, Class type, - Pageable pageable) { + @Nullable Pageable pageable) { List> results = response.getSearchDocuments().stream() // .map(searchDocument -> read(type, searchDocument)) // @@ -653,6 +653,7 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert collectionSource.map(it -> { if (it == null) { + //noinspection ReturnOfNull return null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java index baa01ef51..5ce581e58 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/package-info.java @@ -1,2 +1,3 @@ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.core.convert; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index c309143ce..b4226908a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -124,6 +124,7 @@ public static List from(MultiGetResponse source) { Assert.notNull(source, "MultiGetResponse must not be null"); + //noinspection ReturnOfNull return Arrays.stream(source.getResponses()) // .map(itemResponse -> itemResponse.isFailed() ? null : DocumentAdapters.from(itemResponse.getResponse())) // .filter(Objects::nonNull).collect(Collectors.toList()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/document/package-info.java index 80eaa33be..02405154f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/package-info.java @@ -1,5 +1,3 @@ -/** - * interfaces and classes related to the Document representation of Elasticsearch documents. - */ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.core.document; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/package-info.java new file mode 100644 index 000000000..bb92b2929 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.geo; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java index c3c458a46..2fd24e9c7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java @@ -1,5 +1,3 @@ -/** - * infrastructure to define the Elasticsearch mapping for an index. - */ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.core.index; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 330a5bf04..1111d172c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -41,20 +41,24 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends BasicPersistentEntit private @Nullable ElasticsearchPersistentProperty parentIdProperty; private @Nullable ElasticsearchPersistentProperty scoreProperty; private @Nullable String settingPath; - private VersionType versionType; + private @Nullable VersionType versionType; private boolean createIndexAndMapping; private final Map fieldNamePropertyCache = new ConcurrentHashMap<>(); @@ -133,6 +133,7 @@ public IndexCoordinates getIndexCoordinates() { return IndexCoordinates.of(getIndexName()).withTypes(getIndexType()); } + @Nullable @Override public String getIndexStoreType() { return indexStoreType; @@ -153,21 +154,25 @@ public boolean isUseServerConfiguration() { return useServerConfiguration; } + @Nullable @Override public String getRefreshInterval() { return refreshInterval; } + @Nullable @Override public String getParentType() { return parentType; } + @Nullable @Override public ElasticsearchPersistentProperty getParentIdProperty() { return parentIdProperty; } + @Nullable @Override public VersionType getVersionType() { return versionType; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index 2b2207262..5239b9107 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -53,7 +53,7 @@ public class SimpleElasticsearchPersistentProperty extends private final boolean isParent; private final boolean isId; private final @Nullable String annotatedFieldName; - private ElasticsearchPersistentPropertyConverter propertyConverter; + @Nullable private ElasticsearchPersistentPropertyConverter propertyConverter; public SimpleElasticsearchPersistentProperty(Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { @@ -86,6 +86,7 @@ public boolean hasPropertyConverter() { return propertyConverter != null; } + @Nullable @Override public ElasticsearchPersistentPropertyConverter getPropertyConverter() { return propertyConverter; @@ -167,7 +168,7 @@ public boolean isIdProperty() { */ @Override protected Association createAssociation() { - return null; + throw new UnsupportedOperationException(); } /* diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java index c8e7cb653..3c44ffb2c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/package-info.java @@ -1,5 +1,3 @@ -/** - * Infrastructure for the Elasticsearch document-to-object mapping subsystem. - */ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.core.mapping; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/package-info.java new file mode 100644 index 000000000..9c29d17f6 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 2a98092d8..5853c7123 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -26,6 +26,7 @@ import org.elasticsearch.action.support.IndicesOptions; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -42,21 +43,22 @@ abstract class AbstractQuery implements Query { protected Pageable pageable = DEFAULT_PAGE; - protected Sort sort; + @Nullable protected Sort sort; protected List fields = new ArrayList<>(); - protected SourceFilter sourceFilter; + @Nullable protected SourceFilter sourceFilter; protected float minScore; - protected Collection ids; - protected String route; + @Nullable protected Collection ids; + @Nullable protected String route; protected SearchType searchType = SearchType.DFS_QUERY_THEN_FETCH; - protected IndicesOptions indicesOptions; + @Nullable protected IndicesOptions indicesOptions; protected boolean trackScores; - protected String preference; - protected Integer maxResults; - protected HighlightQuery highlightQuery; + @Nullable protected String preference; + @Nullable protected Integer maxResults; + @Nullable protected HighlightQuery highlightQuery; private boolean trackTotalHits = false; @Override + @Nullable public Sort getSort() { return this.sort; } @@ -90,6 +92,7 @@ public void addSourceFilter(SourceFilter sourceFilter) { this.sourceFilter = sourceFilter; } + @Nullable @Override public SourceFilter getSourceFilter() { return sourceFilter; @@ -120,6 +123,7 @@ public void setMinScore(float minScore) { this.minScore = minScore; } + @Nullable @Override public Collection getIds() { return ids; @@ -129,6 +133,7 @@ public void setIds(Collection ids) { this.ids = ids; } + @Nullable @Override public String getRoute() { return route; @@ -147,6 +152,7 @@ public SearchType getSearchType() { return searchType; } + @Nullable @Override public IndicesOptions getIndicesOptions() { return indicesOptions; @@ -175,6 +181,7 @@ public void setTrackScores(boolean trackScores) { this.trackScores = trackScores; } + @Nullable @Override public String getPreference() { return preference; @@ -190,6 +197,7 @@ public boolean isLimiting() { return maxResults != null; } + @Nullable @Override public Integer getMaxResults() { return maxResults; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java index 2fe6e7509..a679555eb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java @@ -18,6 +18,8 @@ import java.util.Map; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * @author Mohsin Husen @@ -25,12 +27,12 @@ */ public class AliasBuilder { - private String aliasName; - private QueryBuilder filterBuilder; - private Map filter; - private String searchRouting; - private String indexRouting; - private String routing; + @Nullable private String aliasName; + @Nullable private QueryBuilder filterBuilder; + @Nullable private Map filter; + @Nullable private String searchRouting; + @Nullable private String indexRouting; + @Nullable private String routing; public AliasBuilder withAliasName(String aliasName) { this.aliasName = aliasName; @@ -63,8 +65,10 @@ public AliasBuilder withRouting(String routing) { } public AliasQuery build() { - AliasQuery aliasQuery = new AliasQuery(); - aliasQuery.setAliasName(aliasName); + + Assert.notNull(aliasName, "aliasName must not be null"); + + AliasQuery aliasQuery = new AliasQuery(aliasName); aliasQuery.setFilterBuilder(filterBuilder); aliasQuery.setFilter(filter); aliasQuery.setSearchRouting(searchRouting); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java index e4d710dcd..c17eaeb28 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java @@ -18,6 +18,8 @@ import java.util.Map; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * AliasQuery is useful for creating new alias or deleting existing ones @@ -27,21 +29,25 @@ */ public class AliasQuery { + public AliasQuery(String aliasName) { + + Assert.notNull(aliasName, "aliasName must not be null"); + + this.aliasName = aliasName; + } + private String aliasName; - private QueryBuilder filterBuilder; - private Map filter; - private String searchRouting; - private String indexRouting; - private String routing; + @Nullable private QueryBuilder filterBuilder; + @Nullable private Map filter; + @Nullable private String searchRouting; + @Nullable private String indexRouting; + @Nullable private String routing; public String getAliasName() { return aliasName; } - public void setAliasName(String aliasName) { - this.aliasName = aliasName; - } - + @Nullable public QueryBuilder getFilterBuilder() { return filterBuilder; } @@ -50,6 +56,7 @@ public void setFilterBuilder(QueryBuilder filterBuilder) { this.filterBuilder = filterBuilder; } + @Nullable public Map getFilter() { return filter; } @@ -58,6 +65,7 @@ public void setFilter(Map filter) { this.filter = filter; } + @Nullable public String getSearchRouting() { return searchRouting; } @@ -66,6 +74,7 @@ public void setSearchRouting(String searchRouting) { this.searchRouting = searchRouting; } + @Nullable public String getIndexRouting() { return indexRouting; } @@ -74,6 +83,7 @@ public void setIndexRouting(String indexRouting) { this.indexRouting = indexRouting; } + @Nullable public String getRouting() { return routing; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index 88a9fa158..0a2ed5a86 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -29,6 +29,7 @@ import org.springframework.data.geo.Box; import org.springframework.data.geo.Distance; import org.springframework.data.geo.Point; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; @@ -57,7 +58,7 @@ public String toString() { private static final String OR_OPERATOR = " OR "; private static final String AND_OPERATOR = " AND "; - private Field field; + private @Nullable Field field; private float boost = Float.NaN; private boolean negating = false; @@ -84,8 +85,10 @@ public Criteria(String fieldname) { * @param field */ public Criteria(Field field) { + Assert.notNull(field, "Field for criteria must not be null"); Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty"); + this.criteriaChain.add(this); this.field = field; } @@ -95,6 +98,7 @@ protected Criteria(List criteriaChain, String fieldname) { } protected Criteria(List criteriaChain, Field field) { + Assert.notNull(criteriaChain, "CriteriaChain must not be null"); Assert.notNull(field, "Field for criteria must not be null"); Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty"); @@ -525,6 +529,7 @@ private void assertNoBlankInWildcardedQuery(String searchString, boolean leading * * @return */ + @Nullable public Field getField() { return this.field; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java index 885c30b44..b68f9d1d1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.query; import org.springframework.data.domain.Pageable; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -28,7 +29,7 @@ */ public class CriteriaQuery extends AbstractQuery { - private Criteria criteria; + private @Nullable Criteria criteria; private CriteriaQuery() {} @@ -51,9 +52,9 @@ public static Query fromQuery(CriteriaQuery source) { } public static T fromQuery(CriteriaQuery source, T destination) { - if (source == null || destination == null) { - return null; - } + + Assert.notNull(source, "source must not be null"); + Assert.notNull(destination, "destination must not be null"); if (source.getCriteria() != null) { destination.addCriteria(source.getCriteria()); @@ -77,6 +78,7 @@ public final T addCriteria(Criteria criteria) { return (T) this; } + @Nullable public Criteria getCriteria() { return this.criteria; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java index ea17d96c9..9e57522f1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.query; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.lang.Nullable; /** * DeleteQuery @@ -26,10 +27,11 @@ */ public class DeleteQuery { - private QueryBuilder query; - private Integer pageSize; - private Long scrollTimeInMillis; + @Nullable private QueryBuilder query; + @Nullable private Integer pageSize; + @Nullable private Long scrollTimeInMillis; + @Nullable public QueryBuilder getQuery() { return query; } @@ -38,6 +40,7 @@ public void setQuery(QueryBuilder query) { this.query = query; } + @Nullable public Integer getPageSize() { return pageSize; } @@ -46,6 +49,7 @@ public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } + @Nullable public Long getScrollTimeInMillis() { return scrollTimeInMillis; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java index f94d278fa..a1d695cff 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilterBuilder.java @@ -15,15 +15,18 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.lang.Nullable; + /** * SourceFilter builder for providing includes and excludes. * * @Author Jon Tsiros + * @author Peter-Josef Meisch */ public class FetchSourceFilterBuilder { - private String[] includes; - private String[] excludes; + @Nullable private String[] includes; + @Nullable private String[] excludes; public FetchSourceFilterBuilder withIncludes(String... includes) { this.includes = includes; @@ -36,8 +39,10 @@ public FetchSourceFilterBuilder withExcludes(String... excludes) { } public SourceFilter build() { - if (includes == null) includes = new String[0]; - if (excludes == null) excludes = new String[0]; + if (includes == null) + includes = new String[0]; + if (excludes == null) + excludes = new String[0]; return new FetchSourceFilter(includes, excludes); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java index 7fbbb3969..38f02bd75 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java @@ -20,23 +20,21 @@ * * @author Rizwan Idrees * @author Mohsin Husen + * @author Peter-Josef Meisch */ public class GetQuery { + public GetQuery(String id) { + this.id = id; + } + private String id; public String getId() { return id; } - public void setId(String id) { - this.id = id; - } - public static GetQuery getById(String id) { - - GetQuery query = new GetQuery(); - query.setId(id); - return query; + return new GetQuery(id); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index 529d91886..b949720e3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.lang.Nullable; + /** * IndexQuery * @@ -25,12 +27,13 @@ public class IndexQuery { - private String id; - private Object object; - private Long version; - private String source; - private String parentId; + @Nullable private String id; + @Nullable private Object object; + @Nullable private Long version; + @Nullable private String source; + @Nullable private String parentId; + @Nullable public String getId() { return id; } @@ -39,6 +42,7 @@ public void setId(String id) { this.id = id; } + @Nullable public Object getObject() { return object; } @@ -47,6 +51,7 @@ public void setObject(Object object) { this.object = object; } + @Nullable public Long getVersion() { return version; } @@ -55,6 +60,7 @@ public void setVersion(Long version) { this.version = version; } + @Nullable public String getSource() { return source; } @@ -63,6 +69,7 @@ public void setSource(String source) { this.source = source; } + @Nullable public String getParentId() { return parentId; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 579b703ec..33652ba60 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.lang.Nullable; + /** * IndexQuery Builder * @@ -24,11 +26,11 @@ */ public class IndexQueryBuilder { - private String id; - private Object object; - private Long version; - private String source; - private String parentId; + @Nullable private String id; + @Nullable private Object object; + @Nullable private Long version; + @Nullable private String source; + @Nullable private String parentId; public IndexQueryBuilder withId(String id) { this.id = id; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java index c9b56dfc3..025a7b576 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java @@ -22,6 +22,7 @@ import java.util.List; import org.springframework.data.domain.Pageable; +import org.springframework.lang.Nullable; /** * MoreLikeThisQuery @@ -32,22 +33,23 @@ */ public class MoreLikeThisQuery { - private String id; + @Nullable private String id; private List searchIndices = new ArrayList<>(); private List searchTypes = new ArrayList<>(); private List fields = new ArrayList<>(); - private String routing; - private Float percentTermsToMatch; - private Integer minTermFreq; - private Integer maxQueryTerms; + @Nullable private String routing; + @Nullable private Float percentTermsToMatch; + @Nullable private Integer minTermFreq; + @Nullable private Integer maxQueryTerms; private List stopWords = new ArrayList<>(); - private Integer minDocFreq; - private Integer maxDocFreq; - private Integer minWordLen; - private Integer maxWordLen; - private Float boostTerms; + @Nullable private Integer minDocFreq; + @Nullable private Integer maxDocFreq; + @Nullable private Integer minWordLen; + @Nullable private Integer maxWordLen; + @Nullable private Float boostTerms; private Pageable pageable = DEFAULT_PAGE; + @Nullable public String getId() { return id; } @@ -80,6 +82,7 @@ public void addFields(String... fields) { addAll(this.fields, fields); } + @Nullable public String getRouting() { return routing; } @@ -88,6 +91,7 @@ public void setRouting(String routing) { this.routing = routing; } + @Nullable public Float getPercentTermsToMatch() { return percentTermsToMatch; } @@ -96,6 +100,7 @@ public void setPercentTermsToMatch(Float percentTermsToMatch) { this.percentTermsToMatch = percentTermsToMatch; } + @Nullable public Integer getMinTermFreq() { return minTermFreq; } @@ -104,6 +109,7 @@ public void setMinTermFreq(Integer minTermFreq) { this.minTermFreq = minTermFreq; } + @Nullable public Integer getMaxQueryTerms() { return maxQueryTerms; } @@ -120,6 +126,7 @@ public void addStopWords(String... stopWords) { addAll(this.stopWords, stopWords); } + @Nullable public Integer getMinDocFreq() { return minDocFreq; } @@ -128,6 +135,7 @@ public void setMinDocFreq(Integer minDocFreq) { this.minDocFreq = minDocFreq; } + @Nullable public Integer getMaxDocFreq() { return maxDocFreq; } @@ -136,6 +144,7 @@ public void setMaxDocFreq(Integer maxDocFreq) { this.maxDocFreq = maxDocFreq; } + @Nullable public Integer getMinWordLen() { return minWordLen; } @@ -144,6 +153,7 @@ public void setMinWordLen(Integer minWordLen) { this.minWordLen = minWordLen; } + @Nullable public Integer getMaxWordLen() { return maxWordLen; } @@ -152,6 +162,7 @@ public void setMaxWordLen(Integer maxWordLen) { this.maxWordLen = maxWordLen; } + @Nullable public Float getBoostTerms() { return boostTerms; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java index 78ddddd0d..71245a8c3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java @@ -24,6 +24,7 @@ import org.elasticsearch.search.collapse.CollapseBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortBuilder; +import org.springframework.lang.Nullable; /** * NativeSearchQuery @@ -38,14 +39,14 @@ public class NativeSearchQuery extends AbstractQuery { private QueryBuilder query; - private QueryBuilder filter; - private List sorts; + @Nullable private QueryBuilder filter; + @Nullable private List sorts; private final List scriptFields = new ArrayList<>(); - private CollapseBuilder collapseBuilder; - private List aggregations; - private HighlightBuilder highlightBuilder; - private HighlightBuilder.Field[] highlightFields; - private List indicesBoost; + @Nullable private CollapseBuilder collapseBuilder; + @Nullable private List aggregations; + @Nullable private HighlightBuilder highlightBuilder; + @Nullable private HighlightBuilder.Field[] highlightFields; + @Nullable private List indicesBoost; public NativeSearchQuery(QueryBuilder query) { @@ -88,6 +89,7 @@ public QueryBuilder getQuery() { return query; } + @Nullable public QueryBuilder getFilter() { return filter; } @@ -96,6 +98,7 @@ public List getElasticsearchSorts() { return sorts; } + @Nullable public HighlightBuilder getHighlightBuilder() { return highlightBuilder; } @@ -116,6 +119,7 @@ public void addScriptField(ScriptField... scriptField) { scriptFields.addAll(Arrays.asList(scriptField)); } + @Nullable public CollapseBuilder getCollapseBuilder() { return collapseBuilder; } @@ -124,6 +128,7 @@ public void setCollapseBuilder(CollapseBuilder collapseBuilder) { this.collapseBuilder = collapseBuilder; } + @Nullable public List getAggregations() { return aggregations; } @@ -141,6 +146,7 @@ public void setAggregations(List aggregations) { this.aggregations = aggregations; } + @Nullable public List getIndicesBoost() { return indicesBoost; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java index e8b292504..d58264cf9 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQueryBuilder.java @@ -29,6 +29,7 @@ import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.SortBuilder; import org.springframework.data.domain.Pageable; +import org.springframework.lang.Nullable; /** * NativeSearchQuery @@ -46,25 +47,25 @@ */ public class NativeSearchQueryBuilder { - private QueryBuilder queryBuilder; - private QueryBuilder filterBuilder; + @Nullable private QueryBuilder queryBuilder; + @Nullable private QueryBuilder filterBuilder; private List scriptFields = new ArrayList<>(); private List sortBuilders = new ArrayList<>(); private List aggregationBuilders = new ArrayList<>(); - private HighlightBuilder highlightBuilder; - private HighlightBuilder.Field[] highlightFields; + @Nullable private HighlightBuilder highlightBuilder; + @Nullable private HighlightBuilder.Field[] highlightFields; private Pageable pageable = Pageable.unpaged(); - private String[] fields; - private SourceFilter sourceFilter; - private CollapseBuilder collapseBuilder; - private List indicesBoost; + @Nullable private String[] fields; + @Nullable private SourceFilter sourceFilter; + @Nullable private CollapseBuilder collapseBuilder; + @Nullable private List indicesBoost; private float minScore; private boolean trackScores; - private Collection ids; - private String route; - private SearchType searchType; - private IndicesOptions indicesOptions; - private String preference; + @Nullable private Collection ids; + @Nullable private String route; + @Nullable private SearchType searchType; + @Nullable private IndicesOptions indicesOptions; + @Nullable private String preference; public NativeSearchQueryBuilder withQuery(QueryBuilder queryBuilder) { this.queryBuilder = queryBuilder; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 34155b080..ff0ebc37b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -81,6 +81,7 @@ static Query findAll() { /** * @return null if not set */ + @Nullable Sort getSort(); /** @@ -109,6 +110,7 @@ static Query findAll() { * * @return SourceFilter */ + @Nullable SourceFilter getSourceFilter(); /** @@ -131,6 +133,7 @@ static Query findAll() { * * @return */ + @Nullable Collection getIds(); /** @@ -138,6 +141,7 @@ static Query findAll() { * * @return */ + @Nullable String getRoute(); /** @@ -152,6 +156,7 @@ static Query findAll() { * * @return null if not set */ + @Nullable IndicesOptions getIndicesOptions(); /** @@ -160,6 +165,7 @@ static Query findAll() { * @return * @since 3.2 */ + @Nullable String getPreference(); /** @@ -183,17 +189,18 @@ default boolean isLimiting() { * * @since 4.0 */ + @Nullable default Integer getMaxResults() { return null; } /** - * Sets the {@link HighlightQuery}.* + * Sets the {@link HighlightQuery}. * * @param highlightQuery the query to set * @since 4.0 */ - void setHighlightQuery(@Nullable HighlightQuery highlightQuery); + void setHighlightQuery(HighlightQuery highlightQuery); /** * @return the optional set {@link HighlightQuery}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index 9abca6a2d..bf4503492 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -29,12 +29,15 @@ public class SimpleField implements Field { private String name; public SimpleField(String name) { - setName(name); + Assert.notNull(name, "name must not be null"); + + this.name = name; } @Override public void setName(String name) { Assert.notNull(name, "name must not be null"); + this.name = name; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index bf9b02b90..dac5aa425 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.query; import org.elasticsearch.action.update.UpdateRequest; +import org.springframework.lang.Nullable; /** * @author Rizwan Idrees @@ -24,10 +25,11 @@ */ public class UpdateQuery { - private String id; - private UpdateRequest updateRequest; + @Nullable private String id; + @Nullable private UpdateRequest updateRequest; private boolean doUpsert; + @Nullable public String getId() { return id; } @@ -36,6 +38,7 @@ public void setId(String id) { this.id = id; } + @Nullable public UpdateRequest getUpdateRequest() { return updateRequest; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java index a22915192..1e116e69a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java @@ -17,6 +17,7 @@ import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.update.UpdateRequest; +import org.springframework.lang.Nullable; /** * @author Rizwan Idrees @@ -25,9 +26,9 @@ */ public class UpdateQueryBuilder { - private String id; - private UpdateRequest updateRequest; - private IndexRequest indexRequest; + @Nullable private String id; + @Nullable private UpdateRequest updateRequest; + @Nullable private IndexRequest indexRequest; private boolean doUpsert; public UpdateQueryBuilder withId(String id) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/query/package-info.java new file mode 100644 index 000000000..50b90a0ff --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.query; diff --git a/src/main/java/org/springframework/data/elasticsearch/package-info.java b/src/main/java/org/springframework/data/elasticsearch/package-info.java new file mode 100644 index 000000000..c90fb3237 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java new file mode 100644 index 000000000..f11afc98b --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/cdi/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.repository.cdi; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java new file mode 100644 index 000000000..9f8e26676 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/config/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.repository.config; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java new file mode 100644 index 000000000..0db3509f2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.repository.query; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java index 3086bad78..1654f41ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/package-info.java @@ -1,5 +1,3 @@ -/** - * Infrastructure for the Elasticsearch document-to-object mapping subsystem. - */ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.repository.query.parser; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 9df312dbf..544b7fe57 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -79,10 +79,8 @@ public abstract class AbstractElasticsearchRepository implements Elastics protected ElasticsearchOperations operations; protected IndexOperations indexOperations; - protected Class entityClass; - protected ElasticsearchEntityInformation entityInformation; - - public AbstractElasticsearchRepository() {} + protected @Nullable Class entityClass; + protected @Nullable ElasticsearchEntityInformation entityInformation; public AbstractElasticsearchRepository(ElasticsearchOperations operations) { Assert.notNull(operations, "ElasticsearchOperations must not be null."); @@ -125,8 +123,7 @@ private boolean createIndexAndMapping() { @Override public Optional findById(ID id) { - GetQuery query = new GetQuery(); - query.setId(stringIdRepresentation(id)); + GetQuery query = new GetQuery(stringIdRepresentation(id)); return Optional.ofNullable(operations.get(query, getEntityClass(), getIndexCoordinates())); } @@ -250,9 +247,11 @@ public Page search(Query query) { @SuppressWarnings("unchecked") @Override - public Page searchSimilar(T entity, String[] fields, Pageable pageable) { + public Page searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) { + Assert.notNull(entity, "Cannot search similar records for 'null'."); Assert.notNull(pageable, "'pageable' cannot be 'null'"); + MoreLikeThisQuery query = new MoreLikeThisQuery(); query.setId(stringIdRepresentation(extractIdFromBean(entity))); query.setPageable(pageable); @@ -395,7 +394,7 @@ private List stringIdsRepresentation(Iterable ids) { return stringIds; } - protected abstract String stringIdRepresentation(@Nullable ID id); + protected abstract @Nullable String stringIdRepresentation(@Nullable ID id); private Long extractVersionFromBean(T entity) { return entityInformation.getVersion(entity); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java index b0b2a8386..e3b5553b5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactory.java @@ -35,6 +35,7 @@ import org.springframework.data.repository.query.QueryLookupStrategy.Key; import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -47,6 +48,7 @@ * @author Mark Paluch * @author Christoph Strobl * @author Sascha Woo + * @author Peter-Josef Meisch */ public class ElasticsearchRepositoryFactory extends RepositoryFactorySupport { @@ -87,7 +89,7 @@ private static boolean isQueryDslRepository(Class repositoryInterface) { } @Override - protected Optional getQueryLookupStrategy(Key key, + protected Optional getQueryLookupStrategy(@Nullable Key key, QueryMethodEvaluationContextProvider evaluationContextProvider) { return Optional.of(new ElasticsearchQueryLookupStrategy()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java index 625f9e00d..ac1ded77f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchRepositoryFactoryBean.java @@ -21,6 +21,7 @@ import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.data.repository.core.support.RepositoryFactorySupport; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -30,11 +31,12 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Mark Paluch + * @author Peter-Josef Meisch */ -public class ElasticsearchRepositoryFactoryBean, S, ID extends Serializable> extends - RepositoryFactoryBeanSupport { +public class ElasticsearchRepositoryFactoryBean, S, ID extends Serializable> + extends RepositoryFactoryBeanSupport { - private ElasticsearchOperations operations; + @Nullable private ElasticsearchOperations operations; /** * Creates a new {@link ElasticsearchRepositoryFactoryBean} for the given repository interface. @@ -70,6 +72,9 @@ public void afterPropertiesSet() { @Override protected RepositoryFactorySupport createRepositoryFactory() { + + Assert.notNull(operations, "operations are not initialized"); + return new ElasticsearchRepositoryFactory(operations); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index e178aa949..73414212b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -18,6 +18,7 @@ import java.util.Objects; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.lang.Nullable; /** * Elasticsearch specific repository implementation. Likely to be used as target within @@ -27,13 +28,10 @@ * @author Mohsin Husen * @author Ryan Henszey * @author Sascha Woo + * @author Peter-Josef Meisch */ public class SimpleElasticsearchRepository extends AbstractElasticsearchRepository { - public SimpleElasticsearchRepository() { - super(); - } - public SimpleElasticsearchRepository(ElasticsearchEntityInformation metadata, ElasticsearchOperations elasticsearchOperations) { super(metadata, elasticsearchOperations); @@ -44,7 +42,7 @@ public SimpleElasticsearchRepository(ElasticsearchOperations elasticsearchOperat } @Override - protected String stringIdRepresentation(ID id) { + protected @Nullable String stringIdRepresentation(@Nullable ID id) { return Objects.toString(id, null); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java index 3c33bb8e0..17be692af 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/package-info.java @@ -1,5 +1,3 @@ -/** - * infrastructure to define the Elasticsearch mapping for an index. - */ @org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.repository.support; diff --git a/src/main/java/org/springframework/data/elasticsearch/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/support/package-info.java new file mode 100644 index 000000000..0ad015c73 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/support/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.support; diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index d5e2baaf0..8e8150f18 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -149,8 +149,7 @@ public void shouldIndexMultipleLevelNestedObject() { indexOperations.refresh(PersonMultipleLevelNested.class); // then - GetQuery getQuery = new GetQuery(); - getQuery.setId("1"); + GetQuery getQuery = new GetQuery("1"); PersonMultipleLevelNested personIndexed = operations.get(getQuery, PersonMultipleLevelNested.class, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); assertThat(personIndexed).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/package-info.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/package-info.java new file mode 100644 index 000000000..3d808c547 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.client.reactive; diff --git a/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java b/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java new file mode 100644 index 000000000..79701328c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/util/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.client.util; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java index b93bb01da..615c3e3ec 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/ElasticsearchConfigurationTests.java @@ -28,6 +28,7 @@ import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -68,7 +69,7 @@ public void bootstrapsRepository() { @Document(indexName = "test-index-config-abstractelasticsearchconfiguraiton", createIndex = false) static class CreateIndexFalseEntity { - @Id private String id; + @Nullable @Id private String id; } interface CreateIndexFalseRepository extends ElasticsearchRepository {} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/package-info.java b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/package-info.java new file mode 100644 index 000000000..90bdb2cb8 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/abstractelasticsearchconfiguration/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.config.abstractelasticsearchconfiguration; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index e285c3c13..37c3dbf04 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -47,6 +47,7 @@ import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.data.repository.Repository; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -60,7 +61,7 @@ @ContextConfiguration(classes = { EnableElasticsearchRepositoriesTests.Config.class }) public class EnableElasticsearchRepositoriesTests implements ApplicationContextAware { - ApplicationContext context; + @Nullable ApplicationContext context; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java new file mode 100644 index 000000000..55d936ed9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.config.notnested; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java index 6fe403e81..d7a6c913f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -32,6 +32,7 @@ import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.lang.Nullable; /** * Tests for the mapping of {@link CriteriaQuery} by a @@ -95,10 +96,10 @@ void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException { } static class Person { - @Id String id; - @Field(name = "first-name") String firstName; - @Field(name = "last-name") String lastName; - @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, + @Nullable @Id String id; + @Nullable @Field(name = "first-name") String firstName; + @Nullable @Field(name = "last-name") String lastName; + @Nullable @Field(name = "birth-date", type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate birthDate; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java index a1909435b..8382cdc20 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -44,6 +44,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.lang.Nullable; /** * Tests for {@link ElasticsearchPartQuery}. Resides in the core package, as we need an instance of the @@ -549,11 +550,12 @@ private interface SampleRepository extends ElasticsearchRepository } static class Book { - @Id private String id; - private String name; - private Integer price; + @Nullable @Id private String id; + @Nullable private String name; + @Nullable private Integer price; @Field(type = FieldType.Boolean) private boolean available; + @Nullable public String getId() { return id; } @@ -562,6 +564,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -570,6 +573,7 @@ public void setName(String name) { this.name = name; } + @Nullable public Integer getPrice() { return price; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 460d02683..f513ed4d0 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -76,6 +76,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; /** * Base for testing rest/transport templates. Contains the test common to both implementing classes. @@ -199,8 +200,7 @@ public void shouldReturnObjectForGivenId() { operations.index(indexQuery, index); // when - GetQuery getQuery = new GetQuery(); - getQuery.setId(documentId); + GetQuery getQuery = new GetQuery(documentId); SampleEntity sampleEntity1 = operations.get(getQuery, SampleEntity.class, index); // then @@ -415,8 +415,7 @@ public void shouldDoBulkUpdate() { operations.bulkUpdate(queries, index); // then - GetQuery getQuery = new GetQuery(); - getQuery.setId(documentId); + GetQuery getQuery = new GetQuery(documentId); SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -1431,8 +1430,7 @@ public void shouldDoPartialUpdateForExistingDocument() { operations.update(updateQuery, index); // then - GetQuery getQuery = new GetQuery(); - getQuery.setId(documentId); + GetQuery getQuery = new GetQuery(documentId); SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -1497,8 +1495,7 @@ public void shouldDoUpsertIfDocumentDoesNotExist() { operations.update(updateQuery, index); // then - GetQuery getQuery = new GetQuery(); - getQuery.setId(documentId); + GetQuery getQuery = new GetQuery(documentId); SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(message); } @@ -1741,8 +1738,7 @@ public void shouldDoIndexWithoutId() { // then assertThat(sampleEntity.getId()).isEqualTo(documentId); - GetQuery getQuery = new GetQuery(); - getQuery.setId(documentId); + GetQuery getQuery = new GetQuery(documentId); SampleEntity result = operations.get(getQuery, SampleEntity.class, index); assertThat(result.getId()).isEqualTo(documentId); } @@ -3043,8 +3039,10 @@ static class SampleMappingEntity { static class NestedEntity { + @Nullable @Field(type = Text) private String someField; + @Nullable public String getSomeField() { return someField; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java index 693f8ad0a..ab791e3e9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java @@ -35,14 +35,15 @@ import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; +import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch */ class RequestFactoryTest { - private static RequestFactory requestFactory; - private static MappingElasticsearchConverter converter; + @Nullable private static RequestFactory requestFactory; + @Nullable private static MappingElasticsearchConverter converter; @BeforeAll @@ -118,8 +119,8 @@ void shouldAddRouting() throws JSONException { } static class Person { - @Id String id; - @Field(name = "last-name") String lastName; - @Field(name = "current-location") GeoPoint location; + @Nullable @Id String id; + @Nullable @Field(name = "last-name") String lastName; + @Nullable @Field(name = "current-location") GeoPoint location; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 19812e941..0cb33dfc2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -43,6 +43,7 @@ import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -217,10 +218,11 @@ public void shouldFindSuggestionsWithWeightsForGivenCriteriaQueryUsingAnnotatedC */ static class NonDocumentEntity { - @Id private String someId; - private String someField1; - private String someField2; + @Nullable @Id private String someId; + @Nullable private String someField1; + @Nullable private String someField2; + @Nullable public String getSomeField1() { return someField1; } @@ -229,6 +231,7 @@ public void setSomeField1(String someField1) { this.someField1 = someField1; } + @Nullable public String getSomeField2() { return someField2; } @@ -244,11 +247,11 @@ public void setSomeField2(String someField2) { @Document(indexName = "test-index-core-completion", replicas = 0, refreshInterval = "-1") static class CompletionEntity { - @Id private String id; + @Nullable @Id private String id; - private String name; + @Nullable private String name; - @CompletionField(maxInputLength = 100) private Completion suggest; + @Nullable @CompletionField(maxInputLength = 100) private Completion suggest; private CompletionEntity() {} @@ -256,6 +259,7 @@ public CompletionEntity(String id) { this.id = id; } + @Nullable public String getId() { return id; } @@ -264,6 +268,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -272,6 +277,7 @@ public void setName(String name) { this.name = name; } + @Nullable public Completion getSuggest() { return suggest; } @@ -327,10 +333,9 @@ public IndexQuery buildIndex() { @Document(indexName = "test-index-annotated-completion", replicas = 0, refreshInterval = "-1") static class AnnotatedCompletionEntity { - @Id private String id; - private String name; - - @CompletionField(maxInputLength = 100) private Completion suggest; + @Nullable @Id private String id; + @Nullable private String name; + @Nullable @CompletionField(maxInputLength = 100) private Completion suggest; private AnnotatedCompletionEntity() {} @@ -338,6 +343,7 @@ public AnnotatedCompletionEntity(String id) { this.id = id; } + @Nullable public String getId() { return id; } @@ -346,6 +352,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -354,6 +361,7 @@ public void setName(String name) { this.name = name; } + @Nullable public Completion getSuggest() { return suggest; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index b5ed2c959..da770d38d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -51,6 +51,7 @@ import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -216,10 +217,11 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti */ static class NonDocumentEntity { - @Id private String someId; - private String someField1; - private String someField2; + @Nullable @Id private String someId; + @Nullable private String someField1; + @Nullable private String someField2; + @Nullable public String getSomeField1() { return someField1; } @@ -228,6 +230,7 @@ public void setSomeField1(String someField1) { this.someField1 = someField1; } + @Nullable public String getSomeField2() { return someField2; } @@ -245,10 +248,10 @@ public void setSomeField2(String someField2) { static class ContextCompletionEntity { public static final String LANGUAGE_CATEGORY = "language"; - @Id private String id; - private String name; + @Nullable @Id private String id; + @Nullable private String name; - @CompletionField(maxInputLength = 100, contexts = { + @Nullable @CompletionField(maxInputLength = 100, contexts = { @CompletionContext(name = LANGUAGE_CATEGORY, type = ContextMapping.Type.CATEGORY) }) private Completion suggest; private ContextCompletionEntity() {} @@ -257,6 +260,7 @@ public ContextCompletionEntity(String id) { this.id = id; } + @Nullable public String getId() { return id; } @@ -265,6 +269,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -273,6 +278,7 @@ public void setName(String name) { this.name = name; } + @Nullable public Completion getSuggest() { return suggest; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 79a8a950e..35a27b6a4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -26,7 +26,6 @@ import lombok.NoArgsConstructor; import lombok.RequiredArgsConstructor; -import java.io.IOException; import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; @@ -61,6 +60,7 @@ import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; import org.springframework.data.mapping.context.MappingContext; +import org.springframework.lang.Nullable; /** * Unit tests for {@link MappingElasticsearchConverter}. @@ -629,10 +629,10 @@ private Map writeToMap(Object source) { public static class Sample { - public @ReadOnlyProperty String readOnly; - public @Transient String annotatedTransientProperty; - public transient String javaTransientProperty; - public String property; + @Nullable public @ReadOnlyProperty String readOnly; + @Nullable public @Transient String annotatedTransientProperty; + @Nullable public transient String javaTransientProperty; + @Nullable public String property; } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 8ac57c73a..d409c5322 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -65,6 +65,7 @@ import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; import org.springframework.data.geo.Polygon; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -562,59 +563,59 @@ static class FieldNameEntity { @Document(indexName = "fieldname-index") static class IdEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; } @Document(indexName = "fieldname-index") static class TextEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; @Field(name = "text-property", type = FieldType.Text) // - private String textProperty; + @Nullable private String textProperty; } @Document(indexName = "fieldname-index") static class MappingEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; @Field("mapping-property") @Mapping(mappingPath = "/mappings/test-field-analyzed-mappings.json") // - private byte[] mappingProperty; + @Nullable private byte[] mappingProperty; } @Document(indexName = "fieldname-index") static class GeoPointEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; - @Field("geopoint-property") private GeoPoint geoPoint; + @Nullable @Field("geopoint-property") private GeoPoint geoPoint; } @Document(indexName = "fieldname-index") static class CircularEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; - @Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) // + @Nullable @Field(name = "circular-property", type = FieldType.Object, ignoreFields = { "circular-property" }) // private CircularEntity circularProperty; } @Document(indexName = "fieldname-index") static class CompletionEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; - @Field("completion-property") @CompletionField(maxInputLength = 100) // + @Nullable @Field("completion-property") @CompletionField(maxInputLength = 100) // private Completion suggest; } @Document(indexName = "fieldname-index") static class MultiFieldEntity { - @Id @Field("id-property") private String id; + @Nullable @Id @Field("id-property") private String id; - @Field("multifield-property") // + @Nullable @Field("multifield-property") // @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), otherFields = { @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") }) // private String description; @@ -629,9 +630,9 @@ static class MultiFieldEntity { @Document(indexName = "test-index-minimal") static class MinimalChildEntity { - @Id private String id; + @Nullable @Id private String id; - @Parent(type = "parentType") private String parentId; + @Nullable @Parent(type = "parentType") private String parentId; } /** @@ -663,8 +664,9 @@ static class Book { @Document(indexName = "test-index-simple-recursive-mapping-builder", replicas = 0, refreshInterval = "-1") static class SimpleRecursiveEntity { - @Id private String id; - @Field(type = FieldType.Object, ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject; + @Nullable @Id private String id; + @Nullable @Field(type = FieldType.Object, + ignoreFields = { "circularObject" }) private SimpleRecursiveEntity circularObject; } /** @@ -713,9 +715,10 @@ static class NormalizerEntity { */ static class Author { - private String id; - private String name; + @Nullable private String id; + @Nullable private String name; + @Nullable public String getId() { return id; } @@ -724,6 +727,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -739,8 +743,9 @@ public void setName(String name) { @Document(indexName = "test-index-sample-inherited-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleInheritedEntity extends AbstractInheritedEntity { - @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; + @Nullable @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; + @Nullable public String getMessage() { return message; } @@ -808,10 +813,11 @@ static class StockPrice { */ static class AbstractInheritedEntity { - @Id private String id; + @Nullable @Id private String id; - @Field(type = FieldType.Date, index = false) private Date createdDate; + @Nullable @Field(type = FieldType.Date, index = false) private Date createdDate; + @Nullable public String getId() { return id; } @@ -820,6 +826,7 @@ public void setId(String id) { this.id = id; } + @Nullable public Date getCreatedDate() { return createdDate; } @@ -835,12 +842,13 @@ public void setCreatedDate(Date createdDate) { @Document(indexName = "test-index-recursive-mapping-mapping-builder", replicas = 0, refreshInterval = "-1") static class SampleTransientEntity { - @Id private String id; + @Nullable @Id private String id; - @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; + @Nullable @Field(type = Text, index = false, store = true, analyzer = "standard") private String message; - @Transient private SampleTransientEntity.NestedEntity nested; + @Nullable @Transient private SampleTransientEntity.NestedEntity nested; + @Nullable public String getId() { return id; } @@ -849,6 +857,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getMessage() { return message; } @@ -860,7 +869,7 @@ public void setMessage(String message) { static class NestedEntity { @Field private static SampleTransientEntity.NestedEntity someField = new SampleTransientEntity.NestedEntity(); - @Field private Boolean something; + @Nullable @Field private Boolean something; public SampleTransientEntity.NestedEntity getSomeField() { return someField; @@ -870,6 +879,7 @@ public void setSomeField(SampleTransientEntity.NestedEntity someField) { NestedEntity.someField = someField; } + @Nullable public Boolean getSomething() { return something; } @@ -913,7 +923,7 @@ static class GeoEntity { */ @Document(indexName = "test-index-user-mapping-builder") static class User { - @Id private String id; + @Nullable @Id private String id; @Field(type = FieldType.Nested, ignoreFields = { "users" }) private Set groups = new HashSet<>(); } @@ -924,54 +934,55 @@ static class User { @Document(indexName = "test-index-group-mapping-builder") static class Group { - @Id String id; + @Nullable @Id String id; @Field(type = FieldType.Nested, ignoreFields = { "groups" }) private Set users = new HashSet<>(); } @Document(indexName = "test-index-field-mapping-parameters") static class FieldMappingParameters { - @Field private String indexTrue; - @Field(index = false) private String indexFalse; - @Field(store = true) private String storeTrue; - @Field private String storeFalse; - @Field private String coerceTrue; - @Field(coerce = false) private String coerceFalse; - @Field(fielddata = true) private String fielddataTrue; - @Field private String fielddataFalse; - @Field(copyTo = { "foo", "bar" }) private String copyTo; - @Field(ignoreAbove = 42) private String ignoreAbove; - @Field(type = FieldType.Integer) private String type; - @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private LocalDate date; - @Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers; - @Field(type = Keyword) private String docValuesTrue; - @Field(type = Keyword, docValues = false) private String docValuesFalse; - @Field(ignoreMalformed = true) private String ignoreMalformedTrue; - @Field() private String ignoreMalformedFalse; - @Field(indexOptions = IndexOptions.none) private String indexOptionsNone; - @Field(indexOptions = IndexOptions.positions) private String indexOptionsPositions; - @Field(indexPhrases = true) private String indexPhrasesTrue; - @Field() private String indexPhrasesFalse; - @Field(indexPrefixes = @IndexPrefixes) private String defaultIndexPrefixes; - @Field(indexPrefixes = @IndexPrefixes(minChars = 1, maxChars = 10)) private String customIndexPrefixes; - @Field private String normsTrue; - @Field(norms = false) private String normsFalse; - @Field private String nullValueNotSet; - @Field(nullValue = "NULLNULL") private String nullValueSet; - @Field(positionIncrementGap = 42) private String positionIncrementGap; - @Field private String similarityDefault; - @Field(similarity = Similarity.Boolean) private String similarityBoolean; - @Field private String termVectorDefault; - @Field(termVector = TermVector.with_offsets) private String termVectorWithOffsets; - @Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat; + @Nullable @Field private String indexTrue; + @Nullable @Field(index = false) private String indexFalse; + @Nullable @Field(store = true) private String storeTrue; + @Nullable @Field private String storeFalse; + @Nullable @Field private String coerceTrue; + @Nullable @Field(coerce = false) private String coerceFalse; + @Nullable @Field(fielddata = true) private String fielddataTrue; + @Nullable @Field private String fielddataFalse; + @Nullable @Field(copyTo = { "foo", "bar" }) private String copyTo; + @Nullable @Field(ignoreAbove = 42) private String ignoreAbove; + @Nullable @Field(type = FieldType.Integer) private String type; + @Nullable @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "YYYYMMDD") private LocalDate date; + @Nullable @Field(analyzer = "ana", searchAnalyzer = "sana", normalizer = "norma") private String analyzers; + @Nullable @Field(type = Keyword) private String docValuesTrue; + @Nullable @Field(type = Keyword, docValues = false) private String docValuesFalse; + @Nullable @Field(ignoreMalformed = true) private String ignoreMalformedTrue; + @Nullable @Field() private String ignoreMalformedFalse; + @Nullable @Field(indexOptions = IndexOptions.none) private String indexOptionsNone; + @Nullable @Field(indexOptions = IndexOptions.positions) private String indexOptionsPositions; + @Nullable @Field(indexPhrases = true) private String indexPhrasesTrue; + @Nullable @Field() private String indexPhrasesFalse; + @Nullable @Field(indexPrefixes = @IndexPrefixes) private String defaultIndexPrefixes; + @Nullable @Field(indexPrefixes = @IndexPrefixes(minChars = 1, maxChars = 10)) private String customIndexPrefixes; + @Nullable @Field private String normsTrue; + @Nullable @Field(norms = false) private String normsFalse; + @Nullable @Field private String nullValueNotSet; + @Nullable @Field(nullValue = "NULLNULL") private String nullValueSet; + @Nullable @Field(positionIncrementGap = 42) private String positionIncrementGap; + @Nullable @Field private String similarityDefault; + @Nullable @Field(similarity = Similarity.Boolean) private String similarityBoolean; + @Nullable @Field private String termVectorDefault; + @Nullable @Field(termVector = TermVector.with_offsets) private String termVectorWithOffsets; + @Nullable @Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat; } @Document(indexName = "test-index-configure-dynamic-mapping") @DynamicMapping(DynamicMappingValue.False) static class ConfigureDynamicMappingEntity { - @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author; + @Nullable @DynamicMapping(DynamicMappingValue.Strict) @Field(type = FieldType.Object) private Author author; + @Nullable public Author getAuthor() { return author; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java index ecf9b46e3..f12c8e541 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java @@ -10,6 +10,7 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch @@ -59,10 +60,10 @@ public void shouldNotAllowDocValuesFalseOnFieldTypeNested() { } static class AnnotatedClass { - @Field private String field; - @InnerField(suffix = "test", type = FieldType.Text) private String innerField; + @Nullable @Field private String field; + @Nullable @InnerField(suffix = "test", type = FieldType.Text) private String innerField; @Score private float score; - @Field(type = FieldType.Text, docValues = false) private String docValuesText; - @Field(type = FieldType.Nested, docValues = false) private String docValuesNested; + @Nullable @Field(type = FieldType.Text, docValues = false) private String docValuesText; + @Nullable @Field(type = FieldType.Nested, docValues = false) private String docValuesNested; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java index 7ffcdd987..8faff283f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java @@ -17,7 +17,6 @@ import static org.assertj.core.api.Assertions.*; -import java.io.IOException; import java.util.HashMap; import java.util.Map; @@ -29,6 +28,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -46,8 +46,7 @@ public void testCorrectDynamicTemplatesMappings() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntity.class); - String EXPECTED_MAPPING_ONE = "{\"dynamic_templates\":" - + "[{\"with_custom_analyzer\":{" + String EXPECTED_MAPPING_ONE = "{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"names.*\"}}]," + "\"properties\":{\"names\":{\"type\":\"object\"}}}"; @@ -58,8 +57,7 @@ public void testCorrectDynamicTemplatesMappings() { public void testCorrectDynamicTemplatesMappingsTwo() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDynamicTemplatesEntityTwo.class); - String EXPECTED_MAPPING_TWO = "{\"dynamic_templates\":" - + "[{\"with_custom_analyzer\":{" + String EXPECTED_MAPPING_TWO = "{\"dynamic_templates\":" + "[{\"with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," + "\"path_match\":\"names.*\"}}," + "{\"participantA1_with_custom_analyzer\":{" + "\"mapping\":{\"type\":\"string\",\"analyzer\":\"standard_lowercase_asciifolding\"}," @@ -71,27 +69,25 @@ public void testCorrectDynamicTemplatesMappingsTwo() { /** * @author Petr Kukral */ - @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", replicas = 0, refreshInterval = "-1") @DynamicTemplates(mappingPath = "/mappings/test-dynamic_templates_mappings.json") static class SampleDynamicTemplatesEntity { - @Id private String id; + @Nullable @Id private String id; - @Field(type = FieldType.Object) private Map names = new HashMap<>(); + @Nullable @Field(type = FieldType.Object) private Map names = new HashMap<>(); } /** * @author Petr Kukral */ - @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-dynamictemplates", indexStoreType = "memory", replicas = 0, refreshInterval = "-1") @DynamicTemplates(mappingPath = "/mappings/test-dynamic_templates_mappings_two.json") static class SampleDynamicTemplatesEntityTwo { - @Id private String id; + @Nullable @Id private String id; - @Field(type = FieldType.Object) private Map names = new HashMap<>(); + @Nullable @Field(type = FieldType.Object) private Map names = new HashMap<>(); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index d5ee992c8..ec103ba56 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -27,6 +27,7 @@ import org.springframework.data.mapping.model.SimpleTypeHolder; import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; +import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; /** @@ -105,8 +106,9 @@ private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasti private class EntityWithWrongVersionType { - @Version private String version; + @Nullable @Version private String version; + @Nullable public String getVersion() { return version; } @@ -118,9 +120,10 @@ public void setVersion(String version) { private class EntityWithMultipleVersionField { - @Version private Long version1; - @Version private Long version2; + @Nullable @Version private Long version1; + @Nullable @Version private Long version2; + @Nullable public Long getVersion1() { return version1; } @@ -129,6 +132,7 @@ public void setVersion1(Long version1) { this.version1 = version1; } + @Nullable public Long getVersion2() { return version2; } @@ -147,7 +151,7 @@ static class TwoScoreProperties { } private static class FieldNameEntity { - @Id private String id; - @Field(name = "renamed-field") private String renamedField; + @Nullable @Id private String id; + @Nullable @Field(name = "renamed-field") private String renamedField; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index f6b08b2f8..a64ddb0f6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -27,6 +27,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.mapping.MappingException; +import org.springframework.lang.Nullable; /** * Unit tests for {@link SimpleElasticsearchPersistentProperty}. @@ -110,20 +111,20 @@ void shouldConvertToLocalDate() { } static class InvalidScoreProperty { - @Score String scoreProperty; + @Nullable @Score String scoreProperty; } static class FieldNameProperty { - @Field(name = "by-name") String fieldProperty; + @Nullable @Field(name = "by-name") String fieldProperty; } static class FieldValueProperty { - @Field(value = "by-value") String fieldProperty; + @Nullable @Field(value = "by-value") String fieldProperty; } static class DatesProperty { - @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date; - @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate; - @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; + @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date; + @Nullable @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate; + @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java index a1241cac9..48ee821db 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/HighlightQueryBuilderTests.java @@ -30,6 +30,7 @@ import org.springframework.data.elasticsearch.annotations.HighlightParameters; import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -117,10 +118,11 @@ private void annotatedMethodWithManyValue() {} @Document(indexName = "dont-care") private static class HighlightEntity { - @Id private String id; - @Field(name = "some-field") private String someField; - @Field(name = "other-field") private String otherField; + @Nullable @Id private String id; + @Nullable @Field(name = "some-field") private String someField; + @Nullable @Field(name = "other-field") private String otherField; + @Nullable public String getId() { return id; } @@ -129,6 +131,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getSomeField() { return someField; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java index 167288026..bfafdb4cd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryClient.java @@ -17,17 +17,21 @@ import javax.inject.Inject; +import org.springframework.lang.Nullable; + /** * @author Mohsin Husen * @author Oliver Gierke * @author Mark Paluch + * @author Peter-Josef Meisch */ class CdiRepositoryClient { - private CdiProductRepository repository; - private SamplePersonRepository samplePersonRepository; - private QualifiedProductRepository qualifiedProductRepository; + @Nullable private CdiProductRepository repository; + @Nullable private SamplePersonRepository samplePersonRepository; + @Nullable private QualifiedProductRepository qualifiedProductRepository; + @Nullable public CdiProductRepository getRepository() { return repository; } @@ -37,6 +41,7 @@ public void setRepository(CdiProductRepository repository) { this.repository = repository; } + @Nullable public SamplePersonRepository getSamplePersonRepository() { return samplePersonRepository; } @@ -46,6 +51,7 @@ public void setSamplePersonRepository(SamplePersonRepository samplePersonReposit this.samplePersonRepository = samplePersonRepository; } + @Nullable public QualifiedProductRepository getQualifiedProductRepository() { return qualifiedProductRepository; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index d42f2b308..6eafb7cc4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -41,6 +41,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.lang.Nullable; /** * @author Mohsin Husen @@ -50,7 +51,7 @@ */ public class CdiRepositoryTests { - private static CdiTestContainer cdiContainer; + @Nullable private static CdiTestContainer cdiContainer; private CdiProductRepository repository; private SamplePersonRepository personRepository; private QualifiedProductRepository qualifiedProductRepository; @@ -158,8 +159,7 @@ public void returnOneFromCustomImpl() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-product-cdi-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-product-cdi-repository", replicas = 0, refreshInterval = "-1") static class Product { @Id private String id; @@ -188,8 +188,7 @@ static class Product { } @Data - @Document(indexName = "test-index-person-cdi-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-person-cdi-repository", replicas = 0, refreshInterval = "-1") static class Person { @Id private String id; @@ -206,8 +205,7 @@ static class Person { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-cdi-repository", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-cdi-repository", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java new file mode 100644 index 000000000..00c6f2bb9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/package-info.java @@ -0,0 +1,3 @@ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.repositories.cdi; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java index 996e064aa..c0104ffa6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQueryUnitTests.java @@ -50,6 +50,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; +import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -123,18 +124,15 @@ Person findWithRepeatedPlaceholder(String arg0, String arg1, String arg2, String * @author Artur Konczak */ - @Document(indexName = "test-index-person-query-unittest", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-person-query-unittest", replicas = 0, refreshInterval = "-1") static class Person { - @Id private String id; - - private String name; - - @Field(type = FieldType.Nested) private List car; - - @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable @Id private String id; + @Nullable private String name; + @Nullable @Field(type = FieldType.Nested) private List car; + @Nullable @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable public String getId() { return id; } @@ -143,6 +141,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -151,6 +150,7 @@ public void setName(String name) { this.name = name; } + @Nullable public List getCar() { return car; } @@ -159,6 +159,7 @@ public void setCar(List car) { this.car = car; } + @Nullable public List getBooks() { return books; } @@ -178,8 +179,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-query-unittest", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-query-unittest", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -229,9 +229,10 @@ public void setModel(String model) { */ static class Author { - private String id; - private String name; + @Nullable private String id; + @Nullable private String name; + @Nullable public String getId() { return id; } @@ -240,6 +241,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java index bc8aebba2..5aa839cb4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchQueryMethodUnitTests.java @@ -48,6 +48,7 @@ import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; +import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -152,14 +153,15 @@ interface NonReactiveRepository extends Repository { @Document(indexName = INDEX_NAME, replicas = 0, refreshInterval = "-1") static class Person { - @Id private String id; + @Nullable @Id private String id; - private String name; + @Nullable private String name; - @Field(type = FieldType.Nested) private List car; + @Nullable @Field(type = FieldType.Nested) private List car; - @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable public String getId() { return id; } @@ -168,6 +170,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -176,6 +179,7 @@ public void setName(String name) { this.name = name; } + @Nullable public List getCar() { return car; } @@ -184,6 +188,7 @@ public void setCar(List car) { this.car = car; } + @Nullable public List getBooks() { return books; } @@ -203,8 +208,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-reactive-repository-query", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-reactive-repository-query", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -254,9 +258,10 @@ public void setModel(String model) { */ static class Author { - private String id; - private String name; + @Nullable private String id; + @Nullable private String name; + @Nullable public String getId() { return id; } @@ -265,6 +270,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java index a20b391f9..df787404e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java @@ -55,6 +55,7 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider; import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.lang.Nullable; /** * @author Christoph Strobl @@ -175,18 +176,18 @@ Person findWithRepeatedPlaceholder(String arg0, String arg1, String arg2, String * @author Artur Konczak */ - @Document(indexName = "test-index-person-reactive-repository-string-query", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-person-reactive-repository-string-query", replicas = 0, refreshInterval = "-1") public class Person { - @Id private String id; + @Nullable @Id private String id; - private String name; + @Nullable private String name; - @Field(type = FieldType.Nested) private List car; + @Nullable @Field(type = FieldType.Nested) private List car; - @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable @Field(type = FieldType.Nested, includeInParent = true) private List books; + @Nullable public String getId() { return id; } @@ -195,6 +196,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } @@ -203,6 +205,7 @@ public void setName(String name) { this.name = name; } + @Nullable public List getCar() { return car; } @@ -211,6 +214,7 @@ public void setCar(List car) { this.car = car; } + @Nullable public List getBooks() { return books; } @@ -230,8 +234,7 @@ public void setBooks(List books) { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-book-reactive-repository-string-query", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-book-reactive-repository-string-query", replicas = 0, refreshInterval = "-1") static class Book { @Id private String id; @@ -281,9 +284,10 @@ public void setModel(String model) { */ static class Author { - private String id; - private String name; + @Nullable private String id; + @Nullable private String name; + @Nullable public String getId() { return id; } @@ -292,6 +296,7 @@ public void setId(String id) { this.id = id; } + @Nullable public String getName() { return name; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java index f94bee97b..95bacfc92 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/StubParameterAccessor.java @@ -43,7 +43,7 @@ class StubParameterAccessor implements ElasticsearchParameterAccessor { */ @Override public Pageable getPageable() { - return null; + return Pageable.unpaged(); } /* @@ -104,8 +104,8 @@ public Optional> getDynamicProjection() { * (non-Javadoc) * @see org.springframework.data.repository.query.ParameterAccessor#findDynamicProjection() */ - @Override - public Class findDynamicProjection() { - return null; - } + @Override + public Class findDynamicProjection() { + return null; + } } From 0c15eef8588c407b3313f93e0166c8effe63fac5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 9 Feb 2020 19:31:16 +0100 Subject: [PATCH 0062/1191] DATAES-740 - Adapt to spring-data-commons changes. Original PR: #386 --- .../config/ElasticsearchConfigurationSupport.java | 2 +- .../convert/ElasticsearchCustomConversions.java | 14 ++++++++++---- .../elasticsearch/core/convert/GeoConverters.java | 11 ++++++----- .../convert/MappingElasticsearchConverter.java | 2 +- .../MappingElasticsearchConverterUnitTests.java | 2 +- 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index 949822ac5..b33fcde37 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -76,7 +76,7 @@ public SimpleElasticsearchMappingContext elasticsearchMappingContext() { */ @Bean public ElasticsearchCustomConversions elasticsearchCustomConversions() { - return new ElasticsearchCustomConversions(Collections.emptyList()); + return ElasticsearchCustomConversions.of(Collections.emptyList()); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java index c42078491..d44660255 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java @@ -39,11 +39,11 @@ public class ElasticsearchCustomConversions extends CustomConversions { private static final StoreConversions STORE_CONVERSIONS; - private static final List STORE_CONVERTERS; + private static final List> STORE_CONVERTERS; static { - List converters = new ArrayList<>(GeoConverters.getConvertersToRegister()); + List> converters = new ArrayList<>(); converters.add(StringToUUIDConverter.INSTANCE); converters.add(UUIDToStringConverter.INSTANCE); converters.add(BigDecimalToDoubleConverter.INSTANCE); @@ -58,8 +58,14 @@ public class ElasticsearchCustomConversions extends CustomConversions { * * @param converters must not be {@literal null}. */ - public ElasticsearchCustomConversions(Collection converters) { - super(STORE_CONVERSIONS, converters); + public static ElasticsearchCustomConversions of(Collection> converters) { + List> userConverters = new ArrayList<>(GeoConverters.getConvertersToRegister()); + userConverters.addAll(converters); + return new ElasticsearchCustomConversions(STORE_CONVERSIONS, userConverters); + } + + private ElasticsearchCustomConversions(StoreConversions storeConversions, Collection converters) { + super(storeConversions, converters); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java index 4ebb27ab4..b25e12c91 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/GeoConverters.java @@ -31,11 +31,12 @@ * Set of {@link Converter converters} specific to Elasticsearch Geo types. * * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ class GeoConverters { - static Collection getConvertersToRegister() { + static Collection> getConvertersToRegister() { return Arrays.asList(PointToMapConverter.INSTANCE, MapToPointConverter.INSTANCE, GeoPointToMapConverter.INSTANCE, MapToGeoPointConverter.INSTANCE); @@ -50,7 +51,7 @@ enum PointToMapConverter implements Converter> { INSTANCE; @Override - public Map convert(Point source) { + public Map convert(Point source) { Map target = new LinkedHashMap<>(); target.put("lat", source.getX()); @@ -68,7 +69,7 @@ enum GeoPointToMapConverter implements Converter> INSTANCE; @Override - public Map convert(GeoPoint source) { + public Map convert(GeoPoint source) { Map target = new LinkedHashMap<>(); target.put("lat", source.getLat()); target.put("lon", source.getLon()); @@ -85,7 +86,7 @@ enum MapToPointConverter implements Converter, Point> { INSTANCE; @Override - public Point convert(Map source) { + public Point convert(Map source) { Double x = NumberUtils.convertNumberToTargetClass((Number) source.get("lat"), Double.class); Double y = NumberUtils.convertNumberToTargetClass((Number) source.get("lon"), Double.class); @@ -102,7 +103,7 @@ enum MapToGeoPointConverter implements Converter, GeoPoint> INSTANCE; @Override - public GeoPoint convert(Map source) { + public GeoPoint convert(Map source) { Double x = NumberUtils.convertNumberToTargetClass((Number) source.get("lat"), Double.class); Double y = NumberUtils.convertNumberToTargetClass((Number) source.get("lon"), Double.class); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index ab7cb01e6..b54dc54bd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -85,7 +85,7 @@ public class MappingElasticsearchConverter private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final GenericConversionService conversionService; - private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); + private CustomConversions conversions = ElasticsearchCustomConversions.of(Collections.emptyList()); private EntityInstantiators instantiators = new EntityInstantiators(); private ElasticsearchTypeMapper typeMapper; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 35a27b6a4..ba631a838 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -108,7 +108,7 @@ public void init() { mappingElasticsearchConverter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService()); mappingElasticsearchConverter.setConversions( - new ElasticsearchCustomConversions(Arrays.asList(new ShotGunToMapConverter(), new MapToShotGunConverter()))); + ElasticsearchCustomConversions.of(Arrays.asList(new ShotGunToMapConverter(), new MapToShotGunConverter()))); mappingElasticsearchConverter.afterPropertiesSet(); sarahConnor = new Person(); From b2ffc236bf582b5e5d7a0bcd01e1438e72e6adc1 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 10 Feb 2020 22:09:49 +0100 Subject: [PATCH 0063/1191] DATAES-738 - Add entity related save methods to DocumentOperations. Original PR: #389 --- .../core/AbstractElasticsearchTemplate.java | 110 +++++++++++++++++- .../core/DocumentOperations.java | 69 ++++++++++- .../core/ElasticsearchOperations.java | 16 +++ .../core/ElasticsearchRestTemplate.java | 11 +- .../core/ElasticsearchTemplate.java | 9 +- .../AbstractElasticsearchRepository.java | 32 ++--- .../SimpleElasticsearchRepository.java | 4 +- .../core/ElasticsearchTemplateTests.java | 81 ++++++++++++- 8 files changed, 290 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 985e388ff..f2c6b46ca 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -1,10 +1,13 @@ package org.springframework.data.elasticsearch.core; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkResponse; @@ -27,10 +30,13 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.util.CloseableIterator; +import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -83,6 +89,68 @@ public IndexOperations getIndexOperations() { // endregion // region DocumentOperations + + @Override + public T save(T entity) { + + Assert.notNull(entity, "entity must not be null"); + + return save(entity, getIndexCoordinatesFor(entity.getClass())); + } + + @Override + public T save(T entity, IndexCoordinates index) { + + Assert.notNull(entity, "entity must not be null"); + Assert.notNull(index, "index must not be null"); + + index(getIndexQuery(entity), index); + return entity; + } + + @Override + public Iterable save(Iterable entities) { + + Assert.notNull(entities, "entities must not be null"); + + Iterator iterator = entities.iterator(); + if (iterator.hasNext()) { + return save(entities, getIndexCoordinatesFor(iterator.next().getClass())); + } + + return entities; + } + + @Override + public Iterable save(Iterable entities, IndexCoordinates index) { + + Assert.notNull(entities, "entities must not be null"); + Assert.notNull(index, "index must not be null"); + + List indexQueries = Streamable.of(entities).stream().map(this::getIndexQuery) + .collect(Collectors.toList()); + + if (!indexQueries.isEmpty()) { + List ids = bulkIndex(indexQueries, index); + Iterator idIterator = ids.iterator(); + entities.forEach(entity -> { + setPersistentEntityId(entity, idIterator.next()); + }); + } + + return entities; + } + + @Override + public Iterable save(T... entities) { + return save(Arrays.asList(entities)); + } + + @Override + public Iterable save(IndexCoordinates index, T... entities) { + return save(Arrays.asList(entities), index); + } + @Override public void delete(Query query, Class clazz, IndexCoordinates index) { @@ -197,7 +265,11 @@ public IndexCoordinates getIndexCoordinatesFor(Class clazz) { return getRequiredPersistentEntity(clazz).getIndexCoordinates(); } - protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { + /** + * @param bulkResponse + * @return the list of the item id's + */ + protected List checkForBulkOperationFailure(BulkResponse bulkResponse) { if (bulkResponse.hasFailures()) { Map failedDocuments = new HashMap<>(); @@ -211,6 +283,8 @@ protected void checkForBulkOperationFailure(BulkResponse bulkResponse) { + failedDocuments + ']', failedDocuments); } + + return Stream.of(bulkResponse.getItems()).map(BulkItemResponse::getId).collect(Collectors.toList()); } protected void setPersistentEntityId(Object entity, String id) { @@ -227,5 +301,39 @@ protected void setPersistentEntityId(Object entity, String id) { ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } + + @Nullable + private String getEntityId(Object entity) { + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); + + if (idProperty != null) { + return stringIdRepresentation(persistentEntity.getPropertyAccessor(entity).getProperty(idProperty)); + } + + return null; + } + + @Nullable + private Long getEntityVersion(Object entity) { + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); + + if (versionProperty != null) { + Object version = persistentEntity.getPropertyAccessor(entity).getProperty(versionProperty); + + if (version != null && Long.class.isAssignableFrom(version.getClass())) { + return ((Long) version); + } + } + + return null; + } + + private IndexQuery getIndexQuery(T entity) { + return new IndexQueryBuilder().withObject(entity).withId(getEntityId(entity)).withVersion(getEntityVersion(entity)) + .build(); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index a38d4afc0..72285ab83 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -25,6 +25,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.lang.Nullable; /** * The operations for the @@ -35,6 +36,63 @@ */ public interface DocumentOperations { + /** + * Saves an entity to the index specified in the entity's Document annotation + * + * @param entity the entity to save, must not be {@literal null} + * @param the entity type + * @return the saved entity + */ + T save(T entity); + + /** + * Saves an entity to the index specified in the entity's Document annotation + * + * @param entity the entity to save, must not be {@literal null} + * @param index the index to save the entity in, must not be {@literal null} + * @param the entity type + * @return the saved entity + */ + T save(T entity, IndexCoordinates index); + + /** + * saves the given entities to the index retrieved from the entities' Document annotation + * + * @param entities must not be {@literal null} + * @param the entity type + * @return the saved entites + */ + Iterable save(Iterable entities); + + /** + * saves the given entities to the given index + * + * @param entities must not be {@literal null} + * @param index the idnex to save the entities in, must not be {@literal null} + * @param the entity type + * @return the saved entites + */ + Iterable save(Iterable entities, IndexCoordinates index); + + /** + * saves the given entities to the index retrieved from the entities' Document annotation + * + * @param entities must not be {@literal null} + * @param the entity type + * @return the saved entites as Iterable + */ + Iterable save(T... entities); + + /** + * saves the given entities to the given index. + * + * @param index the idnex to save the entities in, must not be {@literal null} + * @param entities must not be {@literal null} + * @param the entity type + * @return the saved entites as Iterable + */ + Iterable save(IndexCoordinates index, T... entities); + /** * Index an object. Will do save or update. * @@ -52,6 +110,7 @@ public interface DocumentOperations { * @param index the index from which the object is read. * @return the found object */ + @Nullable T get(GetQuery query, Class clazz, IndexCoordinates index); /** @@ -68,18 +127,20 @@ public interface DocumentOperations { * Bulk index all objects. Will do save or update. * * @param queries the queries to execute in bulk + * @return the ids of the indexed objects */ - default void bulkIndex(List queries, IndexCoordinates index) { - bulkIndex(queries, BulkOptions.defaultOptions(), index); + default List bulkIndex(List queries, IndexCoordinates index) { + return bulkIndex(queries, BulkOptions.defaultOptions(), index); } /** * Bulk index all objects. Will do save or update. - * + * * @param queries the queries to execute in bulk * @param bulkOptions options to be added to the bulk request + * @return the ids of the indexed objects */ - void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); + List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); /** * Bulk update all objects. Will do update. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 456c91def..f82529548 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -17,11 +17,13 @@ import java.util.List; import java.util.Map; +import java.util.Objects; import org.elasticsearch.cluster.metadata.AliasMetaData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.lang.Nullable; /** * ElasticsearchOperations. Since 4.0 this interface only contains common helper functions, the other methods have been @@ -312,4 +314,18 @@ default void refresh(Class clazz) { getIndexOperations().refresh(clazz); } // endregion + + // region helper + /** + * gets the String representation for an id. + * + * @param id + * @return + * @since 4.0 + */ + @Nullable + default String stringIdRepresentation(@Nullable Object id) { + return Objects.toString(id, null); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index ad2f94c3b..2c20807f7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -127,6 +127,7 @@ public String index(IndexQuery query, IndexCoordinates index) { } @Override + @Nullable public T get(GetQuery query, Class clazz, IndexCoordinates index) { GetRequest request = requestFactory.getRequest(query, index); try { @@ -153,12 +154,12 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) } @Override - public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - doBulkOperation(queries, bulkOptions, index); + return doBulkOperation(queries, bulkOptions, index); } @Override @@ -200,10 +201,10 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } } - private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); try { - checkForBulkOperationFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); + return checkForBulkOperationFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); } catch (IOException e) { throw new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e); } @@ -212,7 +213,7 @@ private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoor // region SearchOperations @Override - public long count(Query query,@Nullable Class clazz, IndexCoordinates index) { + public long count(Query query, @Nullable Class clazz, IndexCoordinates index) { Assert.notNull(query, "query must not be null"); Assert.notNull(index, "index must not be null"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index e8c1c8c93..7ba860ee9 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -127,6 +127,7 @@ public String index(IndexQuery query, IndexCoordinates index) { } @Override + @Nullable public T get(GetQuery query, Class clazz, IndexCoordinates index) { GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, query, index); GetResponse response = getRequestBuilder.execute().actionGet(); @@ -145,12 +146,12 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) } @Override - public void bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - doBulkOperation(queries, bulkOptions, index); + return doBulkOperation(queries, bulkOptions, index); } @Override @@ -178,9 +179,9 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { return updateRequestBuilder.execute().actionGet(); } - private void doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); - checkForBulkOperationFailure(bulkRequest.execute().actionGet()); + return checkForBulkOperationFailure(bulkRequest.execute().actionGet()); } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 544b7fe57..c3ca2a834 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -176,34 +176,35 @@ public long count() { @Override public S save(S entity) { + Assert.notNull(entity, "Cannot save 'null' entity."); - operations.index(createIndexQuery(entity), getIndexCoordinates()); + + operations.save(entity, getIndexCoordinates()); indexOperations.refresh(getIndexCoordinates()); return entity; } public List save(List entities) { + Assert.notNull(entities, "Cannot insert 'null' as a List."); + return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); } @Override public S indexWithoutRefresh(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); - operations.index(createIndexQuery(entity), getIndexCoordinates()); + operations.save(entity); return entity; } @Override public Iterable saveAll(Iterable entities) { + Assert.notNull(entities, "Cannot insert 'null' as a List."); - List queries = Streamable.of(entities).stream().map(this::createIndexQuery) - .collect(Collectors.toList()); - if (!queries.isEmpty()) { - operations.bulkIndex(queries, getIndexCoordinates()); - indexOperations.refresh(getIndexCoordinates()); - } + operations.save(entities, getIndexCoordinates()); + indexOperations.refresh(getIndexCoordinates()); return entities; } @@ -329,14 +330,6 @@ public void refresh() { indexOperations.refresh(getEntityClass()); } - private IndexQuery createIndexQuery(T entity) { - IndexQuery query = new IndexQuery(); - query.setObject(entity); - query.setId(stringIdRepresentation(extractIdFromBean(entity))); - query.setVersion(extractVersionFromBean(entity)); - query.setParentId(extractParentIdFromBean(entity)); - return query; - } @SuppressWarnings("unchecked") private Class resolveReturnedClassFromGenericType() { @@ -396,13 +389,6 @@ private List stringIdsRepresentation(Iterable ids) { protected abstract @Nullable String stringIdRepresentation(@Nullable ID id); - private Long extractVersionFromBean(T entity) { - return entityInformation.getVersion(entity); - } - - private String extractParentIdFromBean(T entity) { - return entityInformation.getParentId(entity); - } private IndexCoordinates getIndexCoordinates() { return operations.getIndexCoordinatesFor(getEntityClass()); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 73414212b..2a4e51863 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -15,8 +15,6 @@ */ package org.springframework.data.elasticsearch.repository.support; -import java.util.Objects; - import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.lang.Nullable; @@ -43,6 +41,6 @@ public SimpleElasticsearchRepository(ElasticsearchOperations elasticsearchOperat @Override protected @Nullable String stringIdRepresentation(@Nullable ID id) { - return Objects.toString(id, null); + return operations.stringIdRepresentation(id); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index f513ed4d0..f1bc0ad99 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -2907,6 +2907,84 @@ void shouldReturnHighlightFieldsInSearchHit() { assertThat(highlightField.get(1)).contains("message"); } + @Test // DATAES-738 + void shouldSaveEntityWithIndexCoordinates() { + String id = "42"; + SampleEntity entity = new SampleEntity(); + entity.setId(id); + entity.setVersion(42L); + entity.setMessage("message"); + + operations.save(entity, index); + indexOperations.refresh(index); + + SampleEntity result = operations.get(new GetQuery(id), SampleEntity.class, index); + + assertThat(result).isEqualTo(entity); + } + + @Test // DATAES-738 + void shouldSaveEntityWithOutIndexCoordinates() { + String id = "42"; + SampleEntity entity = new SampleEntity(); + entity.setId(id); + entity.setVersion(42L); + entity.setMessage("message"); + + operations.save(entity); + indexOperations.refresh(index); + + SampleEntity result = operations.get(new GetQuery(id), SampleEntity.class, index); + + assertThat(result).isEqualTo(entity); + } + + @Test // DATAES-738 + void shouldSaveEntityIterableWithIndexCoordinates() { + String id1 = "42"; + SampleEntity entity1 = new SampleEntity(); + entity1.setId(id1); + entity1.setVersion(42L); + entity1.setMessage("message"); + String id2 = "43"; + SampleEntity entity2 = new SampleEntity(); + entity2.setId(id2); + entity2.setVersion(43L); + entity2.setMessage("message"); + + operations.save(Arrays.asList(entity1, entity2), index); + indexOperations.refresh(index); + + SampleEntity result1 = operations.get(new GetQuery(id1), SampleEntity.class, index); + SampleEntity result2 = operations.get(new GetQuery(id2), SampleEntity.class, index); + + assertThat(result1).isEqualTo(entity1); + assertThat(result2).isEqualTo(entity2); + } + + @Test // DATAES-738 + void shouldSaveEntityIterableWithoutIndexCoordinates() { + String id1 = "42"; + SampleEntity entity1 = new SampleEntity(); + entity1.setId(id1); + entity1.setVersion(42L); + entity1.setMessage("message"); + String id2 = "43"; + SampleEntity entity2 = new SampleEntity(); + entity2.setId(id2); + entity2.setVersion(43L); + entity2.setMessage("message"); + + operations.save(Arrays.asList(entity1, entity2)); + indexOperations.refresh(index); + + SampleEntity result1 = operations.get(new GetQuery(id1), SampleEntity.class, index); + SampleEntity result2 = operations.get(new GetQuery(id2), SampleEntity.class, index); + + assertThat(result1).isEqualTo(entity1); + assertThat(result2).isEqualTo(entity2); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @@ -3039,8 +3117,7 @@ static class SampleMappingEntity { static class NestedEntity { - @Nullable - @Field(type = Text) private String someField; + @Nullable @Field(type = Text) private String someField; @Nullable public String getSomeField() { From 9c64dd9c39d1e3ba6c6c892769193c4cc3b1907c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 11 Feb 2020 18:33:58 +0100 Subject: [PATCH 0064/1191] DATAES-743 - Revert geo converters to back to store converters. Original PR: #390 --- .../config/ElasticsearchConfigurationSupport.java | 2 +- .../core/convert/ElasticsearchCustomConversions.java | 12 +++--------- .../core/convert/MappingElasticsearchConverter.java | 2 +- .../MappingElasticsearchConverterUnitTests.java | 2 +- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index b33fcde37..949822ac5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -76,7 +76,7 @@ public SimpleElasticsearchMappingContext elasticsearchMappingContext() { */ @Bean public ElasticsearchCustomConversions elasticsearchCustomConversions() { - return ElasticsearchCustomConversions.of(Collections.emptyList()); + return new ElasticsearchCustomConversions(Collections.emptyList()); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java index d44660255..d223d1a51 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java @@ -43,7 +43,7 @@ public class ElasticsearchCustomConversions extends CustomConversions { static { - List> converters = new ArrayList<>(); + List> converters = new ArrayList<>(GeoConverters.getConvertersToRegister()); converters.add(StringToUUIDConverter.INSTANCE); converters.add(UUIDToStringConverter.INSTANCE); converters.add(BigDecimalToDoubleConverter.INSTANCE); @@ -58,14 +58,8 @@ public class ElasticsearchCustomConversions extends CustomConversions { * * @param converters must not be {@literal null}. */ - public static ElasticsearchCustomConversions of(Collection> converters) { - List> userConverters = new ArrayList<>(GeoConverters.getConvertersToRegister()); - userConverters.addAll(converters); - return new ElasticsearchCustomConversions(STORE_CONVERSIONS, userConverters); - } - - private ElasticsearchCustomConversions(StoreConversions storeConversions, Collection converters) { - super(storeConversions, converters); + public ElasticsearchCustomConversions(Collection converters) { + super(STORE_CONVERSIONS, converters); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index b54dc54bd..ab7cb01e6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -85,7 +85,7 @@ public class MappingElasticsearchConverter private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final GenericConversionService conversionService; - private CustomConversions conversions = ElasticsearchCustomConversions.of(Collections.emptyList()); + private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); private EntityInstantiators instantiators = new EntityInstantiators(); private ElasticsearchTypeMapper typeMapper; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index ba631a838..35a27b6a4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -108,7 +108,7 @@ public void init() { mappingElasticsearchConverter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService()); mappingElasticsearchConverter.setConversions( - ElasticsearchCustomConversions.of(Arrays.asList(new ShotGunToMapConverter(), new MapToShotGunConverter()))); + new ElasticsearchCustomConversions(Arrays.asList(new ShotGunToMapConverter(), new MapToShotGunConverter()))); mappingElasticsearchConverter.afterPropertiesSet(); sarahConnor = new Person(); From 77f43ce64cf7905c6acbc4d9b0fed47a87c9d6c6 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 11 Feb 2020 19:03:00 +0100 Subject: [PATCH 0065/1191] DATAES-738 - Removing one save method as it does not fit the naming scheme. --- .../core/AbstractElasticsearchTemplate.java | 5 ----- .../core/DocumentOperations.java | 20 +++++-------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index f2c6b46ca..e7a1b019d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -146,11 +146,6 @@ public Iterable save(T... entities) { return save(Arrays.asList(entities)); } - @Override - public Iterable save(IndexCoordinates index, T... entities) { - return save(Arrays.asList(entities), index); - } - @Override public void delete(Query query, Class clazz, IndexCoordinates index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 72285ab83..9442236dc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -38,7 +38,7 @@ public interface DocumentOperations { /** * Saves an entity to the index specified in the entity's Document annotation - * + * * @param entity the entity to save, must not be {@literal null} * @param the entity type * @return the saved entity @@ -47,7 +47,7 @@ public interface DocumentOperations { /** * Saves an entity to the index specified in the entity's Document annotation - * + * * @param entity the entity to save, must not be {@literal null} * @param index the index to save the entity in, must not be {@literal null} * @param the entity type @@ -57,7 +57,7 @@ public interface DocumentOperations { /** * saves the given entities to the index retrieved from the entities' Document annotation - * + * * @param entities must not be {@literal null} * @param the entity type * @return the saved entites @@ -79,20 +79,10 @@ public interface DocumentOperations { * * @param entities must not be {@literal null} * @param the entity type - * @return the saved entites as Iterable + * @return the saved entities as Iterable */ Iterable save(T... entities); - /** - * saves the given entities to the given index. - * - * @param index the idnex to save the entities in, must not be {@literal null} - * @param entities must not be {@literal null} - * @param the entity type - * @return the saved entites as Iterable - */ - Iterable save(IndexCoordinates index, T... entities); - /** * Index an object. Will do save or update. * @@ -135,7 +125,7 @@ default List bulkIndex(List queries, IndexCoordinates index) /** * Bulk index all objects. Will do save or update. - * + * * @param queries the queries to execute in bulk * @param bulkOptions options to be added to the bulk request * @return the ids of the indexed objects From 94f8623349975d38395cf6e5e9be15d2e30ec4ed Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Feb 2020 14:46:55 +0100 Subject: [PATCH 0066/1191] DATAES-732 - Updated changelog. --- src/main/resources/changelog.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index fdde3979e..acc27ee5e 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,18 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.M3 (2020-02-12) +---------------------------------------- +* DATAES-743 - Revert geo converters to back to store converters. +* DATAES-740 - Adapt to spring-data-commons changes. +* DATAES-739 - Introduce nullable annotations for API validation. +* DATAES-738 - Add entity related save methods to DocumentOperations. +* DATAES-735 - Update to Elasticsearch 7.5.2. +* DATAES-734 - Add Sort implementation that allows geo distance sorts. +* DATAES-732 - Release 4.0 M3 (Neumann). +* DATAES-449 - Pass route parameter to created search request. + + Changes in version 4.0.0.M2 (2020-01-17) ---------------------------------------- * DATAES-731 - Release 4.0 M2 (Neumann). @@ -1002,3 +1014,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From c85c20e03975db5bb0d8966724cfc25eb21d76e9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Feb 2020 14:46:56 +0100 Subject: [PATCH 0067/1191] DATAES-732 - Prepare 4.0 M3 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index e90ef3df0..9222ac604 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M3 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.2 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M3 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 652d1ee42..a6d2b5d5b 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 M2 +Spring Data Elasticsearch 4.0 M3 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -10,3 +10,4 @@ code for the these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. + From a9295947c6ee649d0e8bf2ffaef06d0a71365175 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Feb 2020 14:47:16 +0100 Subject: [PATCH 0068/1191] DATAES-732 - Release version 4.0 M3 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9222ac604..739792d24 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.M3 org.springframework.data.build From ead2cb13b74d8089b5cd31f309751d2028478740 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Feb 2020 15:04:21 +0100 Subject: [PATCH 0069/1191] DATAES-732 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 739792d24..9222ac604 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.M3 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From 05df3c3805164f3499a25a758fca09f895305f3e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Feb 2020 15:04:22 +0100 Subject: [PATCH 0070/1191] DATAES-732 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 9222ac604..e90ef3df0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.M3 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.5.2 2.9.1 - 2.3.0.M3 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 36a3d5943a6f1d061c1eff7e4d55b288629d9862 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 14 Feb 2020 21:24:51 +0100 Subject: [PATCH 0071/1191] DATAES-746 - Add store converters to convert binary data. Original PR: #394 --- .../ElasticsearchCustomConversions.java | 35 ++++++++++++++++ .../ElasticsearchCustomConversionsTest.java | 40 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversionsTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java index d223d1a51..998cc21b6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversions.java @@ -17,6 +17,7 @@ import java.math.BigDecimal; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -48,6 +49,8 @@ public class ElasticsearchCustomConversions extends CustomConversions { converters.add(UUIDToStringConverter.INSTANCE); converters.add(BigDecimalToDoubleConverter.INSTANCE); converters.add(DoubleToBigDecimalConverter.INSTANCE); + converters.add(ByteArrayToBase64Converter.INSTANCE); + converters.add(Base64ToByteArrayConverter.INSTANCE); STORE_CONVERTERS = Collections.unmodifiableList(converters); STORE_CONVERSIONS = StoreConversions.of(ElasticsearchSimpleTypes.HOLDER, STORE_CONVERTERS); @@ -117,4 +120,36 @@ public Double convert(BigDecimal source) { return NumberUtils.convertNumberToTargetClass(source, Double.class); } } + + /** + * {@link Converter} to write a byte[] to a base64 encoded {@link String} value. + * + * @since 4.0 + */ + @WritingConverter + enum ByteArrayToBase64Converter implements Converter { + + INSTANCE,; + + @Override + public String convert(byte[] source) { + return Base64.getEncoder().encodeToString(source); + } + } + + /** + * {@link Converter} to read a byte[] from a base64 encoded {@link String} value. + * + * @since 4.0 + */ + @ReadingConverter + enum Base64ToByteArrayConverter implements Converter { + + INSTANCE; + + @Override + public byte[] convert(String source) { + return Base64.getDecoder().decode(source); + } + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversionsTest.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversionsTest.java new file mode 100644 index 000000000..30fe5af41 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchCustomConversionsTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020 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.convert; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions.Base64ToByteArrayConverter; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchCustomConversions.ByteArrayToBase64Converter; + +/** + * @author Peter-Josef Meisch + */ +class ElasticsearchCustomConversionsTest { + + private byte[] bytes = new byte[] { 0x01, 0x02, 0x03, 0x04 }; + private String base64 = "AQIDBA=="; + + void shouldConvertFromByteArrayToBase64() { + assertThat(ByteArrayToBase64Converter.INSTANCE.convert(bytes)).isEqualTo(base64); + } + + @Test + void shouldConvertFromStringToBase64() { + assertThat(Base64ToByteArrayConverter.INSTANCE.convert(base64)).isEqualTo(bytes); + } +} From 9696f418fd249548d36557b7f2ebb380c72c5a58 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 15 Feb 2020 14:45:41 +0100 Subject: [PATCH 0072/1191] DATAES-747 - ElasticsearchConfigurationSupport does not set customConversions into the MappingElasticsearchConverter. Original PR: #395 --- .../elasticsearch-object-mapping.adoc | 31 +++++++------------ .../reference/elasticsearch-operations.adoc | 2 +- .../ElasticsearchConfigurationSupport.java | 5 ++- .../core/AbstractElasticsearchTemplate.java | 11 ++++++- .../core/ElasticsearchRestTemplate.java | 2 +- .../core/ElasticsearchTemplate.java | 3 +- ...toryTest.java => RequestFactoryTests.java} | 4 +-- .../core/index/MappingContextBaseTests.java | 2 +- 8 files changed, 32 insertions(+), 28 deletions(-) rename src/test/java/org/springframework/data/elasticsearch/core/{RequestFactoryTest.java => RequestFactoryTests.java} (98%) diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index 8ca8ba16a..c2fb1c4f4 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -3,12 +3,15 @@ Spring Data Elasticsearch Object Mapping is the process that maps a Java object - the domain entity - into the JSON representation that is stored in Elasticsearch and back. -Earlier versions of Spring Data Elasticsearch used a Jackson based conversion, Spring Data Elasticsearch 3.2.x introduced the <>. As of version 4.0 only the Meta Object Mapping is used, the Jackson based mapper is not available anymore. +Earlier versions of Spring Data Elasticsearch used a Jackson based conversion, Spring Data Elasticsearch 3.2.x introduced the <>. As of version 4.0 only the Meta Object Mapping is used, the Jackson based mapper is not available anymore and the `MappingElasticsearchConverter` is used. The main reasons for the removal of the Jackson based mapper are: * Custom mappings of fields needed to be done with annotations like `@JsonFormat` or `@JsonInclude`. This often caused problems when the same object was used in different JSON based datastores or sent over a JSON based API. * Custom field types and formats also need to be stored into the Elasticsearch index mappings. The Jackson based annotations did not fully provide all the information that is necessary to represent the types of Elasticsearch. +* Fields must be mapped not only when converting fromand to entities, but also an query argument, returned data and on other places. + +Using the `MappingElasticsearchConverter` now covers all these cases. [[elasticsearch.mapping.meta-model]] @@ -20,7 +23,7 @@ This allows to register `Converter` instances for specific domain type mapping. [[elasticsearch.mapping.meta-model.annotations]] === Mapping Annotation Overview -The `ElasticsearchEntityMapper` can use metadata to drive the mapping of objects to documents. The metadata is taken from the entities properties which can be annotated. +The `MappingElasticsearchConverter` uses metadata to drive the mapping of objects to documents. The metadata is taken from the entity's properties which can be annotated. The following annotations are available: @@ -206,25 +209,14 @@ public class Config extends AbstractElasticsearchConfiguration { return RestClients.create(ClientConfiguration.create("localhost:9200")).rest(); } - @Bean - @Override - public EntityMapper entityMapper() { - - ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper( - elasticsearchMappingContext(), new DefaultConversionService()); - entityMapper.setConversions(elasticsearchCustomConversions()); <1> - - return entityMapper; - } - @Bean @Override public ElasticsearchCustomConversions elasticsearchCustomConversions() { return new ElasticsearchCustomConversions( - Arrays.asList(new AddressToMap(), new MapToAddress())); <2> + Arrays.asList(new AddressToMap(), new MapToAddress())); <1> } - @WritingConverter <3> + @WritingConverter <2> static class AddressToMap implements Converter> { @Override @@ -238,7 +230,7 @@ public class Config extends AbstractElasticsearchConfiguration { } } - @ReadingConverter <4> + @ReadingConverter <3> static class MapToAddress implements Converter, Address> { @Override @@ -258,8 +250,7 @@ public class Config extends AbstractElasticsearchConfiguration { "localidad" : { "lat" : 34.118347, "lon" : -118.3026284 } } ---- -<1> Register `ElasticsearchCustomConversions` with the `EntityMapper`. -<2> Add `Converter` implementations. -<3> Set up the `Converter` used for writing `DomainType` to Elasticsearch. -<4> Set up the `Converter` used for reading `DomainType` from search result. +<1> Add `Converter` implementations. +<2> Set up the `Converter` used for writing `DomainType` to Elasticsearch. +<3> Set up the `Converter` used for reading `DomainType` from search result. ==== diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index 1e80e865e..3c3a03095 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -41,7 +41,7 @@ public class TransportClientConfig extends ElasticsearchConfigurationSupport { @Bean(name = {"elasticsearchOperations", "elasticsearchTemplate"}) public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException { <2> - return new ElasticsearchTemplate(elasticsearchClient(), entityMapper()); + return new ElasticsearchTemplate(elasticsearchClient()); } } ---- diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index 949822ac5..e120bc20d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -48,7 +48,10 @@ public class ElasticsearchConfigurationSupport { @Bean public ElasticsearchConverter elasticsearchEntityMapper( SimpleElasticsearchMappingContext elasticsearchMappingContext) { - return new MappingElasticsearchConverter(elasticsearchMappingContext); + MappingElasticsearchConverter elasticsearchConverter = new MappingElasticsearchConverter( + elasticsearchMappingContext); + elasticsearchConverter.setConversions(elasticsearchCustomConversions()); + return elasticsearchConverter; } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index e7a1b019d..7f2b935e0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -326,7 +326,16 @@ private Long getEntityVersion(Object entity) { } private IndexQuery getIndexQuery(T entity) { - return new IndexQueryBuilder().withObject(entity).withId(getEntityId(entity)).withVersion(getEntityVersion(entity)) + String id = getEntityId(entity); + + if (id != null) { + id = elasticsearchConverter.convertId(id); + } + + return new IndexQueryBuilder() // + .withId(id) // + .withVersion(getEntityVersion(entity)) // + .withObject(entity) // .build(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 2c20807f7..1dc87c027 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -173,7 +173,7 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index @Override public String delete(String id, IndexCoordinates index) { - DeleteRequest request = new DeleteRequest(index.getIndexName(), id); + DeleteRequest request = new DeleteRequest(index.getIndexName(), elasticsearchConverter.convertId(id)); try { return client.delete(request, RequestOptions.DEFAULT).getId(); } catch (IOException e) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 7ba860ee9..b2ed56ee3 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -165,7 +165,8 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index @Override public String delete(String id, IndexCoordinates index) { - return client.prepareDelete(index.getIndexName(), IndexCoordinates.TYPE, id).execute().actionGet().getId(); + return client.prepareDelete(index.getIndexName(), IndexCoordinates.TYPE, elasticsearchConverter.convertId(id)) + .execute().actionGet().getId(); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java similarity index 98% rename from src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java rename to src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index ab791e3e9..b2055ef8b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -40,7 +40,7 @@ /** * @author Peter-Josef Meisch */ -class RequestFactoryTest { +class RequestFactoryTests { @Nullable private static RequestFactory requestFactory; @Nullable private static MappingElasticsearchConverter converter; @@ -74,7 +74,7 @@ void shouldBuildSearchWithGeoSortSort() throws JSONException { " \"query_string\": {" + // " \"query\": \"Smith\"," + // " \"fields\": [" + // - " \"first-name^1.0\"" + // + " \"last-name^1.0\"" + // " ]" + // " }" + // " }" + // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java index 11e975921..af0e5068a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingContextBaseTests.java @@ -34,7 +34,7 @@ private ElasticsearchConverter setupElasticsearchConverter() { private SimpleElasticsearchMappingContext setupMappingContext() { - SimpleElasticsearchMappingContext mappingContext = new ElasticsearchConfigurationSupport() {} + SimpleElasticsearchMappingContext mappingContext = new ElasticsearchConfigurationSupport() .elasticsearchMappingContext(); mappingContext.initialize(); return mappingContext; From 1f56a9b9fe8fbd13b928d49775b8ca745c922817 Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Sat, 15 Feb 2020 19:22:40 +0400 Subject: [PATCH 0073/1191] DATAES-741 / Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems. Original PR: #393 --- .../java/org/springframework/data/elasticsearch/Utils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/test/java/org/springframework/data/elasticsearch/Utils.java b/src/test/java/org/springframework/data/elasticsearch/Utils.java index 1c8ffc791..cdaf0e4e6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/Utils.java +++ b/src/test/java/org/springframework/data/elasticsearch/Utils.java @@ -30,6 +30,7 @@ * @author Artur Konczak * @author Ilkang Na * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class Utils { @@ -46,6 +47,11 @@ public static Node getNode() { .put("path.data", pathData) // .put("cluster.name", clusterName) // .put("node.max_local_storage_nodes", 100)// + // the following 3 settings are needed to avoid problems on big, but + // almost full filesystems, see DATAES-741 + .put("cluster.routing.allocation.disk.watermark.low", "1gb")// + .put("cluster.routing.allocation.disk.watermark.high", "1gb")// + .put("cluster.routing.allocation.disk.watermark.flood_stage", "1gb")// .build(), // Collections.singletonList(Netty4Plugin.class)); } From 96ebc72dd1d1b8a03217e1af320de5823256ac8d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 25 Feb 2020 22:01:40 +0100 Subject: [PATCH 0074/1191] Dataes 745 consolidate operations api Original PR: #396 --- .../AbstractElasticsearchConfiguration.java | 6 - .../core/AbstractDefaultIndexOperations.java | 153 +++-- .../core/AbstractElasticsearchTemplate.java | 106 ++- .../core/DefaultIndexOperations.java | 43 +- .../core/DefaultTransportIndexOperations.java | 40 +- .../core/DocumentOperations.java | 102 ++- .../core/ElasticsearchOperations.java | 166 +++-- .../core/ElasticsearchRestTemplate.java | 59 +- .../core/ElasticsearchTemplate.java | 55 +- .../elasticsearch/core/IndexOperations.java | 172 ++--- .../core/ReactiveDocumentOperations.java | 68 +- .../core/ReactiveElasticsearchTemplate.java | 119 ++-- .../elasticsearch/core/RequestFactory.java | 194 +++--- .../elasticsearch/core/SearchOperations.java | 134 ++-- .../elasticsearch/core/document/Document.java | 2 +- .../core/document/MapDocument.java | 2 +- .../core/query/AbstractQuery.java | 13 + .../core/query/CriteriaQuery.java | 20 +- .../elasticsearch/core/query/DeleteQuery.java | 2 + .../elasticsearch/core/query/GetQuery.java | 2 + .../elasticsearch/core/query/IndexQuery.java | 5 + .../core/query/NativeSearchQuery.java | 2 + .../data/elasticsearch/core/query/Query.java | 28 +- .../elasticsearch/core/query/UpdateQuery.java | 155 ++++- .../core/query/UpdateQueryBuilder.java | 67 -- .../core/query/UpdateResponse.java | 45 ++ ...tReactiveElasticsearchRepositoryQuery.java | 2 +- .../query/ElasticsearchPartQuery.java | 2 +- .../AbstractElasticsearchRepository.java | 61 +- .../SimpleElasticsearchRepository.java | 4 - ...SimpleReactiveElasticsearchRepository.java | 8 +- .../data/elasticsearch/NestedObjectTests.java | 25 +- .../EnableElasticsearchRepositoriesTests.java | 9 +- .../core/ElasticsearchRestTemplateTests.java | 12 +- .../core/ElasticsearchTemplateTests.java | 622 ++++++++++-------- .../ElasticsearchTransportTemplateTests.java | 12 +- .../elasticsearch/core/LogEntityTests.java | 9 +- .../ReactiveElasticsearchTemplateTests.java | 94 +-- ...eactiveElasticsearchTemplateUnitTests.java | 12 +- ...ElasticsearchTemplateAggregationTests.java | 9 +- .../ElasticsearchTemplateCompletionTests.java | 16 +- ...chTemplateCompletionWithContextsTests.java | 11 +- .../geo/ElasticsearchTemplateGeoTests.java | 14 +- .../core/index/MappingBuilderTests.java | 74 ++- .../core/query/CriteriaQueryTests.java | 53 +- ...ImmutableElasticsearchRepositoryTests.java | 9 +- .../ElasticsearchTemplateConfiguration.java | 7 - .../ComplexCustomMethodRepositoryTests.java | 10 +- ...stomMethodRepositoryManualWiringTests.java | 9 +- .../CustomMethodRepositoryBaseTests.java | 9 +- .../doubleid/DoubleIDRepositoryTests.java | 9 +- .../dynamicindex/DynamicIndexEntityTests.java | 14 +- .../geo/SpringDataGeoRepositoryTests.java | 9 +- .../integer/IntegerIDRepositoryTests.java | 10 +- .../nestedobject/InnerObjectTests.java | 10 +- ...ettingAndMappingEntityRepositoryTests.java | 28 +- ...ldDynamicMappingEntityRepositoryTests.java | 7 +- .../repositories/spel/SpELEntityTests.java | 7 +- .../synonym/SynonymRepositoryTests.java | 7 +- .../UUIDElasticsearchRepositoryTests.java | 9 +- .../query/keywords/QueryKeywordsTests.java | 9 +- .../SimpleElasticsearchRepositoryTests.java | 7 +- .../elasticsearch/utils/IndexInitializer.java | 21 +- 63 files changed, 1756 insertions(+), 1244 deletions(-) delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/UpdateResponse.java diff --git a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java index c81ade77c..97e680d90 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/AbstractElasticsearchConfiguration.java @@ -19,7 +19,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; -import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; /** @@ -48,9 +47,4 @@ public abstract class AbstractElasticsearchConfiguration extends ElasticsearchCo public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) { return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter); } - - @Bean - public IndexOperations indexOperations(ElasticsearchOperations elasticsearchOperations) { - return elasticsearchOperations.getIndexOperations(); - } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 2032624c8..f6100e8ab 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -18,20 +18,26 @@ import static org.springframework.util.StringUtils.*; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.cluster.metadata.AliasMetaData; import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.settings.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessApiUsageException; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.index.MappingBuilder; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; /** @@ -48,88 +54,145 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations { protected final ElasticsearchConverter elasticsearchConverter; protected final RequestFactory requestFactory; - public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter) { + @Nullable protected final Class boundClass; + protected final IndexCoordinates boundIndex; + + public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter, Class boundClass) { this.elasticsearchConverter = elasticsearchConverter; requestFactory = new RequestFactory(elasticsearchConverter); + + this.boundClass = boundClass; + this.boundIndex = getIndexCoordinatesFor(boundClass); } - // region IndexOperations - @Override - public boolean createIndex(String indexName) { - return createIndex(indexName, null); + public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter, IndexCoordinates boundIndex) { + this.elasticsearchConverter = elasticsearchConverter; + requestFactory = new RequestFactory(elasticsearchConverter); + + this.boundClass = null; + this.boundIndex = boundIndex; } + protected Class checkForBoundClass() { + if (boundClass == null) { + throw new InvalidDataAccessApiUsageException("IndexOperations are not bound"); + } + return boundClass; + } + + // region IndexOperations + @Override - public boolean createIndex(Class clazz) { + public boolean create() { + + if (boundClass != null) { + Class clazz = boundClass; + String indexName = boundIndex.getIndexName(); - String indexName = getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(); - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - if (hasText(settingPath)) { - String settings = ResourceUtil.readFileFromClasspath(settingPath); + if (hasText(settingPath)) { + String settings = ResourceUtil.readFileFromClasspath(settingPath); - if (hasText(settings)) { - return createIndex(indexName, settings); + if (hasText(settings)) { + return doCreate(indexName, Document.parse(settings)); + } + } else { + LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); } - } else { - LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); } + return doCreate(indexName, getDefaultSettings(getRequiredPersistentEntity(clazz))); } - return createIndex(indexName, getDefaultSettings(getRequiredPersistentEntity(clazz))); + return doCreate(boundIndex.getIndexName(), null); + } + + @Override + public boolean create(Document settings) { + return doCreate(boundIndex.getIndexName(), settings); } + protected abstract boolean doCreate(String indexName, @Nullable Document settings); + @Override - public boolean createIndex(Class clazz, Object settings) { - return createIndex(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(), settings); + public boolean delete() { + return doDelete(boundIndex.getIndexName()); } + protected abstract boolean doDelete(String indexName); + @Override - public boolean deleteIndex(Class clazz) { - return deleteIndex(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName()); + public boolean exists() { + return doExists(boundIndex.getIndexName()); } + protected abstract boolean doExists(String indexName); + @Override - public boolean indexExists(Class clazz) { - return indexExists(getIndexCoordinatesFor(clazz).getIndexName()); + public boolean putMapping(Document mapping) { + return doPutMapping(boundIndex, mapping); } + protected abstract boolean doPutMapping(IndexCoordinates index, Document mapping); + @Override - public Map getMapping(Class clazz) { - return getMapping(getIndexCoordinatesFor(clazz)); + public Map getMapping() { + return doGetMapping(boundIndex); } + abstract protected Map doGetMapping(IndexCoordinates index); + @Override - public boolean putMapping(Class clazz) { - return putMapping(clazz, buildMapping(clazz)); + public Map getSettings() { + return getSettings(false); } @Override - public boolean putMapping(Class clazz, Object mapping) { - return putMapping(getIndexCoordinatesFor(clazz), mapping); + public Map getSettings(boolean includeDefaults) { + return doGetSettings(boundIndex.getIndexName(), includeDefaults); } + protected abstract Map doGetSettings(String indexName, boolean includeDefaults); + @Override - public boolean putMapping(IndexCoordinates index, Class clazz) { - return putMapping(index, buildMapping(clazz)); + public void refresh() { + doRefresh(boundIndex); } + protected abstract void doRefresh(IndexCoordinates indexCoordinates); + @Override - public Map getSettings(Class clazz) { - return getSettings(clazz, false); + public boolean addAlias(AliasQuery query) { + return doAddAlias(query, boundIndex); } + protected abstract boolean doAddAlias(AliasQuery query, IndexCoordinates index); + @Override - public Map getSettings(Class clazz, boolean includeDefaults) { - return getSettings(getRequiredPersistentEntity(clazz).getIndexCoordinates().getIndexName(), includeDefaults); + public List queryForAlias() { + return doQueryForAlias(boundIndex.getIndexName()); } + protected abstract List doQueryForAlias(String indexName); + @Override - public void refresh(Class clazz) { - refresh(getIndexCoordinatesFor(clazz)); + public boolean removeAlias(AliasQuery query) { + return doRemoveAlias(query, boundIndex); } - protected String buildMapping(Class clazz) { + protected abstract boolean doRemoveAlias(AliasQuery query, IndexCoordinates index); + + @Override + public Document createMapping() { + return createMapping(checkForBoundClass()); + } + + @Override + public Document createMapping(Class clazz) { + return buildMapping(clazz); + } + + protected Document buildMapping(Class clazz) { // load mapping specified in Mapping annotation if present if (clazz.isAnnotationPresent(Mapping.class)) { @@ -139,7 +202,7 @@ protected String buildMapping(Class clazz) { String mappings = ResourceUtil.readFileFromClasspath(mappingPath); if (!StringUtils.isEmpty(mappings)) { - return mappings; + return Document.parse(mappings); } } else { LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field"); @@ -148,7 +211,8 @@ protected String buildMapping(Class clazz) { // build mapping from field annotations try { - return new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz); + String mapping = new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz); + return Document.parse(mapping); } catch (Exception e) { throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); } @@ -156,15 +220,18 @@ protected String buildMapping(Class clazz) { // endregion // region Helper functions - private Map getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { + private Document getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { - if (persistentEntity.isUseServerConfiguration()) - return new HashMap(); + if (persistentEntity.isUseServerConfiguration()) { + return Document.create(); + } - return new MapBuilder().put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) + Map map = new MapBuilder() + .put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) .put("index.refresh_interval", persistentEntity.getRefreshInterval()) .put("index.store.type", persistentEntity.getIndexStoreType()).map(); + return Document.from(map); } ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 7f2b935e0..c2bbb4173 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -6,6 +6,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -13,11 +14,8 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; -import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -29,7 +27,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; -import org.springframework.data.elasticsearch.core.query.DeleteQuery; +import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; @@ -50,16 +48,14 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper protected @Nullable ElasticsearchConverter elasticsearchConverter; protected @Nullable RequestFactory requestFactory; - protected @Nullable IndexOperations indexOperations; // region Initialization - protected void initialize(ElasticsearchConverter elasticsearchConverter, IndexOperations indexOperations) { + protected void initialize(ElasticsearchConverter elasticsearchConverter) { Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); this.elasticsearchConverter = elasticsearchConverter; requestFactory = new RequestFactory(elasticsearchConverter); - this.indexOperations = indexOperations; } protected ElasticsearchConverter createElasticsearchConverter() { @@ -78,16 +74,6 @@ public void setApplicationContext(ApplicationContext context) throws BeansExcept } // endregion - // region getter/setter - @Override - public IndexOperations getIndexOperations() { - - Assert.notNull("indexOperations are not initialized"); - - return indexOperations; - } - // endregion - // region DocumentOperations @Override @@ -147,24 +133,64 @@ public Iterable save(T... entities) { } @Override - public void delete(Query query, Class clazz, IndexCoordinates index) { + @Nullable + public T get(String id, Class clazz) { + return get(id, clazz, getIndexCoordinatesFor(clazz)); + } + + @Override + @Nullable + public T get(GetQuery query, Class clazz, IndexCoordinates index) { + return get(query.getId(), clazz, index); + } - Assert.notNull(query, "Query must not be null."); + @Override + public boolean exists(String id, Class clazz) { + return exists(id, getIndexCoordinatesFor(clazz)); + } + + @Override + public boolean exists(String id, IndexCoordinates index) { + return doExists(id, index); + } + + abstract protected boolean doExists(String id, IndexCoordinates index); + + @Override + public String delete(String id, Class entityType) { + + Assert.notNull(id, "id must not be null"); + Assert.notNull(entityType, "entityType must not be null"); + + return this.delete(id, getIndexCoordinatesFor(entityType)); + } - SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(searchRequest.source().query()); + @Override + public String delete(Object entity) { + return delete(entity, getIndexCoordinatesFor(entity.getClass())); + } - delete(deleteQuery, index); + @Override + public String delete(Object entity, IndexCoordinates index) { + return this.delete(getEntityId(entity), index); } // endregion // region SearchOperations + @Override + public long count(Query query, Class clazz) { + return count(query, clazz, getIndexCoordinatesFor(clazz)); + } + @Override public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return StreamQueries.streamResults(startScroll(scrollTimeInMillis, query, clazz, index), - scrollId -> continueScroll(scrollId, scrollTimeInMillis, clazz), this::searchScrollClear); + return (CloseableIterator) SearchHitSupport.unwrapSearchHits(searchForStream(query, clazz, index)); + } + + @Override + public CloseableIterator> searchForStream(Query query, Class clazz) { + return searchForStream(query, clazz, getIndexCoordinatesFor(clazz)); } @Override @@ -174,6 +200,11 @@ public CloseableIterator> searchForStream(Query query, Class scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz), this::searchScrollClear); } + @Override + public SearchHits search(MoreLikeThisQuery query, Class clazz) { + return search(query, clazz, getIndexCoordinatesFor(clazz)); + } + @Override public SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index) { @@ -220,6 +251,28 @@ public List> multiSearch(List queries, List SearchHits search(Query query, Class clazz) { + return search(query, clazz, getIndexCoordinatesFor(clazz)); + } + + /* + * internal use only, not for public API + */ + abstract protected ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, + Class clazz, IndexCoordinates index); + + /* + * internal use only, not for public API + */ + abstract protected ScrolledPage> searchScrollContinue(@Nullable String scrollId, + long scrollTimeInMillis, Class clazz); + + /* + * internal use only, not for public API + */ + abstract protected void searchScrollClear(String scrollId); + abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); // endregion @@ -247,9 +300,6 @@ protected static String[] toArray(List values) { return values.toArray(valuesAsArray); } - @Override - public abstract SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); - /** * @param clazz the entity class * @return the IndexCoordinates defined on the entity. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 87aab6cd5..9a7225195 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -41,8 +41,10 @@ import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.client.support.AliasData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import com.fasterxml.jackson.core.type.TypeReference; @@ -60,27 +62,35 @@ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements I private RestHighLevelClient client; - public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { - super(elasticsearchConverter); + public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter, + Class boundClass) { + super(elasticsearchConverter, boundClass); + this.client = client; + } + + public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter, + IndexCoordinates boundIndex) { + super(elasticsearchConverter, boundIndex); this.client = client; } @Override - public boolean createIndex(String indexName, Object settings) { + protected boolean doCreate(String indexName, @Nullable Document settings) { CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); try { return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); } catch (IOException e) { - throw new ElasticsearchException("Error for creating index: " + request.toString(), e); + throw new ElasticsearchException( + "Error for creating index: " + indexName + ", client: " + client.getLowLevelClient().getNodes(), e); } } @Override - public boolean deleteIndex(String indexName) { + protected boolean doDelete(String indexName) { Assert.notNull(indexName, "No index defined for delete operation"); - if (indexExists(indexName)) { + if (doExists(indexName)) { DeleteIndexRequest request = new DeleteIndexRequest(indexName); try { return client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged(); @@ -92,7 +102,7 @@ public boolean deleteIndex(String indexName) { } @Override - public boolean indexExists(String indexName) { + protected boolean doExists(String indexName) { GetIndexRequest request = new GetIndexRequest(indexName); try { return client.indices().exists(request, RequestOptions.DEFAULT); @@ -102,7 +112,7 @@ public boolean indexExists(String indexName) { } @Override - public boolean putMapping(IndexCoordinates index, Object mapping) { + protected boolean doPutMapping(IndexCoordinates index, Document mapping) { Assert.notNull(index, "No index defined for putMapping()"); @@ -115,7 +125,7 @@ public boolean putMapping(IndexCoordinates index, Object mapping) { } @Override - public Map getMapping(IndexCoordinates index) { + protected Map doGetMapping(IndexCoordinates index) { Assert.notNull(index, "No index defined for getMapping()"); @@ -130,7 +140,7 @@ public Map getMapping(IndexCoordinates index) { } @Override - public boolean addAlias(AliasQuery query, IndexCoordinates index) { + protected boolean doAddAlias(AliasQuery query, IndexCoordinates index) { IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); try { return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); @@ -140,7 +150,7 @@ public boolean addAlias(AliasQuery query, IndexCoordinates index) { } @Override - public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); @@ -155,7 +165,7 @@ public boolean removeAlias(AliasQuery query, IndexCoordinates index) { } @Override - public List queryForAlias(String indexName) { + protected List doQueryForAlias(String indexName) { List aliases = null; RestClient restClient = client.getLowLevelClient(); Response response; @@ -172,12 +182,7 @@ public List queryForAlias(String indexName) { } @Override - public Map getSettings(String indexName) { - return getSettings(indexName, false); - } - - @Override - public Map getSettings(String indexName, boolean includeDefaults) { + protected Map doGetSettings(String indexName, boolean includeDefaults) { Assert.notNull(indexName, "No index defined for getSettings"); @@ -196,7 +201,7 @@ public Map getSettings(String indexName, boolean includeDefaults } @Override - public void refresh(IndexCoordinates index) { + protected void doRefresh(IndexCoordinates index) { Assert.notNull(index, "No index defined for refresh()"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index cbc485c48..c185d06ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -32,8 +32,10 @@ import org.elasticsearch.cluster.metadata.AliasMetaData; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -47,36 +49,43 @@ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations imp private final Client client; - public DefaultTransportIndexOperations(Client client, ElasticsearchConverter elasticsearchConverter) { - super(elasticsearchConverter); + public DefaultTransportIndexOperations(Client client, ElasticsearchConverter elasticsearchConverter, + Class boundClass) { + super(elasticsearchConverter, boundClass); + this.client = client; + } + + public DefaultTransportIndexOperations(Client client, ElasticsearchConverter elasticsearchConverter, + IndexCoordinates boundIndex) { + super(elasticsearchConverter, boundIndex); this.client = client; } @Override - public boolean createIndex(String indexName, Object settings) { + protected boolean doCreate(String indexName, @Nullable Document settings) { CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, indexName, settings); return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); } @Override - public boolean deleteIndex(String indexName) { + protected boolean doDelete(String indexName) { Assert.notNull(indexName, "No index defined for delete operation"); - if (indexExists(indexName)) { + if (doExists(indexName)) { return client.admin().indices().delete(new DeleteIndexRequest(indexName)).actionGet().isAcknowledged(); } return false; } @Override - public boolean indexExists(String indexName) { + protected boolean doExists(String indexName) { return client.admin().indices().exists(indicesExistsRequest(indexName)).actionGet().isExists(); } @Override - public boolean putMapping(IndexCoordinates index, Object mapping) { + protected boolean doPutMapping(IndexCoordinates index, Document mapping) { Assert.notNull(index, "No index defined for putMapping()"); @@ -85,7 +94,7 @@ public boolean putMapping(IndexCoordinates index, Object mapping) { } @Override - public Map getMapping(IndexCoordinates index) { + protected Map doGetMapping(IndexCoordinates index) { Assert.notNull(index, "No index defined for getMapping()"); @@ -100,13 +109,13 @@ public Map getMapping(IndexCoordinates index) { } @Override - public boolean addAlias(AliasQuery query, IndexCoordinates index) { + protected boolean doAddAlias(AliasQuery query, IndexCoordinates index) { IndicesAliasesRequest.AliasActions aliasAction = requestFactory.aliasAction(query, index); return client.admin().indices().prepareAliases().addAliasAction(aliasAction).execute().actionGet().isAcknowledged(); } @Override - public boolean removeAlias(AliasQuery query, IndexCoordinates index) { + protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); @@ -116,18 +125,13 @@ public boolean removeAlias(AliasQuery query, IndexCoordinates index) { } @Override - public List queryForAlias(String indexName) { + protected List doQueryForAlias(String indexName) { return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)).actionGet().getAliases() .get(indexName); } @Override - public Map getSettings(String indexName) { - return getSettings(indexName, false); - } - - @Override - public Map getSettings(String indexName, boolean includeDefaults) { + protected Map doGetSettings(String indexName, boolean includeDefaults) { Assert.notNull(indexName, "No index defined for getSettings"); @@ -144,7 +148,7 @@ public Map getSettings(String indexName, boolean includeDefaults } @Override - public void refresh(IndexCoordinates index) { + protected void doRefresh(IndexCoordinates index) { Assert.notNull(index, "No index defined for refresh()"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 9442236dc..f664f38c9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -16,8 +16,8 @@ package org.springframework.data.elasticsearch.core; import java.util.List; +import java.util.Optional; -import org.elasticsearch.action.update.UpdateResponse; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.DeleteQuery; @@ -25,6 +25,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; 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.lang.Nullable; /** @@ -68,9 +69,9 @@ public interface DocumentOperations { * saves the given entities to the given index * * @param entities must not be {@literal null} - * @param index the idnex to save the entities in, must not be {@literal null} + * @param index the index to save the entities in, must not be {@literal null} * @param the entity type - * @return the saved entites + * @return the saved entities */ Iterable save(Iterable entities, IndexCoordinates index); @@ -87,21 +88,32 @@ public interface DocumentOperations { * Index an object. Will do save or update. * * @param query the query defining the object - * @param index the index from which the object is read. + * @param index the index where the object is stored. * @return returns the document id */ String index(IndexQuery query, IndexCoordinates index); /** - * Retrieves an object from an index. + * Retrieves an object from the index specified in the entity's Document annotation. * - * @param query the query defining the id of the object to get - * @param clazz the type of the object to be returned + * @param id the id of the object + * @param clazz the entity class, + * @param the entity type + * @return the entity + */ + @Nullable + T get(String id, Class clazz); + + /** + * Retrieves an object from the index specified in the entity's Document annotation. + * + * @param id the id of the object + * @param clazz the entity class, * @param index the index from which the object is read. - * @return the found object + * @return the entity */ @Nullable - T get(GetQuery query, Class clazz, IndexCoordinates index); + T get(String id, Class clazz, IndexCoordinates index); /** * Execute a multiGet against elasticsearch for the given ids. @@ -113,6 +125,24 @@ public interface DocumentOperations { */ List multiGet(Query query, Class clazz, IndexCoordinates index); + /** + * Check if an entity with given {@literal id} exists. + * + * @param id the {@literal _id} of the document to look for. + * @param clazz the domain type used. + * @return {@literal true} if a matching document exists, {@literal false} otherwise. + */ + boolean exists(String id, Class clazz); + + /** + * Check if an entity with given {@literal id} exists. + * + * @param id the {@literal _id} of the document to look for. + * @param index the target index, must not be {@literal null} + * @return {@literal true} if a matching document exists, {@literal false} otherwise. + */ + boolean exists(String id, IndexCoordinates index); + /** * Bulk index all objects. Will do save or update. * @@ -158,6 +188,32 @@ default void bulkUpdate(List queries, IndexCoordinates index) { */ String delete(String id, IndexCoordinates index); + /** + * Delete the one object with provided id. + * + * @param id the document ot delete + * @param entityType must not be {@literal null}. + * @return documentId of the document deleted + */ + String delete(String id, Class entityType); + + /** + * Deletes the given entity + * + * @param entity the entity to delete + * @return documentId of the document deleted + */ + String delete(Object entity); + + /** + * Deletes the given entity + * + * @param entity the entity to delete + * @param index the index from which to delete + * @return documentId of the document deleted + */ + String delete(Object entity, IndexCoordinates index); + /** * Delete all records matching the query. * @@ -168,20 +224,38 @@ default void bulkUpdate(List queries, IndexCoordinates index) { */ void delete(Query query, Class clazz, IndexCoordinates index); + /** + * Partial update of the document. + * + * @param updateQuery query defining the update + * @param index the index where to update the records + * @return the update response + */ + UpdateResponse update(UpdateQuery updateQuery, IndexCoordinates index); + + // region deprecated /** * Delete all records matching the query. * * @param query query defining the objects * @param index the index where to delete the records + * @deprecated since 4.0, use {@link #delete(Query, Class, IndexCoordinates)} */ + @Deprecated void delete(DeleteQuery query, IndexCoordinates index); /** - * Partial update of the document. + * Retrieves an object from an index. * - * @param updateQuery query defining the update - * @param index the index where to update the records - * @return the update response + * @param query the query defining the id of the object to get + * @param clazz the type of the object to be returned + * @param index the index from which the object is read. + * @return the found object + * @deprecated since 4.0, use {@link #getById(String, Class, IndexCoordinates)} */ - UpdateResponse update(UpdateQuery updateQuery, IndexCoordinates index); + @Deprecated + @Nullable + T get(GetQuery query, Class clazz, IndexCoordinates index); + + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index f82529548..62c87e5ee 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -21,6 +21,7 @@ import org.elasticsearch.cluster.metadata.AliasMetaData; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; @@ -40,7 +41,19 @@ */ public interface ElasticsearchOperations extends DocumentOperations, SearchOperations { - IndexOperations getIndexOperations(); + /** + * get an {@link IndexOperations} that is bound to the given class + * + * @return IndexOperations + */ + IndexOperations indexOps(Class clazz); + + /** + * get an {@link IndexOperations} that is bound to the given class + * + * @return IndexOperations + */ + IndexOperations indexOps(IndexCoordinates index); ElasticsearchConverter getElasticsearchConverter(); @@ -52,11 +65,11 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera * * @param indexName the name of the index * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#createIndex(String) instead} + * @deprecated since 4.0, use {@link IndexOperations#create()} */ @Deprecated default boolean createIndex(String indexName) { - return getIndexOperations().createIndex(indexName); + return indexOps(IndexCoordinates.of(indexName)).create(); } /** @@ -65,11 +78,11 @@ default boolean createIndex(String indexName) { * @param indexName the name of the index * @param settings the index settings * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#createIndex(String, Object)} instead} + * @deprecated since 4.0, use {@link IndexOperations#create(Document)} */ @Deprecated default boolean createIndex(String indexName, Object settings) { - return getIndexOperations().createIndex(indexName, settings); + return indexOps(IndexCoordinates.of(indexName)).create(getDocument(settings)); } /** @@ -78,11 +91,11 @@ default boolean createIndex(String indexName, Object settings) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#createIndex(Class)} instead} + * @deprecated since 4.0, use {@link IndexOperations#create()} */ @Deprecated default boolean createIndex(Class clazz) { - return getIndexOperations().createIndex(clazz); + return indexOps(clazz).create(); } /** @@ -92,11 +105,11 @@ default boolean createIndex(Class clazz) { * {@link org.springframework.data.elasticsearch.annotations.Document} * @param settings the index settings * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#createIndex(Class, Object)} instead} + * @deprecated since 4.0, use {@link IndexOperations#create(Document)} */ @Deprecated default boolean createIndex(Class clazz, Object settings) { - return getIndexOperations().createIndex(clazz, settings); + return indexOps(clazz).create(getDocument(settings)); } /** @@ -105,11 +118,11 @@ default boolean createIndex(Class clazz, Object settings) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return {@literal true} if the index was deleted - * @deprecated since 4.0, use {@link IndexOperations#deleteIndex(Class)} instead} + * @deprecated since 4.0, use {@link IndexOperations#delete()} */ @Deprecated default boolean deleteIndex(Class clazz) { - return getIndexOperations().deleteIndex(clazz); + return indexOps(clazz).delete(); } /** @@ -117,11 +130,23 @@ default boolean deleteIndex(Class clazz) { * * @param indexName the name of the index to delete * @return {@literal true} if the index was deleted - * @deprecated since 4.0, use {@link IndexOperations#deleteIndex(String)} instead} + * @deprecated since 4.0, use {@link IndexOperations#delete()} */ @Deprecated default boolean deleteIndex(String indexName) { - return getIndexOperations().deleteIndex(indexName); + return indexOps(IndexCoordinates.of(indexName)).delete(); + } + + /** + * Deletes an index for an IndexCoordinate + * + * @param index the index to delete + * @return {@literal true} if the index was deleted + * @deprecated since 4.0 use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#delete()} + */ + @Deprecated + default boolean deleteIndex(IndexCoordinates index) { + return indexOps(index).delete(); } /** @@ -129,11 +154,11 @@ default boolean deleteIndex(String indexName) { * * @param indexName the name of the index * @return {@literal true} if the index exists - * @deprecated since 4.0, use {@link IndexOperations#indexExists(String)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#exists()} */ @Deprecated default boolean indexExists(String indexName) { - return getIndexOperations().indexExists(indexName); + return indexOps(IndexCoordinates.of(indexName)).exists(); } /** @@ -142,11 +167,11 @@ default boolean indexExists(String indexName) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return {@literal true} if the index exists - * @deprecated since 4.0, use {@link IndexOperations#indexExists(Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)} and {@link IndexOperations#exists()} */ @Deprecated default boolean indexExists(Class clazz) { - return getIndexOperations().indexExists(clazz); + return indexOps(clazz).exists(); } /** @@ -155,11 +180,13 @@ default boolean indexExists(Class clazz) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return {@literal true} if the mapping could be stored - * @deprecated since 4.0, use {@link IndexOperations#putMapping(Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)}, {@link IndexOperations#createMapping(Class)} and + * {@link IndexOperations#putMapping(Document)} */ @Deprecated default boolean putMapping(Class clazz) { - return getIndexOperations().putMapping(clazz); + IndexOperations indexOps = indexOps(clazz); + return indexOps.putMapping(indexOps.createMapping(clazz)); } /** @@ -169,11 +196,13 @@ default boolean putMapping(Class clazz) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return {@literal true} if the mapping could be stored - * @deprecated since 4.0, use {@link IndexOperations#putMapping(IndexCoordinates, Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)}, {@link IndexOperations#createMapping(Class)} and + * {@link IndexOperations#putMapping(Document)} */ @Deprecated default boolean putMapping(IndexCoordinates index, Class clazz) { - return getIndexOperations().putMapping(index, clazz); + IndexOperations indexOps = indexOps(index); + return indexOps.putMapping(indexOps.createMapping(clazz)); } /** @@ -182,11 +211,11 @@ default boolean putMapping(IndexCoordinates index, Class clazz) { * @param index the index to store the mapping to * @param mappings can be a JSON String or a {@link Map} * @return {@literal true} if the mapping could be stored - * @deprecated since 4.0, use {@link IndexOperations#putMapping(IndexCoordinates, Object)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#putMapping(Document)} */ @Deprecated default boolean putMapping(IndexCoordinates index, Object mappings) { - return getIndexOperations().putMapping(index, mappings); + return indexOps(index).putMapping(getDocument(mappings)); } /** @@ -196,11 +225,11 @@ default boolean putMapping(IndexCoordinates index, Object mappings) { * {@link org.springframework.data.elasticsearch.annotations.Document} * @param mappings can be a JSON String or a {@link Map} * @return {@literal true} if the mapping could be stored - * @deprecated since 4.0, use {@link IndexOperations#putMapping(Class, Object)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)} and {@link IndexOperations#putMapping(Document)} */ @Deprecated default boolean putMapping(Class clazz, Object mappings) { - return getIndexOperations().putMapping(clazz, mappings); + return indexOps(clazz).putMapping(getDocument(mappings)); } /** @@ -209,11 +238,11 @@ default boolean putMapping(Class clazz, Object mappings) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document}. * @return the mapping - * @deprecated since 4.0, use {@link IndexOperations#getMapping(Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)} and {@link IndexOperations#getMapping()} */ @Deprecated default Map getMapping(Class clazz) { - return getIndexOperations().getMapping(clazz); + return indexOps(clazz).getMapping(); } /** @@ -221,11 +250,11 @@ default Map getMapping(Class clazz) { * * @param index the index to read the mapping from * @return the mapping - * @deprecated since 4.0, use {@link IndexOperations#getMapping(IndexCoordinates)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#getMapping()} */ @Deprecated default Map getMapping(IndexCoordinates index) { - return getIndexOperations().getMapping(index); + return indexOps(index).getMapping(); } /** @@ -234,11 +263,11 @@ default Map getMapping(IndexCoordinates index) { * @param query query defining the alias * @param index the index for which to add an alias * @return true if the alias was created - * @deprecated since 4.0, use {@link IndexOperations#addAlias(AliasQuery, IndexCoordinates)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#addAlias(AliasQuery)} */ @Deprecated default boolean addAlias(AliasQuery query, IndexCoordinates index) { - return getIndexOperations().addAlias(query, index); + return indexOps(index).addAlias(query); } /** @@ -247,11 +276,11 @@ default boolean addAlias(AliasQuery query, IndexCoordinates index) { * @param query query defining the alias * @param index the index for which to remove an alias * @return true if the alias was removed - * @deprecated since 4.0, use {@link IndexOperations#removeAlias(AliasQuery, IndexCoordinates)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} {@link IndexOperations#removeAlias(AliasQuery)} */ @Deprecated default boolean removeAlias(AliasQuery query, IndexCoordinates index) { - return getIndexOperations().removeAlias(query, index); + return indexOps(index).removeAlias(query); } /** @@ -259,11 +288,11 @@ default boolean removeAlias(AliasQuery query, IndexCoordinates index) { * * @param indexName the name of the index * @return alias information - * @deprecated since 4.0, use {@link IndexOperations#queryForAlias(String)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#queryForAlias()} */ @Deprecated default List queryForAlias(String indexName) { - return getIndexOperations().queryForAlias(indexName); + return indexOps(IndexCoordinates.of(indexName)).queryForAlias(); } /** @@ -271,11 +300,11 @@ default List queryForAlias(String indexName) { * * @param indexName the name of the index * @return the settings - * @deprecated since 4.0, use {@link IndexOperations#getSettings(String)} )} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#getSettings()} )} */ @Deprecated default Map getSetting(String indexName) { - return getIndexOperations().getSettings(indexName); + return indexOps(IndexCoordinates.of(indexName)).getSettings(); } /** @@ -284,22 +313,48 @@ default Map getSetting(String indexName) { * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} * @return the settings - * @deprecated since 4.0, use {@link IndexOperations#getSettings(Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)} and {@link IndexOperations#getSettings()} */ @Deprecated default Map getSetting(Class clazz) { - return getIndexOperations().getSettings(clazz); + return indexOps(clazz).getSettings(); + } + + /** + * Get settings for a given indexName. + * + * @param indexName the name of the index + * @param includeDefaults whether or not to include all the default settings + * @deprecated since 4.0 use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#getSettings(boolean)} ()} + * @return the settings + */ + @Deprecated + default Map getSettings(String indexName, boolean includeDefaults) { + return indexOps(IndexCoordinates.of(indexName)).getSettings(includeDefaults); + } + + /** + * Get settings for a given class. + * + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @param includeDefaults whether or not to include all the default settings + * @return the settings + * @deprecated since 4.0 use {@link #indexOps(Class)} and {@link IndexOperations#getSettings(boolean)} ()} + */ + default Map getSettings(Class clazz, boolean includeDefaults) { + return indexOps(clazz).getSettings(includeDefaults); } /** * Refresh the index(es). * * @param index the index to refresh - * @deprecated since 4.0, use {@link IndexOperations#refresh(IndexCoordinates)} instead} + * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#refresh()} instead} */ @Deprecated default void refresh(IndexCoordinates index) { - getIndexOperations().refresh(index); + indexOps(index).refresh(); } /** @@ -307,13 +362,36 @@ default void refresh(IndexCoordinates index) { * * @param clazz The entity class, must be annotated with * {@link org.springframework.data.elasticsearch.annotations.Document} - * @deprecated since 4.0, use {@link IndexOperations#refresh(Class)} instead} + * @deprecated since 4.0, use {@link #indexOps(Class)} and {@link IndexOperations#refresh()} instead} */ @Deprecated default void refresh(Class clazz) { - getIndexOperations().refresh(clazz); + indexOps(clazz).refresh(); } - // endregion + + /** + * converts an object to a Document + * + * @param object + * @return + * @deprecated since 4.0, helper method for deprecated functions + */ + @Deprecated + @Nullable + default Document getDocument(Object object) { + Document document = null; + + try { + if (object instanceof String) { + document = Document.parse((String) object); + } else if (object instanceof Map) { + document = Document.from((Map) object); + } + } catch (Exception e) { + throw new IllegalArgumentException("object cannot be converted to Document", e); + } + return document; + } // endregion // region helper /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 1dc87c027..26e617a58 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.List; +import java.util.Optional; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; @@ -32,7 +33,6 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.action.update.UpdateRequest; -import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; @@ -47,10 +47,10 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.DeleteQuery; -import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; 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.support.SearchHitsUtil; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -103,9 +103,29 @@ public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConver } private void initialize(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { + Assert.notNull(client, "Client must not be null!"); + this.client = client; - initialize(elasticsearchConverter, new DefaultIndexOperations(client, elasticsearchConverter)); + initialize(elasticsearchConverter); + } + // endregion + + // region IndexOperations + @Override + public IndexOperations indexOps(Class clazz) { + + Assert.notNull(clazz, "clazz must not be null"); + + return new DefaultIndexOperations(client, elasticsearchConverter, clazz); + } + + @Override + public IndexOperations indexOps(IndexCoordinates index) { + + Assert.notNull(index, "index must not be null"); + + return new DefaultIndexOperations(client, elasticsearchConverter, index); } // endregion @@ -128,8 +148,8 @@ public String index(IndexQuery query, IndexCoordinates index) { @Override @Nullable - public T get(GetQuery query, Class clazz, IndexCoordinates index) { - GetRequest request = requestFactory.getRequest(query, index); + public T get(String id, Class clazz, IndexCoordinates index) { + GetRequest request = requestFactory.getRequest(id, index); try { GetResponse response = client.get(request, RequestOptions.DEFAULT); return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); @@ -153,6 +173,16 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) } } + @Override + protected boolean doExists(String id, IndexCoordinates index) { + GetRequest request = requestFactory.getRequest(id, index); + try { + return client.get(request, RequestOptions.DEFAULT).isExists(); + } catch (IOException e) { + throw new ElasticsearchException("Error while getting for request: " + request.toString(), e); + } + } + @Override public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { @@ -173,6 +203,10 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index @Override public String delete(String id, IndexCoordinates index) { + + Assert.notNull(id, "id must not be null"); + Assert.notNull(index, "index must not be null"); + DeleteRequest request = new DeleteRequest(index.getIndexName(), elasticsearchConverter.convertId(id)); try { return client.delete(request, RequestOptions.DEFAULT).getId(); @@ -182,6 +216,17 @@ public String delete(String id, IndexCoordinates index) { } @Override + public void delete(Query query, Class clazz, IndexCoordinates index) { + DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(query, clazz, index); + try { + client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); + } catch (IOException e) { + throw new ElasticsearchException("Error for delete request: " + deleteByQueryRequest.toString(), e); + } + } + + @Override + @Deprecated public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(deleteQuery, index); try { @@ -195,7 +240,9 @@ public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { UpdateRequest request = requestFactory.updateRequest(query, index); try { - return client.update(request, RequestOptions.DEFAULT); + org.elasticsearch.action.update.UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT); + UpdateResponse.Result result = UpdateResponse.Result.valueOf(updateResponse.getResult().name()); + return new UpdateResponse(result); } catch (IOException e) { throw new ElasticsearchException("Error while update for request: " + request.toString(), e); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index b2ed56ee3..848ed4dc2 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core; import java.util.List; +import java.util.Optional; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.bulk.BulkRequestBuilder; @@ -28,7 +29,6 @@ import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequestBuilder; -import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.search.suggest.SuggestBuilder; @@ -41,10 +41,10 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.DeleteQuery; -import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; 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.support.SearchHitsUtil; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -97,9 +97,29 @@ public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearch } private void initialize(Client client, ElasticsearchConverter elasticsearchConverter) { + Assert.notNull(client, "Client must not be null!"); + this.client = client; - initialize(elasticsearchConverter, new DefaultTransportIndexOperations(client, elasticsearchConverter)); + initialize(elasticsearchConverter); + } + // endregion + + // region IndexOperations + @Override + public IndexOperations indexOps(Class clazz) { + + Assert.notNull(clazz, "clazz must not be null"); + + return new DefaultTransportIndexOperations(client, elasticsearchConverter, clazz); + } + + @Override + public IndexOperations indexOps(IndexCoordinates index) { + + Assert.notNull(index, "index must not be null"); + + return new DefaultTransportIndexOperations(client, elasticsearchConverter, index); } // endregion @@ -128,8 +148,8 @@ public String index(IndexQuery query, IndexCoordinates index) { @Override @Nullable - public T get(GetQuery query, Class clazz, IndexCoordinates index) { - GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, query, index); + public T get(String id, Class clazz, IndexCoordinates index) { + GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, id, index); GetResponse response = getRequestBuilder.execute().actionGet(); return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); } @@ -145,6 +165,12 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) return elasticsearchConverter.mapDocuments(DocumentAdapters.from(builder.execute().actionGet()), clazz); } + @Override + protected boolean doExists(String id, IndexCoordinates index) { + GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, id, index); + return getRequestBuilder.execute().actionGet().isExists(); + } + @Override public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { @@ -165,19 +191,36 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index @Override public String delete(String id, IndexCoordinates index) { + + Assert.notNull(id, "id must not be null"); + Assert.notNull(index, "index must not be null"); + return client.prepareDelete(index.getIndexName(), IndexCoordinates.TYPE, elasticsearchConverter.convertId(id)) .execute().actionGet().getId(); } @Override + @Deprecated public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { requestFactory.deleteByQueryRequestBuilder(client, deleteQuery, index).get(); } + @Override + public void delete(Query query, Class clazz, IndexCoordinates index) { + requestFactory.deleteByQueryRequestBuilder(client, query, clazz, index).get(); + } + + @Override + public String delete(Object entity, IndexCoordinates index) { + return super.delete(entity, index); + } + @Override public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { UpdateRequestBuilder updateRequestBuilder = requestFactory.updateRequestBuilderFor(client, query, index); - return updateRequestBuilder.execute().actionGet(); + org.elasticsearch.action.update.UpdateResponse updateResponse = updateRequestBuilder.execute().actionGet(); + UpdateResponse.Result result = UpdateResponse.Result.valueOf(updateResponse.getResult().name()); + return new UpdateResponse(result); } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 31f79f2c5..1eeaeb52d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -19,13 +19,17 @@ import java.util.Map; import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; /** * The operations for the * Elasticsearch Index APIs. - * + *
+ * IndexOperations are bound to an entity class or an IndexCoordinate by + * {@link ElasticsearchOperations#indexOps(IndexCoordinates)} or {@link ElasticsearchOperations#indexOps(Class)} + * * @author Peter-Josef Meisch * @author Sascha Woo * @since 4.0 @@ -33,204 +37,104 @@ public interface IndexOperations { /** - * Create an index for given indexName. + * Create an index. * - * @param indexName the name of the index * @return {@literal true} if the index was created */ - boolean createIndex(String indexName); + boolean create(); /** - * Create an index for given indexName and Settings. + * Create an index for given Settings. * - * @param indexName the name of the index * @param settings the index settings * @return {@literal true} if the index was created */ - boolean createIndex(String indexName, Object settings); - - /** - * Create an index for a class. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @return {@literal true} if the index was created - */ - boolean createIndex(Class clazz); - - /** - * Create an index for given class and Settings. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @param settings the index settings - * @return {@literal true} if the index was created - */ - boolean createIndex(Class clazz, Object settings); - - /** - * Deletes an index for given entity. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @return {@literal true} if the index was deleted - */ - boolean deleteIndex(Class clazz); + boolean create(Document settings); /** - * Deletes an index. + * Deletes the index this {@link IndexOperations} is bound to * - * @param indexName the name of the index to delete * @return {@literal true} if the index was deleted */ - boolean deleteIndex(String indexName); + boolean delete(); /** - * check if index exists. + * Checks if the index this IndexOperations is bound to exists * - * @param indexName the name of the index * @return {@literal true} if the index exists */ - boolean indexExists(String indexName); + boolean exists(); /** - * check if index is exists. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @return {@literal true} if the index exists + * Refresh the index(es) this IndexOperations is bound to */ - boolean indexExists(Class clazz); + void refresh(); /** - * Create mapping for a class and store it to the index. + * Creates the index mapping for the entity this IndexOperations is bound to. * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @return {@literal true} if the mapping could be stored + * @return mapping object */ - boolean putMapping(Class clazz); + Document createMapping(); /** - * Create mapping for the given class and put the mapping to the given index. + * Creates the index mapping for the given class * - * @param index the index to store the mapping to - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @return {@literal true} if the mapping could be stored + * @param clazz the clazz to create a mapping for + * @return mapping object */ - boolean putMapping(IndexCoordinates index, Class clazz); + Document createMapping(Class clazz); /** - * Stores a mapping to an index. - * - * @param index the index to store the mapping to - * @param mappings can be a JSON String or a {@link Map} + * writes a mapping to the index + * + * @param mapping the Document with the mapping definitions * @return {@literal true} if the mapping could be stored */ - boolean putMapping(IndexCoordinates index, Object mappings); - - /** - * Create mapping for a class Stores a mapping to an index. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @param mappings can be a JSON String or a {@link Map} - * @return {@literal true} if the mapping could be stored - */ - boolean putMapping(Class clazz, Object mappings); + boolean putMapping(Document mapping); /** * Get mapping for an index defined by a class. * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document}. * @return the mapping */ - Map getMapping(Class clazz); - - /** - * Get mapping for a given index. - * - * @param index the index to read the mapping from - * @return the mapping - */ - Map getMapping(IndexCoordinates index); + Map getMapping(); /** * Add an alias. * * @param query query defining the alias - * @param index the index for which to add an alias * @return true if the alias was created */ - boolean addAlias(AliasQuery query, IndexCoordinates index); - - /** - * Remove an alias. - * - * @param query query defining the alias - * @param index the index for which to remove an alias - * @return true if the alias was removed - */ - boolean removeAlias(AliasQuery query, IndexCoordinates index); + boolean addAlias(AliasQuery query); /** * Get the alias informations for a specified index. * - * @param indexName the name of the index * @return alias information */ - List queryForAlias(String indexName); - - /** - * Get settings for a given indexName. - * - * @param indexName the name of the index - * @return the settings - */ - Map getSettings(String indexName); + List queryForAlias(); /** - * Get settings for a given indexName. + * Remove an alias. * - * @param indexName the name of the index - * @param includeDefaults whether or not to include all the default settings - * @return the settings + * @param query query defining the alias + * @return true if the alias was removed */ - Map getSettings(String indexName, boolean includeDefaults); + boolean removeAlias(AliasQuery query); /** - * Get settings for a given class. + * Get the index settings. * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} * @return the settings */ - Map getSettings(Class clazz); + Map getSettings(); /** - * Get settings for a given class. + * Get settings for a given indexName. * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - * @param includeDefaults whether or not to include all the default settings + * @param includeDefaults wehther or not to include all the default settings * @return the settings */ - Map getSettings(Class clazz, boolean includeDefaults); - - /** - * Refresh the index(es). - * - * @param index the index to refresh - */ - void refresh(IndexCoordinates index); - - /** - * Refresh the index. - * - * @param clazz The entity class, must be annotated with - * {@link org.springframework.data.elasticsearch.annotations.Document} - */ - void refresh(Class clazz); + Map getSettings(boolean includeDefaults); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index d0c8b353e..955a122bb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -151,8 +151,37 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param entityType the domain type used for mapping the document. * @param * @return {@link Mono#empty()} if not found. + * @deprecated since 4.0 use {@link #get(String, Class)} */ - Mono findById(String id, Class entityType); + @Deprecated + default Mono findById(String id, Class entityType) { + return get(id, entityType); + } + + /** + * Fetch the entity with given {@literal id}. + * + * @param id must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @param + * @return the {@link Mono} emitting the entity or signalling completion if none found. + * @deprecated since 4.0, use {@link #get(String, Class, IndexCoordinates)} + */ + @Deprecated + default Mono findById(String id, Class entityType, IndexCoordinates index) { + return get(id, entityType, index); + } + + /** + * Find the document with the given {@literal id} mapped onto the given {@literal entityType}. + * + * @param id the {@literal _id} of the document to fetch. + * @param entityType the domain type used for mapping the document. + * @param + * @return {@link Mono#empty()} if not found. + * @since 4.0 + */ + Mono get(String id, Class entityType); /** * Fetch the entity with given {@literal id}. @@ -162,7 +191,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param * @return the {@link Mono} emitting the entity or signalling completion if none found. */ - Mono findById(String id, Class entityType, IndexCoordinates index); + Mono get(String id, Class entityType, IndexCoordinates index); /** * Check if an entity with given {@literal id} exists. @@ -180,6 +209,17 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. */ + Mono exists(String id, IndexCoordinates index); + + /** + * Check if an entity with given {@literal id} exists. + * + * @param id the {@literal _id} of the document to look for. + * @param index the target index, must not be {@literal null} + * @return a {@link Mono} emitting {@literal true} if a matching document exists, {@literal false} otherwise. + * @deprecated since 4.0, use {@link #exists(String, Class)} or {@link #exists(String, IndexCoordinates)} + */ + @Deprecated Mono exists(String id, Class entityType, IndexCoordinates index); /** @@ -188,7 +228,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param entity must not be {@literal null}. * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - Mono delete(Object entity); + Mono delete(Object entity); /** * Delete the given entity extracting index and type from entity metadata. @@ -197,7 +237,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - Mono delete(Object entity, IndexCoordinates index); + Mono delete(Object entity, IndexCoordinates index); /** * Delete the entity with given {@literal id}. @@ -206,12 +246,7 @@ default Mono bulkUpdate(List queries, IndexCoordinates index) * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - default Mono deleteById(String id, IndexCoordinates index) { - - Assert.notNull(index, "Index must not be null!"); - - return deleteById(id, Object.class, index); - } + Mono delete(String id, IndexCoordinates index); /** * Delete the entity with given {@literal id} extracting index and type from entity metadata. @@ -219,8 +254,9 @@ default Mono deleteById(String id, IndexCoordinates index) { * @param id must not be {@literal null}. * @param entityType must not be {@literal null}. * @return a {@link Mono} emitting the {@literal id} of the removed document. + * @since 4.0 */ - Mono deleteById(String id, Class entityType); + Mono delete(String id, Class entityType); /** * Delete the entity with given {@literal id} extracting index and type from entity metadata. @@ -229,8 +265,12 @@ default Mono deleteById(String id, IndexCoordinates index) { * @param entityType must not be {@literal null}. * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. + * @deprecated since 4.0, use {@link #delete(String, Class)} or {@link #deleteById(String, IndexCoordinates)} */ - Mono deleteById(String id, Class entityType, IndexCoordinates index); + @Deprecated + default Mono delete(String id, Class entityType, IndexCoordinates index) { + return delete(id, index); + } /** * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. @@ -239,7 +279,7 @@ default Mono deleteById(String id, IndexCoordinates index) { * @param entityType must not be {@literal null}. * @return a {@link Mono} emitting the number of the removed documents. */ - Mono deleteBy(Query query, Class entityType); + Mono delete(Query query, Class entityType); /** * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. @@ -249,5 +289,5 @@ default Mono deleteById(String id, IndexCoordinates index) { * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the number of the removed documents. */ - Mono deleteBy(Query query, Class entityType, IndexCoordinates index); + Mono delete(Query query, Class entityType, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8c5826362..ada81c511 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -243,21 +243,31 @@ protected Mono checkForBulkOperationFailure(BulkResponse bulkRespo } } - /** - * Customization hook on the actual execution result {@link Publisher}.
- * - * @param request the already prepared {@link GetRequest} ready to be executed. - * @return a {@link Mono} emitting the result of the operation. - */ - protected Mono doFindById(GetRequest request) { + @Override + public Mono exists(String id, Class entityType) { + return doExists(id, getIndexCoordinatesFor(entityType)); + } - return Mono.from(execute(client -> client.get(request))) // - .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); + @Override + public Mono exists(String id, IndexCoordinates index) { + return doExists(id, index); } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exists(String, Class, IndexCoordinates) + */ @Override - public Mono exists(String id, Class entityType) { - return exists(id, entityType, getIndexCoordinatesFor(entityType)); + public Mono exists(String id, Class entityType, IndexCoordinates index) { + + Assert.notNull(id, "Id must not be null!"); + + return doExists(id, index); + } + + private Mono doExists(String id, @Nullable IndexCoordinates index) { + + return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), id))); } /** @@ -320,46 +330,35 @@ private IndexQuery getIndexQuery(Object value, AdaptibleEntity entity) { } @Override - public Mono findById(String id, Class entityType) { - return findById(id, entityType, getIndexCoordinatesFor(entityType)); + public Mono get(String id, Class entityType) { + return get(id, entityType, getIndexCoordinatesFor(entityType)); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#findById(String, Class, IndexCoordinates) - */ @Override - public Mono findById(String id, Class entityType, IndexCoordinates index) { + public Mono get(String id, Class entityType, IndexCoordinates index) { Assert.notNull(id, "Id must not be null!"); - return doFindById(id, getPersistentEntityFor(entityType), index) + return doGet(id, getPersistentEntityFor(entityType), index) .map(it -> converter.mapDocument(DocumentAdapters.from(it), entityType)); } - private Mono doFindById(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - + private Mono doGet(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { return Mono.defer(() -> { - - return doFindById(new GetRequest(index.getIndexName(), id)); + return doGet(new GetRequest(index.getIndexName(), id)); }); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exists(String, Class, IndexCoordinates) + /** + * Customization hook on the actual execution result {@link Publisher}.
+ * + * @param request the already prepared {@link GetRequest} ready to be executed. + * @return a {@link Mono} emitting the result of the operation. */ - @Override - public Mono exists(String id, Class entityType, IndexCoordinates index) { - - Assert.notNull(id, "Id must not be null!"); - - return doExists(id, getPersistentEntityFor(entityType), index); - } - - private Mono doExists(String id, ElasticsearchPersistentEntity entity, @Nullable IndexCoordinates index) { + protected Mono doGet(GetRequest request) { - return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), id))); + return Mono.from(execute(client -> client.get(request))) // + .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } /* @@ -367,52 +366,50 @@ private Mono doExists(String id, ElasticsearchPersistentEntity entit * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(Object, String, String) */ @Override - public Mono delete(Object entity, IndexCoordinates index) { + public Mono delete(Object entity, IndexCoordinates index) { Entity elasticsearchEntity = operations.forEntity(entity); - return Mono.defer(() -> doDeleteById(entity, converter.convertId(elasticsearchEntity.getId()), - elasticsearchEntity.getPersistentEntity(), index)); + return Mono.defer(() -> doDeleteById(converter.convertId(elasticsearchEntity.getId()), index)); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(String, Class, IndexCoordinates) - */ @Override - public Mono deleteById(String id, Class entityType, IndexCoordinates index) { + public Mono delete(Object entity) { + return delete(entity, getIndexCoordinatesFor(entity.getClass())); + } - Assert.notNull(id, "Id must not be null!"); + @Override + public Mono delete(String id, Class entityType) { - return doDeleteById(null, id, getPersistentEntityFor(entityType), index); + Assert.notNull(id, "id must not be null"); + Assert.notNull(entityType, "entityType must not be null"); + return delete(id, getIndexCoordinatesFor(entityType)); } @Override - public Mono delete(Object entity) { - return delete(entity, getIndexCoordinatesFor(entity.getClass())); - } + public Mono delete(String id, IndexCoordinates index) { - @Override - public Mono deleteById(String id, Class entityType) { - return deleteById(id, entityType, getIndexCoordinatesFor(entityType)); + Assert.notNull(id, "id must not be null"); + Assert.notNull(index, "index must not be null"); + + return doDeleteById(id, index); } - private Mono doDeleteById(@Nullable Object source, String id, ElasticsearchPersistentEntity entity, - IndexCoordinates index) { + private Mono doDeleteById(String id, IndexCoordinates index) { return Mono.defer(() -> { - return doDelete(prepareDeleteRequest(source, new DeleteRequest(index.getIndexName(), id))); + return doDelete(prepareDeleteRequest(new DeleteRequest(index.getIndexName(), id))); }); } /* * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#deleteBy(Query, Class, IndexCoordinates) + * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(Query, Class, IndexCoordinates) */ @Override - public Mono deleteBy(Query query, Class entityType, IndexCoordinates index) { + public Mono delete(Query query, Class entityType, IndexCoordinates index) { Assert.notNull(query, "Query must not be null!"); @@ -421,8 +418,8 @@ public Mono deleteBy(Query query, Class entityType, IndexCoordinates in } @Override - public Mono deleteBy(Query query, Class entityType) { - return deleteBy(query, entityType, getIndexCoordinatesFor(entityType)); + public Mono delete(Query query, Class entityType) { + return delete(query, entityType, getIndexCoordinatesFor(entityType)); } private Flux doDeleteBy(Query query, ElasticsearchPersistentEntity entity, @@ -473,12 +470,10 @@ protected Mono doDeleteBy(DeleteByQueryRequest request) { * Customization hook to modify a generated {@link DeleteRequest} prior to its execution. Eg. by setting the * {@link WriteRequest#setRefreshPolicy(String) refresh policy} if applicable. * - * @param source the source object the {@link DeleteRequest} was derived from. My be {@literal null} if using the - * {@literal id} directly. * @param request the generated {@link DeleteRequest}. * @return never {@literal null}. */ - protected DeleteRequest prepareDeleteRequest(@Nullable Object source, DeleteRequest request) { + protected DeleteRequest prepareDeleteRequest(DeleteRequest request) { return prepareWriteRequest(request); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 95113f373..e54d5aa23 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -19,6 +19,7 @@ import static org.springframework.util.CollectionUtils.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -44,8 +45,6 @@ import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.common.xcontent.XContentBuilder; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.VersionType; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; @@ -53,9 +52,10 @@ import org.elasticsearch.index.reindex.DeleteByQueryAction; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder; +import org.elasticsearch.script.Script; +import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.GeoDistanceSortBuilder; @@ -67,6 +67,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -180,31 +181,27 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, Bul } @SuppressWarnings("unchecked") - public CreateIndexRequest createIndexRequest(String indexName, Object settings) { + public CreateIndexRequest createIndexRequest(String indexName, @Nullable Document settings) { CreateIndexRequest request = new CreateIndexRequest(indexName); - if (settings instanceof String) { - request.settings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); - } else if (settings instanceof Map) { - request.settings((Map) settings); - } else if (settings instanceof XContentBuilder) { - request.settings((XContentBuilder) settings); + + if (settings != null) { + request.settings(settings); } return request; } @SuppressWarnings("unchecked") - public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, Object settings) { + public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, + @Nullable Document settings) { CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); - if (settings instanceof String) { - createIndexRequestBuilder.setSettings(String.valueOf(settings), Requests.INDEX_CONTENT_TYPE); - } else if (settings instanceof Map) { - createIndexRequestBuilder.setSettings((Map) settings); - } else if (settings instanceof XContentBuilder) { - createIndexRequestBuilder.setSettings((XContentBuilder) settings); + + if (settings != null) { + createIndexRequestBuilder.setSettings(settings); } return createIndexRequestBuilder; } + @Deprecated public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexCoordinates index) { DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) // .setQuery(deleteQuery.getQuery()) // @@ -220,6 +217,25 @@ public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexC return deleteByQueryRequest; } + public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, IndexCoordinates index) { + SearchRequest searchRequest = searchRequest(query, clazz, index); + DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) // + .setQuery(searchRequest.source().query()) // + .setAbortOnVersionConflict(false) // + .setRefresh(true); + + if (query.isLimiting()) { + deleteByQueryRequest.setBatchSize(query.getMaxResults()); + } + + if (query.hasScrollTime()) { + deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); + } + + return deleteByQueryRequest; + } + + @Deprecated public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, DeleteQuery deleteQuery, IndexCoordinates index) { DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) // @@ -236,14 +252,37 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, De return requestBuilder; } - public GetRequest getRequest(GetQuery query, IndexCoordinates index) { - return new GetRequest(index.getIndexName(), query.getId()); + public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, Query query, Class clazz, + IndexCoordinates index) { + SearchRequest searchRequest = searchRequest(query, clazz, index); + DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) // + .source(index.getIndexNames()) // + .filter(searchRequest.source().query()) // + .abortOnVersionConflict(false) // + .refresh(true); + + SearchRequestBuilder source = requestBuilder.source(); + + if (query.isLimiting()) { + source.setSize(query.getMaxResults()); + } + + if (query.hasScrollTime()) { + source.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); + } + + return requestBuilder; } - public GetRequestBuilder getRequestBuilder(Client client, GetQuery query, IndexCoordinates index) { - return client.prepareGet(index.getIndexName(), null, query.getId()); + public GetRequest getRequest(String id, IndexCoordinates index) { + return new GetRequest(index.getIndexName(), id); } + public GetRequestBuilder getRequestBuilder(Client client, String id, IndexCoordinates index) { + return client.prepareGet(index.getIndexName(), null, id); + } + + @Nullable public HighlightBuilder highlightBuilder(Query query) { HighlightBuilder highlightBuilder = query.getHighlightQuery().map(HighlightQuery::getHighlightBuilder).orElse(null); @@ -420,39 +459,40 @@ public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nu public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { - Assert.notNull(query.getId(), "No Id define for Query"); - Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); + UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), query.getId()); - UpdateRequest queryUpdateRequest = query.getUpdateRequest(); + if (query.getScript() != null) { + Map params = query.getParams(); - UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), query.getId()) // - .routing(queryUpdateRequest.routing()) // - .retryOnConflict(queryUpdateRequest.retryOnConflict()) // - .timeout(queryUpdateRequest.timeout()) // - .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // - .waitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .scriptedUpsert(queryUpdateRequest.scriptedUpsert()) // - .docAsUpsert(queryUpdateRequest.docAsUpsert()); + if (params == null) { + params = new HashMap<>(); + } + Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); + updateRequest.script(script); + } - if (query.DoUpsert()) { - updateRequest.docAsUpsert(true); + if (query.getDocument() != null) { + updateRequest.doc(query.getDocument()); } - if (queryUpdateRequest.script() != null) { - updateRequest.script(queryUpdateRequest.script()); + if (query.getUpsert() != null) { + updateRequest.upsert(query.getUpsert()); } - if (queryUpdateRequest.doc() != null) { - updateRequest.doc(queryUpdateRequest.doc()); + if (query.getRouting() != null) { + updateRequest.routing(query.getRouting()); } - if (queryUpdateRequest.upsertRequest() != null) { - updateRequest.upsert(queryUpdateRequest.upsertRequest()); + if (query.getScriptedUpsert() != null) { + updateRequest.scriptedUpsert(query.getScriptedUpsert()); } - if (queryUpdateRequest.fetchSource() != null) { - updateRequest.fetchSource(queryUpdateRequest.fetchSource()); + if (query.getDocAsUpsert() != null) { + updateRequest.docAsUpsert(query.getDocAsUpsert()); + } + + if (query.getFetchSource() != null) { + updateRequest.fetchSource(query.getFetchSource()); } return updateRequest; @@ -460,41 +500,41 @@ public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery query, IndexCoordinates index) { - Assert.notNull(query.getId(), "No Id define for Query"); - Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query"); + UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(index.getIndexName(), IndexCoordinates.TYPE, + query.getId()); + + if (query.getScript() != null) { + Map params = query.getParams(); - UpdateRequest queryUpdateRequest = query.getUpdateRequest(); + if (params == null) { + params = new HashMap<>(); + } + Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); + updateRequestBuilder.setScript(script); + } - UpdateRequestBuilder updateRequestBuilder = client - .prepareUpdate(index.getIndexName(), IndexCoordinates.TYPE, query.getId()) // - .setRouting(queryUpdateRequest.routing()) // - .setRetryOnConflict(queryUpdateRequest.retryOnConflict()) // - .setTimeout(queryUpdateRequest.timeout()) // - .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setRefreshPolicy(queryUpdateRequest.getRefreshPolicy()) // - .setWaitForActiveShards(queryUpdateRequest.waitForActiveShards()) // - .setScriptedUpsert(queryUpdateRequest.scriptedUpsert()) // - .setDocAsUpsert(queryUpdateRequest.docAsUpsert()); + if (query.getDocument() != null) { + updateRequestBuilder.setDoc(query.getDocument()); + } - if (query.DoUpsert()) { - updateRequestBuilder.setDocAsUpsert(true); + if (query.getUpsert() != null) { + updateRequestBuilder.setUpsert(query.getUpsert()); } - if (queryUpdateRequest.script() != null) { - updateRequestBuilder.setScript(queryUpdateRequest.script()); + if (query.getRouting() != null) { + updateRequestBuilder.setRouting(query.getRouting()); } - if (queryUpdateRequest.doc() != null) { - updateRequestBuilder.setDoc(queryUpdateRequest.doc()); + if (query.getScriptedUpsert() != null) { + updateRequestBuilder.setScriptedUpsert(query.getScriptedUpsert()); } - if (queryUpdateRequest.upsertRequest() != null) { - updateRequestBuilder.setUpsert(queryUpdateRequest.upsertRequest()); + if (query.getDocAsUpsert() != null) { + updateRequestBuilder.setDocAsUpsert(query.getDocAsUpsert()); } - FetchSourceContext fetchSourceContext = queryUpdateRequest.fetchSource(); - if (fetchSourceContext != null) { - updateRequestBuilder.setFetchSource(fetchSourceContext.includes(), fetchSourceContext.excludes()); + if (query.getFetchSource() != null) { + updateRequestBuilder.setFetchSource(query.getFetchSource()); } return updateRequestBuilder; @@ -569,29 +609,17 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz } @SuppressWarnings("unchecked") - public PutMappingRequest putMappingRequest(IndexCoordinates index, Object mapping) { + public PutMappingRequest putMappingRequest(IndexCoordinates index, Document mapping) { PutMappingRequest request = new PutMappingRequest(index.getIndexName()); - if (mapping instanceof String) { - request.source(String.valueOf(mapping), XContentType.JSON); - } else if (mapping instanceof Map) { - request.source((Map) mapping); - } else if (mapping instanceof XContentBuilder) { - request.source((XContentBuilder) mapping); - } + request.source(mapping); return request; } @SuppressWarnings("rawtypes") - public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Object mapping) { + public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Document mapping) { PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(index.getIndexName()) .setType(IndexCoordinates.TYPE); - if (mapping instanceof String) { - requestBuilder.setSource(String.valueOf(mapping), XContentType.JSON); - } else if (mapping instanceof Map) { - requestBuilder.setSource((Map) mapping); - } else if (mapping instanceof XContentBuilder) { - requestBuilder.setSource((XContentBuilder) mapping); - } + requestBuilder.setSource(mapping); return requestBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 4c173264b..9346d7e59 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -50,6 +50,15 @@ default long count(Query query, IndexCoordinates index) { return count(query, null, index); } + /** + * return number of elements found by given query + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping and index name extraction + * @return count + */ + long count(Query query, Class clazz); + /** * return number of elements found by given query * @@ -211,50 +220,6 @@ default List queryForIds(Query query, Class clazz, IndexCoordinates i return search(query, clazz, index).map(SearchHit::getId).toList(); } - /** - * Returns scrolled page for given query - * - * @param scrollTimeInMillis duration of the scroll time - * @param query The search query. - * @param clazz The class of entity to retrieve. - * @param index the index to run the query against - * @return scrolled page result - * @deprecated since 4.0, use {@link #searchScrollStart(long, Query, Class, IndexCoordinates)}. - */ - @Deprecated - default ScrolledPage startScroll(long scrollTimeInMillis, Query query, Class clazz, - IndexCoordinates index) { - return (ScrolledPage) SearchHitSupport - .unwrapSearchHits(searchScrollStart(scrollTimeInMillis, query, clazz, index)); - } - - /** - * Returns next scrolled page. - * - * @param scrollId the scroll id - * @param scrollTimeInMillis duration of the scroll time - * @param clazz The class of entity to retrieve. - * @return scrolled page result - * @deprecated since 4.0, use {@link #searchScrollContinue(String, long, Class)}. - */ - @SuppressWarnings("unchecked") - @Deprecated - default ScrolledPage continueScroll(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { - return (ScrolledPage) SearchHitSupport - .unwrapSearchHits(searchScrollContinue(scrollId, scrollTimeInMillis, clazz)); - } - - /** - * Clears the search contexts associated with specified scroll ids. - * - * @param scrollId the scroll id - * @deprecated since 4.0, use {@link #searchScrollClear(String)}. - */ - @Deprecated - default void clearScroll(String scrollId) { - searchScrollClear(scrollId); - } - /** * more like this query to search for documents that are "like" a specific document. * @@ -271,8 +236,32 @@ default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class cla AggregatedPage> aggregatedPage = SearchHitSupport.page(searchHits, query.getPageable()); return (AggregatedPage) SearchHitSupport.unwrapSearchHits(aggregatedPage); } + + // endregion + /** + * Does a suggest query + * + * @param suggestion the query + * @param index the index to run the query against + * @return the suggest response + */ + SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); + + /** + * Execute the query against elasticsearch and return the first returned object. + * + * @param query the query to execute + * @param clazz the entity clazz used for property mapping and indexname extraction + * @return the first found object + */ + @Nullable + default SearchHit searchOne(Query query, Class clazz) { + List> content = search(query, clazz).getSearchHits(); + return content.isEmpty() ? null : content.get(0); + } + /** * Execute the query against elasticsearch and return the first returned object. * @@ -313,14 +302,13 @@ default SearchHit searchOne(Query query, Class clazz, IndexCoordinates * * @param element return type * @param query the query to execute - * @param clazz the entity clazz used for property mapping - * @param index the index to run the query against + * @param clazz the entity clazz used for property mapping and index name extraction * @return SearchHits containing the list of found objects */ - SearchHits search(Query query, Class clazz, IndexCoordinates index); + SearchHits search(Query query, Class clazz); /** - * more like this query to search for documents that are "like" a specific document. + * Execute the criteria query against elasticsearch and return result as {@link SearchHits} * * @param element return type * @param query the query to execute @@ -328,37 +316,40 @@ default SearchHit searchOne(Query query, Class clazz, IndexCoordinates * @param index the index to run the query against * @return SearchHits containing the list of found objects */ - SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); + SearchHits search(Query query, Class clazz, IndexCoordinates index); /** - * Returns scrolled page for given query + * more like this query to search for documents that are "like" a specific document. * - * @param scrollTimeInMillis duration of the scroll time - * @param query The search query. - * @param clazz The class of entity to retrieve. - * @param index the index to run the query against - * @return scrolled page result + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping and index name extraction + * @return SearchHits containing the list of found objects */ - ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, - IndexCoordinates index); + SearchHits search(MoreLikeThisQuery query, Class clazz); /** - * Returns next scrolled page + * more like this query to search for documents that are "like" a specific document. * - * @param scrollId the scroll id - * @param scrollTimeInMillis duration of the scroll time - * @param clazz The class of entity to retrieve. - * @return scrolled page result + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping + * @param index the index to run the query against + * @return SearchHits containing the list of found objects */ - ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz); + SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); /** - * Clears the search contexts associated with specified scroll ids. + * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. + *

* - * @param scrollId the scroll id + * @param element return type + * @param query the query to execute + * @param clazz the entity clazz used for property mapping and index name extraction + * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * + * error. */ - void searchScrollClear(String scrollId); + CloseableIterator> searchForStream(Query query, Class clazz); /** * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. @@ -372,13 +363,4 @@ ScrolledPage> searchScrollContinue(@Nullable String scrollId, l * error. */ CloseableIterator> searchForStream(Query query, Class clazz, IndexCoordinates index); - - /** - * Does a suggest query - * - * @param suggestion the query - * @param index the index to run the query against - * @return the suggest response - */ - SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index 1c5c856cc..82c91ccfc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -58,7 +58,7 @@ static Document create() { * @param map source map containing key-value pairs and sub-documents. must not be {@literal null}. * @return a new {@link Document}. */ - static Document from(Map map) { + static Document from(Map map) { Assert.notNull(map, "Map must not be null"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java index 665629197..a9f114969 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java @@ -46,7 +46,7 @@ class MapDocument implements Document { this(new LinkedHashMap<>()); } - MapDocument(Map documentAsMap) { + MapDocument(Map documentAsMap) { this.documentAsMap = new LinkedHashMap<>(documentAsMap); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java index 5853c7123..3bb80a398 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AbstractQuery.java @@ -17,6 +17,7 @@ import static java.util.Collections.*; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -56,6 +57,7 @@ abstract class AbstractQuery implements Query { @Nullable protected Integer maxResults; @Nullable protected HighlightQuery highlightQuery; private boolean trackTotalHits = false; + @Nullable private Duration scrollTime; @Override @Nullable @@ -226,4 +228,15 @@ public void setTrackTotalHits(boolean trackTotalHits) { public boolean getTrackTotalHits() { return trackTotalHits; } + + @Nullable + @Override + public Duration getScrollTime() { + return scrollTime; + } + + @Override + public void setScrollTime(@Nullable Duration scrollTime) { + this.scrollTime = scrollTime; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java index b68f9d1d1..47de35a8b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/CriteriaQuery.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.core.query; import org.springframework.data.domain.Pageable; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -29,9 +28,7 @@ */ public class CriteriaQuery extends AbstractQuery { - private @Nullable Criteria criteria; - - private CriteriaQuery() {} + private Criteria criteria; public CriteriaQuery(Criteria criteria) { this(criteria, Pageable.unpaged()); @@ -48,7 +45,7 @@ public CriteriaQuery(Criteria criteria, Pageable pageable) { } public static Query fromQuery(CriteriaQuery source) { - return fromQuery(source, new CriteriaQuery()); + return fromQuery(source, new CriteriaQuery(source.criteria)); } public static T fromQuery(CriteriaQuery source, T destination) { @@ -56,9 +53,7 @@ public static T fromQuery(CriteriaQuery source, T dest Assert.notNull(source, "source must not be null"); Assert.notNull(destination, "destination must not be null"); - if (source.getCriteria() != null) { - destination.addCriteria(source.getCriteria()); - } + destination.addCriteria(source.getCriteria()); if (source.getSort() != null) { destination.addSort(source.getSort()); @@ -69,16 +64,13 @@ public static T fromQuery(CriteriaQuery source, T dest @SuppressWarnings("unchecked") public final T addCriteria(Criteria criteria) { + Assert.notNull(criteria, "Cannot add null criteria."); - if (this.criteria == null) { - this.criteria = criteria; - } else { - this.criteria.and(criteria); - } + + this.criteria.and(criteria); return (T) this; } - @Nullable public Criteria getCriteria() { return this.criteria; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java index 9e57522f1..1dc5179ad 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/DeleteQuery.java @@ -24,7 +24,9 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @deprecated since 4.0, use {@link Query} implementations and set {@link Query#setScrollTimeInMillis(Long)} and {@link Query#getMaxResults()} */ +@Deprecated public class DeleteQuery { @Nullable private QueryBuilder query; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java index 38f02bd75..7874c9769 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/GetQuery.java @@ -21,7 +21,9 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @deprecated since 4.0 */ +@Deprecated public class GetQuery { public GetQuery(String id) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index b949720e3..5865571e4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -69,7 +69,12 @@ public void setSource(String source) { this.source = source; } + /** + * @deprecated from 4.0. Elasticsearch 7 does not support the parent id in an index request. parent/child relations + * must be modeled using the join datatype. Setting it here will have no effect. + */ @Nullable + @Deprecated public String getParentId() { return parentId; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java index 71245a8c3..28702eb83 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/NativeSearchQuery.java @@ -94,6 +94,7 @@ public QueryBuilder getFilter() { return filter; } + @Nullable public List getElasticsearchSorts() { return sorts; } @@ -103,6 +104,7 @@ public HighlightBuilder getHighlightBuilder() { return highlightBuilder; } + @Nullable public HighlightBuilder.Field[] getHighlightFields() { return highlightFields; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index ff0ebc37b..62656dd29 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.query; +import java.time.Duration; import java.util.Collection; import java.util.List; import java.util.Optional; @@ -45,7 +46,7 @@ public interface Query { Pageable DEFAULT_PAGE = PageRequest.of(0, DEFAULT_PAGE_SIZE); /** - * Get get a {@link Query} that matches all documents in the index. + * Get a {@link Query} that matches all documents in the index. * * @return new instance of {@link Query}. * @since 3.2 @@ -229,4 +230,29 @@ default Optional getHighlightQuery() { * @since 4.0 */ boolean getTrackTotalHits(); + + /** + * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete queries. + * + * @return the scrolltime settings + * @since 4.0 + */ + @Nullable + Duration getScrollTime(); + + /** + * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete queries. + * + * @param scrollTime the scrolltime settings + * @since 4.0 + */ + void setScrollTime(@Nullable Duration scrollTime); + + /** + * @return {@literal true} if scrollTimeMillis is set. + * @since 4.0 + */ + default boolean hasScrollTime() { + return getScrollTime() != null; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index dac5aa425..a346bf344 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -15,43 +15,168 @@ */ package org.springframework.data.elasticsearch.core.query; -import org.elasticsearch.action.update.UpdateRequest; +import java.util.Map; + +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.lang.Nullable; /** + * Defines an update request. + * * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @see params) { + this.params = params; + return this; + } + + public Builder withDocument(Document document) { + this.document = document; + return this; + } + + public Builder withUpsert(Document upsert) { + this.upsert = upsert; + return this; + } + + public Builder withLang(String lang) { + this.lang = lang; + return this; + } + + public Builder withRouting(String routing) { + this.routing = routing; + return this; + } + + public Builder withScriptedUpsert(Boolean scriptedUpsert) { + this.scriptedUpsert = scriptedUpsert; + return this; + } + + public Builder withDocAsUpsert(Boolean docAsUpsert) { + this.docAsUpsert = docAsUpsert; + return this; + } + + public Builder withFetchSource(Boolean fetchSource) { + this.fetchSource = fetchSource; + return this; + } + + public UpdateQuery build() { + + if (script == null && document == null) { + throw new IllegalArgumentException("either script or document must be set"); + } + return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert, + fetchSource); + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java deleted file mode 100644 index 1e116e69a..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQueryBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2013-2020 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.query; - -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.update.UpdateRequest; -import org.springframework.lang.Nullable; - -/** - * @author Rizwan Idrees - * @author Mohsin Husen - * @author Peter-Josef Meisch - */ -public class UpdateQueryBuilder { - - @Nullable private String id; - @Nullable private UpdateRequest updateRequest; - @Nullable private IndexRequest indexRequest; - private boolean doUpsert; - - public UpdateQueryBuilder withId(String id) { - this.id = id; - return this; - } - - public UpdateQueryBuilder withUpdateRequest(UpdateRequest updateRequest) { - this.updateRequest = updateRequest; - return this; - } - - public UpdateQueryBuilder withIndexRequest(IndexRequest indexRequest) { - this.indexRequest = indexRequest; - return this; - } - - public UpdateQueryBuilder withDoUpsert(boolean doUpsert) { - this.doUpsert = doUpsert; - return this; - } - - public UpdateQuery build() { - UpdateQuery updateQuery = new UpdateQuery(); - updateQuery.setId(id); - if (this.indexRequest != null) { - if (this.updateRequest == null) { - updateRequest = new UpdateRequest(); - } - updateRequest.doc(indexRequest); - } - updateQuery.setUpdateRequest(updateRequest); - updateQuery.setDoUpsert(doUpsert); - return updateQuery; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateResponse.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateResponse.java new file mode 100644 index 000000000..ada659e81 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateResponse.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 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.query; + +import org.springframework.util.Assert; + +/** + * Response data from an update request ({@link UpdateQuery}). Currently contains only the result status value from + * Elasticsearch. Should be extended if further information is needed. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class UpdateResponse { + + private Result result; + + public UpdateResponse(Result result) { + + Assert.notNull(result, "result must not be null"); + + this.result = result; + } + + public Result getResult() { + return result; + } + + public enum Result { + CREATED, UPDATED, DELETED, NOT_FOUND, NOOP; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index 09f8999b1..dcfd49b1e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -116,7 +116,7 @@ private ReactiveElasticsearchQueryExecution getExecutionToWrap(ElasticsearchPara ReactiveElasticsearchOperations operations) { if (isDeleteQuery()) { - return (query, type, targetType, indexCoordinates) -> operations.deleteBy(query, type, indexCoordinates); + return (query, type, targetType, indexCoordinates) -> operations.delete(query, type, indexCoordinates); } else if (isCountQuery()) { return (query, type, targetType, indexCoordinates) -> operations.count(query, type, indexCoordinates); } else if (isExistsQuery()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 528701e41..c78f5e34d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -82,7 +82,7 @@ public Object execute(Object[] parameters) { if (tree.isDelete()) { result = countOrGetDocumentsForDelete(query, accessor); elasticsearchOperations.delete(query, clazz, index); - elasticsearchOperations.getIndexOperations().refresh(index); + elasticsearchOperations.indexOps(index).refresh(); } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index c3ca2a834..b33bdc564 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -44,9 +44,6 @@ import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.DeleteQuery; -import org.springframework.data.elasticsearch.core.query.GetQuery; -import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -79,23 +76,18 @@ public abstract class AbstractElasticsearchRepository implements Elastics protected ElasticsearchOperations operations; protected IndexOperations indexOperations; - protected @Nullable Class entityClass; + protected Class entityClass; protected @Nullable ElasticsearchEntityInformation entityInformation; - public AbstractElasticsearchRepository(ElasticsearchOperations operations) { - Assert.notNull(operations, "ElasticsearchOperations must not be null."); - this.operations = operations; - this.indexOperations = operations.getIndexOperations(); - } - public AbstractElasticsearchRepository(ElasticsearchEntityInformation metadata, ElasticsearchOperations operations) { - this(operations); + this.operations = operations; Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); this.entityInformation = metadata; - setEntityClass(this.entityInformation.getJavaType()); + this.entityClass = this.entityInformation.getJavaType(); + this.indexOperations = operations.indexOps(this.entityClass); try { if (createIndexAndMapping()) { createIndex(); @@ -107,11 +99,11 @@ public AbstractElasticsearchRepository(ElasticsearchEntityInformation met } private void createIndex() { - indexOperations.createIndex(getEntityClass()); + indexOperations.create(); } private void putMapping() { - indexOperations.putMapping(getEntityClass()); + indexOperations.putMapping(indexOperations.createMapping(entityClass)); } private boolean createIndexAndMapping() { @@ -123,8 +115,7 @@ private boolean createIndexAndMapping() { @Override public Optional findById(ID id) { - GetQuery query = new GetQuery(stringIdRepresentation(id)); - return Optional.ofNullable(operations.get(query, getEntityClass(), getIndexCoordinates())); + return Optional.ofNullable(operations.get(stringIdRepresentation(id), getEntityClass(), getIndexCoordinates())); } @Override @@ -180,7 +171,7 @@ public S save(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); operations.save(entity, getIndexCoordinates()); - indexOperations.refresh(getIndexCoordinates()); + operations.indexOps(entity.getClass()).refresh(); return entity; } @@ -203,15 +194,16 @@ public Iterable saveAll(Iterable entities) { Assert.notNull(entities, "Cannot insert 'null' as a List."); - operations.save(entities, getIndexCoordinates()); - indexOperations.refresh(getIndexCoordinates()); + IndexCoordinates indexCoordinates = getIndexCoordinates(); + operations.save(entities, indexCoordinates); + operations.indexOps(indexCoordinates).refresh(); return entities; } @Override public boolean existsById(ID id) { - return findById(id).isPresent(); + return operations.exists(stringIdRepresentation(id), getIndexCoordinates()); } @SuppressWarnings("unchecked") @@ -273,7 +265,7 @@ public void deleteById(ID id) { IndexCoordinates indexCoordinates = getIndexCoordinates(); doDelete(id, indexCoordinates); - indexOperations.refresh(indexCoordinates); + indexOperations.refresh(); } @Override @@ -283,7 +275,7 @@ public void delete(T entity) { IndexCoordinates indexCoordinates = getIndexCoordinates(); doDelete(extractIdFromBean(entity), indexCoordinates); - indexOperations.refresh(indexCoordinates); + indexOperations.refresh(); } @Override @@ -303,11 +295,11 @@ public void deleteAll(Iterable entities) { if (idsQueryBuilder.ids().isEmpty()) { return; } - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(idsQueryBuilder); - operations.delete(deleteQuery, indexCoordinates); - indexOperations.refresh(indexCoordinates); + Query query = new NativeSearchQueryBuilder().withQuery(idsQueryBuilder).build(); + + operations.delete(query, getEntityClass(), indexCoordinates); + indexOperations.refresh(); } private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { @@ -318,19 +310,18 @@ private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { @Override public void deleteAll() { - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(matchAllQuery()); IndexCoordinates indexCoordinates = getIndexCoordinates(); - operations.delete(deleteQuery, indexCoordinates); - indexOperations.refresh(indexCoordinates); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + + operations.delete(query, getEntityClass(), indexCoordinates); + indexOperations.refresh(); } @Override public void refresh() { - indexOperations.refresh(getEntityClass()); + indexOperations.refresh(); } - @SuppressWarnings("unchecked") private Class resolveReturnedClassFromGenericType() { ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass()); @@ -367,11 +358,6 @@ private boolean isEntityClassSet() { return entityClass != null; } - public final void setEntityClass(Class entityClass) { - Assert.notNull(entityClass, "EntityClass must not be null."); - this.entityClass = entityClass; - } - @Nullable protected ID extractIdFromBean(T entity) { return entityInformation.getId(entity); @@ -389,7 +375,6 @@ private List stringIdsRepresentation(Iterable ids) { protected abstract @Nullable String stringIdRepresentation(@Nullable ID id); - private IndexCoordinates getIndexCoordinates() { return operations.getIndexCoordinatesFor(getEntityClass()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 2a4e51863..006bbded0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -35,10 +35,6 @@ public SimpleElasticsearchRepository(ElasticsearchEntityInformation metad super(metadata, elasticsearchOperations); } - public SimpleElasticsearchRepository(ElasticsearchOperations elasticsearchOperations) { - super(elasticsearchOperations); - } - @Override protected @Nullable String stringIdRepresentation(@Nullable ID id) { return operations.stringIdRepresentation(id); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index 9de865e0a..d75ed583c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -79,7 +79,7 @@ public Flux saveAll(Publisher entityStream) { public Mono findById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.findById(convertId(id), entityInformation.getJavaType(), + return elasticsearchOperations.get(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @@ -154,7 +154,7 @@ public Mono deleteById(ID id) { Assert.notNull(id, "Id must not be null!"); return elasticsearchOperations - .deleteById(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // + .delete(convertId(id), entityInformation.getIndexCoordinates()) // .then(); } @@ -200,7 +200,7 @@ public Mono deleteAll(Publisher entityStream) { }) // .flatMap(query -> { - return elasticsearchOperations.deleteBy(query, entityInformation.getJavaType(), + return elasticsearchOperations.delete(query, entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); }) // .then(); @@ -210,7 +210,7 @@ public Mono deleteAll(Publisher entityStream) { public Mono deleteAll() { return elasticsearchOperations - .deleteBy(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // + .delete(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // .then(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 8e8150f18..e57bb32fc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -30,6 +30,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.index.query.BoolQueryBuilder; @@ -44,10 +45,8 @@ import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; @@ -68,13 +67,12 @@ public class NestedObjectTests { @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, Book.class); - IndexInitializer.init(indexOperations, Person.class); - IndexInitializer.init(indexOperations, PersonMultipleLevelNested.class); + IndexInitializer.init(operations.indexOps(Book.class)); + IndexInitializer.init(operations.indexOps(Person.class)); + IndexInitializer.init(operations.indexOps(PersonMultipleLevelNested.class)); } @Test @@ -126,7 +124,7 @@ public void shouldIndexInitialLevelNestedObject() { IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(Person.class); + operations.indexOps(Person.class).refresh(); QueryBuilder builder = nestedQuery("car", boolQuery().must(termQuery("car.name", "saturn")).must(termQuery("car.model", "imprezza")), ScoreMode.None); @@ -146,11 +144,10 @@ public void shouldIndexMultipleLevelNestedObject() { // when operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); - indexOperations.refresh(PersonMultipleLevelNested.class); + operations.indexOps(PersonMultipleLevelNested.class).refresh(); // then - GetQuery getQuery = new GetQuery("1"); - PersonMultipleLevelNested personIndexed = operations.get(getQuery, PersonMultipleLevelNested.class, + PersonMultipleLevelNested personIndexed = operations.get("1", PersonMultipleLevelNested.class, IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); assertThat(personIndexed).isNotNull(); } @@ -166,7 +163,7 @@ public void shouldIndexMultipleLevelNestedObjectWithIncludeInParent() { IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); // then - Map mapping = indexOperations.getMapping(PersonMultipleLevelNested.class); + Map mapping = operations.indexOps(PersonMultipleLevelNested.class).getMapping(); assertThat(mapping).isNotNull(); Map propertyMap = (Map) mapping.get("properties"); @@ -184,7 +181,7 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { // when IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user"); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(PersonMultipleLevelNested.class); + operations.indexOps(PersonMultipleLevelNested.class).refresh(); // then BoolQueryBuilder builder = boolQuery(); @@ -324,7 +321,7 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(Person.class); + operations.indexOps(Person.class).refresh(); // when QueryBuilder builder = nestedQuery("books", boolQuery().must(termQuery("books.name", "java")), ScoreMode.None); @@ -373,7 +370,7 @@ public void shouldIndexAndSearchMapAsNestedType() { // when IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes("book"); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(Book.class); + operations.indexOps(Book.class).refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index 37c3dbf04..6b5855602 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -39,6 +39,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; @@ -74,17 +75,19 @@ public void setApplicationContext(ApplicationContext applicationContext) throws @EnableElasticsearchRepositories static class Config {} - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired private SampleElasticsearchRepository repository; @Autowired(required = false) private SampleRepository nestedRepository; - interface SampleRepository extends Repository {} + interface SampleRepository extends Repository {} @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + IndexInitializer.init(indexOperations); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 781f427c2..0abe01445 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -23,14 +23,11 @@ import lombok.Data; import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.common.xcontent.XContentType; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.query.UpdateQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; @@ -57,16 +54,15 @@ public class ElasticsearchRestTemplateTests extends ElasticsearchTemplateTests { public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() { // when - IndexRequest indexRequest = new IndexRequest(); - indexRequest.source("{}", XContentType.JSON); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + UpdateQuery updateQuery = UpdateQuery.builder(randomNumeric(5)).withDocument(document).build(); assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(ElasticsearchStatusException.class); } @Data @Builder - @Document(indexName = "test-index-sample-core-rest-template", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-core-rest-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index f1bc0ad99..4c2d7a541 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.core.document.Document.*; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; import lombok.AllArgsConstructor; @@ -37,11 +38,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import org.assertj.core.util.Lists; -import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.update.UpdateRequest; @@ -112,20 +113,23 @@ public abstract class ElasticsearchTemplateTests { protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME); @Autowired protected ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { + indexOperations = operations.indexOps(SampleEntity.class); deleteIndices(); - indexOperations.createIndex(SampleEntity.class); - indexOperations.putMapping(SampleEntity.class); + indexOperations.create(); + indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); - indexOperations.createIndex(SampleEntityUUIDKeyed.class); - indexOperations.putMapping(SampleEntityUUIDKeyed.class); + IndexOperations indexOpsSampleEntityUUIDKeyed = operations.indexOps(SampleEntityUUIDKeyed.class); + indexOpsSampleEntityUUIDKeyed.create(); + indexOpsSampleEntityUUIDKeyed.putMapping(indexOpsSampleEntityUUIDKeyed.createMapping(SampleEntityUUIDKeyed.class)); - indexOperations.createIndex(SearchHitsEntity.class); - indexOperations.putMapping(SearchHitsEntity.class); + IndexOperations indexOpsSearchHitsEntity = operations.indexOps(SearchHitsEntity.class); + indexOpsSearchHitsEntity.create(); + indexOpsSearchHitsEntity.putMapping(indexOpsSearchHitsEntity.createMapping(SearchHitsEntity.class)); } @AfterEach @@ -136,16 +140,16 @@ public void after() { private void deleteIndices() { - indexOperations.deleteIndex(SampleEntity.class); - indexOperations.deleteIndex(SampleEntityUUIDKeyed.class); - indexOperations.deleteIndex(UseServerConfigurationEntity.class); - indexOperations.deleteIndex(SampleMappingEntity.class); - indexOperations.deleteIndex(Book.class); - indexOperations.deleteIndex(INDEX_1_NAME); - indexOperations.deleteIndex(INDEX_2_NAME); - indexOperations.deleteIndex(INDEX_3_NAME); - indexOperations.deleteIndex(SearchHitsEntity.class); - indexOperations.deleteIndex(HighlightEntity.class); + indexOperations.delete(); + operations.indexOps(SampleEntityUUIDKeyed.class).delete(); + operations.indexOps(UseServerConfigurationEntity.class).delete(); + operations.indexOps(SampleMappingEntity.class).delete(); + operations.indexOps(Book.class).delete(); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).delete(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).delete(); + operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).delete(); + operations.indexOps(SearchHitsEntity.class).delete(); + operations.indexOps(HighlightEntity.class).delete(); } @Test // DATAES-106 @@ -158,7 +162,8 @@ public void shouldReturnCountForGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); + ; CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when @@ -179,7 +184,8 @@ public void shouldReturnCountForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); + ; NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -200,11 +206,9 @@ public void shouldReturnObjectForGivenId() { operations.index(indexQuery, index); // when - GetQuery getQuery = new GetQuery(documentId); - SampleEntity sampleEntity1 = operations.get(getQuery, SampleEntity.class, index); + SampleEntity sampleEntity1 = operations.get(documentId, SampleEntity.class, index); // then - assertThat(sampleEntity1).isNotNull(); assertThat(sampleEntity1).isEqualTo(sampleEntity); } @@ -225,7 +229,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); @@ -254,7 +258,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)) @@ -276,7 +280,7 @@ public void shouldReturnSearchHitsForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -300,7 +304,7 @@ public void shouldReturnSearchHitsUsingLocalPreferenceForGivenSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQueryWithValidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_local").build(); @@ -324,7 +328,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQueryWithInvalidPreference = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPreference("_only_nodes:oops").build(); @@ -345,7 +349,7 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); operations.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); @@ -377,7 +381,7 @@ public void shouldDoBulkIndex() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -402,11 +406,14 @@ public void shouldDoBulkUpdate() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); - IndexRequest indexRequest = new IndexRequest(); - indexRequest.source("message", messageAfterUpdate); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withIndexRequest(indexRequest).build(); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + document.put("message", messageAfterUpdate); + UpdateQuery updateQuery = UpdateQuery.builder(documentId) // + .withDocument(document) // + .build(); List queries = new ArrayList<>(); queries.add(updateQuery); @@ -415,8 +422,7 @@ public void shouldDoBulkUpdate() { operations.bulkUpdate(queries, index); // then - GetQuery getQuery = new GetQuery(documentId); - SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); + SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -434,7 +440,7 @@ public void shouldDeleteDocumentForGivenId() { // when operations.delete(documentId, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -457,7 +463,7 @@ public void shouldDeleteEntityForGivenId() { // when operations.delete(documentId, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -476,13 +482,12 @@ public void shouldDeleteDocumentForGivenQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(termQuery("id", documentId)); - operations.delete(deleteQuery, index); - indexOperations.refresh(SampleEntity.class); + Query query = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + operations.delete(query, SampleEntity.class, index); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -502,21 +507,19 @@ public void shouldDeleteAcrossIndex() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // when - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(termQuery("message", "foo")); - - operations.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + Query query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")).build(); + operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")).build(); @@ -536,21 +539,20 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // when - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(termQuery("message", "negative")); + Query query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "negative")).build(); - operations.delete(deleteQuery, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "positive")).build(); @@ -568,7 +570,7 @@ public void shouldFilterSearchResultsForGivenFilter() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); @@ -603,7 +605,7 @@ public void shouldSortResultsGivenSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)).build(); @@ -639,7 +641,7 @@ public void shouldSortResultsGivenMultipleSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) @@ -678,7 +680,7 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsFirst()))).build(); @@ -716,7 +718,7 @@ public void shouldSortResultsGivenNullLastSortCriteria() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("message").nullsLast()))).build(); @@ -740,7 +742,7 @@ public void shouldSortResultsByScore() { SampleEntity.builder().id("3").message("blue").build()); operations.bulkIndex(getIndexQueries(entities), index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(matchQuery("message", "green")) // @@ -767,7 +769,7 @@ public void shouldExecuteStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); @@ -794,7 +796,7 @@ public void shouldUseScriptedFields() { indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); Map params = new HashMap<>(); params.put("factor", 2); @@ -821,7 +823,7 @@ public void shouldReturnPageableResultsGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10)); @@ -847,7 +849,7 @@ public void shouldReturnSortedResultsGivenStringQuery() { indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), PageRequest.of(0, 10), Sort.by(Order.asc("message"))); @@ -870,7 +872,7 @@ public void shouldReturnObjectMatchingGivenStringQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); StringQuery stringQuery = new StringQuery(termQuery("id", documentId).toString()); @@ -887,7 +889,7 @@ public void shouldCreateIndexGivenEntityClass() { // when // creation is done in setup method - Map setting = indexOperations.getSettings(SampleEntity.class); + Map setting = indexOperations.getSettings(); // then assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); @@ -905,7 +907,7 @@ public void shouldExecuteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when @@ -926,12 +928,12 @@ public void shouldDeleteGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); // when operations.delete(criteriaQuery, SampleEntity.class, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); @@ -953,7 +955,7 @@ public void shouldReturnSpecifiedFields() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .build(); @@ -981,7 +983,7 @@ public void shouldReturnFieldsBasedOnSourceFilter() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); FetchSourceFilterBuilder sourceFilter = new FetchSourceFilterBuilder(); sourceFilter.withIncludes("message"); @@ -1022,7 +1024,7 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { getIndexQuery( SampleEntity.builder().id(documentId2).message(sampleMessage).version(System.currentTimeMillis()).build()), index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); MoreLikeThisQuery moreLikeThisQuery = new MoreLikeThisQuery(); moreLikeThisQuery.setId(documentId2); @@ -1047,20 +1049,21 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + criteriaQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } - operations.searchScrollClear(scroll.getScrollId()); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1072,21 +1075,22 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } - operations.searchScrollClear(scroll.getScrollId()); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); } @@ -1098,23 +1102,23 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1126,22 +1130,22 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .withQuery(matchAllQuery()).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1153,22 +1157,22 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1180,22 +1184,22 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1207,22 +1211,22 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1234,22 +1238,22 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); scrollId = scroll.getScrollId(); - scroll = operations.searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } - operations.searchScrollClear(scrollId); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); } @@ -1261,7 +1265,7 @@ public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); @@ -1317,7 +1321,7 @@ public void shouldReturnListForGivenCriteria() { // when operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery singleCriteriaQuery = new CriteriaQuery(new Criteria("message").contains("test")); CriteriaQuery multipleCriteriaQuery = new CriteriaQuery( @@ -1354,7 +1358,7 @@ public void shouldReturnListForGivenStringQuery() { // when operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); SearchHits sampleEntities = operations.search(stringQuery, SampleEntity.class, index); @@ -1367,14 +1371,14 @@ public void shouldReturnListForGivenStringQuery() { public void shouldPutMappingForGivenEntity() { // given - Class entity = SampleEntity.class; - indexOperations.deleteIndex(entity); - indexOperations.createIndex(entity); + Class entityClass = SampleEntity.class; + operations.indexOps(entityClass).delete(); + operations.indexOps(entityClass).create(); // when // then - assertThat(indexOperations.putMapping(entity)).isTrue(); + assertThat(indexOperations.putMapping(indexOperations.createMapping(entityClass))).isTrue(); } @Test // DATAES-305 @@ -1382,14 +1386,15 @@ public void shouldPutMappingWithCustomIndexName() { // given Class entity = SampleEntity.class; - indexOperations.deleteIndex(INDEX_1_NAME); - indexOperations.createIndex(INDEX_1_NAME); + IndexOperations indexOperations1 = operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations1.delete(); + indexOperations1.create(); // when - indexOperations.putMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME), entity); + indexOperations1.putMapping(indexOperations1.createMapping(entity)); // then - Map mapping = indexOperations.getMapping(IndexCoordinates.of(INDEX_1_NAME).withTypes(TYPE_NAME)); + Map mapping = indexOperations.getMapping(); assertThat(mapping.get("properties")).isNotNull(); } @@ -1400,10 +1405,10 @@ public void shouldDeleteIndexForGivenEntity() { Class clazz = SampleEntity.class; // when - indexOperations.deleteIndex(clazz); + indexOperations.delete(); // then - assertThat(indexOperations.indexExists(clazz)).isFalse(); + assertThat(indexOperations.exists()).isFalse(); } @Test @@ -1420,18 +1425,20 @@ public void shouldDoPartialUpdateForExistingDocument() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); - IndexRequest indexRequest = new IndexRequest(); - indexRequest.source("message", messageAfterUpdate); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withIndexRequest(indexRequest).build(); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + document.put("message", messageAfterUpdate); + UpdateQuery updateQuery = UpdateQuery.builder(documentId)// + .withDocument(document) // + .build(); // when operations.update(updateQuery, index); // then - GetQuery getQuery = new GetQuery(documentId); - SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); + SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class, index); assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate); } @@ -1443,13 +1450,13 @@ public void shouldUseUpsertOnUpdate() { doc.put("id", "1"); doc.put("message", "test"); - UpdateRequest updateRequest = new UpdateRequest() // - .doc(doc) // - .upsert(doc); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .from(doc); - UpdateQuery updateQuery = new UpdateQueryBuilder() // - .withId("1") // - .withUpdateRequest(updateRequest).build(); + UpdateQuery updateQuery = UpdateQuery.builder("1") // + .withDocument(document) // + .withUpsert(document) // + .build(); // when UpdateRequest request = getRequestFactory().updateRequest(updateQuery, IndexCoordinates.of("index")); @@ -1466,11 +1473,13 @@ public void shouldReturnSourceWhenRequested() { doc.put("id", "1"); doc.put("message", "test"); - UpdateRequest updateRequest = new UpdateRequest().doc(doc).fetchSource(FetchSourceContext.FETCH_SOURCE); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .from(doc); - UpdateQuery updateQuery = new UpdateQueryBuilder() // - .withId("1") // - .withUpdateRequest(updateRequest).build(); + UpdateQuery updateQuery = UpdateQuery.builder("1") // + .withDocument(document) // + .withFetchSource(true) // + .build(); // when UpdateRequest request = getRequestFactory().updateRequest(updateQuery, IndexCoordinates.of("index")); @@ -1485,19 +1494,20 @@ public void shouldDoUpsertIfDocumentDoesNotExist() { // given String documentId = randomNumeric(5); - String message = "test message"; - IndexRequest indexRequest = new IndexRequest(); - indexRequest.source("message", message); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId).withDoUpsert(true) - .withIndexRequest(indexRequest).build(); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + document.put("message", "test message"); + UpdateQuery updateQuery = UpdateQuery.builder(documentId) // + .withDocument(document) // + .withDocAsUpsert(true) // + .build(); // when operations.update(updateQuery, index); // then - GetQuery getQuery = new GetQuery(documentId); - SampleEntity indexedEntity = operations.get(getQuery, SampleEntity.class, index); - assertThat(indexedEntity.getMessage()).isEqualTo(message); + SampleEntity indexedEntity = operations.get(documentId, SampleEntity.class, index); + assertThat(indexedEntity.getMessage()).isEqualTo("test message"); } @Test // DATAES-671 @@ -1513,19 +1523,20 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { IndexCoordinates index = IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type"); operations.index(idxQuery, index); - indexOperations.refresh(index); + operations.indexOps(index).refresh(); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - ScrolledPage> scroll = operations.searchScrollStart(scrollTimeInMillis, searchQuery, - SampleEntity.class, index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations) + .searchScrollStart(scrollTimeInMillis, searchQuery, SampleEntity.class, index); List> entities = new ArrayList<>(scroll.getContent()); while (scroll.hasContent()) { - scroll = operations.searchScrollContinue(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), + scrollTimeInMillis, SampleEntity.class); entities.addAll(scroll.getContent()); } @@ -1546,7 +1557,7 @@ public void shouldReturnSameEntityForMultiSearch() { indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when List queries = new ArrayList<>(); @@ -1567,17 +1578,18 @@ public void shouldReturnDifferentEntityForMultiSearch() { // given Class clazz = Book.class; - indexOperations.deleteIndex(clazz); - indexOperations.createIndex(clazz); - indexOperations.putMapping(clazz); - indexOperations.refresh(clazz); + IndexOperations bookIndexOperations = operations.indexOps(Book.class); + bookIndexOperations.delete(); + bookIndexOperations.create(); + indexOperations.putMapping(indexOperations.createMapping(clazz)); + bookIndexOperations.refresh(); IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template").withTypes("book"); operations.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()), index); operations.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex); - indexOperations.refresh(SampleEntity.class); - indexOperations.refresh(clazz); + indexOperations.refresh(); + bookIndexOperations.refresh(); // when List queries = new ArrayList<>(); @@ -1609,13 +1621,12 @@ public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(termQuery("id", documentId)); - operations.delete(deleteQuery, index); - indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + Query query = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); + operations.delete(query, SampleEntity.class, index); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); @@ -1634,7 +1645,7 @@ public void shouldIndexDocumentForSpecifiedSource() { // when operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) .build(); @@ -1664,7 +1675,7 @@ public void shouldReturnIds() { List entities = createSampleEntitiesWithMessage("Test message", 30); // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) .withPageable(PageRequest.of(0, 100)).build(); // then @@ -1682,7 +1693,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() @@ -1707,7 +1718,7 @@ public void shouldReturnScores() { indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac xz hi").build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "xz")) @@ -1738,8 +1749,7 @@ public void shouldDoIndexWithoutId() { // then assertThat(sampleEntity.getId()).isEqualTo(documentId); - GetQuery getQuery = new GetQuery(documentId); - SampleEntity result = operations.get(getQuery, SampleEntity.class, index); + SampleEntity result = operations.get(documentId, SampleEntity.class, index); assertThat(result.getId()).isEqualTo(documentId); } @@ -1768,7 +1778,7 @@ public void shouldDoBulkIndexWithoutId() { // when operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -1812,7 +1822,7 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { // when operations.bulkIndex(indexQueries, index); - indexOperations.refresh(index); + indexOperations.refresh(); // then NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -1835,7 +1845,7 @@ public void shouldIndexGteEntityWithVersionType() { .withObject(entity); operations.index(indexQueryBuilder.build(), index); - indexOperations.refresh(index); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -1846,7 +1856,7 @@ public void shouldIndexGteEntityWithVersionType() { // reindex with same version operations.index(indexQueryBuilder.build(), index); - indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); // reindex with version one below assertThatThrownBy(() -> operations.index(indexQueryBuilder.withVersion(entity.getVersion() - 1).build(), index)) @@ -1864,7 +1874,7 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { IndexQuery indexQuery = new IndexQueryBuilder().withId(documentId).withObject(sampleEntity).build(); operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -1886,7 +1896,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQue IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when @@ -1906,7 +1916,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -1926,7 +1936,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when @@ -1946,7 +1956,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearch IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -1975,8 +1985,8 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); @@ -2006,8 +2016,8 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -2019,24 +2029,26 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { } private void cleanUpIndices() { - indexOperations.deleteIndex(INDEX_1_NAME); - indexOperations.deleteIndex(INDEX_2_NAME); - indexOperations.createIndex(INDEX_1_NAME); - indexOperations.createIndex(INDEX_2_NAME); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)); + IndexOperations indexOperations1 = operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)); + indexOperations1.delete(); + IndexOperations indexOperations2 = operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)); + indexOperations2.delete(); + indexOperations1.create(); + indexOperations2.create(); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME, INDEX_2_NAME)).refresh(); } @Test // DATAES-71 public void shouldCreatedIndexWithSpecifiedIndexName() { // given - indexOperations.deleteIndex(INDEX_3_NAME); + operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).delete(); // when - indexOperations.createIndex(INDEX_3_NAME); + operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).create(); // then - assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue(); + assertThat(operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).exists()).isTrue(); } @Test // DATAES-72 @@ -2044,14 +2056,15 @@ public void shouldDeleteIndexForSpecifiedIndexName() { // given String indexName = "some-random-index"; - indexOperations.createIndex(indexName); - indexOperations.refresh(IndexCoordinates.of(indexName)); + IndexCoordinates index = IndexCoordinates.of(indexName); + operations.indexOps(index).create(); + operations.indexOps(index).refresh(); // when - indexOperations.deleteIndex(indexName); + operations.indexOps(index).delete(); // then - assertThat(indexOperations.indexExists(indexName)).isFalse(); + assertThat(operations.indexOps(index).exists()).isFalse(); } @Test // DATAES-106 @@ -2073,8 +2086,8 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); @@ -2104,8 +2117,8 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -2126,7 +2139,7 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when @@ -2144,7 +2157,7 @@ public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCoun IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when @@ -2163,14 +2176,15 @@ public void shouldCreateIndexWithGivenSettings() { + " \"tokenizer\": \"uax_url_email\"\n" + " }\n" + " }\n" + " }\n" + " }\n" + '}'; - indexOperations.deleteIndex(INDEX_3_NAME); + IndexOperations indexOperations3 = operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)); + indexOperations3.delete(); // when - indexOperations.createIndex(INDEX_3_NAME, settings); + operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).create(parse(settings)); // then - Map map = indexOperations.getSettings(INDEX_3_NAME); - assertThat(indexOperations.indexExists(INDEX_3_NAME)).isTrue(); + Map map = indexOperations3.getSettings(); + assertThat(indexOperations3.exists()).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); assertThat(map.get("index.analysis.analyzer.emailAnalyzer.tokenizer")).isEqualTo("uax_url_email"); } @@ -2182,8 +2196,8 @@ public void shouldCreateGivenSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - Map map = indexOperations.getSettings(SampleEntity.class); - assertThat(indexOperations.indexExists(SampleEntity.class)).isTrue(); + Map map = indexOperations.getSettings(); + assertThat(indexOperations.exists()).isTrue(); assertThat(map.containsKey("index.refresh_interval")).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); @@ -2206,14 +2220,14 @@ public void shouldCreateIndexWithGivenClassAndSettings() { + " }\n" + " }\n" + " }\n" + '}'; // when - indexOperations.deleteIndex(SampleEntity.class); - indexOperations.createIndex(SampleEntity.class, settings); - indexOperations.putMapping(SampleEntity.class); - indexOperations.refresh(SampleEntity.class); + indexOperations.delete(); + indexOperations.create(parse(settings)); + indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.refresh(); // then - Map map = indexOperations.getSettings(SampleEntity.class); - assertThat(indexOperations.indexExists(INDEX_NAME_SAMPLE_ENTITY)).isTrue(); + Map map = indexOperations.getSettings(); + assertThat(operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).exists()).isTrue(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); assertThat((String) map.get("index.number_of_replicas")).isEqualTo("0"); @@ -2238,8 +2252,8 @@ public void shouldTestResultsAcrossMultipleIndices() { operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -2266,8 +2280,8 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("hetro")); operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("hetro")); - indexOperations.refresh(IndexCoordinates.of(INDEX_1_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_2_NAME)); + operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); + operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -2279,15 +2293,15 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { @Test public void shouldCreateIndexUsingServerDefaultConfiguration() { - // given + IndexOperations indexOps = operations.indexOps(UseServerConfigurationEntity.class); // when - boolean created = indexOperations.createIndex(UseServerConfigurationEntity.class); + boolean created = indexOps.create(); // then assertThat(created).isTrue(); - Map setting = indexOperations.getSettings(UseServerConfigurationEntity.class); + Map setting = indexOps.getSettings(); assertThat(setting.get("index.number_of_shards")).isEqualTo("1"); assertThat(setting.get("index.number_of_replicas")).isEqualTo("1"); } @@ -2298,7 +2312,7 @@ public void shouldReturnMappingForGivenEntityClass() { // given // when - Map mapping = indexOperations.getMapping(SampleEntity.class); + Map mapping = indexOperations.getMapping(); // then assertThat(mapping).isNotNull(); @@ -2321,13 +2335,12 @@ public void shouldDeleteOnlyDocumentsMatchedByDeleteQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when - DeleteQuery deleteQuery = new DeleteQuery(); - deleteQuery.setQuery(idsQuery().addIds(documentIdToDelete)); - operations.delete(deleteQuery, index); - indexOperations.refresh(SampleEntity.class); + Query query = new NativeSearchQueryBuilder().withQuery(idsQuery().addIds(documentIdToDelete)).build(); + operations.delete(query, SampleEntity.class, index); + indexOperations.refresh(); // then // document with id "remainingDocumentId" should still be indexed @@ -2353,12 +2366,12 @@ public void shouldDeleteOnlyDocumentsMatchedByCriteriaQuery() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("id").is(documentIdToDelete)); operations.delete(criteriaQuery, SampleEntity.class, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then // document with id "remainingDocumentId" should still be indexed @@ -2383,11 +2396,11 @@ public void shouldDeleteDocumentForGivenIdOnly() { indexQueries.add(getIndexQuery(SampleEntity.builder().id(remainingDocumentId).message("some other message") .version(System.currentTimeMillis()).build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when operations.delete(documentIdToDelete, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then // document with id "remainingDocumentId" should still be indexed @@ -2412,20 +2425,21 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { .version(System.currentTimeMillis()).build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("message")); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = operations.searchScrollStart(1000, criteriaQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + criteriaQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } - operations.searchScrollClear(scroll.getScrollId()); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); @@ -2449,20 +2463,21 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { .version(System.currentTimeMillis()).build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } - operations.searchScrollClear(scroll.getScrollId()); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); // then assertThat(sampleEntities).hasSize(2); @@ -2479,7 +2494,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { // when operations.bulkIndex(entities, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // then SourceFilter sourceFilter = new FetchSourceFilter(new String[] { "id" }, new String[] {}); @@ -2487,14 +2502,15 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build(); - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } - operations.searchScrollClear(scroll.getScrollId()); + ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(3); assertThat(sampleEntities.stream().map(SearchHit::getContent).map(SampleEntity::getId).collect(Collectors.toList())) .doesNotContain((String) null); @@ -2526,19 +2542,20 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); // when - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } // then @@ -2573,7 +2590,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable( @@ -2581,12 +2598,13 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { .build(); // when - ScrolledPage> scroll = operations.searchScrollStart(1000, searchQuery, SampleEntity.class, - index); + ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); while (scroll.hasContent()) { sampleEntities.addAll(scroll.getContent()); - scroll = operations.searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, + SampleEntity.class); } // then @@ -2612,7 +2630,7 @@ public void shouldReturnDocumentWithCollapsedField() { List indexQueries = getIndexQueries(Arrays.asList(sampleEntity, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withCollapseField("rate") .build(); @@ -2651,10 +2669,10 @@ public void shouldAddAlias() { .build(); // when - indexOperations.addAlias(aliasQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + indexOperations.addAlias(aliasQuery); // then - List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); } @@ -2678,8 +2696,8 @@ public void shouldAddAliasForVariousRoutingValues() { // when IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); - indexOperations.addAlias(aliasQuery1, index); - indexOperations.addAlias(aliasQuery2, index); + indexOperations.addAlias(aliasQuery1); + indexOperations.addAlias(aliasQuery2); String documentId = randomNumeric(5); SampleEntity entity = SampleEntity.builder() // @@ -2696,7 +2714,7 @@ public void shouldAddAliasForVariousRoutingValues() { operations.index(indexQuery, IndexCoordinates.of(alias1).withTypes(TYPE_NAME)); // then - List aliasMetaData = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliasMetaData = indexOperations.queryForAlias(); assertThat(aliasMetaData).isNotEmpty(); AliasMetaData aliasMetaData1 = aliasMetaData.get(0); @@ -2710,8 +2728,8 @@ public void shouldAddAliasForVariousRoutingValues() { assertThat(aliasMetaData2.searchRouting()).isEqualTo("1"); // cleanup - indexOperations.removeAlias(aliasQuery1, index); - indexOperations.removeAlias(aliasQuery2, index); + indexOperations.removeAlias(aliasQuery1); + indexOperations.removeAlias(aliasQuery2); } @Test // DATAES-70 @@ -2727,7 +2745,7 @@ public void shouldAddAliasWithGivenRoutingValue() { .build(); // when - indexOperations.addAlias(aliasQuery, index); + indexOperations.addAlias(aliasQuery); String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder() // @@ -2742,7 +2760,7 @@ public void shouldAddAliasWithGivenRoutingValue() { .build(); operations.index(indexQuery, IndexCoordinates.of(alias).withTypes(TYPE_NAME)); - indexOperations.refresh(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // @@ -2751,7 +2769,7 @@ public void shouldAddAliasWithGivenRoutingValue() { long count = operations.count(query, IndexCoordinates.of(alias)); // then - List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); AliasMetaData aliasMetaData = aliases.get(0); assertThat(aliasMetaData.alias()).isEqualTo(alias); @@ -2760,7 +2778,7 @@ public void shouldAddAliasWithGivenRoutingValue() { assertThat(count).isEqualTo(1); // cleanup - indexOperations.removeAlias(aliasQuery, index); + indexOperations.removeAlias(aliasQuery); } @Test // DATAES-541 @@ -2775,14 +2793,14 @@ public void shouldRemoveAlias() { .build(); // when - indexOperations.addAlias(aliasQuery, index); - List aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + indexOperations.addAlias(aliasQuery); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); // then - indexOperations.removeAlias(aliasQuery, index); - aliases = indexOperations.queryForAlias(INDEX_NAME_SAMPLE_ENTITY); + indexOperations.removeAlias(aliasQuery); + aliases = indexOperations.queryForAlias(); assertThat(aliases).isEmpty(); } @@ -2827,7 +2845,7 @@ public void shouldNotIncludeDefaultsGetIndexSettings() { // given // when - Map map = indexOperations.getSettings(SampleEntity.class); + Map map = indexOperations.getSettings(); // then assertThat(map).doesNotContainKey("index.max_result_window"); @@ -2838,7 +2856,7 @@ public void shouldIncludeDefaultsOnGetIndexSettings() { // given // when - Map map = indexOperations.getSettings(SampleEntity.class, true); + Map map = indexOperations.getSettings(true); // then assertThat(map).containsKey("index.max_result_window"); @@ -2850,7 +2868,7 @@ void shouldReturnSortFieldsInSearchHits() { SearchHitsEntity entity = SearchHitsEntity.builder().id("1").number(1000L).keyword("thousands").build(); IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build(); operations.index(indexQuery, index); - indexOperations.refresh(index); + operations.indexOps(index).refresh(); NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(matchAllQuery()) // @@ -2888,7 +2906,7 @@ void shouldReturnHighlightFieldsInSearchHit() { .build(); IndexQuery indexQuery = new IndexQueryBuilder().withId(entity.getId()).withObject(entity).build(); operations.index(indexQuery, index); - indexOperations.refresh(index); + operations.indexOps(index).refresh(); NativeSearchQuery query = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "message")) // @@ -2916,9 +2934,9 @@ void shouldSaveEntityWithIndexCoordinates() { entity.setMessage("message"); operations.save(entity, index); - indexOperations.refresh(index); + indexOperations.refresh(); - SampleEntity result = operations.get(new GetQuery(id), SampleEntity.class, index); + SampleEntity result = operations.get(id, SampleEntity.class, index); assertThat(result).isEqualTo(entity); } @@ -2932,9 +2950,9 @@ void shouldSaveEntityWithOutIndexCoordinates() { entity.setMessage("message"); operations.save(entity); - indexOperations.refresh(index); + indexOperations.refresh(); - SampleEntity result = operations.get(new GetQuery(id), SampleEntity.class, index); + SampleEntity result = operations.get(id, SampleEntity.class, index); assertThat(result).isEqualTo(entity); } @@ -2953,10 +2971,10 @@ void shouldSaveEntityIterableWithIndexCoordinates() { entity2.setMessage("message"); operations.save(Arrays.asList(entity1, entity2), index); - indexOperations.refresh(index); + indexOperations.refresh(); - SampleEntity result1 = operations.get(new GetQuery(id1), SampleEntity.class, index); - SampleEntity result2 = operations.get(new GetQuery(id2), SampleEntity.class, index); + SampleEntity result1 = operations.get(id1, SampleEntity.class, index); + SampleEntity result2 = operations.get(id2, SampleEntity.class, index); assertThat(result1).isEqualTo(entity1); assertThat(result2).isEqualTo(entity2); @@ -2976,15 +2994,43 @@ void shouldSaveEntityIterableWithoutIndexCoordinates() { entity2.setMessage("message"); operations.save(Arrays.asList(entity1, entity2)); - indexOperations.refresh(index); + indexOperations.refresh(); - SampleEntity result1 = operations.get(new GetQuery(id1), SampleEntity.class, index); - SampleEntity result2 = operations.get(new GetQuery(id2), SampleEntity.class, index); + SampleEntity result1 = operations.get(id1, SampleEntity.class, index); + SampleEntity result2 = operations.get(id2, SampleEntity.class, index); assertThat(result1).isEqualTo(entity1); assertThat(result2).isEqualTo(entity2); } + @Test // DATAES-745 + void shouldDoExistsWithEntity() { + String id = "42"; + SampleEntity entity = new SampleEntity(); + entity.setId(id); + entity.setVersion(42L); + entity.setMessage("message"); + + operations.save(entity); + indexOperations.refresh(); + + assertThat(operations.exists("42", SampleEntity.class)).isTrue(); + } + + @Test // DATAES-745 + void shouldDoExistsWithIndexCoordinates() { + String id = "42"; + SampleEntity entity = new SampleEntity(); + entity.setId(id); + entity.setVersion(42L); + entity.setMessage("message"); + + operations.save(entity); + indexOperations.refresh(); + + assertThat(operations.exists("42", index)).isTrue(); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 02c3c55ba..5c2e2469f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -21,10 +21,8 @@ import lombok.Data; -import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.Client; -import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.engine.DocumentMissingException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -38,7 +36,6 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.test.context.ContextConfiguration; @@ -56,9 +53,9 @@ public class ElasticsearchTransportTemplateTests extends ElasticsearchTemplateTe @Test public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() { // when - IndexRequest indexRequest = new IndexRequest(); - indexRequest.source("{}", XContentType.JSON); - UpdateQuery updateQuery = new UpdateQueryBuilder().withId(randomNumeric(5)).withIndexRequest(indexRequest).build(); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + UpdateQuery updateQuery = UpdateQuery.builder(randomNumeric(5)).withDocument(document).build(); assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(DocumentMissingException.class); } @@ -87,8 +84,7 @@ public long getOffset() { } @Data - @Document(indexName = "test-index-sample-core-transport-template", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-core-transport-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 0b450777c..1b816daeb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -62,11 +62,12 @@ static class Config {} private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes("test-log-type"); @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() throws ParseException { - IndexInitializer.init(indexOperations, LogEntity.class); + indexOperations = operations.indexOps(LogEntity.class); + IndexInitializer.init(indexOperations); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); IndexQuery indexQuery1 = new LogEntityBuilder("1").action("update").date(dateFormatter.parse("2013-10-18 18:01")) @@ -82,12 +83,12 @@ public void before() throws ParseException { .code(2).ip("10.10.10.4").buildIndex(); operations.bulkIndex(Arrays.asList(indexQuery1, indexQuery2, indexQuery3, indexQuery4), index); - indexOperations.refresh(LogEntity.class); + indexOperations.refresh(); } @AfterEach void after() { - indexOperations.deleteIndex(LogEntity.class); + indexOperations.delete(); } @Test // DATAES-66 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index f560315c6..6312888d5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -40,7 +40,6 @@ import java.util.stream.IntStream; import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.junit.jupiter.api.AfterEach; @@ -66,7 +65,6 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; @@ -89,16 +87,18 @@ public class ReactiveElasticsearchTemplateTests { private ElasticsearchRestTemplate restTemplate; private ReactiveElasticsearchTemplate template; + private IndexOperations indexOperations; @BeforeEach public void setUp() { + restTemplate = new ElasticsearchRestTemplate(TestUtils.restHighLevelClient()); + indexOperations = restTemplate.indexOps(SampleEntity.class); deleteIndices(); - restTemplate = new ElasticsearchRestTemplate(TestUtils.restHighLevelClient()); - restTemplate.createIndex(SampleEntity.class); - restTemplate.putMapping(SampleEntity.class); - restTemplate.refresh(SampleEntity.class); + indexOperations.create(); + indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.refresh(); template = new ReactiveElasticsearchTemplate(TestUtils.reactiveClient(), restTemplate.getElasticsearchConverter()); } @@ -142,7 +142,7 @@ public void insertWithIdShouldWork() { .expectNextCount(1)// .verifyComplete(); - restTemplate.refresh(SampleEntity.class); + indexOperations.refresh(); SearchHits result = restTemplate.search( new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, @@ -161,7 +161,7 @@ public void insertWithAutogeneratedIdShouldUpdateEntityId() { assertThat(it.getId()).isNotNull(); - restTemplate.refresh(SampleEntity.class); + indexOperations.refresh(); assertThat(TestUtils.documentWithId(it.getId()).existsIn(DEFAULT_INDEX)).isTrue(); }) // .verifyComplete(); @@ -205,27 +205,27 @@ public void insertShouldErrorOnNullEntity() { } @Test // DATAES-519 - public void findByIdShouldCompleteWhenIndexDoesNotExist() { + public void getByIdShouldCompleteWhenIndexDoesNotExist() { - template.findById("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // + template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // .as(StepVerifier::create) // .verifyComplete(); } @Test // DATAES-504 - public void findByIdShouldReturnEntity() { + public void getByIdShouldReturnEntity() { SampleEntity sampleEntity = randomEntity("some message"); index(sampleEntity); - template.findById(sampleEntity.getId(), SampleEntity.class) // + template.get(sampleEntity.getId(), SampleEntity.class) // .as(StepVerifier::create) // .expectNext(sampleEntity) // .verifyComplete(); } @Test // DATAES-504 - public void findByIdWhenIdIsAutogeneratedShouldHaveIdSetCorrectly() { + public void getByIdWhenIdIsAutogeneratedShouldHaveIdSetCorrectly() { SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setMessage("some message"); @@ -234,32 +234,32 @@ public void findByIdWhenIdIsAutogeneratedShouldHaveIdSetCorrectly() { assertThat(sampleEntity.getId()).isNotNull(); - template.findById(sampleEntity.getId(), SampleEntity.class) // + template.get(sampleEntity.getId(), SampleEntity.class) // .as(StepVerifier::create) // .consumeNextWith(it -> assertThat(it.getId()).isEqualTo(sampleEntity.getId())) // .verifyComplete(); } @Test // DATAES-504 - public void findByIdShouldCompleteWhenNotingFound() { + public void getByIdShouldCompleteWhenNotingFound() { SampleEntity sampleEntity = randomEntity("some message"); index(sampleEntity); - template.findById("foo", SampleEntity.class) // + template.get("foo", SampleEntity.class) // .as(StepVerifier::create) // .verifyComplete(); } @Test // DATAES-504 - public void findByIdShouldErrorForNullId() { + public void getByIdShouldErrorForNullId() { assertThatThrownBy(() -> { - template.findById(null, SampleEntity.class); + template.get(null, SampleEntity.class); }).isInstanceOf(IllegalArgumentException.class); } @Test // DATAES-504 - public void findByIdWithExplicitIndexNameShouldOverwriteMetadata() { + public void getByIdWithExplicitIndexNameShouldOverwriteMetadata() { SampleEntity sampleEntity = randomEntity("some message"); @@ -269,16 +269,16 @@ public void findByIdWithExplicitIndexNameShouldOverwriteMetadata() { IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX).withTypes("test-type"); restTemplate.index(indexQuery, alternateIndex); - restTemplate.refresh(SampleEntity.class); + indexOperations.refresh(); - restTemplate.refresh(defaultIndex); - restTemplate.refresh(alternateIndex); + restTemplate.indexOps(defaultIndex).refresh(); + restTemplate.indexOps(alternateIndex).refresh(); - template.findById(sampleEntity.getId(), SampleEntity.class, defaultIndex) // + template.get(sampleEntity.getId(), SampleEntity.class, defaultIndex) // .as(StepVerifier::create) // .verifyComplete(); - template.findById(sampleEntity.getId(), SampleEntity.class, alternateIndex) // + template.get(sampleEntity.getId(), SampleEntity.class, alternateIndex) // .as(StepVerifier::create)// .expectNextCount(1) // .verifyComplete(); @@ -520,20 +520,20 @@ public void countShouldReturnCountMatchingDocuments() { } @Test // DATAES-519 - public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { + public void deleteShouldCompleteWhenIndexDoesNotExist() { - template.deleteById("does-not-exists", SampleEntity.class, IndexCoordinates.of("no-such-index")) // + template.delete("does-not-exists", IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create)// .verifyComplete(); } @Test // DATAES-504 - public void deleteByIdShouldRemoveExistingDocumentById() { + public void deleteShouldRemoveExistingDocumentById() { SampleEntity sampleEntity = randomEntity("test message"); index(sampleEntity); - template.deleteById(sampleEntity.getId(), SampleEntity.class) // + template.delete(sampleEntity.getId(), SampleEntity.class) // .as(StepVerifier::create)// .expectNext(sampleEntity.getId()) // .verifyComplete(); @@ -545,7 +545,7 @@ public void deleteShouldRemoveExistingDocumentByIdUsingIndexName() { SampleEntity sampleEntity = randomEntity("test message"); index(sampleEntity); - template.deleteById(sampleEntity.getId(), IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type")) // + template.delete(sampleEntity.getId(), IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type")) // .as(StepVerifier::create)// .expectNext(sampleEntity.getId()) // .verifyComplete(); @@ -564,7 +564,7 @@ public void deleteShouldRemoveExistingDocument() { } @Test // DATAES-504 - public void deleteByIdShouldCompleteWhenNothingDeleted() { + public void deleteShouldCompleteWhenNothingDeleted() { SampleEntity sampleEntity = randomEntity("test message"); @@ -579,7 +579,7 @@ public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() { CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test")); - template.deleteBy(query, SampleEntity.class) // + template.delete(query, SampleEntity.class) // .as(StepVerifier::create) // .expectNext(0L) // .verifyComplete(); @@ -606,7 +606,7 @@ public void shouldDeleteAcrossIndex() { .withQuery(termQuery("message", "test")) // .build(); - template.deleteBy(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // + template.delete(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // .as(StepVerifier::create) // .expectNext(2L) // .verifyComplete(); @@ -635,7 +635,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .withQuery(termQuery("message", "negative")) // .build(); - template.deleteBy(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // + template.delete(searchQuery, SampleEntity.class, IndexCoordinates.of(indexPrefix + '*')) // .as(StepVerifier::create) // .expectNext(0L) // .verifyComplete(); @@ -651,7 +651,7 @@ public void deleteByQueryShouldReturnNumberOfDeletedDocuments() { CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test")); - template.deleteBy(query, SampleEntity.class) // + template.delete(query, SampleEntity.class) // .as(StepVerifier::create) // .expectNext(2L) // .verifyComplete(); @@ -665,7 +665,7 @@ public void deleteByQueryShouldReturnZeroIfNothingDeleted() { CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("luke")); - template.deleteBy(query, SampleEntity.class) // + template.delete(query, SampleEntity.class) // .as(StepVerifier::create) // .expectNext(0L) // .verifyComplete(); @@ -763,17 +763,19 @@ public void shouldDoBulkUpdate() { entity2.rate = 2; index(entity2); - IndexRequest indexRequest1 = new IndexRequest(); - indexRequest1.source("message", "updated 1"); - UpdateQuery updateQuery1 = new UpdateQueryBuilder() // - .withId(entity1.getId()) // - .withIndexRequest(indexRequest1).build(); + org.springframework.data.elasticsearch.core.document.Document document1 = org.springframework.data.elasticsearch.core.document.Document + .create(); + document1.put("message", "updated 1"); + UpdateQuery updateQuery1 = UpdateQuery.builder(entity1.getId()) // + .withDocument(document1) // + .build(); - IndexRequest indexRequest2 = new IndexRequest(); - indexRequest2.source("message", "updated 2"); - UpdateQuery updateQuery2 = new UpdateQueryBuilder() // - .withId(entity2.getId()) // - .withIndexRequest(indexRequest2).build(); + org.springframework.data.elasticsearch.core.document.Document document2 = org.springframework.data.elasticsearch.core.document.Document + .create(); + document2.put("message", "updated 2"); + UpdateQuery updateQuery2 = UpdateQuery.builder(entity2.getId()) // + .withDocument(document2) // + .build(); List queries = Arrays.asList(updateQuery1, updateQuery2); template.bulkUpdate(queries, IndexCoordinates.of(DEFAULT_INDEX)).block(); @@ -858,7 +860,7 @@ private void index(SampleEntity... entities) { restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates); } - restTemplate.refresh(SampleEntity.class); + indexOperations.refresh(); } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index 7e0b30e3a..a1a412790 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -170,7 +170,7 @@ public void deleteShouldUseDefaultRefreshPolicy() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteRequest.class); when(client.delete(captor.capture())).thenReturn(Mono.empty()); - template.deleteById("id", index) // + template.delete("id", index) // .as(StepVerifier::create) // .verifyComplete(); @@ -185,7 +185,7 @@ public void deleteShouldApplyRefreshPolicy() { template.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL); - template.deleteById("id", index) // + template.delete("id", index) // .as(StepVerifier::create) // .verifyComplete(); @@ -198,7 +198,7 @@ public void deleteByShouldUseDefaultRefreshPolicy() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteByQueryRequest.class); when(client.deleteBy(captor.capture())).thenReturn(Mono.empty()); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // + template.delete(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -213,7 +213,7 @@ public void deleteByShouldApplyRefreshPolicy() { template.setRefreshPolicy(RefreshPolicy.NONE); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // + template.delete(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -226,7 +226,7 @@ public void deleteByShouldApplyIndicesOptions() { ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteByQueryRequest.class); when(client.deleteBy(captor.capture())).thenReturn(Mono.empty()); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // + template.delete(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); @@ -241,7 +241,7 @@ public void deleteByShouldApplyIndicesOptionsIfSet() { template.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN); - template.deleteBy(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // + template.delete(new StringQuery(QueryBuilders.matchAllQuery().toString()), Object.class, index) // .as(StepVerifier::create) // .verifyComplete(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index a606f2027..911fb6e12 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -77,11 +77,12 @@ static class Config {} static final String INDEX_NAME = "test-index-articles-core-aggregation"; @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, ArticleEntity.class); + indexOperations = operations.indexOps(ArticleEntity.class); + IndexInitializer.init(indexOperations); IndexQuery article1 = new ArticleEntityBuilder("1").title("article four").subject("computing") .addAuthor(RIZWAN_IDREES).addAuthor(ARTUR_KONCZAK).addAuthor(MOHSIN_HUSEN).addAuthor(JONATHAN_YAN).score(10) @@ -101,12 +102,12 @@ public void before() { operations.index(article2, index); operations.index(article3, index); operations.index(article4, index); - operations.refresh(ArticleEntity.class); + indexOperations.refresh(); } @AfterEach public void after() { - indexOperations.deleteIndex(ArticleEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 0cb33dfc2..2acfb331a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -37,7 +37,6 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.AbstractElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -63,18 +62,17 @@ public class ElasticsearchTemplateCompletionTests { static class Config {} @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; @BeforeEach private void setup() { - IndexInitializer.init(indexOperations, CompletionEntity.class); - IndexInitializer.init(indexOperations, AnnotatedCompletionEntity.class); + IndexInitializer.init(operations.indexOps(CompletionEntity.class)); + IndexInitializer.init(operations.indexOps(AnnotatedCompletionEntity.class)); } @AfterEach void after() { - indexOperations.deleteIndex("test-index-annotated-completion"); - indexOperations.deleteIndex("test-index-core-completion"); + operations.indexOps(CompletionEntity.class).delete(); + operations.indexOps(AnnotatedCompletionEntity.class).delete(); } private void loadCompletionObjectEntities() { @@ -90,7 +88,7 @@ private void loadCompletionObjectEntities() { .buildIndex()); operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); - operations.refresh(CompletionEntity.class); + operations.indexOps(CompletionEntity.class).refresh(); } private void loadAnnotatedCompletionObjectEntities() { @@ -111,7 +109,7 @@ private void loadAnnotatedCompletionObjectEntities() { operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); - operations.refresh(AnnotatedCompletionEntity.class); + operations.indexOps(AnnotatedCompletionEntity.class).refresh(); } private void loadAnnotatedCompletionObjectEntitiesWithWeights() { @@ -128,7 +126,7 @@ private void loadAnnotatedCompletionObjectEntitiesWithWeights() { operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); - operations.refresh(AnnotatedCompletionEntity.class); + operations.indexOps(AnnotatedCompletionEntity.class).refresh(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index da770d38d..77bdc2d9b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -67,21 +67,22 @@ public class ElasticsearchTemplateCompletionWithContextsTests { static class Config {} @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach void setup() { - indexOperations.deleteIndex(ContextCompletionEntity.class); + indexOperations = operations.indexOps(ContextCompletionEntity.class); + indexOperations.delete(); } @AfterEach void after() { - indexOperations.deleteIndex(ContextCompletionEntity.class); + indexOperations.delete(); } private void loadContextCompletionObjectEntities() { - IndexInitializer.init(indexOperations, ContextCompletionEntity.class); + IndexInitializer.init(indexOperations); NonDocumentEntity nonDocumentEntity = new NonDocumentEntity(); nonDocumentEntity.setSomeField1("foo"); @@ -111,7 +112,7 @@ private void loadContextCompletionObjectEntities() { operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); - operations.refresh(ContextCompletionEntity.class); + operations.indexOps(ContextCompletionEntity.class).refresh(); } @Test // DATAES-536 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index 573c356d6..0d5bf827a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -39,7 +39,6 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -78,18 +77,17 @@ static class Config {} .withTypes("geo-class-point-type"); @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, AuthorMarkerEntity.class); - IndexInitializer.init(indexOperations, LocationMarkerEntity.class); + IndexInitializer.init(operations.indexOps(AuthorMarkerEntity.class)); + IndexInitializer.init(operations.indexOps(LocationMarkerEntity.class)); } @AfterEach void after() { - indexOperations.deleteIndex(AuthorMarkerEntity.class); - indexOperations.deleteIndex(LocationMarkerEntity.class); + operations.indexOps(AuthorMarkerEntity.class).delete(); + operations.indexOps(LocationMarkerEntity.class).delete(); } private void loadClassBaseEntities() { @@ -100,7 +98,7 @@ private void loadClassBaseEntities() { indexQueries.add(new AuthorMarkerEntityBuilder("2").name("Mohsin Husen").location(51.5171d, 0.1062d).buildIndex()); indexQueries.add(new AuthorMarkerEntityBuilder("3").name("Rizwan Idrees").location(51.5171d, 0.1062d).buildIndex()); operations.bulkIndex(indexQueries, authorMarkerIndex); - operations.refresh(AuthorMarkerEntity.class); + operations.indexOps(AuthorMarkerEntity.class).refresh(); } private void loadAnnotationBaseEntities() { @@ -132,7 +130,7 @@ private void loadAnnotationBaseEntities() { indexQueries.add(buildIndex(location3)); operations.bulkIndex(indexQueries, locationMarkerIndex); - operations.refresh(LocationMarkerEntity.class); + operations.indexOps(LocationMarkerEntity.class).refresh(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index d409c5322..2427311f7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -84,28 +84,27 @@ public class MappingBuilderTests extends MappingContextBaseTests { @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - - indexOperations.deleteIndex(StockPrice.class); - indexOperations.deleteIndex(SimpleRecursiveEntity.class); - indexOperations.deleteIndex(StockPrice.class); - indexOperations.deleteIndex(SampleInheritedEntity.class); - indexOperations.deleteIndex(User.class); - indexOperations.deleteIndex(Group.class); - indexOperations.deleteIndex(Book.class); - indexOperations.deleteIndex(NormalizerEntity.class); - indexOperations.deleteIndex(CopyToEntity.class); + indexOperations = operations.indexOps(SimpleRecursiveEntity.class); + indexOperations.delete(); + operations.indexOps(StockPrice.class).delete(); + operations.indexOps(SampleInheritedEntity.class).delete(); + operations.indexOps(User.class).delete(); + operations.indexOps(Group.class).delete(); + operations.indexOps(Book.class).delete(); + operations.indexOps(NormalizerEntity.class).delete(); + operations.indexOps(CopyToEntity.class).delete(); } @Test public void shouldNotFailOnCircularReference() { - indexOperations.createIndex(SimpleRecursiveEntity.class); - indexOperations.putMapping(SimpleRecursiveEntity.class); - indexOperations.refresh(SimpleRecursiveEntity.class); + operations.indexOps(SimpleRecursiveEntity.class).create(); + indexOperations.putMapping(indexOperations.createMapping(SimpleRecursiveEntity.class)); + indexOperations.refresh(); } @Test // DATAES-568 @@ -136,10 +135,11 @@ public void shouldUseValueFromAnnotationType() throws JSONException { public void shouldAddStockPriceDocumentToIndex() { // Given + IndexOperations indexOps = operations.indexOps(StockPrice.class); // When - indexOperations.createIndex(StockPrice.class); - indexOperations.putMapping(StockPrice.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(StockPrice.class)); String symbol = "AU"; double price = 2.34; String id = "abc"; @@ -150,7 +150,7 @@ public void shouldAddStockPriceDocumentToIndex() { .symbol(symbol) // .price(BigDecimal.valueOf(price)) // .build()), index); - indexOperations.refresh(StockPrice.class); + operations.indexOps(StockPrice.class).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); SearchHits result = operations.search(searchQuery, StockPrice.class, index); @@ -186,19 +186,19 @@ public void shouldBuildMappingWithSuperclass() throws JSONException { @Test // DATAES-76 public void shouldAddSampleInheritedEntityDocumentToIndex() { - // given + IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes("mapping"); + IndexOperations indexOps = operations.indexOps(index); // when - indexOperations.createIndex(SampleInheritedEntity.class); - indexOperations.putMapping(SampleInheritedEntity.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(SampleInheritedEntity.class)); Date createdDate = new Date(); String message = "msg"; String id = "abc"; - IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes("mapping"); operations.index(new SampleInheritedEntityBuilder(id).createdDate(createdDate).message(message).buildIndex(), index); - operations.refresh(SampleInheritedEntity.class); + operations.indexOps(SampleInheritedEntity.class).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); SearchHits result = operations.search(searchQuery, SampleInheritedEntity.class, index); @@ -231,10 +231,13 @@ public void shouldBuildMappingsForGeoPoint() throws JSONException { public void shouldHandleReverseRelationship() { // given - indexOperations.createIndex(User.class); - indexOperations.putMapping(User.class); - indexOperations.createIndex(Group.class); - indexOperations.putMapping(Group.class); + IndexOperations indexOpsUser = operations.indexOps(User.class); + indexOpsUser.create(); + indexOpsUser.putMapping(indexOpsUser.createMapping(User.class)); + + IndexOperations indexOpsGroup = operations.indexOps(Group.class); + indexOpsGroup.create(); + indexOpsGroup.putMapping(indexOpsGroup.createMapping(Group.class)); // when @@ -245,8 +248,9 @@ public void shouldHandleReverseRelationship() { public void shouldMapBooks() { // given - indexOperations.createIndex(Book.class); - indexOperations.putMapping(Book.class); + IndexOperations indexOps = operations.indexOps(Book.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(Book.class)); // when @@ -257,11 +261,12 @@ public void shouldMapBooks() { public void shouldUseBothAnalyzer() { // given - indexOperations.createIndex(Book.class); - indexOperations.putMapping(Book.class); + IndexOperations indexOps = this.operations.indexOps(Book.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(Book.class)); // when - Map mapping = operations.getMapping(Book.class); + Map mapping = indexOps.getMapping(); Map descriptionMapping = (Map) ((Map) mapping.get("properties")).get("description"); Map prefixDescription = (Map) ((Map) descriptionMapping.get("fields")).get("prefix"); @@ -298,11 +303,12 @@ public void shouldUseKeywordNormalizer() { public void shouldUseCopyTo() { // given - indexOperations.createIndex(CopyToEntity.class); - indexOperations.putMapping(CopyToEntity.class); + IndexOperations indexOps = operations.indexOps(CopyToEntity.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(CopyToEntity.class)); // when - Map mapping = operations.getMapping(CopyToEntity.class); + Map mapping = indexOps.getMapping(); Map properties = (Map) mapping.get("properties"); Map fieldFirstName = (Map) properties.get("firstName"); Map fieldLastName = (Map) properties.get("lastName"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index a0a34b3ec..c83367f1c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -67,19 +67,20 @@ static class Config {} private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes("test-type"); @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - indexOperations.deleteIndex(SampleEntity.class); - indexOperations.createIndex(SampleEntity.class); - indexOperations.putMapping(SampleEntity.class); - indexOperations.refresh(SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + indexOperations.delete(); + indexOperations.create(); + indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.refresh(); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntity.class); + indexOperations.delete(); } @Test @@ -96,7 +97,7 @@ public void shouldPerformAndOperation() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("test").and("message").contains("some")); @@ -139,7 +140,7 @@ public void shouldPerformOrOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").contains("some").or("message").contains("test")); @@ -170,7 +171,7 @@ public void shouldPerformAndOperationWithinCriteria() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); // when @@ -201,7 +202,7 @@ public void shouldPerformOrOperationWithinCriteria() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when @@ -230,7 +231,7 @@ public void shouldPerformIsOperation() { indexQueries.add(indexQuery); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when @@ -272,7 +273,7 @@ public void shouldPerformMultipleIsOperations() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("some message")); // when @@ -314,7 +315,7 @@ public void shouldPerformEndsWithOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); Criteria criteria = new Criteria("message").endsWith("end"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); @@ -356,7 +357,7 @@ public void shouldPerformStartsWithOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); Criteria criteria = new Criteria("message").startsWith("start"); CriteriaQuery criteriaQuery = new CriteriaQuery(criteria); @@ -398,7 +399,7 @@ public void shouldPerformContainsOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("contains")); // when @@ -439,7 +440,7 @@ public void shouldExecuteExpression() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").expression("+elasticsearch || test")); // when @@ -480,7 +481,7 @@ public void shouldExecuteCriteriaChain() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery( new Criteria("message").startsWith("some").endsWith("search").contains("message").is("some message search")); @@ -522,7 +523,7 @@ public void shouldPerformIsNotOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("foo").not()); // when @@ -566,7 +567,7 @@ public void shouldPerformBetweenOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(100, 150)); // when @@ -608,7 +609,7 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(350, null)); // when @@ -651,7 +652,7 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").between(null, 550)); // when @@ -694,7 +695,7 @@ public void shouldPerformLessThanEqualOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").lessThanEqual(750)); // when @@ -737,7 +738,7 @@ public void shouldPerformGreaterThanEquals() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("rate").greaterThanEqual(950)); // when @@ -780,7 +781,7 @@ public void shouldPerformBoostOperation() { indexQueries.add(indexQuery2); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("foo").boost(1)); // when @@ -801,7 +802,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { indexQueries.add(buildIndex(SampleEntity.builder().id("3").message("ac").build())); operations.bulkIndex(indexQueries, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); // when CriteriaQuery criteriaQuery = new CriteriaQuery( @@ -828,7 +829,7 @@ public void shouldEscapeValue() { indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); operations.index(indexQuery, index); - indexOperations.refresh(SampleEntity.class); + indexOperations.refresh(); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").is("Hello World!")); diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index b4d4a949a..74e6308a1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -57,10 +58,10 @@ static class Config {} @BeforeEach public void before() { - - operations.deleteIndex(ImmutableEntity.class); - operations.createIndex(ImmutableEntity.class); - operations.refresh(ImmutableEntity.class); + IndexOperations indexOperations = operations.indexOps(ImmutableEntity.class); + indexOperations.delete(); + indexOperations.create(); + indexOperations.refresh(); } @Test // DATAES-281 diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java index a7f88efb7..8795f3c81 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java @@ -19,9 +19,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; -import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; /** @@ -43,9 +41,4 @@ public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient, ElasticsearchConverter elasticsearchConverter) { return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter); } - - @Bean - IndexOperations indexOperations(ElasticsearchOperations elasticsearchOperations) { - return elasticsearchOperations.getIndexOperations(); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java index 8b0633828..0ebf14e2e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/autowiring/ComplexCustomMethodRepositoryTests.java @@ -29,6 +29,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -52,16 +53,19 @@ static class Config {} @Autowired private ComplexElasticsearchRepository complexRepository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java index 86944a0f1..4af00a9bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/complex/custommethod/manualwiring/ComplexCustomMethodRepositoryManualWiringTests.java @@ -29,6 +29,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -51,16 +52,18 @@ static class Config {} @Autowired private ComplexElasticsearchRepositoryManualWiring complexRepository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 75f0e044b..fa95ca6bd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -49,6 +49,7 @@ import org.springframework.data.elasticsearch.annotations.Highlight; import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.Query; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; @@ -80,16 +81,18 @@ public abstract class CustomMethodRepositoryBaseTests { @Autowired private SampleStreamingCustomMethodRepository streamingRepository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index 544fe2e27..ea69d7f33 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -30,6 +30,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -56,16 +57,18 @@ static class Config {} @Autowired private DoubleIDRepository repository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, DoubleIDEntity.class); + indexOperations = operations.indexOps(DoubleIDEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach public void after() { - indexOperations.deleteIndex(DoubleIDEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 469b25186..1db09a7ff 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -26,7 +26,9 @@ import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -56,15 +58,17 @@ public IndexNameProvider indexNameProvider() { @Autowired private DynamicIndexRepository repository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired private IndexNameProvider indexNameProvider; @BeforeEach public void init() { + indexOperations = operations.indexOps(IndexCoordinates.of("index1")); deleteIndexes(); - indexOperations.createIndex("index1"); - indexOperations.createIndex("index2"); + operations.indexOps(IndexCoordinates.of("index1")).create(); + operations.indexOps(IndexCoordinates.of("index2")).create(); } @AfterEach @@ -74,8 +78,8 @@ public void after() { private void deleteIndexes() { - indexOperations.deleteIndex("index1"); - indexOperations.deleteIndex("index2"); + indexOperations.delete(); + operations.indexOps(IndexCoordinates.of("index2")).delete(); } @Test // DATAES-456 diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java index 5f20dbb99..a3d2fd2bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/geo/SpringDataGeoRepositoryTests.java @@ -35,6 +35,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.GeoPointField; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; @@ -62,18 +63,20 @@ public class SpringDataGeoRepositoryTests { @EnableElasticsearchRepositories(considerNestedRepositories = true) static class Config {} - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @Autowired SpringDataGeoRepository repository; @BeforeEach public void init() { - IndexInitializer.init(indexOperations, GeoEntity.class); + indexOperations = operations.indexOps(GeoEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(GeoEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index 8a3f5ae88..03f889152 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -30,6 +30,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -56,16 +57,19 @@ static class Config {} @Autowired private IntegerIDRepository repository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, IntegerIDEntity.class); + indexOperations = operations.indexOps(IntegerIDEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(IntegerIDEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index 0118ba8dd..1e6c6e564 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -41,6 +41,7 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -65,16 +66,19 @@ static class Config {} @Autowired private SampleElasticSearchBookRepository bookRepository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, Book.class); + indexOperations = operations.indexOps(Book.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(Book.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index 0d8e38bc4..b19050ad9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.repositories.setting.dynamic; import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.elasticsearch.core.document.Document.*; import java.util.Map; @@ -61,18 +62,19 @@ public class DynamicSettingAndMappingEntityRepositoryTests { static class Config {} @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @Autowired private DynamicSettingAndMappingEntityRepository repository; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, DynamicSettingAndMappingEntity.class); + indexOperations = operations.indexOps(DynamicSettingAndMappingEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(DynamicSettingAndMappingEntity.class); + indexOperations.delete(); } @Test // DATAES-64 @@ -82,8 +84,8 @@ public void shouldCreateGivenDynamicSettingsForGivenIndex() { // delete , create and apply mapping in before method // then - assertThat(indexOperations.indexExists(DynamicSettingAndMappingEntity.class)).isTrue(); - Map map = indexOperations.getSettings(DynamicSettingAndMappingEntity.class); + assertThat(indexOperations.exists()).isTrue(); + Map map = indexOperations.getSettings(); assertThat(map.containsKey("index.number_of_replicas")).isTrue(); assertThat(map.containsKey("index.number_of_shards")).isTrue(); assertThat(map.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); @@ -134,7 +136,7 @@ public void shouldGetMappingForGivenIndexAndType() { // delete , create and apply mapping in before method // when - Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(); // then Map properties = (Map) mapping.get("properties"); @@ -149,9 +151,9 @@ public void shouldGetMappingForGivenIndexAndType() { public void shouldCreateMappingWithSpecifiedMappings() { // given - indexOperations.deleteIndex(DynamicSettingAndMappingEntity.class); - indexOperations.createIndex(DynamicSettingAndMappingEntity.class); - indexOperations.refresh(DynamicSettingAndMappingEntity.class); + indexOperations.delete(); + indexOperations.create(); + indexOperations.refresh(); // when String mappings = "{\n" + // @@ -159,11 +161,11 @@ public void shouldCreateMappingWithSpecifiedMappings() { " \"email\" : {\"type\" : \"text\", \"analyzer\" : \"emailAnalyzer\" }\n" + // " }\n" + // '}'; - indexOperations.putMapping(DynamicSettingAndMappingEntity.class, mappings); - indexOperations.refresh(DynamicSettingAndMappingEntity.class); + indexOperations.putMapping(parse(mappings)); + indexOperations.refresh(); // then - Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); @@ -178,7 +180,7 @@ public void shouldCreateMappingWithUsingMappingAnnotation() { // given // then - Map mapping = indexOperations.getMapping(DynamicSettingAndMappingEntity.class); + Map mapping = indexOperations.getMapping(); Map properties = (Map) mapping.get("properties"); assertThat(mapping).isNotNull(); assertThat(properties).isNotNull(); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java index 267b6ce0d..1daeadef1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/fielddynamic/FieldDynamicMappingEntityRepositoryTests.java @@ -53,16 +53,17 @@ public class FieldDynamicMappingEntityRepositoryTests { static class Config {} @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, FieldDynamicMappingEntity.class); + indexOperations = operations.indexOps(FieldDynamicMappingEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(FieldDynamicMappingEntity.class); + indexOperations.delete(); } @Test // DATAES-209 diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java index 8ac6c018b..ac3fe0a52 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/spel/SpELEntityTests.java @@ -55,16 +55,17 @@ static class Config {} @Autowired private SpELRepository repository; @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SpELEntity.class); + indexOperations = operations.indexOps(SpELEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex("test-index-abz-*"); + operations.indexOps(IndexCoordinates.of("test-index-abz-*")).delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 1da59ef11..22ffaa154 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -60,16 +60,17 @@ static class Config {} @Autowired private SynonymRepository repository; @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SynonymEntity.class); + indexOperations = operations.indexOps(SynonymEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SynonymEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java index f70facbf6..c789aa015 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/uuidkeyed/UUIDElasticsearchRepositoryTests.java @@ -45,6 +45,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; @@ -76,16 +77,18 @@ static class Config {} @Autowired private SampleUUIDKeyedElasticsearchRepository repository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntityUUIDKeyed.class); + indexOperations = operations.indexOps(SampleEntityUUIDKeyed.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntityUUIDKeyed.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java index cac633f21..6354ee8fd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/keywords/QueryKeywordsTests.java @@ -37,6 +37,7 @@ 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.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -65,11 +66,13 @@ static class Config {} @Autowired private ProductRepository repository; - @Autowired private IndexOperations indexOperations; + @Autowired ElasticsearchOperations operations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, Product.class); + indexOperations = operations.indexOps(Product.class); + IndexInitializer.init(indexOperations); Product product1 = Product.builder().id("1").name("Sugar").text("Cane sugar").price(1.0f).available(false) .sortName("sort5").build(); @@ -89,7 +92,7 @@ public void before() { @AfterEach void after() { - indexOperations.deleteIndex(Product.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index ef31e8434..54b943f4d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -81,16 +81,17 @@ static class Config {} @Autowired private SampleElasticsearchRepository repository; @Autowired private ElasticsearchOperations operations; - @Autowired private IndexOperations indexOperations; + private IndexOperations indexOperations; @BeforeEach public void before() { - IndexInitializer.init(indexOperations, SampleEntity.class); + indexOperations = operations.indexOps(SampleEntity.class); + IndexInitializer.init(indexOperations); } @AfterEach void after() { - indexOperations.deleteIndex(SampleEntity.class); + indexOperations.delete(); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java index 9cd564bcb..f5b950728 100644 --- a/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IndexInitializer.java @@ -32,27 +32,22 @@ private IndexInitializer() {} * * @param operations * @param clazz - * @deprecated since 4.0, use {@link IndexInitializer#init(IndexOperations, Class)} + * @deprecated since 4.0, use {@link IndexInitializer#init(IndexOperations)} */ @Deprecated public static void init(ElasticsearchOperations operations, Class clazz) { - IndexOperations indexOperations = operations.getIndexOperations(); - indexOperations.deleteIndex(clazz); - indexOperations.createIndex(clazz); - indexOperations.putMapping(clazz); - indexOperations.refresh(clazz); + init(operations.indexOps(clazz)); } /** * Initialize a fresh index with mappings for {@link Class}. Drops the index if it exists before creation. * - * @param operations - * @param clazz + * @param indexOperations */ - public static void init(IndexOperations operations, Class clazz) { - operations.deleteIndex(clazz); - operations.createIndex(clazz); - operations.putMapping(clazz); - operations.refresh(clazz); + public static void init(IndexOperations indexOperations) { + indexOperations.delete(); + indexOperations.create(); + indexOperations.putMapping(indexOperations.createMapping()); + indexOperations.refresh(); } } From f5411335699d6a13eb028c27a46cbb858cb998ae Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 26 Feb 2020 11:11:27 +0100 Subject: [PATCH 0075/1191] DATAES-729 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index acc27ee5e..7c537af63 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.16.RELEASE (2020-02-26) +---------------------------------------------- +* DATAES-729 - Release 3.1.16 (Lovelace SR16). + + Changes in version 4.0.0.M3 (2020-02-12) ---------------------------------------- * DATAES-743 - Revert geo converters to back to store converters. @@ -1015,3 +1020,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From dc795eb7ee9fbbffb5e743c1603fd03e5f8557c9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 26 Feb 2020 11:37:57 +0100 Subject: [PATCH 0076/1191] DATAES-730 - Updated changelog. --- src/main/resources/changelog.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 7c537af63..b91d31b28 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,14 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.5.RELEASE (2020-02-26) +--------------------------------------------- +* DATAES-752 - Upgrade to Elasticsearch 6.8.6. +* DATAES-741 - Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems. +* DATAES-730 - Release 3.2.5 (Moore SR5). +* DATAES-214 - ElasticsearchTemplate's prepareSearch(Query query) method should use getOffset(). + + Changes in version 3.1.16.RELEASE (2020-02-26) ---------------------------------------------- * DATAES-729 - Release 3.1.16 (Lovelace SR16). @@ -1021,3 +1029,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 6a4a7483aae0541715e9b49cfbb2e1acdd206de5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 26 Feb 2020 21:13:30 +0100 Subject: [PATCH 0077/1191] DATAES-749 - Introduce SearchPage as return type for repository methods. Original PR: #397 --- .../elasticsearch/core/SearchHitSupport.java | 36 +++++++++++++++-- .../data/elasticsearch/core/SearchPage.java | 28 +++++++++++++ .../query/ElasticsearchPartQuery.java | 6 ++- .../query/ElasticsearchQueryMethod.java | 20 ++++++++++ .../support/ReactiveSupport.java | 39 +++++++++++++++++++ .../CustomMethodRepositoryBaseTests.java | 20 ++++++++++ 6 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchPage.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 51552a8a6..842f9d39f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -21,9 +21,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; +import org.springframework.data.elasticsearch.support.ReactiveSupport; +import org.springframework.lang.Nullable; /** * Utility class with helper methods for working with {@link SearchHit}. @@ -75,9 +78,12 @@ public static Object unwrapSearchHits(Object result) { return unwrapSearchHits(searchHits.getSearchHits()); } - if (result instanceof Flux) { - Flux flux = (Flux) result; - return flux.map(SearchHitSupport::unwrapSearchHits); + if (ReactiveSupport.isReactorAvailable()) { + + if (result instanceof Flux) { + Flux flux = (Flux) result; + return flux.map(SearchHitSupport::unwrapSearchHits); + } } return result; @@ -94,4 +100,28 @@ public static AggregatedPage> page(SearchHits searchHits, Pa return new AggregatedPageImpl<>(searchHits.getSearchHits(), pageable, searchHits.getTotalHits(), searchHits.getAggregations(), searchHits.getScrollId(), searchHits.getMaxScore()); } + + public static SearchPage searchPageFor(SearchHits searchHits, @Nullable Pageable pageable) { + return new SearchPageImpl<>(searchHits, (pageable != null) ? pageable : Pageable.unpaged()); + } + + /** + * SearchPage implementation. + * + * @param + */ + static class SearchPageImpl extends PageImpl> implements SearchPage { + + private final SearchHits searchHits; + + public SearchPageImpl(SearchHits searchHits, Pageable pageable) { + super(searchHits.getSearchHits(), pageable, searchHits.getTotalHits()); + this.searchHits = searchHits; + } + + @Override + public SearchHits getSearchHits() { + return searchHits; + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchPage.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchPage.java new file mode 100644 index 000000000..e497ba36a --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchPage.java @@ -0,0 +1,28 @@ +/* + * Copyright 2020 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; + +import org.springframework.data.domain.Page; + +/** + * Page definition for repositories that need to return a paged SearchHits. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public interface SearchPage extends Page> { + SearchHits getSearchHits(); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index c78f5e34d..151740a7a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -86,7 +86,11 @@ public Object execute(Object[] parameters) { } else if (queryMethod.isPageQuery()) { query.setPageable(accessor.getPageable()); SearchHits searchHits = elasticsearchOperations.search(query, clazz, index); - result = SearchHitSupport.page(searchHits, query.getPageable()); + if (queryMethod.isSearchPageMethod()) { + result = SearchHitSupport.searchPageFor(searchHits, query.getPageable()); + } else { + result = SearchHitSupport.page(searchHits, query.getPageable()); + } } else if (queryMethod.isStreamQuery()) { if (accessor.getPageable().isUnpaged()) { query.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE)); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java index 3b1d28876..911295b30 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchQueryMethod.java @@ -25,6 +25,7 @@ import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.SearchPage; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.HighlightQuery; @@ -171,6 +172,25 @@ public boolean isSearchHitMethod() { return false; } + /** + * checks if the return type is {@link SearchPage}. + * + * @since 4.0 + */ + public boolean isSearchPageMethod() { + return SearchPage.class.isAssignableFrom(methodReturnType()); + } + + /** + * retusn the declared return type for this method. + * + * @return the return type + * @since 4.0 + */ + public Class methodReturnType() { + return method.getReturnType(); + } + protected boolean isAllowedGenericType(ParameterizedType methodGenericReturnType) { return Collection.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()) || Stream.class.isAssignableFrom((Class) methodGenericReturnType.getRawType()); diff --git a/src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java b/src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java new file mode 100644 index 000000000..205ec8e9f --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020 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.support; + +import java.util.concurrent.atomic.AtomicBoolean; + +import org.springframework.data.repository.util.ClassUtils; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +public final class ReactiveSupport { + private ReactiveSupport() {} + + /** + * @return true if project reactor is on the classpath + */ + public static boolean isReactorAvailable() { + AtomicBoolean available = new AtomicBoolean(false); + ClassUtils.ifPresent("reactor.core.publisher.Flux", null, aClass -> { + available.set(true); + }); + return available.get(); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index fa95ca6bd..9bb1d2050 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -53,6 +53,7 @@ import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.SearchPage; import org.springframework.data.elasticsearch.core.geo.GeoBox; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; @@ -1479,6 +1480,23 @@ void shouldUseGeoSortParameter() { assertThat(searchHits.getSearchHit(2).getId()).isEqualTo("oslo"); } + @Test // DATAES-749 + void shouldReturnSearchPage() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + // when + SearchPage searchPage = repository.searchByMessage("Message", PageRequest.of(0, 10)); + + assertThat(searchPage).isNotNull(); + SearchHits searchHits = searchPage.getSearchHits(); + assertThat(searchHits).isNotNull(); + assertThat((searchHits.getTotalHits())).isEqualTo(20); + assertThat(searchHits.getSearchHits()).hasSize(10); + Pageable nextPageable = searchPage.nextPageable(); + assertThat((nextPageable.getPageNumber())).isEqualTo(1); + } + private List createSampleEntities(String type, int numberOfEntities) { List entities = new ArrayList<>(); @@ -1627,6 +1645,8 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository> readByMessage(String message); SearchHits searchBy(Sort sort); + + SearchPage searchByMessage(String message, Pageable pageable); } /** From bf51de3805b64bb0817c037ff64c7c6c113b6277 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 26 Feb 2020 21:50:42 +0100 Subject: [PATCH 0078/1191] DATAES-753 - Reactive Elasticsearch repository: Bulk update fails on empty entity list. Original PR: #398 --- .../elasticsearch/core/ReactiveDocumentOperations.java | 8 ++++---- .../elasticsearch/core/ReactiveElasticsearchTemplate.java | 7 ++++++- .../core/ReactiveElasticsearchTemplateTests.java | 7 +++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 955a122bb..66f1eebee 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -88,7 +88,7 @@ default Mono save(Mono entityPublisher, IndexCoordinates ind /** * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is - * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. + * {@literal null} or empty the index name provided via entity metadata is used. * * @param entities must not be {@literal null}. * @param index the target index, must not be {@literal null} @@ -104,7 +104,7 @@ default Flux saveAll(Iterable entities, IndexCoordinates index) { /** * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is - * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. + * {@literal null} or empty the index name provided via entity metadata is used. * * @param entities must not be {@literal null}. * @param index the target index, must not be {@literal null} @@ -228,7 +228,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in * @param entity must not be {@literal null}. * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - Mono delete(Object entity); + Mono delete(Object entity); /** * Delete the given entity extracting index and type from entity metadata. @@ -237,7 +237,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in * @param index the target index, must not be {@literal null} * @return a {@link Mono} emitting the {@literal id} of the removed document. */ - Mono delete(Object entity, IndexCoordinates index); + Mono delete(Object entity, IndexCoordinates index); /** * Delete the entity with given {@literal id}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index ada81c511..32123cda2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -160,6 +160,11 @@ public Flux saveAll(Mono> entities, Ind List> adaptibleEntities = entityList.stream() // .map(e -> operations.forEntity(e, converter.getConversionService())) // .collect(Collectors.toList()); + + if (adaptibleEntities.isEmpty()) { + return Flux.empty(); + } + Iterator> iterator = adaptibleEntities.iterator(); List indexRequests = adaptibleEntities.stream() // .map(e -> getIndexQuery(e.getBean(), e)) // @@ -366,7 +371,7 @@ protected Mono doGet(GetRequest request) { * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#delete(Object, String, String) */ @Override - public Mono delete(Object entity, IndexCoordinates index) { + public Mono delete(Object entity, IndexCoordinates index) { Entity elasticsearchEntity = operations.forEntity(entity); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 6312888d5..02d0e60c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -811,6 +811,13 @@ void shouldSaveAll() { .verifyComplete(); } + @Test // DATAES-753 + void shouldReturnEmptyFluxOnSaveAllWithEmptyInput() { + template.saveAll(Collections.emptyList(), IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .verifyComplete(); + } + @Data @Document(indexName = "marvel") static class Person { From 251adc1eec41f8e2442b3dc0fe017ee563ca808c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 26 Feb 2020 22:34:44 +0100 Subject: [PATCH 0079/1191] DATAES-754 - Completion field deserialization is failing due to class cast error. Original PR: #399 --- .../data/elasticsearch/core/completion/Completion.java | 6 ++++++ .../ElasticsearchTemplateCompletionTests.java | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java index ee0fc4ace..ef8673316 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java @@ -3,6 +3,7 @@ import java.util.List; import java.util.Map; +import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.lang.Nullable; /** @@ -23,6 +24,11 @@ public Completion(String[] input) { this.input = input; } + @PersistenceConstructor + public Completion(List input) { + this.input = input.toArray(new String[0]); + } + public String[] getInput() { return input; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 2acfb331a..316e707ce 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -87,7 +87,8 @@ private void loadCompletionObjectEntities() { indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[] { "Artur", "Konczak" }) .buildIndex()); - operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); + IndexCoordinates index = IndexCoordinates.of("test-index-core-completion"); + operations.bulkIndex(indexQueries, index); operations.indexOps(CompletionEntity.class).refresh(); } @@ -151,6 +152,13 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() { assertThat(options.get(1).getText().string()).isIn("Marchand", "Mohsin"); } + @Test // DATAES-754 + void shouldRetrieveEntityWithCompletion() { + loadCompletionObjectEntities(); + IndexCoordinates index = IndexCoordinates.of("test-index-core-completion"); + operations.get("1", CompletionEntity.class, index); + } + @Test public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEntity() { From ec214a009e081260e323780ef4bafbbe63e57625 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 6 Mar 2020 19:08:49 +0100 Subject: [PATCH 0080/1191] DATAES-758 - Fix documentation for @Query annotation. Original PR: #403 --- .../elasticsearch-repository-queries.adoc | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index 7dd13bb88..8cb90d08e 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -274,7 +274,8 @@ Repository methods can be defined to have the following return types for returni * `Stream` * `SearchHits` * `List>` -* `Stream<>>SearchHit>` +* `Stream>` +* `SearchPage` [[elasticsearch.query-methods.at-query]] == Using @Query Annotation @@ -284,8 +285,21 @@ Repository methods can be defined to have the following return types for returni [source,java] ---- interface BookRepository extends ElasticsearchRepository { - @Query("{\"bool\" : {\"must\" : {\"field\" : {\"name\" : \"?0\"}}}}") + @Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}") Page findByName(String name,Pageable pageable); } ---- +The String that is set as the annotation argument must be a valid Elasticsearch JSON query. It will be sent to Easticsearch as value of the query element; if for example the function is called with the parameter _John_, it would produce the following query body: +[source,json] +---- +{ + "query": { + "match": { + "name": { + "query": "John" + } + } + } +} +---- ==== From 9258cdde8438845f8a4730394873aeb4199b2979 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 7 Mar 2020 23:00:19 +0100 Subject: [PATCH 0081/1191] DATAES-759 - Update to Elasticsearch 7.6.1. OriginalPR: #404 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 4 ++-- .../asciidoc/reference/elasticsearch-new.adoc | 2 +- .../analysis-common/analysis-common-7.5.2.jar | Bin 193638 -> 0 bytes .../analysis-common/analysis-common-7.6.1.jar | Bin 0 -> 198566 bytes .../plugin-descriptor.properties | 4 ++-- .../elasticsearch-dissect-7.5.2.jar | Bin 24484 -> 0 bytes .../elasticsearch-dissect-7.6.1.jar | Bin 0 -> 24704 bytes .../elasticsearch-grok-7.5.2.jar | Bin 32238 -> 0 bytes .../elasticsearch-grok-7.6.1.jar | Bin 0 -> 33792 bytes .../ingest-common/ingest-common-7.5.2.jar | Bin 107807 -> 0 bytes .../ingest-common/ingest-common-7.6.1.jar | Bin 0 -> 115431 bytes .../plugin-descriptor.properties | 4 ++-- .../lang-expression/lang-expression-7.5.2.jar | Bin 61184 -> 0 bytes .../lang-expression/lang-expression-7.6.1.jar | Bin 0 -> 66047 bytes ...8.3.0.jar => lucene-expressions-8.4.0.jar} | Bin 73071 -> 73069 bytes .../plugin-descriptor.properties | 4 ++-- ...ticsearch-scripting-painless-spi-7.5.2.jar | Bin 26239 -> 0 bytes ...ticsearch-scripting-painless-spi-7.6.1.jar | Bin 0 -> 27878 bytes .../lang-painless/lang-painless-7.5.2.jar | Bin 552144 -> 0 bytes .../lang-painless/lang-painless-7.6.1.jar | Bin 0 -> 558852 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../repository-url/repository-url-7.5.2.jar | Bin 14566 -> 0 bytes .../repository-url/repository-url-7.6.1.jar | Bin 0 -> 14743 bytes 27 files changed, 18 insertions(+), 18 deletions(-) delete mode 100644 src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.1.jar rename src/test/resources/test-home-dir/modules/lang-expression/{lucene-expressions-8.3.0.jar => lucene-expressions-8.4.0.jar} (87%) delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/repository-url/repository-url-7.5.2.jar create mode 100644 src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.1.jar diff --git a/pom.xml b/pom.xml index e90ef3df0..3119d320a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.5.2 + 7.6.1 2.9.1 2.3.0.BUILD-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 5913f6cd3..ce2185f0e 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,8 +35,8 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.5.2 |2.3.xfootnote:cdv[] -| Moore | 3.2.x |6.8.4 | 2.2.x +| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.6.1 |2.3.xfootnote:cdv[] +| Moore | 3.2.x |6.8.6 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] | Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index f41bf934f..7684c084d 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -5,7 +5,7 @@ == New in Spring Data Elasticsearch 4.0 * Uses Spring 5.2. -* Upgrade to Elasticsearch 7.5.2. +* Upgrade to Elasticsearch 7.6.1. * Deprecation of `TransportClient` usage. * Implements most of the mapping-types available for the index mappings. * Removal of the Jackson `ObjectMapper`, now using the <> diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.2.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.5.2.jar deleted file mode 100644 index a2c7da81a6bd9bf9d83aa4da1eed2a474755654a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193638 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%0A1b+j1(6v%U)W@xHBa$1120*>rqQ6f z0nJ~B3r@fePXjNJzNS&2`G3*C38vwB;3c@%JnDCE!1J3R7akd2S9y&*L3ab>Kdy*> zoCnt`OL!W172GvVG^`){h9}q`nmBlDc&*blHX8E{u>Vp%!Q;Yrj9=qYz-Ej8bDMu1 zntvW|@K0f{p=rf#0R5lOWZ}0RzMOkaASinSg5Qd}@W}9Y8`sF+RBnKLJ+l7u-UFTr xKDE83I#9a-)qhEJ;aT9bfNK^GtsAiXJtt6>M}?{GVA(kAWe3a1X`lT3_AexWOsW6? diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.6.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.6.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..d98f28316e637878e4e42d0a02bdb2d6230e9163 GIT binary patch literal 24704 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 Ka{>PO?*9Nmu6h3e literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.5.2.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.5.2.jar deleted file mode 100644 index 86c594ac96cf854d24ceead70b7ae7e2c24aed94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32238 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%0Dn1<@<;{kY%*t7(P3fQfE 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.5.2.jar b/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.5.2.jar deleted file mode 100644 index 482a81a703bac0220f842b89f301935b550a7007..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107807 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%0A-4&v&%RUUPqSGy=l|&5Dpc3 zNuY!^(E6gVaDN619E$Jhv^I=ZEdf$AI<$~O@zMv8k*)P_a-ag!&b0N$Fnm5-O9$4= z0&ZxPSlmI!?n^9a5|FS-<5*c#(*k&{GL6lXkVAE0Nin%gl+$%o&jfi@1yoPGX9FNA;NJ=L&I1L?5gp(|dJH}}q9Xs85t?{H}>hojh#37)~e&E)!@o!D518@iRn zXPNUCIjIXCcpYxeRvc$5`eJT-W8pD7-)YBZ*J5{uHlx?SI)41M{1UoFY9<1yUX|MDA~O4*n1#47%*dVCkJX+Ou`l||)q`RF!1 zwtLL(W%&gIMEh$Y=jB}Zu~K*u)2)q$ptoT8V(Y=V$ymrtD3%ki_6F;#!A`IXuV9$H zg9mnxX>?yiF7zjhw8bbsmoQ)1FYCxd@_@B%VJn9ZeCj>6RbqY1A^crhhDo=i0mBJ< ziPbz_Fjk+41hX(DKoNeG5ss3I^$-0-Co_!(NY|019LhtI8? z**|LA|Mn(O*;GgRFa>88*98q`ollinTE-9zAhiPxO?H&Rjg~r0PSsaNxC4m-OeB=R zWt`8QsqAi2;3sCFOS3HP*RZ_H<;Xuu4l?bXukmW07B;>5b-i9Te0)5{34m+`;t!b> zo1_m^2l~_~-df>gGM4T6<7hM184`t3qMK+Ag57$S6OxQd08&lP1i2%tF*Sm<=p)q{ zJgfIuV5~utv(7s@fMkl zdt8lKJmge0!j9X8j>uYF7v+s`}V=?Pgp{kzt~JK;04froPP6ljwuA8v+-{3$>#(f~0H z2G}L*2r8EF!5p7C%HlEOD|u6E%gPL1t%`bIp~=HZZ2U?`8cL>J+c+M~rB~YduF8fm zUo)B~Ax&V)JdT1Y)~ViDeJezhpoUCnJ!Uywr;|~c@i#9B1vOs;<>?sllF|dfj?yhe zFKLN>GdcB7p$SQY?togkaKT>no0v$4TiFqK*?4LCE5#8~d+By(_O>raA=)Ri{Xu){ z@i@BL10LIQ!*&`W>GCyT(k*vqDL`2`F3x;S+q|Wa)<9Y{L&iaeG9J33a)`(e3t?_u zeU?QIX4Ph*IeNnA(yZtLySt}4{K;fkl}GDy-(xQmiwkS< zvh!mV&sn|^@)ufIbxT)4zbwcee%mQ|_F?rAHwhlCJt8VL{pBGVyKs+lwA#EH{CK`D zL=qny4diBu6w>|+!Hzk|xHktHjhtD<3d!@1wv1@$4o?u8E`S6zU`+ZplB%M=m(`CwT6k zhzsl6Za-uKXOTO}=DWMX@S)E9+{o|8)Cv&8&X8rF=d31~kcvE%@=!ni^j8PwD@wRsSN5*{PVhD!G|Cd;POn|4*s@e`27PQt9cc2%-H+D6Q91Yrnh$ zFpUKzGg(pS1~9+NeI3922L+1Gp#(;*BSVm5m{udnz0 z8)ICV*O4Pfn7?eszCQlrZNDf4?2?!1z9ywMr4}XZ8d?pN?t>Xni8Q{hgfO1JMgfqd1sj8Zuub}Plcn{eJh!&~JXl7lKwSwn?KE-#h)SvM;tQ2i{S ze;OtQd18Lk*#NSpQvqkuK}l6+QEuO*M6H|hrq|KEwx=O$2WgxZDr?%lzLK@a`f`~{ zH%(UDupQfTaW}qz`S$z|A zYpgBdjNPDxB>DEhDnS%I6G-BST9z>27>8q$MNs!RA6(j-hv_cY2$*JG7v*}fHT^la zd-}>{rbV~YhyNG7aSrv(kGY~dD8ST#s#b!+1Ja)T@n2pYiJHOVyL_E*Km~`}W4oUwlIl^9d-tJ3sAK%gxU&l7WmVtk?{gc9FKX`l?iuTl>TiS)&sYV@OJ12jI0 z_VULS!qObz2{|@gn^aca(|_3t zGQKSPgk2y!?%C{SYpXL0_h8L22a8cSAU

+@ceW(8ScH7G4tf#GK7^a?8Do*UoFO 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 literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.3.0.jar b/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.4.0.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.3.0.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.4.0.jar index b870ca615308061e25e8cb3dad9601ef5ac26609..f0a43e718c7579fc97f3887c172e85069f0ba8dc 100644 GIT binary patch delta 5392 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 Jz-Kk={{T`AFN**G diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties index d5ecfbf5e..c52e59353 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Lucene expressions integration for Elasticsearch # # 'version': plugin's version -version=7.5.2 +version=7.6.1 # # 'name': the plugin name name=lang-expression @@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.5.2 +elasticsearch.version=7.6.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.5.2.jar deleted file mode 100644 index d4cf33bdd4f83c1d9520be6308755a0c861cd239..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26239 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 F{tvk8cs>9C diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..19714bc92e42e00f664c91e6147fc106aa6b3b01 GIT binary patch literal 27878 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 BAgKTV literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.5.2.jar deleted file mode 100644 index 0287d08ac0117b1f10f1e85e65abaafbdd8c7621..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 552144 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%0D< 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

+dy&am=@Xl8D#QIx1FuLP!`4;2@Mj3KUGM>%@nv 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Ê`!MeZq!<2~ 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 LkeD`sufqNhiZX*t diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..42374bf1781b7c7f5054cf53a93c68e7f3ed8452 GIT binary patch literal 558852 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

$P`5~2In>$+nsbFPuS?R@r0!9l-~ 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�AtlBO*$GCU|yHnVG40c{! z=whF}86)nnxL{bU`U+RFnM>VZ6@Zxw8&mOg_P{*Ye&ffu zRw-JIRW*)DrMxD}4wbxE+KA|^QyN+`)|hmh&3lwGcOw}ieO?9<^YY4=5E!(h&qZC=O~nps->fN%w(bnAK9yV^B;QB8DZ9?QTFtGJf;`5`m*2mo(UbRNFs+pzM0pYcb>gXV_XQmQ-M2Hx;uos9dS8e%e;-V#j1xR`ZDta;&tD zdMcT%Yr2$~+-3JL@RpbrI_Z+}71dwbh8tnOjr{{)+VCG!vDuxA`g zr&k=&Q#yX9cqMoBzI2-m@FLxGIK$fG1ZbJn)B@m_(RljL#@WU3b7Q0bEUQ03_{>A8 z@0I0OD4FpuV_||gR9xUcRqy_3WId?PQdzNq*(2HYOZMv(U|T@u$vBq5S02ILCpk1p z_Ujj5=Lph_1GeL+O61PRMyE}yKY_o`ofP=qw^cA$bD!b??*FN*>OVD|mYmz*ZnT}w zfPA)Q{L?Vot_#SVRq4zc&}(e$UM6Kg@mE^?eNn1}bL>J10)%b*&b=Vbd+4V%gw3U& z@Kuo8N=Mip$sT9&=hPQdfmz_|krU=D%iYlaZG4@gSwLM+Y@C*%pI%OMoYj4ECs#y* zaB?Iawk&*`QBAjN-Gbrs5zuqg=r0|RK$K%>Nm>=NzRqjYf^U$l+`0aO{b$A#hbAY; z0ESgg6&E|g3j)rJ^+*{)<&xn(}ar{Gt zu=Bl+MBO$9V8z9rb$2w4#i$-Uc|^-un@Z3ly8n0WOQZ2f^}(7I^?@&{I6;0|8f%q0 zDIV`S6euCS0~ofmiXoha{qq02VL)KmY9ANab3C7X&hcwAo>?jx5||!F?Yw+Gjz-TY z7hCa4r%phFNSbFkxr|!oJnPw&S%L^SM7~2FCMpf0Tw;LWMz5~7_WDCZNd23``_~hX z4uGHNLcY~0fk`8IWNftr6$Px-NrWMjux1?fATsPF`UPt{^d(vs{`#;`jTfPh1 z)n2jX;5X}|3x-zaoUd!T;&-b8a5uOxSE5x^J~a0FTgRtD@a7p3eV9-Nh#wY}ilk9Y zm7V040+t$YObAQ(QBx48nE$<_YnyN!7C!=1>2mEyFp3X}ON7!)ryQph(tKuC+e@e$ z5iYvO1@S57)QrNac@YPM+P+74Xrr8{9XeDZyi`n}4(k4sk3EVecgCnq4K%1_!YyQi_-JyK99pZ>ErvdUuEI>&!rCt9=Q-6>vqXq&z(Ynp|7 zW&Ljee|*3v;Ge*i5C~e61LGZU2^7h)<#sjSMw?Y+joy*vwWZ}jE$JRR5bsM_{}Y%1 zCcz7GY`ANXHK-7!0cbOBuMx&1tb(iN==Q}M>Imz9+kygBsbx62E_~)f8Ra*n6e7Bw z@uLlt4nKinTER8A5Ji=Z+?WRT&{?yM`}nk0Ra-G#xQT%6yaao|i4t+6)+I+e4TKBG zQX&o3#E-7RvjtgS*vb%T0*KA!G_zk0>Ys*K{3~Y5ZXB3RiVe_amA@jBQgVNdhFae( zv%Nhk#&f?EwLB&2f!_9HQ~nXbJD^?7z@dYTd!ZdpJtI@#YaASd-_6g;?FG3!Hnb|- zWk)0+Xxk-}ai8$(sBL=baPmyK4nsQsF)0rjg=f;P?7gD78jIB*{%${Ln0@JH!j-a1 z;QmYI%L?KOuYUhIVy^+AotLjD5))uI4wr)qX51s0z55gtZX#unbwp<}Np(c@Xwzk%5=O#n8 zq1@Ng0OBZpM-nQ&@SB~+V}(eb1KMOp3OO3ukR=C~`0&`5UsHFHhV`bLEv*1664IPt znjYSFm8H~qT}2589jXm(`+qrnh&lSq2Ys#Zo^FPP$T>7)80yBSJw%mnWrkitk(-@T zEe`e?jaWvM;sR3cTYTPvux4jR#$;`LfjFC3#s?T?oD^tvt84Js2_3_ma-w3Fzm9o+ z`+V4Ab1ArrODshG;3SFV+T6hiJ=BEAi2I^26@a@TO4>_SG`p1=g)Y~%96QAN^8J{f z1N-_E^s{jQU5UJA=ds80dKkm!jEtWgBXxzN^<(#~;_!FnkSyD{!T1~^0v)n{`*Z2U z0%|9cyDQPa;1tZggv3%LcN@?; zkk$pY`1)DHAG3Wra&1eB0O%Ow=%1G8z}{ZZW~XGDoQ$U#7WU@!<6L?N-Eg#g<^cn} zM}5=}ElYhz;o?bPl&bCP;i|jluC?k5b-ggqHVj@L(vd0D7c~rS{+QXOGYo$0&Ao6t z$g{njlFpjuF%2r5zFXhXOKUZGu1lws1-*F z)j~7nlAY4@x8w0)&@-Wo^*B-#*S(C7d2{n9-qRRq9q&ychA>iKC>skzG8?D>*ES1T zWp|T;f46%&81i@YeuhKS0{@Koc(9hx$&s5mBrI1#Ax29)n^7U=Up+5F7FKYqz`snY zbr`|9Osrc8{5km;@{rt4`542(-*XgUOE>p*k$u?yCyNlr6QX?M8EN{49xUw4U*vm@ zR>ti@2Ox8UP<>Z?md1CCncx#**qSd1lVEOZwJvGUciPC3w5aHozK|sgv6L})L(%eLwebZAIBA%`mvQHPNuc7?hqDOl(E0Gbphe|p^EqS>|@PF za7dPf#8jZv32VcI;$-w-Dury}^jao`d(_Ui^f5uhWzDLESJXMim}Nj)rS%P2286CF zUUqBoOree&%~)NX_u9Sm(>-AHk{CF07$8ZWG0qyHjR@3gwj4FkHB%R!zW>`V2iC94 zAkZ{OAcmVQMIxmcA|WCY_+yuTl{3*{63KHupA4)RGe^zEr7;c?Z5jo0FVhYi%=mqG zvDwH(tZ0O#Oc-7g-t!hSB_Az{)O%uB-4uJ0B&7_QRECO;2f)|F(28QvkI;mrZ)cLO z*qdQC49aUW*a?;Dy;2mn2i^X9r@GRzj%>9Mdy~%1V4WK}>b`sbvKHBvcX)hBN->T$ zEzQtPgtWgu1I9Drn~1~yOc??Dj!}*C<+kvoYyfs?+EW|qE9oECU=pJ^*!VjwLQ)Zr z`}lWDfna(fO4~smkf*UVkZ#S_l$PF`9m+wXMj-#hn9d9N1jnZf9y>}ie~=eBx{~U+ zc1U-~B@`A&7xf||+EIqP3p;y4Zl}=&ZF(@GZ6}F5_`xFHKKTVY)VxfK%J_*VEovIM4gZv4h1^t$D(g*AaNmE0RkBR6c+p$-ocPP$umgzqByA{ zX%$e=0i8}1)m&aI0;${rvo9tuVtvlK=CF-pc=hlqEUbL%d7|bJ>kxV@4Fo|0&BD18 z`Rj&4=3$-i5Eka<2zG(_lT5~xcx~{1-sMps^Voj46ZLC!dSk5(e5>yWLa$b&2v;JD zE`#cBS`Ce&mdZNCs?q3TP*KSD{^m~gbM?WY1G2Ec@6TG_x;No@lRB{Ln4SI^#Qe)d z+i2p0n4Zbrn>HplH~E#w`GyG2J}|PlDxS9o{qC3)F_fN(JhQ34@%00eo{3*aqFIJj zll9MjHp8S+9YLZp5`FEjiX!Z|-RTs^Vx>N(l9?~n(M$UxN5r`&Hs=?*nDApFO#NS0 zHzX5507HUKbL9eE1LT=%(>W$hS`WuT4oovLm6(sQC^CPx|6~t$^3s2{odKkF4L@$PUA8NNLh{_Ty%__{#x^v9hhXbJpMLx2@oh(qDEZX$# zdyhkU;zdN|WRxCs$pOv%i}yN)pRPsEYnP6sfphumyBwhB`JDP2;_)N&t8}zUxIb{d zKG%0appWdg{&gd0M*X4(Wy&;T!f!IBs-=MZ}q)Il7HOIfwG%!cy=AL1)PsNuvI5HZT*w@}`p|-l7H(Z4i}X ziP0F!e+OOG-jLVjOM>Hr;=QM4^g~(~Jq%<=ojwB+=ZAEPBFYvA{1cE8)?ppqKUq;& z)$k;|CrNRL7CWr}xSx-&pU*qJhiCF*(dwvXX{V+&KL*51@IVOVS+zE_gXXHrp5@C9 zf^F;TJ+G=ZJ8*btC&yB7{!pcBAM+GnP=2%)-9Ib$$p!Xf4z5Q4W9wKNQ8rhRm7X6S zn_utY_50f+?%o#vSaV^Eup^&;d5=&eG+>*vDE*gv^e=y4v)SaQ$KGeu19<2|u|Qj9q8*G2sF5Y;|m*!4iniz495CE8DD ziY$wgo=H0BXG(;WO!TE93JvO#D=MNiCnt2N=a#4Naf$D80rOF1e*#k-Bf1PW8dZ}t zH810nv#?5@niEp^XQ&F8Bm*9pl}S9#RAR93p=GVzYK*ZJ)q%Cgt0Yl~nW?ZKQF8;7 z=HxM5F_Vn@w;4(xt8Ygc5p|ahJ0vfJVK?9|x!@%&HGtxLOU^!(5)>^3PTyYH#`RUW z8p?~X?vE|7&B_A}mf5p0?NMc2`qvKTR-Ig=ubm$m$bHd&L@iVTanj+%O&R1U?+rn; zel(d9gN>1JW#XAY)PSc!I{SNhv=09PvQwqrD=}p6y0R_ZD>Dr2a1j$nDHOyU?4YA+ zpZ}D$E1|i07O)HsC@pwz0HU#I%2b-g)J9EX$sAWh1ZQfsD(eYQ#5H5JPBd$3^k#22D{T*|d{ zM9iaHXj$(nzmOMs)~RML)e-jZT%lC*6`}SR%ch~Wl-nq&O@SaTnKJ`f(tRFjn-bfK ztf<*{Pa3yVj%=ul9)SjWRNy26BbF>C{`U;@s|q35yK@Xe{gD1w59N&XUJk!yxyB>#pxt8M}XsSo0p=jra z<7Bw;7qJ*x9_*3lQG>{d(lojDcW!tyaz;HUF5UY!P{s`K(LQI-Qh4ToVTRF z6>pt*x;e*f@-6c#DLa|fw<719oIYr9?3CS3%w}s$-YD4~?R7E=n-j6;oVZ@oa8Av+ zX^QtDsk%Uw0}~KueBq8EGUx@nBcC8Q$alLOk~^}|l=9A3^S3qo}OJVOT>HC;#vR#O7ocQH- zMX`vdTL4w`I*v?8P{v>Fv7ZtWja8wIP>;?h81r zU+k!T3oP@Ws8}|6R8{^A0xL2pFtE&YZFKTIi zs;d1vTI?jAL;+lDMBbfARgM>A3|4&Bo}n)`cdjw76=@egy?wwAT!_oS7wc0RD*hOQ zwJYYBQMZQdDt=Pt#&gYmns$T$+DUM^3JOh)I&F*7#3&f%R8KeT>Qa*#Q zkO}X5Rq<%mJp(x}&T&jyfVEHc9`I8kv`l#GH&GE>p??g=EC#s=V?z>%hZuNPNtw}R zr3m;LpQ1C{z%r2(QvrJaccW9=SRda(Kigbi&scxcP=C`zpWjxW-$K93Mn7LXtwH3M zdjoWI^G$8!RyVN;B-4R-Vr3qln+ZWTFX zl^LHl5UepJ(vm)DMmtW#W=z~>Ow?vf(uP{dhB`>6*w_f%MtLo=85FJg6t+2E!2y$} zYjfe$tzE$Ze%=aGDsG{?d>Koz`J{rmk^nelJ74q4op+>m@e^;U0!Q9Njfbq#NZz{DS_Mt(y&M~v> z5>Y!IUU&noSi%f#+zOx0lyOlycTqlvRXT@NK95#9mn>Yu98j~0Y|Ah!6(^fFbtGo- zOq~%cFOSsKLscDMOMqZ2f>wphtyOeG)~$**%tGp$)j-CxL-;al2ohH0Sz-~UqL0LS zlLf~29gZ5Z!zF5H_NSV8Aw>4*Amx&87ou*f)(Sh3rO>SG?4H9vl_(tGY$`#(l6-2A zJi=rE@8a9=Fs&Hir50|b)Cz}mAu_?>C4#Qd!SKyx8oC(d`+Kg6N4ks`h%62zg(a$z zW7gu^*e-@=TL_MdhLw;8nJBB^z=h#l<}&_sCmRhWXu~NR=ReoT7)M17{ry?4_MT}S zM0^u^cmzibyi#c$b4cXHx+8$l7_J}T`9vCpT+4Y}iV~y(;1DvU{Y^qxo1_LI=FFu=6AYHW}7 zLW>vU8mi9I11tKO%QS(77o&wJ8u5D}iC&K%GB>>?Hmzf4z#xqHJyg14pNXc^zAP}b zh0QwTuT-?sv9j-7;?j9_+w5rj91ixBholS}b;4J9iPR)n>rS#nu+M(SykuS1?82FQ zk#Mz5Zl{I#`e9w#2u{6DeyPpq8>GKYeQBMNvqFBUg}6z2B~YmNcU0>+pD?O8<#_TD z`gAB>fuf*M$Q#D(4({wgYhlc#Ea_O8lCjtERNNJVF~7kR`$)P*DEomXi@XcrSjwSq zXpYyh@S&SKu4#T%>i!HgnxG{ObTbHalj6ZMx_Sh6HaGlX1%$7iVEqf4mA{0A(CD{> zIR#Y$;3eh4O+iMlkg8mz@8x@G0PnoSi_H5&ImqetD?J*54&vD9A6p1Tp5jThBSBPF7|%_)B%Lzv z?RfJwcg`4xVrt01B0F%h{$i_d{{?*`Z1{CE?l8} z#L{=94^n_=3;2$-)0s!J$@e3r%W<#O z^yQu3ThB)#M8^m~?ck;munuMxRDwD>Gx_5i)=%3?`Y?@&JS|24A9`e9!$p zQnhMrE4~o7NV0YJ^}lGJ)SlXs;7`_PoH}Z-Yj4T?Zp9cj%MXoHIBh@d?-j^=u*!!&U3T-W`^dPfbaSocQ+ZIyogUM;ltytg0Tr@ zx2#gIJ$g3EWdE<;-M%sS zwW#VGVL?%@kaTH3>|N5GYFW6er@|Kfb)Wt+bWTd{Fm0IhqQWb7XX2wYPBS6K2`)J6 zEE}}2y21+N<``jokj(cq`JA0$VYg`nHw69ikz#{N80WkfY6I4|nKB3PY${G1GLgPz zZfMw$ThupX-nYM`K-<}ufyd84zdS{gJI-I<{C zXeXNj+Dk%nbk}4QIbHC*%|}(lt3{8Eqwi-_Fg2aCZ^U-gXRR^27F{hB72$LgX0AFZ z>T~B;u{qGP@e5A)Vhip?(e$vSXN`+aG>a^y<)ZYLsoQVz(4^>d zkl402%XTW^F2*s<8uHiP;6WQkIPV*fL%EVtE!HA8>{YDYCt$QK@i~RCoW`Mr&qM_K&^~{5PGj zje)BP7uRTUoff^#6(NoM4nV65S&{SyV9ogmo$$EJbkfo`QXh?v<8I`g@>qL@t-A&@ zi0SEf;jTGn>&GhG@Z<#8E;!f@;Xj|iaT!c&{yqLg{iKWGLSoKwczHhVQjCNJC5 zHo6&GH-%!eb|C$1W}!^aKwQvc1wyj9Gn?ivB^-u*sw8l-1Fa?t^S25fFCSN0YC;hn zyn&T_Pz|TZ-t!+awGmyudEHb?AnnomQ*^i@-<#^mML9?-K^|Bwu@=bJtXR$2gE39W zkC7y1CkMfngi%5-692)r?ZJ$_loNSo^0&bF6NUE07-IK_vT2Eno1)CwUVF*%ZII2AY^I1U_*K{F)7+WNQ9>B( zXU>{dLE=DXDkcUGhHg9$o5zBEDA5o-w|pc$v>xkGUK)r zAreOCV6%C_lhou!_%^6?D;;EF*D8In(Vba)=r`EUoQ*&Vy>X-tC{vBpp|>kVF#P$I zlSSH;@D6W+jRm z1in77tKx~r8%L2EMv?y7dy%_1Pp_gR{xtFq;cDbH+T+^TFe84ds4KQjZ==^fZfnKZoULdth(N#M4@cBfDXLp7=0jbR+JcgqH{-&b;oI@UI>? zu-rYjrTt4M3+VIUOxLyY(4Q|<7zLQ6DH{see??uv?}vzVC({bS$o1nJ~n!3Se~#jin=n-v3~gpi57xCfH88p=pS*q z*o_t(18!^d{S_M->B6`zC!<(gdOCLJ?rN+{#f=gCF~3EGy@F$^QH1;zxAuY>>qv;R zYhW4jUL_IHR1=DPlxBK(VoGiV;b|O#9EX;$y#)2B_JWHxi^l=LoSkfsD1o;!Pi$U~ zl|F*tl6cf%bCsQSpoZK=rHqMXhU;Z1VnuWv!s7h#b6Y6|ZeJ5OdZILaLSFQ!d+B-D zXgnh)CF~)k&e;zqse_^$aUONmYob9#N;`AZNj9I^-iUfN2TqYycKzpNeMB{i6cFY4 z`>?1NJO2fi8f?L3Z6@QKaXBL<5PM>yYNDkXfct{6_nRlfqC~{>fqnEBz7)g&h}uFr zH3H?7+^yY10ZOxMl3RVHVgm!QEX^UMt`-eh9h;QVX?!0~!J}Ic-x7971Dxg{La_D{ zK8~iM=8*S*_7Y^ZnV-?mbI1h}o=|M+q z_fyH@mtltA+`mtShx{mQZycQHqMrX54AoHysNQC;z>QCsD6iEhum-qgyjHM#Z+UZ( zU55LwRl=zbAd21YL(>&+UdQK{@gok&tj2hD2=J1aFaOhMO)9s|h-=Wzf`T|%9dEa? z7D9K!G!Me;YP<-2j7vi^GNFTiV8cC$g#XZCQyQc=hu1COj1NC~V{7<&1M?%a@$t)e zjbr5)wX|b(wKfy&Cuph7N5(x~^|YL(=w;$Sc3$;_<@ciC_mY}^_U=&?!qF({-ImfN z04_&n(#IkFe6TkgcsR0T<<&LG#Rkw{j7ojo(_cPvte?kTeiFUpj#A)D^%lZ|91o)0 z{7D1-LY9(Y$fUwuCq!I6u6+p<;}E!GyTAwi%~6rJ&MtC1Cb%w4cnH@n_4OOyHIVhB z{EpFmMm0+~b-ZUyIF&1yA?cqDB>z121Kukq?+J{>4D7-7W!^D&uzk0W? zuKUagPq04CbwhBqGlXB(M=Jh%t1zF@ z5yCH>atwjz4F2cS%sJnf`wW09SpWKVP1xWP&O5j?7XQI*D$n7r%zXwoTiD^Qu_?HF z2>Ss)$K8D3+6yge@mi4Bz#jqyTFsn1A3R50WRC;0)Uyl7A5U0cv{JeP$qAnD7+a2$Fve`+;j3 z*?q<&OIYzHrZITR2_pMjS_sKMhV7bvEX8}`YcVsFGwVK+lr60I98(vZa|Gv|Vo{0z z0B14Nz`uWy2gDZ=O{Bz)k#qUu2^yavk#X3zd`4S`I752%Tcl|6S>{X`tc*kTa_lw+ z^AK!WjBYAi%Mt&;n?jgnA@He(UQ-a}oVRvj=uV67zSb8K=u0O!Q2!&5KU7m;*cm28 zl{j5WQz6*&jU$CzQxFq)s_8ybj~2lB6R4#*Jy;J1Owdd*@xo3)*Q_3J=19T2#-p<^ z=EelJX-*B?;m{qMoQ^nyq%>(V46^(>B%xF6zq6#9?!CjJ<1}o;0_tfJM1KQ0D+k{Q z=qiY`&LWBlzcY|(tQB;~LifARnL9RBlI_@u%qO!)w|P z-Feb^`G9=rk*3IN9$!`s-l@|8@_nxcoY|KI`<>xa3{1R0zrMui6o=msHFJV`_MLgq zfiQH61Bv&3JSjePd_RHcnmLh&&zjZ$ajofoXY>>clQu-4OD!KH(53FcSpX3TS;t2R z9I5O40mQ89L;^0?bwUBB>pHQ3xpkdjiP(l-)G0J6sl?f-CSK%As9~ z026LdpiM1a@S*nyf9m?9rn8^z;GG1W!|)vj9jB2OZc2;j-T!3OS(=_6e}ew_f%na- z``<`wz8R1vW~OHL|C67kuJ<1%DE@WOQ^{TxG!Q}M1%D!CF)?jg1;}ry{Ys#MpMF2W zx76N#9^pTcb^j@~|DqbnM3SKntutiZ^zmqT-bnJX=lJI6yg(a5z`}sSWze^<8Qo== zoUr#5cUP&m8KoC!%(ot1j+9=!Tu zzwxKM+6`>{u}7RDXRs0i=-0gRd^79NqWP=rhI=s2KEr6pKA&aI8O7p-v)g{BjFF@1X5G3l3S1rH|%ylm3!v zW(&yiuFkZ0z9+LH3thf!Ul>ZB8Vpx3K|yh;MWyS^nLV1RFO&|54_p<9dJ1! zsd~#aB>5Z3KD<_ks6alVTmelao67e}$_R?o-#5-3a#TWP+mSR`V6dvj4r)#mOJM7e zv^6IT(=~UO+zHB46P?h8?i04qfGJ*}-|~$23d}K{;{6xh=H+cI>D81Y{;gvnctB;O zU>M*5*+Q)V_33Jy&dXu6)FRGgiu5hz>pmw{cxfG@2o3HUsU%uJmTh>nTk?hRzq4ah zc8W15zu8of-|%p;{~vbD|G@YwIk>o*TY3I>LRHHDrH5CE%4HRW|G}WLpo$mmQ<{>8 zvLmGtr%{?Md)Bd##?+;(&xRrh_1G!c__YJtM~@hq=C(0248l&V!q?Hzu|07yQT=(p zyzKDf%2<5_D|povx8$2UEDJ>4XmX#xNR6ZCn?8th=s1#C+1#n7)Wv5GOD4vg1hm@8 zmd^W<(#VfsI{5u`I^l^cjsMlBM1avc`|ts{vy(Exa)A10wvNFsPTld9;n8a4Qfj0T zae-dZ=4Ms`Jl|m7Y~Baz8M!AwYGAq*VQGXvTFJw7OwmWP5lfA{KxL_?>g*wn^pcgh znyRD?Lx@Z`Sk|%H`K55Dy*=Y`jpx;lSOi~Y zNkNC!zjHXxjpI?_!WL;A!%9~-W)dV2poC4(>qnUC81Qd9yE^DMaJHMJle8QXyXdcE z77>$~10=oSfd4wi;Kl#}FzH5iA(jP{!bUCs79K5EPWp&!JBO%!)Gj0$oW^}?7w4>O z-!@9SOw|7_-9VJ{xCt-*HFGJ7p|zn8V*FRZ@g{5I7<-ca*{_2YHpJw^wRx@mPHlh} zq)M}3Jyai+ZQQ)Yw_k;nxbg=+{M{~fZCa+Oxa|DU$QbeR;6!@FxM9_uzK$X}|8!ur zv;1PF8GtX@+6PWwMpr@t8F=;d1r$K7VpNf+_?db_&kFq*9jtuK!e66wO~7UiGUh8W zFR;7fVd=AgKj6!S4&j)*R({3yjj2skGZ_^}9%CR`{XGLgaz`bGe9Azw`8xtpY(|zy zObt3eVc|ZsA(#2Ku4RJ=nl!N02rMFc(~4N63B!@J_pB8<$((hg{}QP}Vj+!#`!j#K z@Brj@V~%8Wt7yZ*oL-_Sj!P(En%D2!evgTRo}B}%Cm6En_@dbr5XzARW(v?VTMx78 zG43~+Hpz!~{%D!|U)qR2&*_3C1ASy47$K@q2$DMGAQrY#PR~W!K0{0s4_L<7#?Z<9 z|A#CG+YUrD<-4i#g!tcq;zXRyjBNhfV_5b7=->2z7@~!u{~!HZD#i{cUq*yZD)00^ z=-+df_N=^iJEbp-H{kza()d&!?pP1KA+PJB$o4t@hQ&?i_;~!6@Q@D!C4xCE$2P5h zx4WL+z|rb5&F&j^eB+nYF`jVb-Kcjwhp8fo_Y)cpN6IiFf8qG?l$_eLVei{_NFA0R zro>)Dts9npF)mY$)BAYkb}YZ@l)Q;jk|>hKPOS6oJ7jmzL32C7Qs`x33bKKV{;c;r zrmYr}Z9PjHHym@fQ#YTfZ}YzSV*)XpKoXa-yk(H0A8o{~)8$-jT%FSkHXxEK<+k3E zOc|aqToj1gI+o`VtXW1iAn|WQ;i(|4;_8lp6aR{1;Q2l{x={OuHQ; zW~VKXGKl+48EHkJIw?J6j^VTpPUw2A#WmCW6^jISwRa)sUTazj2807I=<8i^5bGX^ zR9zD0I#FNJO+Mi6sF2?(;S>07e%Ah%7Mbq~Z))Xg#YIn#^B`%MaGjQF(Qss?r#tdj9HD(@QTAkg&yGy^`I%$TC1%ru{W7cL>;MC!(uirOYziV@ZZXz$ScccxH^$|E) zNKE|+MU_I8&{81vr1kB$b$^wFwIL7LMEXn3jooA@dXoZGN|*H=SgD-Yy)F5j=x{I(8Gf3%dyCE3bJWF;S_0%?uM+G@B=w zd*L>!e_3d}w7d-kz#MS`2PCzc?<#(XkN)EtKyL2q(quL&D0Gqa#vNZc5q_csXBm!& znwJD4CV#q@ma_1Xlff##F@5q>e=AtBuZCT8T;h)_st7#yw24bR;zo!&p&$GD1`kvs z4{IEjT%R->-&GJe6_YY4wpr?8@qRojfhGFVXZ~5ViPoLJU?jxruaoK0uDP{xdPK-~ zCi6y#JCDK$kk9#;APWCn+@>140ZPR(%RU0GG`l(V`_P^XM)8# z!eW|AOV^9>gTR;gM9nYZ9WefLx;c#3L%Ffrvx;CFXJp~L{tA{5jr+tdTj*|rC z@jjV*&Dpc$@nvPY_i9F9r&e7X^HV8itE4sw(n<7EYB!pH`#OYU=4 zoJ~XTa#Gnd+H|YDq{CiPVnRc5R&5m-H{pyZ*=0=i;4NHlcnf}pa+zcE}~x?!SJl8D^d2MhTE$@);N zJcZ8!L6`zj`?-y+N}*dT=?A{jU)S47{;yxVsNWtLnLO|WtODxBf>QT-^=n_I|eoYqUMgaLjFPf-M>)~mjGzog9>0wd?DY7U_sCyAs7+ej-jrW=| zI=1(Ezt)a69W{DcL8&NlD2b{|&O^Ufn3TIIdzc9vrNQ0u#%&uNw?`ue%>$^FG_x!7 z!zYg(bTXwZEc)~|5>2E6*&dfLj-O)GYRu}1bUvnE;}Fn{m=kNbVJP_HLux=n&upuV z%Sn8!9UI6vR4HDvB z>tL@fT`)DAQ5rD;1Uq)vl`Uyf)>Usrxkz08vBR(i_He!Y@?wM}W-xr;j8@U0K)G!V z>|<8Vdt(v<1j93+?QWvI8=HM{fN8BVGO(Oaw4-`F{(6OnRn7W~{b8DQ7lQo%aQ0SV zac)7^U^lbgSV2JzyMmdEC&ww6nhh(B!pc&K&njFI7dl= z5~C<3BdtV&>~d!3*znoHy5mda-Iv-5X@8|ZZ@*HY`5l;PlliVA6)+vbjNmrfZx;Y8d(y^k=*fxC*v4+jV zAn7fr5)8@KvgE7UgU&Km87@b%ls}`Ul`gMl1xN{cHKInAx$(KUTyn8Ye~wx08FO*) zPl2$yUxlvgIeCXy5522biHy#Fjd73Ll0*CS!;E)u&~T^0&|5Ve0F;|$%*7V8MbPul z$HZNJ`HCDY6U7wIwjJ^}MJ67x!Fc7tP1kzc;Ns5UB4$|?TH-=`5BX8r?Q)H7{Mv)( z_$k0Jxry|e%p6&{opEaow_qtk-zrFEHBEoDTPWz z7#<^L*W8_4cE-lswbQ*{pXc~PHAm-M4>5m3+KUV*o|k48)O&uRWhJExmCsjFA)-T0Uy4}iU8Ed z&*S5x_rt4@4{K2S7DD{{)Z;6MdhnH>mo#ZVkHf=%UND!Yg}cW)#BIe5)s zo**4z7*ab{lkt(1K!3wc=_JInkXNp9))SUr8EeY!wR%eTH-)@U`0rzKf7_les~r+%ZpBU2?VB4U7&jueTB>f&@=KW=( z{=igtJfeF|#-OMsv7Ad2nA;ue7ME)hvy@<1CTis5st)7hJGHVu1WWSYCFC=ri++4qRx)PZ$w^_~Zs;)eY6Md^^V! z8qEDuFWDs4dZLBV$VF{q-~N}w&;6xa&Jazeb#n{f1S99lgG>GnRU*GJPAc8vCV9W} zsl*0J4Z!u__;r!L#b3#Y+|gw_?h{vGa?#X=`I96-z7CYe8SP=Uew z{f;mMPs3%r)a4ARtTZ^~FAxQOY9fbQ;A2cB()9<;5h&4K`p*XYe2bEEw=f(6Iw^T7 zE|_#TykLf>Ai`cXgd#g`+n;UmeBDcl1^w}PMamf9d!E-kIeV*HcNZ_^;wp<9E{ot3jpM>nHducArHzKLpdsaU@@9DB-$ zHm^72&`!{quw&X)zC+(*GI0#Y3H#qGskJbgiLqeH%BFhwY%J@i=l;*H=Q93pPfsY_eBaoZ zzo((jfhfLFMHT#A&}OR5{!c;c^fILUJF?*Me-*U0T-Z$}o9fU47%PhS!rVq*OnbYT zd(Lp1(O~ofNk6ZlO_!%oC484?&Zz2eZTvjy{DM+GvO2|BPgWt}r6voCub?Q9H8H># zxWh!)v+GvMEmCdVvstTC8I3g&*02>N%(sO$hAE$3kG^I1HFdCcj!hj$B;@><$I zgIh^R!!;Lw#=U)SGkTK(T`q$=#8Ie>-WN|5A?UF;1C+z!i1QWHCV2gthlC&8?{hkp zUXN@IH-S!cBdL{`8}%`{2Zk}NIZQe@o`G<-l%gFX0}Z8et0OG7H+`*eAma_9Yqr|V z2>;V8Nd4w1Z>;yzI$W&R;@7WMnhq{0b5qLq)FcbKzN15uz&IRlUWuXoHXBJ`*_DBt ztL&3e%e)3|+1W4e&%?hzE?oZpOySCl_(?P~fl$D^;;K%B8Anac>UvcEYtExTKcx@%O?9%m5BI7?rot;zh7zQrrPL>qf7_1< z+CM(UFt%RsN_?$G*m>r=>TLOwc*M^Qk**LOSi5jIt-4SCH2dhOS1E9oqJ3oEf!Nk< z&kraUlx{Inw0a1C_4d)86lPBK(Jy&G!a2F#(dCsNa?!v`eJmq8)Q=d=95Vg@YbWbi zx+BIS%?o@Pnuo$lw38VBtIxG=4K}g4fA6$87TfsjLfd$sd5Gl;I4zto$_JiMWQoP9 zeT_lzXc?>Mk#~#nJ+{$s7BGwX2{%?2#uxODYXPIV(E{7eLP0QSW0{lN4+0%Il0eNxS_APmG2Anr>50xhv{2 z;8v;FB^FuNzYK7$_!)QbA#sTSiOc^2d5V}C+qfAz{UiGp{%_aPqNYMzsfxe|5A_0u z)`*Bywct&POcnO}Enf{vQxa=>Sp9_3g?G;8Lfm>7L(A8+)lBy$VW?i`DNo}OSNBOx@S$Kona{;T4l8X`c zrHmvc5JUoMf!azXLY%d7Y&cx3Ty(+%S@l-%5cHa*WwS=>xTquM zs)sBmaW4s8haGW*r&7@?4`KM`~+Zs zIF_7I7Rmh8ejq7}$_oBlM|Z!DI#NzmCsvWRjM2wpjx5P7`U#d@)T(BAO$sK35$2OW z+B&JfGp@Y$&mhFUExni*vm=r~5|eLvo65fKpM_20>A@13%SNRwEwn1hRa)$c47`+0 zYRw7j+-XtGe`Vuw(1l72rSU4e=+B{pceRpN*E3z_iiQ=~*&qj&s8fc?@+Z4+ zGq_C}?6UdotS0y6x|YkR1?U71(cd;_oY;?(QuEL7g_9_?_g~~tzjNISlZ z-{V|o;D*lFEjB8=9g&x;%{-$nlEGWWT)P~aZu%M-u(y7njAYLcO#5a)oum25U(h4- z1&tB*51Mb#=x*_{HFG$fNvW;ZmUPF3z4x~B5d6am6o2~U0AkLnppQU*+uzoufpUvK zdcQ<4YclAkJw(LI6M6*F=bfWR`d!dWG^D~}Wvh4B%a?D_R!&>B5;*ex)gkrU8+QWG zwNZR%oSNq#K8+$JHWX@?0P!kidg(i~EF}`{|oO4H*Y+4 z1AO@KrugB*xBoA_ zCnnlG*{*MX^Hz0AiYU)zX8cxiaUcO&xL(V#+&GCYAUXwAfMX60){JWAFTp-j%gVWY zatba%6nfLh$N@zS*s>a1QQQ@tgTxlP%|0QS$Q%{r7LyV+Hax6_9Mq4wT)T~+fIp1` z7#$Dgd3hGA5;qImLNpLF0G#vnwE|w=R9Rjmzr)H;#i!Fh-7GWmQu^0_oCg4;+6Jeyg};B%g;=$z~^%5m<_Z$xp-JKe8DvzLRtH(#KQ7=hT|F}H`$Q) zxvfLd(<4~!@KcLliADJ4t7-)S58oij;iN9c_v~1`zS?uV@(rXn@j21xWc{heTN=LO zTM;;K|JG;}B^c1-3Sf&m6ilhjlg~NH)RI?NXJzAkGo4*b5ytH>V(}MVIQ}-bp>ltVmme zRvzz@S|83m%kp66e zINa>kzM@9u5XgU;jOmU0B|s*;@|r$nBG-tERNKePT7POHlo&!^f9t8J;&7E0*MDLg z`pawPj@tB0O0b2;0TMm76%7pm5VsWT&fBBuVMv&C^|iBJz)<< z#@MiE;L+QJ$2+zU2^^Dt->!|W%w%-RjjQ(A+Ety{H*nzy*x+i`jQ{Tea(kP zhZDMMD{je|DMqi$(T?2ZQuOm02>9DoFP|`U#+vWTb zZvrJ`(i_{oQqq-=!CeH-#1SCCJM{m)`ye+;>Bce*Rbhd9O%z&}rz`Usv?NERpR{Ju zpVF9^Qb7G@47RY{#vKiB`D`rMjMM~nF$hsu&BRK;ghFM>TYvXcbGhg_Ut|62dSV`Z zy_@&cMTY{GR{21qu(eoff63#7!;-#WRN3NkjH0FH?+)p#Zs(K(Q+Q2P({A2r(_d*l8Y_%uLr82nH5j-?w(*k#%Z-zohMZCPr@~!LTI^ADjg6s>TAX{f z`huKCw2kkm_AT_Ioq0Xmk7OaqwI}6fcD&DJ`C}8EJbYXm2fI!W?|F4hX7 z^iP%ba^S&ulPHuuriqg8z zaPMRyLkaWoYSFd_%y_yfsP(YWg@^5J)Fbdw4W~X|=*D&Brs znrN#Jv9vM!&01bj4h>KHQ4r}H9g3`g`rL8>3{FJSP!$&8vXvC;Cnam;q>I|9|>`ejV?rgHPf}_cZPu5SI^&8ZUXG~q3GV8(7uq>vaH#zs_4Fm?$hDMdu6Z8f(d_u^Zd;cP~ni6Vxw@T^VVt+1(fc=dHX0 zzA#mXd@0sCEhzClnXiiA9OkrYD9`(ZyjQx2yJ ziZhle#|sRYi>EmOe;?trnx`C!Vx4z~{Mc%ZW3-ou6n@rI3AE-A$1u>4)y6V_d|dYC zB^!mg$BRs++BK}CaD@awQaIXTo(!n;D+5_Lf~5inc~@f%dlxus75)XkkTxGJ8geWQ zi89im0_?_GgiMHb;ad6B%@p|cJdzmE9*PQB(cBAGEq`$-hwvVbt3;|*nxG~zR)pVu zKjN%_gXPPl4-}lFB&gS-(c;vg0?08h2(E4g9pfA^Js5cmxX=kgq#_VeD#{V z{*7^4j@`_$P=Lb|CsFSaWd$SpjosDq=Z;L9sbi;Hi&M8YQZ4JLV_L!B5gh?CA=Bmh zRyBx}g()mv*p#55Rq#u82ROu|QL#J|d%VV_rOaXmpMUz8Q}p^o*NZlzeIK=uSdr-F9nr|IWMZ8Jva#*&}qK zM|1gnd>E(?-^vWM7sEu^`0RsWYxt0|nP^D|Zi3qYHFEgyUYuIOgWX{^!reH1a4&Q% zxxnu58$oyMK1>%Kmc-zDSo^|Pzy|Tl2cD@5noaoW9uV+1cfO;^f zr6vyu542jg57ZB(E*V?JK{nH4*s1Km2q_-Et4wfGETLh#y{W zer%xz3W%T*ydgZ~-=uBD1_=ntoO2p8~h^Vcs!(moBP) z_$POoJuLKe32v~zXm4&5ode%=FV3g$QQo0Q6(6gJXJUA1nqZ+oE-vN3P z)P32F*e&}b^CQ(qE_gerRg7kA2kXto?$aNF&aA z;~#?`W1+J@d_(tOor2o`;oI%E`C$sW^22_BaQ8 zZulRlABo}kKl%V3xGy9(mAlPYdgtegq zF{zgL|KHD$i&>i5m>3!xn>suH15fxrxf{aLxG6%`iYg+aq6G}K5n+88M)U?5NkWI9 z2cG&w*6KCR726wmgB9uF$`*0^Hn+)Q+_5Cbg@PV$;}PjvJAbb zF{SxM%7j&tPzeDQT=Bf5dO7HLA)rFmkjb{D=&}fx8KBs%t(G3JfZod-qMX9np$IMEOPn2Jm5OKj%ilO={ zs5;qaKg{_pGfH7y-FTc0%|q0+$vZqXYg@G4srA#jh;x!Ur-qlbeYfjp{<=zTRYn_C z;=upLb4)WIYBRam=rH3VY87ZFbFvHDjq=oYq#%F-P-hnUqw19*_Jj2=D)dtnA2EZR zD@L7sj)LPSI-TNgtE)kZ+faL4uNSSvZw*XuDa7kH;I7O5*vGAFzlWwykEi;^3%p+V zB)ah3A>123E3j+C)CNgG*FCjZ=86^;ZCkWstQwe5X37r4jlrz-NoWOEe|ym z3wAjoA+10cNvlYrf+g!Ed`KEV?*Ap>A;MXAQC_M2d;B^aYWS+K%==-@CysdAcrdw1 z#A39YxN3{|l5Z7nWPE_sI`q?|$CB`vSKrNR?mOAd+rN;xKJrl}CDi0y7Ud?QTJ25>FVB#TAU@rAVme+E* zCuiIL0!shlth-!b#4&L|iiI2oAe692jDbMJKDSHs=aU= zsJ+~&v(suB=B2w|WUFzN(zLd%rmJBH!~BH=7!oW9^2ynn71gWRm=nphTHYQq1JWaF zR}dj38giCWm*zn)M%XZpsDbNmBjRkO5j3&YM7dgOG#SEw1v7(3{pzZa#}6gWKU3n1 z0)zp=A|`EyFNP`7IH(?pqi|fKP5}vXb*a26FEAyCo>rV%C?$Qzh zrGt3y8Z{+Le_Ut#24jI##$Xc3{uSNHAF*L4O0&HL(v~f`=vBp*A231kn#H@r*$2@i z3SWkqb>?JimP$?#rT4tyG%@{IxBW zN|a96qj^BxSS%r0 zJSU89I8m?=nqPtv58EXa_+`3^sz~5@NUi75w(JGqkld{ztMZRMWPfmB4x{VsK4pErg-2*Kwn1($Q$IUd0q5DO4)_ zfF1qB&mqjaxj5~iG%fI>9z$r^cSpZl8vWZBk3Dgc32r;AV%T9@^2x8x`(y5BZk_KB zFRlgbnk>sl$N$VN|8L`x(oRv9awz!1{P?j^1X)Rb*nb_})3zT$fn86NY z6hje!!cTL+BFC8lnk=(wt|D(%U-_Oz?=(_jx7(gF(C5EsgoNopdru(`T0? zI-CM1fh?JGQ{zxQ)W}XIm78^}+>mF0+z8J!71>uF^2JLX6@->Tc6$2Z!10CV&5z+#<|9Ml7i@=vn&eM4tVV{wtR^K%=Yfk>KAl)+ zd>1iJ?f#-=BkD%BuH#$~4_FK+Zx6?l&3yCw_eqqF4O{#3XeH_fQ&Gk@ymD3XLO&l0 z;IVLNU+B`V(xLndYo3HNF!UR~BSS?Fy!5^nCE#^Sz?{F(P_6|h!b+pf9#p1s{Sc|L zgA7K&?)wO5Pah=;dn`pigQ)B<^@hsfCPt2nk5Qr1#|GhC)GJ%O%K2QUPkv2Cr>1bp z!JrH@tA7pstd}RqW#5I7=IdF{IgG4OKSTjTZ+#K}L@8(At2(8S5FVQKH(m;dL@ zvGmOxiT>Xda?$_LjHnqpSsEJI{JVbA{hM^aH>)N!DpaF7_Y|IY2dybeK9CSmN@7Vr z)xCUgn4S~>VUf4}n?=qLj~Y(Exzyrrc9!M6znb}Y`@G`*0a-(abl@-EvI^wLwrqCY zp5&H%cSsYm)ymVvCw(;Tu)I5hO&bkUNzRf7q0NGt&|@d-n-hFSF*pYA`Z@=hmvOSU zP7pH<8x^W>3HY}+E&K)5`BoAMbG@YyAgot1Tf2&{D|rcG_{NeJ_ya6G3ei#pr6!@} zLB>R6(laS~$s~HzjW61AR?QLg=701ZMrPL{O&Y8VSZ9J1c}0y;kNXp&GG z6fTEE!}jwkls%IN;Lnv(EtQC9-Sq>=IJB{|vw=>giWT(Dj>=ISth;JV{o2M2RV1i4 z4qA>8i*apnf z!qM*4oOa<>FnVz|gQ4`Cw$2Z}G9?JXPsl7fR5EAOFIcf$np|L7BE~W0M8W~jNj7|H z74F|B+oVrM$ycJNzm$#5^e%5F2rS?3q z6=_K{ntb#G*0zJ`DC|Q*sA2rY@1mRII}}Uwo`^`=-y;&3+l7w*MX;gr*(3IVypjwM4xP|{ zxbNx~mjAl!6_82>QylAUz^%5XqeTc>7V*BZv%m&<%W45O3fc}O8iVeee2QYN!MRr5 z4)r6=EAGX|z)&Q;XYGhGBt+G`GB2|ZjZS(5s>Q3Ux;p31>(lh}v8UK~y_Zi0cwN9S z7LDxHT9KgVks9Bg!VcSp<{i%9bL~}C6w3-wYPrsnP*GfWT7V-a93?P<43yK+b;>TX zy3c%DBn(q+rHPskVDPPI}{pmZU*RDOKEvBKT2&q06;v`JvI`c#o>G>Y9HBiz* z*Tx{J9&-SKxdEq9LP~jNQI+4ze5(=Z%fg-D3OM(sU#x|f$i$?JJ?G(+foy<6Ma16} z#m7Tvech}4NII5{b9(oWpLUR;uPI|T5BZTA_aQoT&quZQ z@fNxKvoCB|E`)D>*$`ka;}Z!GJ_F-_`tWBrgdUF)+Rk+3;`=dUbHbwpvPA&wRV+k; z;r1@qpqBfRE^kK$5=o~AyNo;bcept#5Akfwxn`7ma@yNC93B2~V9jkL%yIFp#$fHU zDz9hATZsWA$K3=hYm!x=*XHv0_Bl8cSHH@ZAk(=>v*>J~4rbetmo!(n;f>_v@|9q= z*hZ$zwDZ?)1SLfNj;XoUi<8bbU>Um~HL1GQqdgGsrrG~0&j03}MkP%)Y`2mMwa89$wz>Z{ z@74GOepZlZ%GPs<2N~^~tH}#0)?m!<*J$(#ZQaQu>w09+cxt9nP?Ef+N zaiR=O&|BRh`HW3RIN;3kmswatoPS9F26M81c>k(%R@jzf_6c6C3m3XU@r~47%p1(h zN>JBSzy5c00m$l>QN76*k#*OrqnZN;vM*kVetX?*AxKM~2dH5?isB2Hz_$3s!|Nox z(v4Dg%u6}(FU0@MV}wvoq0f*!whw^;{tGwuZ%yJqYM=j$ox?z1kNi6i;Wi@gF7MYp zvUXXKm5>s8?iK&9L^s#Al`%VlN18We-|7FM=ENvs`Z8y0rW6^lsAY_erH?*Na2@dS zzP|hci+@;fP#2EM-5qWv`FsZ7xQEPG0h-=!{DZK;)l9%WqY+ay3W??kHGK9e54$gV zaFXQA1%?`-Aapoqgb!SUjRT)s*;HNdn zrY&F%YXC?#WrRpo+P`ZBZ!J4jX|2-gl#DRCVSN4o(w79atdL8dl+phFdxF{tuO%v(?}=WXac$y`S95IS>K%>seZtzX8H?%1U$H|4^<8vHz+B1- z!-pNNgK^83XU84K2B7sc_Bne5fVpGL(=~fr47cX@vN*%brZD@!jv`CI*W=Lnlsj0@ z+S>|a>c1q&h65wf`;rli3gWV#g>=Z1KfF3S)^KNqkE# zbR(*H$y0dNF!8(e|N@*DRt>i(6J`4N;_y98PHiA^<$8_tHuDON?K*wWxAqW~=k ze^o1EnK0@N?w^r$EO8mc0?C+%knaD#REUC3=B~D;cK?d56m3X_2n229E@HQeehQ2@ zz`XnM3;ugSLzqY+rE0j!S@Ea>PUEaut1X0-GyYn_=&Xt> zCCmgi8WLO}vR}ZO|5c__CM9me`x+)R>!2e}{Dg^QMG<`l(E$K$y47y6m^U9M zi^b`gNWhtDY8*awE5onpaQ)D|Uk~Az*3kA|q{EAuvmXLbdn0Hsq%5Q10VvRbmg+Dn z6ieEgb*(}{fFTk_} zOsi-}@b=%TW!4?sle1M9M7YoauX(1npuupH!&0};D1mp3iu@oe)Fl zCzi_=(wybmDfCs`tGR_no^X84G*?ctHf$mol2%bpvsfH~0xy}^pLk2#DC+k+Cn>?z zz=37=dsSQi(DUF;li7YFN{Bji-^Pw_ui?W?lTk8-JATB7d|m&e+))d&GwK!jQL0>z zR70-JWuFsfbp82mQf6ohA5)>ix+wing)m_!RhRqf@g=AHG{eRjl1@=qykK(Rh#K{EHC9mlXUMk@c-bMp9mt)1HRE=x(Z-n?Dke?e8oxy$&TBpOVMhEZwo1iye`KzjHJR^oGy>VZEP&<-0ZFY*|$}w{ja`F zSUS~?E{U`xEFwZe+XNdbUM)B&jeU!*w&x&MW~A3m+r0@T?eP6V;Nb@ozAy6wgfG6n z#8|j#WKk`9zy8R5klk{BR?y|={|;q6Ix{W(U*G}nZBgo>qEmb$SXf5Gr!qS3;+CJi(Dpk%WOQ)*c*LPc{8jM~iW&8W)w1s*Wed1ZNz!3mA1cFy&;#FN<4N zVeV$0HRI$&8FZj?1H3j94Wa;8Z|3$^CDVcH>?S&8BTFjMqzjF1qSNC8%)#17c7u-a zV8GG!=vmG2?xPo8CA-QQaKDj(!2B*t#nU03rpoxE2(t@g#Zd@Fgn--DgfYUwuu^Rb ziuAAFBig;cA5$dRhWDi6Gc#8?cNcR2ZM-0G+&ikLN!ZoSCo_#J4*h-DFC%D$KQL-q zx0WQ5mE}s&nO6N&P~{5^lR0(HX2LZCNY1)sVXd`Kl;di!WW_vcsLMn;FRCJbGI%)b zB|SOvMm2%^nH^ds;OBRQWE*=DM-RQ+^s;|W=&WjQspgQk8Ya=7{kFMMcY0dgm^oPa z+D1$zDi7zHuT&SgolF9K`?K;SI7--(Nh77YV^m5Z@&<0TIlPYVN1F>W7glJUL}A5rD}%TQ#0lY&=Ah2J182<2gpk(QFt1HT09WH9 z)(pWQS*%(Q4Eyr<1yJ5ctA%tyDEv*{9IL}x5zC4;qfdF6BG)nP&v)o0tgjO9Fh$|MMR;JxX z@(|>d)Jtm|CzH|#rH1```h>pgEK&(6J4yfJ^hwsx!P3t1U%4^KR(@6iYw+DYGszX! z1#|8(>_;VmQh&fNG&g zuY=Xlw~3Z_XRr5{*GJ^<==RusK>p@hON31CPE)TyY3B_K=h2#w1H9EsTT2^puq`7W z$pM$=iWB|DcH^z+P}!e{?J4#6ZWLH!e5@!ol}dzY3qYdmmjCf$o`B-S{3nl80#5e~ zvE(5=OW`V5L$7wb={Ul{CavB>lF1HTrCid&@3YJS!*nK13>7%3;;$wHBZ9TqAP+fv z81b&sEu0y^PSFa#R;pcOZbrE-lZ>Q2b@O;N4{4F1XUh2q7HitH1H3z4y&W^I<(L97 zUqjDR(v5TfL$mi6nXV)uoO|qVQx|Blz$;Y!a2*J9feUC+@uSvU(7%ZsJw{A` z3jg>vRaj0S;Vd(#_~tWmN`iA5nf@PJ@Hd>Hgk}lxFr?F%c-8BT_%U2L=G)Vch9u-; zH*TWA-QJ*s`iZz8IcunL?3&t;jUgY1>K7~h1yyFyLFbEiEPVx~P$T|{%zm8Q@xj9q zzd+2;29 z2Fm<%^q}G+6{oJKQ4jnD$q%%bkJ~Y}qV?r}EzgXt@*ZS)Pd0SDJwm2L{6uXf%rN2E zFr@pX@rty~F>*n8skAtj_ztE%tb1}^4ikXL;KrqWrRXahe! zQAYNEQ54If2Av@v$o^w zR-8aZI}S7`%yo~%;Q5s955t#Iih~G_K_P&35nv?Jd^q>0x%9B$a~X=;Kmj(MlFes| z^q4*ct#@8rh_dhcYcY{fVK9+GgUXak25!Rzn)Xe@sWNn(KS9L`R!GSVa`W2y`p0=^ z9<^#=>mav>jm?J*$DiA3P+*jkeO5-hZJhAMS=&_-cChYAa_yvLlly$d@8ZG&W97G4 zoe8>1>8~r(Vv;CQRvm5KPmdH=lm0`u6fNQ26fN?H5u)zi$R4R{FG6eYKj}_zAd3&+ z?~nSZpT8W`TNtGDTi5_%tKV?{*=Lk>Su;RGuFWarDV6;X$eggDgNv(^rJcFi|H~b! zfb4dFOfo>84^vLV0|8_8l(E>o|-2%w>3U~6w9zWuw0?b$QX<~wkgPCcC z<_pFvzM6}ok%eb-dvWLpMdVJEJ*1OmtXx9?>j09n;#8l2RE`_tA21nmzTRSAIY4=O zor~-(H%gz?ft1>P^pfgcF~_}MK|wXuiIz1O!O(NUL-q+nWvHb%f+9&aN1xby_&iQf?Q~9M@+SOogwd`vBj22|IFUE@{G_%bU0+x-kfb(F*a`!g$ug zsK?p~NTIsHwPloJFhMcxGQNOLSh5F>`3%e>xYf?-6{lnme01xblo5-U8u)Y(diN;o z5h0l;u%do`FQa&qW#o0B(p=4SI0mao#8fJ)h?QUekw=mjOy~0UubIBNqNPR&B-(-? zIJm%nh&IW8zR?g6{BI@s+i%DGMKvRbZdhf6xDTBLB?^E2&~DHwvv#Ro>gt@!xMAOFCXTo9s*Vkv_4`+tb!ht;w z9ne85MNA=k&a-u&qC06mXFhit^32>tojSDIdhy@SNNgjcT=THgGk=S~>-_Dv=0G?c zO9AeMO4Yq*a0mX5JasG0uLcQ<-vjJ7C8l>kH{4vUtA7v&>$%p{+sjDCFX+z(#&UWHpD-;q`h5%kq&hjyeA0`QFJazDJ%X9SF1$A<%?f$<>qIyLFE8cBhphueTjup1K0)EUq;b_ zyh_%m3jpoQ@aVp$npVM%rn?OXX*IUyaBchu9w}tbBcKF3?vd7~&6cW6e7os zYn97gm-7^D1}DvtLIV(6msPIK%$p>2&4!Hw--w^WwHE5>*Nch#p1zjK(s5`xfwPr( z^kReh<8rVT+up?E*P;WI%U#+8$8p^YEj!kjpGk(qDxN)3?D*t5N!-HE3Kn$TH#OTS zupX{VqV3Clfj5miQ&45N%*B+F(Y|XF6D7&~Y>8BIa%|!u);C(?!mmmOB?dpw^k+{P z_bp)PlP2jWej1$dMPoM0-g`D=Yk&leeGh}|9YX1`IcfDGBLr~q-WgsMfdd<;J8XM8 z5!-CUaT%bYSV0ppwEKK&dJ)BDG|4TfPBJEJe~6%_DA{=lGwbIkrl=5W!v}Epf#Qd2 z?t;r;3vy7p2@`C(NpUVCyuxFyHbSA8>fGU1@V(+!(|jkb@UbJ(%HT`aE48+Q(XMTu z7NzBG(`#3)Eb(rO*;rE4`sCV0h@0cn8t*$-*sK z?xkypGS+Z{^nqKr7oSmt-VOWoD%dUO@>uq=kgcD|bOm7ZIrZW?6cJyJ!>;1UjL=68^6re5`{bhs{aw%`&-re|0K^PL&$UAA?=H_rP3E28*FU*ze+kj zT>4py)*Q>2myxQN`RMe@X(CusExBFfKM?v%;S%~f+{~lyd2pgMOl?oGunpUB9=uH2 zPkxp3dwshj>}L4J%F=DH@KVO0LqvT96Zkw)1lb$rEQ+?cs$6N$B;GW-iW)2sCDxl+87U3^J!OCbODWEIQe)*S>;^cVnuPnSym8 z8?0}dpKBXQuJBD3dlBeCxqQ(-NRla|8P<2*ge4akN599P0taMeG`Kzy(9gV5XATEZm_aQg_ zk*Lv*vR5l#X>MA9K$8K)=>0uFV;yck=9&OdPi=5 z7yy5@>-vdp&5GN7xT2XEV%AH^_E=if#PtiQYO7D6U-*1h>8OAFY~iS2D|H-O_%26! zEBZJ*q7?6tcvPvEZ>N*28e0yM7ev;D3&}sTk1udK%I`u0$joSxwkIP@mN=Iob6mx* zq*~E-nAvK3&8zlfpLXZDOKT^!qtuL|Nt?UCoN?#L^~S!dUIwAewq2PySN+_7nl?&X z)i*6uP&p#-J;ZWKmP$K@tf;Pg4O}3L#|;??vRm!+B14;jU~HQ;`UbmCwRYxh!D4PQ%4VAl^vTQK)q^13ou_^{n06_QR2~bOJ!7da zoe0g2nr(?S+~kHn^sCnd^Tt36(N@|LVm^HALXWZA1LN3|jkmFSogcIbR0{G?B= z)m3w>TAgy@3xp4o(37Zw9z=BdTP?4UCCE+QP}k-yCpJdBbGGl*&2K$uxI&R zj+~$HvOfqh>G18+O=Uq<(}1;GL5sD6MtYfW#NrL9vkr_vL_IEP9k|y4Dj?1 zjccZ&9?Kv1xzE2`_et5ixEeu$whsTFNBfUV;~63>GcKG@<9rDz_!;<_jAV9<5+{Lb z7t89xOH*9)+Zktr&Ktp@L7+*&)UUu9grJ&dn(gIN?R;$Gc&ZMl`tGYow@Y_J;`8I} zDc?tyuOZWeV2e>XHQ<`N>jbW@wT^Z8aS5rd&Tff`q}xz#wWAdZ4||VB0{a{zn@u{D zWJ_i#E`ulpN7|_W3T&~0#>HXO_474|mowzL-Zrd){Oy#(wO%#;+L~$utbM6Vcqc*m zn>N0ZvHHUUv3zyK*lhVw3?oH?qFwW18cPWT5&9WgO}>6pV9fp`@`)trd|;f|`p$4d z6Df@&^?+>QttWJ*S!NEm_5v9rw>yQ9rp?H$r<)@VzO`W*Ac9+(mH}{7HujKIkqrpH zfBBwJ^45m*hE0||tg&RZ-DH&WX0tsI3JSznck>J2F!x;G?o(k*kbid^x_fJv&vVGR zHf)IKfxR|_A#!CK|9<|BmVg1oJ=V-!hKsX^{@V2MUG)0K)lHR1ASqeJf@xYTHIoo3 zWRGE}(0I>Hg&{feSQz(LyHJki#%ycdaPirspG8AM@hV_hri^VjQAeBcE2G(dDqdOH zWq`fE^%!bTV)z)`k>WKWhT#X7pG*nrT@mnYCE-|lj1BuzdaJazl<23=hlQKswLowA z3W?Esv$v_Fm@=CqtCW^2a3w%De?ksN5o(nT z9CdjepV}1`eFmck@^)lZB+u({=cDyXRY?r8I|Q{0`QQ(8OdJCk**6CKyan@?x!>gU zFoH}ziNMD6qFJs4b9V)uDPJ&RnbIfQNs@_?hX;oW43?qKWSqPs32R=tK99+EsLCP! zSB4FKD8K*;@?KY@aY$&w&DZG%8^vnBL;FL&QQA~Z70%J?wIBKc z&|~XJDxuN6G-3m-ss!&E^tL3b6&lkBKhO(H1*#}?ulu8q8kiFprk{=XPbSS_ZVZ&j z;&em>Sx-B6gjSB7g6FSpE0byQwDGIi7-A9U5^`?zlErb^;GwI9pbd0m(o{h73;|!I zaGT=yZ9n^!HLFbG=DXnC)VVL4F^~@UvrPe!%kTBUALXtJm_Sth8`d4O8%m#Q9j;Q# zRt}cQRBr;QfW!Fb8$Az_x7RQHAV4_27Nor0bx^#ffl)QlVHJCHUN3T$vD&mYHV`R5 z!<$`5qc9GB72Ni)y)UH29jkD2Qq1kIeu{H>yDEpmt@9`KUt6 zk-1BkFK7FEZN*@J9g(7mauw~)C*tu|`ug;Hm4<}Z&ocQ>>fUV4YdQ6U6#!(j&{2KF zBQVe=hFmpT^a@tW0T7Tt6^hfx;D_q^*Ea75X;nj`4&d%XJ$Dz8p!j3hBamo@muOH0 zpD57*;0z9>HVsEMEqG8Hi-})|gzBVHVpwi}zY}H^O#_*VA%22#_YSg1W8Y-MX=WqR zYutyQP|K$HljuA~5U{*U{<1+OQyPw;gU+gAWvV<3dR(LRM-xjz^m}fELN>EHLtZ0* z(u@k34_;Vra4#clA)TKz;ICguicNI8?qS)I$IBAm}zm>R-%qR$Qycm9=Rvs4o1Fa(pGg<})!d$Lf0)|fWEx>W1f@;{xb^fPgRyn~XA;_yoXEH4 zez}pjv67zkompJg7)1C2pe#uQDMUJV&&5q3f1c@JV#b!fV>(hhuf6v^xtO$Ng1BrJ^()+a6 zk*{;s>{K6KsxM*a2fzdxhLxRLqdMn4?6Z(&B1=JL+U+Bv?R|74lN|_L6Rw;coXb0W zUcg%?hnxc|0kjmTbBo%^q^dqLiY{oNjWyRmOJ(Roffjv|d5rAUgx&`i{d2ON{X06I z$e#0M46g;8?n#hEQ&~kZYh5(^yK2JE*D(rMHV2G}e0oxzerkSC76-fj&Ua5cR%T&b zpR4CZ)jSA`nelx3ZU^GZ(o5oStP>b5fwP|kt9N#X4O5;$POVd~fY7r3Qv#xC7+_W4 zI79(Mfa+a8j5fmh^$si%mVDNcAzG{?>wC0%1GM@n*cCyf`tQi~xqwDup|KX`ME5Y$ z&I?eT@Fi?vZZ%le3y`kDnA<1DvvZgupn-ijxoiEPyS#;7BuJ+97~{H$LM6=2l+Y=c zU{6luv9=&9PoA9B)|<<}KV?j$5bn46-uq6J^d<_to7L~aJT2yJ;Ax4(ELDOiCTRy^ zaqhoBuKWJ?vPklnO^Sz>g*o&o_%|{mRcE)qpInRow;Vw0W09E!lN#7=%#t|qG(jPM z-Fk%A?_}CQcptsG|8-07k>_h^ zydhY3fi-x7-#|O($Jh!7uP$%%#rq(>?y9J0%Z|QeYE^hzT`3bu3H$-TLfTTP>;jJ4 z(&f;nDexLr_u&~zs8M@syS6o~<&#YpkBA$gL379^Jt;t?tl71->+CGd8XjaiH|-W> zn3Rv3ItWRyt434s0x(KT+;c!o>*fL7j=CdiJ7Iad?r0iGtL9~R1gZ2Yj2v^V!(igK zCA9p99dwcJsa)53<>0IE2H((vHb(Z{N)Q&5O=9m_ja*92I#)N|rWi~Vd|b6!n{mRs z1C9kaNQYS@;5nHBk(T6TJujl1bE*YW!6);cWR-Ccz*y87XDs07NB{KvdYVNIYy!PyOZAUmaes=X+^|B@O_D}1Ag!G z+!EXyHi>{tu{G4O@$bn5KZQ1;!8x6x62;ftxqw4POr?-^3LZGdCK_aPoW)<7n>idGg!D_>d+6qGl!tjK-_-kuudV@)k5@RoZ*q=- z#$f&)d*slTH&!jMcc*p@qs7Nz>f<~1KYs0LH|lNs%lx9XY%LFp^R888R%Y_`qeTp)^>Pp{p|15(h&&s!i1gxnVah<_<8-`q zcy+q1N5)ZLk>`>HjEL{!3?w14&D=t`O<&qe0ov&dBJE^)b+h)i$UVbcgb}86 zITP8aXEIH(f!ei&$d)=kDz>)B_v=S9knuf(30fEkdJo$-!zzYdE>ptv#-KS8X6xe9g6Tx^Z7Id=;6E%bq(3x>HmtO~zk z9E*)#xDF{-kR4(>CNM2$r$YH2?;knS&sB7t>*R%q09UUu3ZZ+X`i%)Xr4h|OF#jnj zPZs+of9fY)MHm?up1K7njkJsU#t+~7+7tIpgW>@kMZiA>a#$eF+MipM0CXT%_!r#~ zv?5$wo!v~JT&n+LkEHe={{*h|YH?Bl+!1xe3c4u{X8fXXAiEWm!rv#+z#yXa-^o1S z6EpBXDx7sDSZPxG+R?9TzgwXyoc+n4ce%uZuVqb0qh1Yk(jKuc;fyb;M$!wf$7e>E zAFS1z4%NDm)_BjUiD~La_3T&J6LbD9u=@7c8$%YH1NNp2o*7ZRM3DfeFltxWMVzMO zBX^&^W*a?0N#DB9J+hUT&Ept~?Bm=)i)u z76TXE4enYNkf~=aeJ!StleU##t!?9K9T)>5Q6ZO-{U%XtJJq;f#cJYrFD(un8a8Hb z7&j#aGTX!*N+)%zI^sz5nmeht4-#(uc4H7EKIV%>41pCF0Nu0Jw$4f_oNn4u>T+r` zT-fcC|ryR-tZ9>S5#f0A;(FF z*v%cnn@=js)Q^TNMNCv#s#ggDyD+6`H4Dg;!p8ZdLX)?lN&*x}PWX zO7yQ>JecKEydeke%UE>GHu8DU4EP+^EwCicz>of?NoTsePcg!#z^=1xKP7O~Oeo#! z{UsO(6vh9-m@DV=*HW%fG!sRqD&i1QOW%jIcpPuR+UwNGw|Kn6<&%80p^-$0I+48`p`Jc{)It zfIjSnM^;L|RIczQBUMI4#=IsZik)>b${M5eFg59JySmm~6g+bI3VU9DZ!5eKJNe_+ z=zd=pJPxz_?bDB0fu@zUOI=J@+`AGxFrT9L;K> zynXi_#R*^v982tHr}WSzeaP&DC;%8TT4NNLKU84SK%+A}D+1WrGGq43SO-)&J<8CX zMhEv>g<7m0PM6dUTYweI_r+|<&Y|$#hMKt;hto*!cE_<(E|bG+oDxZ$N=6!Qfc`mI zD<92e+Ft9O5O!fV(-k|Sw4koBIN@nQ9v{TkhHMh>oK4e?Su3-6&+6vQF2E0;@Tc*Q zj|2l@^(5SCgq9m#IwF8uIQ4+T_U-U>`D4j1RD#Y{6e@RiXGG422mahZjZ*pEi(kt7 zBN&zEiRv)}#-?S#QOrtX_)X12V7=wa^HWv|v7QuQGxJA5^+;ZkAWwn{4Sm2A^D92x z%=<}OH+kv{%!rVqgwT5JSY!In$><#%OW=4T;b?wAD@cCL5mAdRTe zE3$>qUrZ6gEMtxX?cKF2zcuCEGvV{iHI;C9CrfCkXbswP-c|&aCyqQ;8)@p zGvYk=UoodKcMdo|d-#F|GT$sae3`ZFjLe>=H;Ii4w*&lOzP(HhTYf7XuwqdokrRKH z<-6hzpUgDFcyH&?MdweFIl^9S_zM&1o^`%VF7YY+TmCz=5Vq$Fb7W(9};pi*Q(TGD~C+nUhNq*0CiCeBX?fj3C03N#I$?KP1*G zn!ac($t+1p#C|;9Uvp)aD$a_MGq6s1CNmcc|JGX#-gNQ%Bv|A#tAy28`!;EyI6mPx z+uHK**@HABk1s{;HF#|ezNW(+F`2?oSc%`Z4fzYca#JTqxpicQjWoCtTvT9C7NLzf z1>9PGhf3A99R}eP4v4SQKew|bt86;^dMKm`cq`}=7=``Y*c|EyQLMtXnAotInq2YQ z2qPJYtS@P`zn||msL(%772x}_QRwFEN_o!UE%zPsdX}N_VgJr^__K&r4Grbv#VZWc zT33atY02+etQ-3@{jMEvBo2JP!Ccq%I=-Pk^p5bx!z{%GXG{%lJJfFTZ`G6$h@@1H zUMy1Y9AsDvLf#`|A4YGw2B(E%i2T-zMPgaudvRHM%%6N@t9_s>TE&{}3Jc&&a>U)g z$K19X^km-pj*98pEgFVQx<$qRyT7mH+fzH6UohDPu~Bz$*ud!sS+Lc_58tq+1L83; z?+p33x-qqL*b`lvTV}C&HF|-@ghEiambbZic7c{x#l`DHX0Wl&niAScm3O6{cmsm}5C^(Q8o5vD{s>DysgbAr^n@t=V3{(=NbM7Mt4*mngEhN z=rt_JTb4feN4qg!hPBI(GD>(t0f@KdG}xHCJ(>IbY2rf5o&`468nOofpTw92+lE-} zDfZJ5#HjCts|wYL6GqYxnM!a*Vf15>u^y4K-Bj7weW9U&jJYUiCePQKISm+nQ(iqv zlVnJ3WwJ+)C}RMoe=T@$#<$o|^& zg(RtL^rOk?&toz%<_Y(xUS~zo%FE@3leIP+KI2&AQQ~GNz48!vW$+OVuGQ$J7QDe{ za=qB~Z{$WbQGS7D54`ulHyIc)c`!~$*{to;6SWN`no11|qAQNA9EAq}w>@kTh7|dl zty_~5sZCAcVgGk|86+bkh!zm?%A~FBdO~`e5B)-KY@<~zWYsXaBaOZE#fj0_Y}?Pm zzP6!xz^OKh-KEL)@eUmByP}QZR%vj5o?# zyGv>80e?O->y2VeDx=lhA_h#30*A)|q$8g@DL)%?n3A=A#6&7&9d?Y*Ka_%xkQC*W zOurqOC8X^OkQz2qiV(^s@G8aV$AOr-e(o(S$)6IV?a^i$vs0tJESqph=HbBPs{kpj zs#(1)cAa7J)^S0`d8C5%Un(meRIV(3mZS(@xvk_+X(F~E{O=AELy z&r4>;D_2lswuI%%i^x*;-r^w9b7xhr{kpmpsPY}Vn4OY5_KirFw8z&?dvD-`_eUP@@#LKf9E7=&!_$V`hc5hSgc z?dPB)$*YDmn6>pv&*=HcY{&e`btGzESLyGlIfoQon7XK!zsR(MH*-m!6gfana1S&& z1J$6m{*!bgPeKP(>^ibGoPvg-Nw~)BLbHbtON-SH--a$wjPGVtLj7N0ZekKY!F!`I zZb=6Gc%85v$-U_7`INkPnu zDUXfN(Ti+)mzm_Z-k+4bg^Bo2XBs7@Ja0ZrNW8y40KJ{(I?t`?-+)FxPj`Tq%SR}8 z@(d$BYF%~z@FLEen_9E(+*U6>cbJ!<;U6?>KmN5A{Sx`|kLSf*Pu1p+1^C}G`u|vf zO&$K>#ZZIlh7~dRQ9z(vF3uE z!gZOXI)xUT;7ozqrUXElOscQ;i#qwmLI7%=3QSihEtfnF>k>Ndz~FLQXHE8`c|LlU zZM*K|j_9dsgMV%Q!kf5!yFzO#{dLj+avlA{lAPnxpCk$iIYr;?I?fI{4Z}n)8|Jd` zyvk0+#`2Lft z?D*@od<)G^W#?8I|Hd}dhE|Cbdy)4CkT7;qvTO_+e$oSVRFVi-()eVR!*XWe^E_{L zT*wu&k=c4^n!P;=NpR|i+0f*8;SBdg-wW_Z9QDpb@ex6HFkK@{f_Bti{w$NzO&mk< zu<1R*7BM(MK$uB=yNi-*}<-o#% zkd`=FPqoIr0a`Ml zihL_cLyB-ELa8X0By#=SN~dugH7FwH(+GGGSAT99k8{A+-i^cHZWI3QUIucsoO6OW zpdt*E%jcclTWoJ2m&Rw0qRu}~gD&hT=_2JQ`E&_$u7Hd(I^Ixo6VvxAVkhkpj-v3q zLsxX0u|u$`%O45Eu8x$hg=P#?0#SYQjw1$O?z%R}2w!zR@`e%AT=14}HAK0)d*orQ zwsoD86Dol?OdgIO%BDCwY7Kn=gaouuzOqfgt2a$UY*q6pZYq2n?jF^fU8u^T42;qL z5NK5NvwGv#hg+AwBoK6eBoK{5-v1+k(7~2kB23g_tS;(74?=R#XopH55}^`^8#JJL zH7^-^1T?rJ)!ccPb$xQ&zs`U3SxRN^54r*%=4tz4=)Z}E5_ zw`g=T#xSKD9{YX}*4OK|JqCWt2$>H)<52 zIiu>o0#)-pqspiDF)Cj7e9Be z{^Zo+m4p43k(*vYntksHFX$7IEB0DUI9Jf@Tp}m21w2iHN=|Yg_{3R z1xr~qc#}gp;2#gl+f#QGP1skjx>5g~BSqfK9jq$FL4!aHdpP%X z2I{h$OwdO~>lYzCtdr(%>UPF-qGdB5Xhmzied~fToAumXI0;~T!oL@E_Z2d~Kh+UT z8sWIa9Y#RX%1^_ue1+8(~bgPv+%~hTdsLeUs z>Q{nFwpVlNn3$L3YKFUDA&x>qvO$5|1Bn8qQ=cz$ZMqLnGKijh_MH0MeEoOW2Jc!8 z+zp&Vjr5su_oV~ZKD^uD>TKWEL0G%spNwX`Lt_|eTw2r1!3o5|SG5ET$caZAsZtN4 zTu-wfb(;}TR_Efms^yA^5H?Sw(bC0TR}D7lU}Q(G)Ib-YcqR$YHa zy{S?ecSphuzGIIv%GxyM`$W2gdSE6YVl-~Mvh@J??cdURw)m*Gl!^hTVqyAdN*F>U zw_Op44o!2uW!o7okVG4=^Br%jGHAtXe>)z&@qQprpoP-66KXXyr};!@f9pBqf)14S zKFnGipR}WGow%q~*ho=p@Lf`2LD3s{Hw!QcEvR980r{U8*v67s?`g$xD|qN%MC7Wm z#KvN;%^3b*5^48PgF9huDsqRI=C#&3EO+FTjVs)?U>8gF=aG<$P7i47Y?LhAs-$uZ zD1IWt(HwRDrTt_W>SN|IQj()OT9x)QF?k7tdzP|Rwi{H zqLVh%MqGDnwS8g^m-v~GTUR{60z=bZ4ubgUwL zxUiSoNKaKOqD4ZDq|S-g{f*5iVX!y85w9 z$G$uFN&4qIKa~mFcDI^-4Tjgmb{_XJnotuBFIpSJMt9a^a(GUU4wDBZPuJ{fgNplO zD#GCL<$I@~4a+%<04ea=z#G2+Sq&6m5iW*8Y!rHq;RQ|;!hyy+jJHomU?N2wo2Wh! zU*UN9ld|7a1$)$F`vDLMcImG@GD>Ta#oN@tv#hG-uQ8*`%Z9Q{dA>|)rcy(%#3%`S zut>>3hQkCR6yl9np0ane10pqX)^};~$sP;u&TT?G{maE7#E^Qfb2ui3nXPPN!<76d_!t&z(`h z2d&Gw_LpdjmT#IEgkO2F_U~8n-`!C3`YxPan-1)c%Fo}vT>i#4r(jSp87vdM_t2HH zkayf}L0g=_RVOp0R2*D-eN2$F^NdDeLw60|(6eQ{$6-Df@MGY0=a}MG#i9<8*L)_(1z!y4k86q6PbpNO zbS+||bNt$BYEiQZ3YuQ=Mz$;I^X-Wvtex)G{dMLH zhGjxy|GL)Y)A1m1-Y~`AF(UZV{fN?wTY+y3Fdw%`TdRBeFz;vYb8FIIhqAQU?XY71 z!*fsnSF44Oz};SaFC3~1FFOUu-CVY({+NST?hM|)Z5RI0syEK|B5#p*lWCyDNUJR( z_+;O`MYd)ezF>5scYE!#6EshJ)$1GYmKf?az(c>qUsIn+VyW(<7=)7Ss&)Iq@ry;P zt!mCUy;WD+7NeB%2!pS;KD?hCzeZdH6^MR0@PyHV49y_|ilsg_;C|cZN~ntaK7Wa; z4pfGT4_l}=607w@IJeeZsDrpcD(8|7)98^jU{{szt*o@#U{KFl)-sgtVKyW4c8lvi zMe+*tQqES=KR{9pxepq+WAou1B&D7YE|6*vhS;lrh@fh?`N9T~1~d;~TSjY>>OkOz z>U50$CSCJ~{OxG^Fet`c`{kpkKHEGcNrfNu?{A6_#-MK%&MI%kc)8B~=GzG;-4E1EDDSF!x!Qii|Zs%a0 zrCq;b0Sl!LIp#l>X|E^qv1OcL*ND~A0q2NS8^>3gOI5SH6XVZ=SM9P9Tk43vy*{iA zwTRp$x-11akxNvjHypcdQ2oe$aoKGxFI+EoLrD3a1s7?w+lbfWfd1&|0-vRvudXu2 zH0^y%t=2&ps4CO6n&{eMq2&;kUC1}^=wG?L@Y|2HFIC}Tul=)#vQG6lzniYhibDFR z!{TgO-vPJGG!jDqEqEuc)aO%f)2O$m~DRcNt> zWVFarMV|WooG{IDd&rb!*5m}De7Y<8`1XgM?9oFMI2XPhRb-xc_QNJbtDIO2X*49t z(BK0R5Sdmmwni}WalqE;zDS-|`sWw<7x!mHL%fGMh#_=~TBvX%6PSFwLREKPyQB&t z$>C*m1Kp<#XcY#ds8_!b^VgVPCN;_+59K3^KdYej4 zuTPkuJEWI{^t4f1aPm7s`%cX*1$Ec&!_rcP*(O1RmNlj2O3RMb;SsX(%Rj^m?4+YZ zaL{kUJE(X;@?U%tq@ch8DRtm%pqF86#E;-S+~D)DnB>3Pm^&QFJ>P&y z8}uV21c=Yj0{gejG&0Qk2wetfoUC*TbU9m3wPWf|m{Z$SaARU#4HR;sM^7TnZJ~LX z%}iq3X`HmKBML7$kwr1N62q|A$Y?mr2;jxUe!-wcyptNjy8XbLvbv*Yuertq1PL>j z)?a2xs||dX$Cn>+-)#n4*P@oH@b&}HS9dvjRGcjrG%aEIdA$b?M3OdFX6o5s=Mto| z%z%-E$xfWz72DVYs+mO^W?JoH)WQCMU?+GBkas2B;WRX!pJnh98!Lwxt?<-!&y>>{#xZ^dRB8F>oq#RtxZ#4Jvp{$+ z@uOW_sN1x6p0}F;rOBxw)LxtQwPE(zm1?C|iu(HZ{O5{nYt9y2uTg|U?RdD%4xG@( zAy@yB^m|*rrU$RBo1#xO*z_^9xJA;vTF{IA&1ut<+`D!yMd}5$e zGke@)jOCBeP+mnoEoz>yKXBf+w^4M?nVnM1e38oNI9;^&8@HWSYuC+I`VJNcxf(O_ z@u=}~g~$KUEod_Ple0o62y^HJq4+OK4LU*m!Gruywf&!l2z9$ZLxexPGAA=iari9$ zXJ$pWL`8MF6=`GX3}LxUSY*r-u2gV;^SJ$_dC(8ROM`i4&l{-U`BuWKvtfBKPBxBa zbUC}jV_)E|&EqV4S@7ll)Z^8-XTD*SkjENKwvPB5+p(N|>#azaQCjm*rrdfh|M&t| z(1_fCoikSiMm24kVm`^&3s=!=KDFl{tIQlL&AnLP?~Z!gjR)U|1TTU82y2x*HBh=o zUb1v~{VRvUcg)B3<3GQWSNkySdq;OjKneJ27P-*4HxP0ms}`SC>y0U|`-cy~B^7Cd z*aL0_^$Yc$7Zs!6nq&j~5r{qL=O=v%!3o=nDl4y&;?#+fR2;-PI(w2yup7}QQZ7U= z!yxAXkqz=CBjmA+)Sg%F+~>N8x*LSUX5?SM_2sE3E4u)XOXOot+;g8pKYq0O%VMZnjh%E3JL6`j{2r^u4I-!*)PhhF+y z(L*=2oeGs{!@88^udq0%znC_T6BDT}y2V~8x7YKB9*veQc?G$5EJQ-H>oj)dO5b_# zdKvw3Ok5MXuN=58cVRj@r)y6r9PTt*%p0ghiN8`FT~LQV+>;3B>Xo0#=5<)LYIEzh zN4^;REz6872(TV)rXAnf*=dxaV7^akWtj#*led_;AekcSacD&t*#TQzaQCA9rLG1A zr9MDvB*fBEi{UBobH)zK?3=g3#4_7#2@5~p-4EVpiSzoJ{+u%V2`Ybjs)pKsYl;R~ zuS1Ajifx`h?D-3u2WT8U%Y^%s|1Ow+iWt<5Pd`?^hH^72?F4YsM#wF~ZZnyszV=-0 z@A##KzK#qXGzJ*gZN)FM=>`Nz3eMM~bIj%7en7Iqf%BfakQ}BZ-EhYe6IEpm2R?a5)3ix3H9* zk#rCda98~rg@YN(f7Ykqewj#9D15MBFA!`VR3w*BuD&f~oHN(7E3;ZQ!!3a(%zjEB zdN5That9mT!A@oMh#TMYk5(W#xWYLDx-yS|USZ7#PQ^ z)aJd#lzfELF~jSMtRpDoq)F><{sh|^LD8A=1fH{^FTww>yXpNZQ?xDxXY1(XUsV6@ zr^(U(s@iSBz`&f(1pS-c^^69NR(2pc`;M3kzo3q>_+jf-z1>+n)=xktOW<_AQQW3j z?oz3APNi)Na>rUBOyC_ekm;Mu~@EK;4M4Gc(vFt8*Jb#+&M0m?*y z#RAUe9Rr6E2P*x;8SW$KXE3Udlt7xbdOA3uf^=KPU(+mv+mcuk<2GlEQZ;?GN#$7` z%A`7Tj`2p_3Pl;Gt7C~Gl19QKX1Yc|dxSa>CD7tSsmEvX5L>g%mbOjD7W>b(wkR?< zkhozE)Fn5l{vERRU1z?JeH5kbC(wR*vILOv$lxL#`n~bp%;6a=MHy;wa)nlPbq^JC zdH@kNL^GUWz;ei4tZCsJ#_SFOnpgtP)Rug-4BxlVzO@b(MnrUg3>E4*=!#<0r6p90! z7zrJ+9~Vi9xH~%#!(pu3KxQ&pSbY5z~0AyQrGP>XCw0S zN8QaWEOM?VdCqMg9;WVyUzLCz@*?}3yAmjE&*-&o;O-)h)zf80aJwCxB$jh-DLVc7 z`3*eb+d+H0x~^9K9Vau{uGycDY3i!(F+z;;MnswKf#!U00()k=_7S`>n~qXtr8qjl zFaiTZp8i1^ZDuZ|re@)%rEiYKqcX?0jz*CDzNFw>o!q+`YNdkc`f}R zC1)8;4mG(-n5(#O@-UVgjJCW5)~FE|AC@HQU^R@56sSq$pc=^-DhPrZppyRqwah<- zn1`7ckuOBWG#j+F4Mu!Yf~*qa8jIa4x9JOtJB|%nWf=j>j_SNW0dp2a-{rO6w!?*J zYOiC6C7+G(WN|t64T|X+OP*!Ve$>j-FKem>cQBoDD9~qZkjwQsXBX$;zhLxDQ{zvX zL%U?a@N{!7ijjhZK1xAmMP!#QqSS3iIG`9Pn26Vqsi3xYgI0-gdAN~8I{DfWkho8St|aDW+XTWN#gxpbDEbHVQF6^v1Z^yNFu>-ntq$+>{E9 z`v-6I{9Pf~TTGz%e*+p*bhffHa{l{DzW9GZW2Ytd+REBA*fi+*@AEcXHLyv=DokmG zF~yb@)|GgFL=|3ASigkJX~b(@y!J&Sfh8CuT#Z<%4z!kGbNQ2a!N2tU^KM+@6@uqk z!5{{OH+EQBsknIg4_;mrD%}drBCFoya5peb|7$2{j6+q?ZS$AoCQE1I%{wkW#2Zx* z53UfJpJ22YGZZvN0KXrtI_nD3=Xe-*LK|3|RA zUgsH0b!9M0T*N=U=pMNA|G_lm!voOyHfgH6HsFU8h3L4vu9^Mau zg2pzcWGAO;P@teOYavu*>n8q@v0c=w8v321K;4nTz%@$O(Sp@%p2tjk|H7lEQS4@y z`Tppj5m)0RzXYeB{{f9n)n5H00$_$yXXP`r>Dh-iJ^#kTr)*|q`gdVz(qERQk(X86 z7=83<=qZytVg+Fb8>OHsx&#SHN+@{cZoJM4y=H0eY^7J?Qs)OjR5$q7BD1mV4L#7J z#zLi*g~w_(JAJ+F``1a?pT{){xv#M=RE2``=iTw!Yg>=gA@r>#?6+uKb~3HilXg?i zHxs>UJ2CWGZPJM+(yP#ni&8QO3*0t7wk#NXpuQRQJE|f;1$EQTjgjRWjah|H=ZIV6 zDr%RoW=m^I)fmuEvnG#EZ2YVsHa?fSE_JrqzPc7K6ah{ ztx`FJk)_>u*ead?d8~3YuxwdV|P11mQA?GREo9F9#5Vw{#X#UiFiDj^Y z7N!_#!4MiYnqIWk;eLJ~*M*Y-cz?;kH1XU5Vo?(b*tHg?6)%Z}Jc{)>zHPD0rnDJt z`6S9TS|AZd6hxQ+>a)`x*^R$K^^jb;w@(|;OHh@kfDujaB&S$dLl|`VO)lFbDE8~@ zt@*wFYa#19$J|K}>zCPd)227-yf1L&9%*C5=Zli_NycXGmZo^^e8GG$=U z^Ez!f5xfFSdDm9#GVaK4)V>zC*R0PHZ0EGJfV$dH)Qu0&fV%W}nmbkE*|B1>U2J2| zJuzML*rMVf;C3J@BTQ9>BMh#{3+~-w1ups&i`ge7W(t>;he39=;Z)mOIcizHLHdL2#R*hGjhO;gmC*bGEht7=TwX{-G?q@+>i-OuE z>!t(&k86$2`*h<%(T8iZoe+?G*UvKyl%rV(j?60i+aH6rKnUNvsG&puurbE zzJn~AbwIk)@kqJkZ85kS{Iyw<4oSl^=A;k&KV=f15%IgpO!EQV4z-%Qti_;rpMbgT zu-M1(ZJ|+=6_h~@7!|ZwK)@}>D>FT~ZQ5-PX`)rr+uI7DjbIHjhuK3bBz|3)wuZKxOa=^Btd9-{1@JqCK&zYEq!o?A8gk{uowXOz(?96G%9{k_wg zGPMu6E+2T!lOBpsDxCaQ^{&;V0#2Svjp1JGNbe4Cy`WNv^&!VR;(Eflq3VRokorKn zrng-snaThYS-_Khqey*d zV3cN6;(^F*HLl1;GDM^%zMxw@H_&OV*u6iu@FC5|RV@v!Q3Y^7`t?Gfy(frJqU%yg z4zCd{lPpcUmfp+0#E0zjqm z(E95TxTzPE@+Ch7(Hwkibj?7cSaCTNvaeQl^4({$A+=DxW;OtfWB&SpBl3Qx!gn{MVOP?MraU$qW4(% zQ8hg?Wla^?+5*>1w)XwA-MPp8%Vf0ZJG3*-S2;xv>&iu~7Keu*i>I}VKmH9)x^d(F z#ymf}@8+JTcl`UVTRbgxs?VpB_5|@3ksbgE;-u#^-&GU(Z|o3lX%^gl){v;gKyHTQ z_89i$0)C(|z1JESlV6Qs;5>5a^T65^7b45oc~((|s4wcsmU--da#X=PG>IBFA} z=8P1bk$_3-z<(G#y1@=CSBm{nKilKB2jh2Szv`jG<{2Z_=whper01xP8 z?4D24VU{842jEjoZLQO?Z}#xi=?U`;^(d8MEDa(ES9Dnk1oZeVNwkd@Y-0r+14Dp( zKYSg`7U@*-2(xLksjY;UntnYoI{{`1E%kRfgM)^o$feDgJHkd838avu_g*d4 zQUBzZE4x=U=--ah(egZZJ%c=yXUntz`a;LO+#Wzc*=-#ADoL!fJlD@F6T8e-d7S&^ z;-<4OE|8^6S{e~)r!uyAxjbR<$nzYMT~%4_G*ybu*Q>4O&>!^Ern;Fy7MRIh9)$>F{HQ@TXT zJ)E5%eMNp2fH;k342OSHNq;s;HBXIWzb3WUJQ`B9b>U}C#4aGw&AUf6o_@bkwGZp> zM<}^QDO$psh-DHH#+w5c_Fpu_bTRKx$UT1L>}1&qOuX70e$XO%uS@P?-B~nmr`+pG zxy*>!Ou6zje`$?@pgPnBbEgrQ1LP)EE%wXXla2ARGVA$4xP;&p>VwJr4Pb`0^Yc-X; z13y7qjOiDHZQ#ceT}+3H3~B7d;Qob9ilJiCM$hq$h9J>_|G8#&F)upG?<*o39XkS- z3AD2GJcB4Xl3s70pD{kbwX0&9GA!qpUZ$Qk7lWM*2@&*V_$u%{NtK$`Ql~up-E;`h z2^1(;4M}zE$M$3@qYwviC2>^QCoY&6$}RQB@$Uf;=J;8_A-a7s=e$Hmi5=^@tt}q3 z&_IQ~mh|5pA2=l->!Q6|g$n6I>o0LB12L)~Bt_14w2Za3g1C>6ZlGwteA-#gbqJv) z$zgcRSiyu?4&>5zM(TvzHeQ`xY9ye}v8w8v1rYgI3J@%|i{@8PlQY5RBia^eS!Cmu zVD)m95Mi=JAifGXPatvRh~su-Oj9v|Y9ex_Ufn@HyZ@z}kwf1X`onOq+x`^Ak;C3x z+H>*QfY)`W-oeyT3{*n_dH2$NW?n zqeCFqHhCI)-!ZdxDrnR>o{;Gs;AgGw-nT`jle$BJ*Rhr`oucJ)aH@~qYnn#%Y0>4N z-Mk!%zsRq{hy}+XfB$H(#GzwH!jz}Z=C7kpLZ@L_*Nf1tYeL(zOKm;pFP=7L)J~hx zFQs6gs$qWANY=6KUf<;A0+U!VlqG&sRP^k2@P#k`tBzHTY*!;cO?th8h4IRLV zX;$smVu$ntVYCJYVsx|OY1x4U1zFA*b@VgAz@)J+!?@V|Rwl!tK>*NK7|^8lYt%WT z%P&HZXIRF9$`iKU_N{a} z4{veDDvrd8;f%qKMqt$e+N8KO$h>^}`sv=I0@(sl{(NU4=q!@XaR=2CVXx6|DVf{N zuS$VEwjrl{6jicaJ=KZj zSppi2T@G7rpko*+2ce(>zw|-ePni$U#+-x*J{3n?_CJHuHfiT(Cu6f@dbNwVEiY1n z^l*%KNI<>MDT~tONd#ABgf?|$Cjw^@r47DZ_fTM4hk7Xzv0zH=_1xW-_X)F%-yb(4~{3Swf!jJ{NAe=Zo%H+ZwYA2dD{Ni5bk}&t)A5M zl3G6yRe+Nv8nB@QB!_pKzYewUvWAP~S-!>q+#Q7j@~d|07Z$k{XUAA!UWwrQnue#- zN|yi8w%G#wr~*PC+^)^P zfmH3R`Cps-*sK|$9hL8qqQ^ax9+!2H0wmPvsCJRr;_56xg~uwQmF|i9HFagfaE)3> z0tvgmBACXXsEj-AyCGdBWn1vB(7#S}ZSJY8q9{Ln;1+>w|3Bl`{~ZAQisXm8=pE?f zSzlMDADRZn+vbgax1NJE6vQw8S=?NUeC@cJ^62b^0M!?@e+M~-+W)c-uK;Xzl;-oczqp;skv+% z!LH+I8;0eJHbbA_JUaSe1#ic+$gQbUfuy~lQ!#8{sAu>U$Dod`uC_6+__Ld`qECnu z!m)rG&s+uS!V{AY+@f=F`?i0<)%fV2jM0_7^f%Dc(aN44|F_w3n*HEWyrRbz@4bz+ zTDYHRciXzt%A2G)dR>i;c|Ka~b@`QLt|KcMqfef-27ks|BUpOITWcjJ5{-04c`;-> z+#TE{(5*&F+0OU^r7T1g8FgEjm@CB1Ij#P({nlAlB{}8d+q%}N3Qp&qo8OTFde)Ku zrnl-fWdPfEM~C<9t1ACkUmbs{rkTLTXG7E0sw%B4N1MaL-E-x=NFm@eYW>ZL!=$3_KnA|9o~}MAj4Q^71OVcva8lsDxr>pjlv&Yv$E3m+w^ZG6OOhTvF5}Ofz`)E zp8Vs9r)`vHYK`}#gB0x`9ih4L#AWu0{(*T_?XHZvWVWA!bwWvd=8QjS0|uG7Qsaj{ z&#tkM`RkV%f5oA}aIgK|uF~-Ol`k-${;^YOQh+cZ3*>aG;&sO%!{6rl1;!4tyI^cRFlVT zm0O3^ON5hB4?R=&%nP5BIApxV^^xlc-B5SRi=UH`O-u~!R5#AcnNvAryCr~^g$WIs z`2tAbmL+6C!w1PqgyzktQtHX$gXH=`!86X3Qu0{pMVgdK@;Ea^KtL$BI3Z&!uC!c1 zC@Q1Ga587u^o%tihFhADITmkFZYT6|#tRV4EtbZhgi9xv6gn~k30`wcr72UoR=Ctrx&L;o16UaFZ!J&v_6?-s^cs(7IgK=~0a)U|ZY(QRq&_|sQ{ufa+k zfF`l1SDaJZlCiT!`lWe<%R80#NDl`IZsS$b@%TDBrAq6(4~*!EFo}pGNOHluQAH0{ zBWR^4g|PC5jI^H>)>-6=3;WgY57aRfjvmwJm{Wa*)F~9?YYRIk)w>9a-xA=z5F^@P z7WE{6z7Qibrq8g;_n9%msWTOE%l=K4RwX79Pi?eB^Gj)hx*E%POwqR0h}k{AuusX@>_F1i z^!c)g3;FB!F|(Yo5stB?t&DjK?OqnM0)Oo_7PE4@RDWJNm&Teto>dVcKx2(ifXAAB z!7^M+H*2?%V*Vok$yI9ylF^QCJKu!ePiM8xKD+wXc0=}e)ZOg({b2WHJk}0;<_>i4 zCWGnP)o$7xx|)8kLnfCWG|7Z2+X^SNIjmeH1s3}rEYZvyo-Ohxoz|`ofAD`)MYHu- zoyo91{h|JpLvnlhV4XE%WfMm`?w>lEFUP`l-aNWyfn;H6<;OkgbRQjXT{CumNB=;5 zyz_eZfsO-nc^kPI1}R8Z!|&rK%;mFuKi`%P1D1I1w$b%Hq`mK{53ZwX=Qbp)f^NbgvB12lyz9*%C*EM_#?@5=L3+@j;nE(ZHE67(Wywq(-irCvZt_TInw~( z!PdPsp*u+Q*vfQ2<Oh=q;0+?dq~>o zB;QHeI3?@n13$`#=L2cvhw_0`@+J9m#6@*#g7M}$Y|?)@6LXCuT&=m0N~8I1>)NHMM$R+wtnLl0OHx${(@l?lFZr*CI2{%sFvdm z(7y_1XZ2P~OKs;@gc(QXqxA0M&Sq2mAwaMALl1u=9v5-;5D%cg{s`WYMd{;?)ak3w zj_w8eSB2Y9{s^^^SLj>(o*L#vS%J7I?L)0dV2E=jS%x+%tP@T_J%4=sofw$0l_|I$ z-gJ8^dwv9@*qF5mK0mJibR?K{_N`S+RIy#I#5dP*S_PZ$2)H=!Ah-_i9G_vi z!aZKuQ+&OAlhSe8hUy3^1f+&R1gts2a-+ZGaO1l~O8O};Vj=zP!1H&o%xc^^@Ia~c z)2(T!uwDmg-g3Fl{4w?w50BuRyKpenW<)EwbN#DQ%7S7?QKP{3)ot0v@}>cf?xuO6 zeoxKT)g!|OF7g(Mq5&F(G$W}hX2e7ii!utfr~(KVR5rRRW@hR4fwF*^|l%}v18`smk zRp3aIgs1h5P+ptYR|(G&)h4n$Wful#EBq1PyyyH@^qA*aSy4ohekCFw{;b^s%+trI zohh85k6ZLDX=FwOMr_3&swU}MDBIOY;o55wc8f18IdHtL6%)VqejOm)ssKxGOJi8@ zg*8QTeQOG9!g0z`S{CXRk~>2^r`o{VP-<@rjk*ubEKS;1PxS43mOVphikJ=hy03os zb^&Dz>{huldB7Zz0QYGgI}2D)AW_hIbNj_SED4W(CjTsUCHX*eIdZ|ct%36E0oaU3 zz`jQOSz_7BDDR{W?3V2R$uGNhGMo+5*ef=Q4a62%+WiARshzZwsuSI>C~%qa?D2p;SagwPo9Nj`X3Fb4B%hcC_SN)Z z^UJ9{ugX6`0Eg31fFSbEvVxN#Fg@@%8zKQ8xN$e`wfFDngkqE4%ypu1n&zv_dr^9_ z9NqlwM7fdg6r1W~sIV97gChvqD0HIUxWl(_TJ+pvctZE5znt)7@cq%5>9hQ5k?4D4 zX*>7(yy&FEIPb*Y2ZhIW`d;JitxEk4>h+^wWq_)vdKn|i*=Q5 z=D&RPA#usvP+qItEcR)dw=DCNImaA=-kcYrg=&^4DQVj%ot^#KRpQy7mVNc)pOt;~ z1oQeG7vV*yrJTpjikFbQRwrqmw4J78%*Ay%vevZZA zeuLUUj18RPSKOiC%-;(~6Qm)QiILzaHfwO1%O!x{NfQf)-D$279Rv<@D-!~jxRi-Y zc3Ru)2N?@eo=kIh2ReCI$!fLX3E0+y+MoWp2Gg(0vEtb`oKSSa$MV z^ju+#IS&(%6-#V(YQ@5(cA{Kj2it6?0JF`OQ;#dnJ(_p+NXv3{Fghw>i+ zOcIQtJqOcXroF6%DFe)f<2W7*E|+4SmT^K}W(=&(df&!xEtAsV+k4g`UNcF?rDrn# zj2H5SNN~3CqR}Mjc z-&an0Szjwk6isUz_a`*|BVx%FyK3Lqj2(0j?FqACHKPE{{+PFHn%I^0JPyM_7s!K= zw(GescFl0>IV?;y(jBgJC3+np$40cTcJ2Jn_nFZ>7I?44OdN!I&p=h(?91`!zbAVW z$D{1q)Zt;!T9$jmV<_(vU9*tm{HbGl%=DfRjvs=(Zuf?Y$J>XyrphK8kKU&h_DK8j zXH4_GRzASah@)z|rmx-BsNk(KeX;b-{TlufE#+mc-DV?JWAfQypS2E+FLc?mQHE<} z{4i>RcjWqy5S=&3d$FC&EXu$#T<-gy6Yi0aKfe3^GU+B<=jHXYe-QR@6s)hg>2N~LM;WUdl3!bSB=waf86713MOJaG409qE%$?hLw0<1#q*g1p_5 zM?4`AF~|!Ac1#5GBJPW-AWYCMw*6CPbr1z%eD`Z+ci4TBMR__+h-Vpd>n z`p<#b$+QFxWpnb0L}OQ%e%c<;Xz(aVo`Bi1ZvD@gyh*VZbFdaObMWoMETt7A8{r<@ zj&{WFi@mdoo7Aw4+7^4w~MrZo~>19g4XL-T9!{ysh& z@)$lrGW<__N~=ci0D51%RL-vY!on$p^k|csc5jQ8$GWT&_v$gzyTp>msmYm=M-#RX z<#xB9_HfQb7bNVAM;-9ma|iS|+BE10!|t{7>~MjANcyh1uSagRKGu7TuC?&yQ%GL|SnUG+2fS{Sd2Y-D;NSZO^#WD*$^byIHlNL&z@ZPKk4 z$HeQEeV6ffh%__dp7qaxqL8-%PHbYS< zaOG%{NSZ1UP(Q5L0z~DmFt*wo}#tJZVxZT7fU%HWfxRBx$$S0>+9;U8Pnrz4PbxE;O+* zRA0~_GvmV!4`EdhSezOUm5{s6g2jy9p(Xn22>+5ggqqJoj?i+U3L%}q={Q=RXF zwq!<$+HYoEPuvvbh52|w)2iL@$QRy>JWkfBISjYA<&QD1? zW7!tqh`I4t#&wrhmPC0iqb*S=A1X0P9y>rb!}^(NAB+mc`VAR7Lj7awY-@)vc3AqE z)`Qj#JuY=NdBg={5&OLDVFGHt2fH;?z9FFt&) zUOEm6SFH4`VQVU!ikEs`fBAs#Zg^s>ny7PhyDKv$iJs?nNb%S@TxaVZ8%?n*vz0d# z@0yzW6deDChf4JCe#wK)1pM3gAd@5K!V7Ia*kfk93)s*DxJi^a{H1du zKGEnbk1)D7Pi@xH^3uv)US;%4gVDPOCfAPaVAAgrnkujP80N^qcEPvvDLnJ%@W+NP z(3!`k0RaQ!RabV-C$_)(Ci7g6kC_2J;c%4~&)ZJH z2JKm!_>W|KU1LK0$M;exU<0_t{jY7da@CzcJ+YI%Up&C0i-?zvv5cY5?7ey9&5sgq zh;j5&)3fL=Xensy%UI2|Y-Dd-DS(Bn7o-h;Fa21*k?HG4?QHI)LDD!k!>xzV%aXkO zT1$ti3BnyjURa^vZd6;>K06KAwU<3eu zuRScAI8rc19xedA*C3P=R#f~0MX8t<*|!puPRE-_vJU30vrnZ+`wI&TJ!El$W-4QM zFZD|JpggOuW{lo-FE7&Yo83PU$HKphm_&E{%1*#=lB!Q;Wkedd42fQYW$jGDDqqF>Si2s`?KsQ#Z4{JXEcF}Zm+wIw5xY-r%(c! zh}>v9XTx&hElR%Kc)loqp~F(cD5ogwIQ+V{FYLec_0(GgJ?wriYw^@zsCx4}q<1+w z_-kS6K&S54QPAg;Ack!5%%FX4NxSWHl5|5URB& zzYFe3Df&%e%IWJ(lUSGCbRgW5Nc0=};XUh9l~`5X;d$_e$#fu$Pmme)tt7k3= z>yvM8litl{$Od3~6QN@){~hXvJo*jlumk^9VhVB$^%Mfj6NMN>?IA_TXVd9-*rzn9 zK*Xm|sdv~L#^^W3L+$7{t0^niC+evK)+ggH#`TBsV#bY!fpGrw`GN3Hty1r#H;`Wi zcgP$4#y8c(`t&3BT>qvkr>a4aF(a0 zT=(cVr>SD8ck~+s{8!Q3F2Hoow>QXpwnHbqn{%dfhN-~xq;@>=u@JN)>t>;_@}V18quj=AiF+IQG5joALi(B2TZ@A zM4v%F{lL%q@T7ykj(1bVDu{LC#L`M~xT#-{`s9gU@$IcYzb)jgL+akd|KoN*nXmZc z%VfU_()%;@z&vo9#xLvRXUwr5Y0>=X_2UcCfWD0n=z|Xa)%~gF$ItaLywJ9HCL%p& z$a}B$uj%U`7oiZakl@d!6~Zn#HzLAQ80S(4%v>RTM-qDy=z+=jJ_iYhk#9N2N-us+ zPQsg+AGZR((@a>-RfqFcqg&=i8!-UnLq z;gy8$E0}q%CNvHknh_)}v#R$7GSq^WK|8Pxj4XV-!@rh7Pp>W}Cp`-+I`4Gp*HV$0 z@7EfN13FJr532C=i#kk}uyUMMZh8T;#@r{rCY#nTdjT>_(w{fAAN^L>+3bZzQ?cxP zv9)zSOdNTJX}fVwV7yh^GrV|%A@{5O?#;9ttXH9>!*a=;0`9+M&MBX4KCWl*cl)!X zpCU{O4-eM%*&_?dYski~q4=?rX&6~MvRVP<0 zuw;!+h0{7Txz#*P_c^m){+F~9Uya;NoD%dq?$5q!vz(9`wr=GPbE4IwZk3@kJEE^9 zjb|6(q7?n`mC=T;-AmoCrXefVCWHb9pT>LxF3Q;--1#Tg>rp>nEN{W&pnbk@3lU16 z<;_l!LLlIic^$dLX_5VOWL`(kz8Q?pTatAf>)Zc=a^l(&81!-Sx~WbrGRS%Y`j7WO z*GJ`m@vd%4wmUY=J^6R&5`#VCgu{f8Z~5({Q;a$=@>lX-ezYUA8&$#p$Bdy*sH&h8 z6BeO8QZ}I#lQ*GG=mLpUQ@fyl4I9Iqe5yh?p>%>hVRV8&p>={gVdaCm``!dYHzEY} zJlY2JJTm_6bhL?% zVbVKJwdNaJx4=~(%tXpNLbc+X@t3X_gy!qgNVmTeZq1h$1PFoXVK7n1O?|OCUZfk| zVbNa4c%Q%>I$pvXeqo+HZB-YQUe9t{Y32t`eS?&eLAqFx4(I~_qk3Ce!PO= zy$Vx8xJFTDc^55*6v+1lAq?%LB9h?iDJk5}5B`$is@x=o7oHpJFg9sEH80wy$X*u| zB~|{jyh!9BC2l!zb2J?@Y11@r*v{vSGUqi}J>;RR>URAm=Xq#p!|NxDC{H#c}2)4Vfp=#Gxcz3YZ>Jg3mCpjsF?~%MMBPW zWt87lOCBy^Q2U~mpO7z!B^8;DOB=-~@5LbhC!c{MGe7i4z9fH81n9oNFi3mtKm_w{OO}Q$1`W)Mr;?o{zU4!um{}-mBCb%M(7+hzwu# z0{LC(M7FX}K2rbv)Ri;WLm~700Isl#p9%vurh;jvLfk{##xYZEkB8_GAMHWZ@!n(> zEL&bFDMG0=$TBdQ2VU{xp7v%{{CBkwInl>=+|85b{wDqvuYw&8Cs)7jCV_wtFO-{? zH|)o{{a5xlThn8t#v!u^dN-J<={q<>RG;&Y&vn=6?LW4op@)TEN(yc%J&FEnZ$}qp z59L4NI2=fC;(wB^`Nt{zuiaS5|D7nXVOD5@E7Y2Mii9vY^#+2i?FtqW5^yDLd`^Kx zW7{50%UQe^8ZQK1A=4-!P5Nv}6&gidID}q~zn+pG0ANK&WgesjaH;~tN(SLv(QXCYb$V#b#QIMs#RoO>X z`B6B&aK!M1zD)5-Ipw8Q+FzqDDmwDia{|_T<%_om4toW?$8EmOSR+@A3EjDig+-+W zdy$$ET6u{8Z7X-xxx;9EA7gOQ#u8{j&Vm}(l>r=aax{d}?rjZiCre78J>cHjcjWYp zUQ`RR}O>ykPJKclhUDNZ3Vb zNj9B|Q&AID;deu(J6O|uy)Z>`V4+2CCk{LwG7z!GX#o0hP{z@a`pJ`U^gS=~mvKvF zG(OK+dEoqAA$N$~ZywO}~;yG7rL=sry28W!+_N|G}k3%j)hvdlWL z_3>BHv(ey)#*t}8HU-`W8!BkESz?EK9REcCbBs>civkQ&Es_Cp{xOK<#QcJFKOFBF z4}iZPQMdSxh)F9*MpbUvMVT>vYPNlhB)(3s=&k|>JL&r^ynZr48gwVD&1F*L+LiDU ze7OddxP0DB+G`Yd!c$vMa=BdQ$;py{7$`WXa{It&{+;^Cp3T>356jzaos%Z_G4gZq zJI-e2kj8tOPLeP_R*|Z=Fm-vNq4>?ewdxvI7izabS`z~x0IvT8w)4;50pJSwe`E#~ z+N-W4QkWuUdiu-y#tA*&u${%lrv^q$xB2O?J+RZegUw5-M+c5|GZN{Isx-?}nEa66 zyCuAk;4n13_6it$q|ItlE#$F(*?KyPl&IYQ%%0B)e7zI;rbMcn25{CFo5dnO53Sw6 z68@FL@9@cA1t^GqFTv)Voe6d$2TGa%QURX5N=^5Y>nMTN(XL|{17ptQNV@omy!-5v z7eHcu@(a~QzmVbTC0wwlp$aOU{PHNu#!lSOYq191jq>!kR&x1gOQ%_+)&Pdd(An_V zlTZ59L>|T9`5iHuQ7IAyT}$28;mSVeW6lnPz+w{l$_Xkvs!26fKsg9r}^;0do0Q`zJ~ zwmz~whc(!?7HSke!bZA3m)}o@tMLk}LGku$y$+zg?2KsZVDR(j`1j({>+30cp!19P zT%Rej=S5`L?^x0+)W>q1a)8|&R}2w8_vBUN4RMfQ#wl}RQB%3WUoIlCVDx4Ha#Y^W zaV0#vLQ*8>M#WCqV!Xf6uV>3Oh_)|F1?j*dt%D6Lj6&kfk>v}?MAZAYcp5I<*ns7P zx)WNxqzep-*#iLI$DsxV_@Yw&7mdP!to+eDAwz6xeu%bvhqHeSVg3lm9V(ViNScyK zJ?!KmOo4W3pN6SypoTdCmhsi-So3MTFCjeHaMeJ)aubt{$aI-hDrxJs)f(qwCot)_ zdPQbz;V5gd_lZUqwVXgpc7{j(#UA<}B-d=ZVXoJ4iPi@1$9eVBX^U2&q<*_yqVxTonEdjZ__4<%Ys1s# z<^#tORH>gJzHjUUNx#vwGyMHwma4)fDe2LwKbKz=nk{2ivx+vdX^4J<<=$-RqAuY^ zC;75t`f29Meh_GxQ_&-GL@`J1D8n+5805-5XS@05OX-G${j6Z$0X07>PDv9eh_`b0 zMz#+Ztt1hgOhdSRGr>ObikP?iP1W^FL}x7g2yI~+oo4eJ%Er6*2kt7~p{9fg(K!>o zCrcRiXjwl%#2M!AC_939v=hTq_z2dL0OIXNvPceI{ziH)TXmpx#da3sOHczvjjmTn z!%J1OK!^^Ut!QzowiPu^wCs?=_XsYSM55#xnL}fA;j(nAxo3G_E1RT^s=qGo=OljR zlouZ3@jGtR&~E-frRMoG zHeu+<#X=Va0aW)0s`)OWHd!dB9e{uWe4}d>D691gS*yYYt`Ub3;#PzrmfS?!NTzEX z_lgCyVHU}f8kXEK9J|4mdLBxE%N@mepB=$ZCc%K1g;iU<_O?j-{JKJm6&`98J8rJ{ z6*+_r9HnIusnFcziUpFZZVBr&(`KS%)%q~pVp@pjQmtrX!c_huAzW5!d;B|(Y?!Z&T=$*A%>#N?UC$>7lfl8Z*=UzN{>;-kL z8Ln000!a}FN>Hl#Y^QLJM1cs19ARm+BsFA*Vojlt$m9wc>O^>CMEa_UgzLgPQswS& z{|-)&8KtB%;9u5)m<3VWdlP(s*9|Tf#NI@l{VU#ko?-5*TBpxG+Z-L`$ers=pXH_i zxV(+lxBaDUIg~%?$DBK9>^nEg&Yhd=&vd!D)LhGowKxp(DmzB1*YIf2m+8IzQ1fQ! zBFFEJ^f|iJR&+}muwnEINF~R4Eynib37^PnOV&-}RR8w>h5H_a^n}ki&ML2wMD|Dp zxFA1XZirtxXr3VfHBEjvPGJ(48jt|1jpLK@|1t=Ty{JUz_?=BV9zaI@%kl0Pc3%aT zi9b+D%TMbpN%jpxTq46#yS$xp9xPm}`$V$Th11Znb7zDKNiGO3dmzN_EPO@o9w{E% z^8gPu7U^}gS@H@G>o>Lwr#XHa4iNE33@FuY%u4;b2bZ^XnKbzjr5_&GX}zjxd^Gtp z2`K4ftUsuHhahmj!2h?`B#hI5kbzx)r9^PpZ7bO&{jF?2_p=~jrDNFyu zT&xNzndu>Uti+8e0&2PU9Zsb$$8HFTS1gNMgK_&l!F!$43yCfr8(v__@79u{!CQ%# zyYS6(q{a3N#Z~&%!S=sJ-;21#v$$`fKiiNt2xyQ|#1}{lv`gKWUcK^iZ#U%``}5TY zXBxe@vwhCUh){cZr0##h>bm`yZzxHAj!LynCfQDL*~Vsy7bezkj=-@T@3j@(9Oj9D zHA~hH6y3%!mc%+oqp}o?NDt`G>5NcFyT=r`(hkR$^N)`%y`lURxG3{beqc?#UJ$$G zpS&W|26C@jI3l;>eMQ0V9MFA2L@A}XP)EF4I5{x4 z8V(Tih&%Z~`1)`0`3yT=@(IWUpXxs}LyK7gEnI=tPVQFL|H|6`-~7Nv!zZykDK)Gv ztmmNLR8%#gvc!rRxHK~f56vuQLe(d{ZL{!!QSUtne$$5`|G@SyCp=2w%JQb^)_o7o z*4!pV+=N~)uaEgYpy^u4ze+PCLIKMogR?QrYP{0FuyKvG69Of81vj{!?8Wg`nI zr4FH`8v(1fCkr}5U*km>u!DxPIl0$D5rSD^T42WL%S8VkIMj zojQiGcGmJpGbNjT#1W$%*2kxhAhcGVF2pNUtF_2^>M;9H-j=$S(vRuQIJub8HiHH^ zYdy>=0v1nsb)7)jUm+urp$1uk=|xWSr(wWw?%ow{OnT}-ChXg`Q(}%t&D+fJY0~vi zGT3Oqc74=&2EF_Q#}8l(K#bb7UHg!dHtw>?S8QjEM^GtCh2} zxgEYbj@3OVyyWSOEeO{egmr~ z8IBb_2otfIUVw_ z<)DdAK;LfMIfzR3Rx`z03<17AsNkTUfnj8$VI%*~k$haI) z|0wFqQrtuEv&AIZgIafj?M3cBnez{TfE@(P3wuTd)K=;`h2Kud44Q&gloF32Ub0n(G>g$$ru|l~ z(=YtRbDGJBb?_6Eee7<;L3!MW?DD2R04l%;zm0C@G%MMhqdqt^6nK1> z@8BmdM#4ne7Dl_;hn<;PS0Q2}t7Z|vrKh9M$jb0(v84-b3e;hGFZ*yrGvtF8Ak zx<1@^bj-a!=t~JPt*peAWcB`|@8%|AHl|E4^o`BZdc1WOI7c_?M^u2ML!U!;rNAETFks$B7@=HKlB2VlHIaaR%*p*i zmNugUCFst3W93u6C+8vCtR%B)VI=&%7aOO54dKg!QCR*W@d|uxkBplIj4}_6APAy(b_`+awgdFm|a$=;cxEc!LT?rnrmOAw}ovwY`Ib2bgQeq9X z`3KW$6(sFMtt|3otYmvALbSjUb?ioQ)aI3bt*~?2F!(EbsfAZ`uPKvoaWB_jv%^=g zCLWus}a?^8IE;{Pv*@hV{YrkZEu+idnu*P+uynj$twfTVsAP`9y^0%~+k@U>Y<~f+z zck#sauVC-J(wVJHdge4RiP`uUH+FMse?$ini+^Ql3UHNYa(-KtE2c55vE3ic z`G?@>)|9&Y*hyHIQ)_a*mRhkQl${kK-PoG|HBmF!6n>ZMWoHMufR3uUc~efD-GPH< z=2ETdIz-!Hrp)|1g+a%|*kY^4P^v|CcJWSsN7(Ue z%TML4WZ)|N4Vw$AzKY0%igbK~7-sDKHT~m(KyO<4F~cnH@`j=F5$61bLbqri*-Ae9~PH!n$;Oc6)5T?uYl7 zrV-B_{qika+{WZ*wiqkZL~{6D+S1WA(S{{k#<==vQAFzPDe89L>1ZA>K|aqoGo0Y) zBVrNF12N8{MRj1#0oac!nKffGc2Pvl`7S=iVl=|m-OvOE21^B<_z5r}JwuGw{T$=vg(!fW zHW|tPEyf?yTY5v>IE3X-!lB!fap(q>QQ~;wkKB6N!e5Ae%!U7MoYzj#3H%PZ=q>+4 zI+L=y{lBgs|DQ{Kv~f%a<<~8Y+FZcL@`!$2d)bVHgk=4qyMK6;|6KBpBoB;lD1JSM zA=CfND$hJ9albbMlCpdcCbHZnvwiEj0s^1WP2kGq`Uz2G8qfePi%G@I&7Ai!pMEsb z8Z2%#S}_)2Ig&s;GersAu{6>^8jexbI4}Rajk@1uX1?1~W`qtXRewn#jAxFn7QJ7O z)**JUcoMhvDjuO=M#`9CRWcj5^0SjDS7gS*q$ziZ3?mOaMN(n}T}Q@BSbCw5wF6l~ z*x35fn7`BvnTX0-aJ>L+4@g+{xN>YzEjh_AAiLHrk+qNdQZDV3%C)u%W+jcUsF|o~w?d0Zns{Xg? zoO|z!d)}<-s=ar0)${DNx>v7WpRceWBXM6`nSa${na^kM2;fq6j74^#i2h&qbc~{0 zkBJhQinFYJb6div06aw(|0zpXcS-;oTZ#KyDjddj?A#L{G)fD@_3gA@F3i`n{-zCwI&^ODaU=Yw>T1JW6q zrP(h#UVgI(gj39M#K`W0WusY6JDoBb_A&H@m;2dmOP@C4v{FK0*iTfb0X%|P9)-?B zL!>ASO57XN!Pv3bUE*p|Ki$kh(%T1NM2zb+I_f}Kk6w{g=7#b;Ov|A;7zzOcp)^=z zb0{rhz!iU=$~T6xP{=|+opNwI*^lH6X1|zl6rHmhGED3A;x4-xv9DKPUN? z@BcgY|8hGeYHQ@|{QoK<{~rvi67r|K4i&u)Lv_ItZNwT}LqynM0TD69ti`y0LOLr2W2x#a zsTnzqu)9b)mOE6+*=v?K;w9_UP%onUclH;Pn&P3{i~p@9iU0vB$6lh6H@LQFr!Wku zkG1I5AG5$OgjB9}epdq~RcTf$M%G*%X384O+9gEGYS2U$gKe=eI8!g=l)^}3`l!$# zVBne2yyZ%KXktG-2Us>pzEKXb~OzH+jHnmdU%rPN+n&DZxv)L zCw~X!Pz}<9wng^use{l@coaKdv-p0CPfyv=Qn3W1Hfv4e z_HPWU@;)wwRf3w%v3a!2!1~*GSf?EqeB@Vg9Gh%qq#020kXv|j(?pZ&3jA-8lOCoV z&T2>_tY-&OA4GIZYzNya9Ol5v*xm(aEG*Y1*o=?17t#cFOjrgwWMA*BqhsLzzWlwJ}7qvAi)`qC~gce8cpmHNsuSSzihKee~vNT8)5#uclczZxCvM(^|QFLQWZgh zna@u2Sdenb*c!oS3!)@T3??z zO-=_4KbTXlI1wfowpXxeFlv{Ov;3YEv~XIiboMFduJO@CuY@lKW7dTfbjvWe-e*c` z_xZW`xoKSvX$4aBsdV;dSS z%C^AFrp$GH0~H6L^zngqC3z+f#i))y8Sa2xl(?hhkX{sP(F_A2VUw)>pOpNWW6c$& zN!L^K9oyTie|Liqw6zE@%Ee9Bfen;j?S9xDu%_6M5kPY3=(UVEvmSG0g#yd7jVebg zk1Jt|)J`KV_*%xE@L;viwuV1>*M;+ct|<)t;s*}wf-Wy->$@zmmD`>5FkNXfU+&nf zlAF3Y;x9=1D0%vfv3RHl?LU4+l_P$$$ep+|DVuuKQqOcIx(EWODkT>8>_roLvuJ0s zOLDGEFNAZ@n&JPdbrQSQTY7{;D%d|3rG^UYHP8`%*vKh@3@R8*-KYnis^+4>nz*10 z?S6FhIU+rk`wBUzKqo@om+Xt~`UXFZA`wg3#V*(Sh(!22I3j-MW#pb~L%lYbGwZ{G zgQmz|Y+^DXOfFosLf3o< zv6fl8%=DxOCX1j|eLmMddgbbF4SVDO6YY%TeV9rUSlkJ)LU!qYKOYXjN6KgL_&dF z150VUt*sX&jvhfDNZ?KFzoX6PlwCJ$PBo(WT zx@oNSI8HWLzCeUC74Eal!K)mjU`1ep0AbE=&ms}y1m}N4IKziGlAu&-4Zs@RaQDo{ z{bi1|fp?dX>0?q#l5Aj*5u~A~_0HRs0WLDj_!DXOJ9tpj?EqskpCgi74%R#knBG^4 zZ^xE+cq{XsJ3}2j78#2iaSd$R3ilb{fg6ss5TocB)LZb0AnSAWjxl_vOO&G07{L<} z5F7}^!e)$u>+5uOC?F=Ly{v=MYzYbz{fE34uf$I@kNKjsr%r{|yihHa-wHHQFC&1B z+gpDc3U+I~2Sjo<2Cg{14o2&mi&lQ=&w&txq1fHO+Z7?M<2M_MA9vJ3@UpWb1l1MJ|ZSo5xnFpjqN-CiEO3p)LobnK-K6JK8I(K(M$S_%%wka5) zpc5$Vo(@tg2koxLT^}0G4E!(`uU{d;K*3P~XZ4RbefkA2LJz6vylDq3JxySgoWsg@ zDW$ERu-Bd*&Lk(}TeQb7ry#;MRV2^Mi)D|vcrW*(vBVNBnW7**11bL|PeHMZl4=W8 z6&khaC&h_T8PO|)`VGdAB$)7vP4E6chwkel*&4wD1GP$!!RX5t0_5dq+erk#u8s^m2xE*yiRn z3CGxr9z+a=SopsWF0Zp@TfMLk$Kf)%;Tsy8cyg{zOduMsZX$-+ri`1aqrN+0IZ1E+ zN7BkRlxH^jowO=`C#_=ti#0>u)y~Yx%H)5PCjO5eC>_0B-~X)#Iw&I*R8F+$1XGnP zW&ku(#`qQlby@$T@Qn?HlOT-x4$Dy%6C$>H;UN^8cNdc{Jto!ACAG)3;MazGkps3^=9 zfwfmUY9fxq&hQj-caqCYH$cqotmMDD2-#jgUz~ zu4^&+*~xAv6&;sKEn1ar@Oy%Zvv_@@^c0n+bB#^Bvr<5c>7E|58PhBx_w(x15E^}q z1wI);W>$(bc;Oi+MH}8w?cCU3yxZd)No+A;$uybM9L6R9=X?e)Z6%fI&E6_~a;RJ1 zbW%dNki9t{e1b!aqgHcPAkWI{tt{86vuB`F?7C2Qqu+!j!86gOAxLv*ip0apEjNMr zi@xQ^(bpn=nLqwIL#erKJ}DT};`>%uss72~xqcQrKQ@Vt+jlR|mLnKBZzTWjaDHs1 zsg?*vxfFu13CdMZ(_S`zAJrx%N?WfV(|?#mF>~u=fZ%|@^J|goAAP?4ARD*u$V-ly zj`y=rCT*fAyETNp2P6Jx6TQbH{ud*)&$sh_@0@<`?mh2VKM8t;wm=%<&n~TdBQS`6Un^6b4ShRRI1%IDYp~;@)P5G!XG=w)P*(_lze2-T0>}VCatk} z=Kr~irjEMgCr{tfHff%+);i)8+-`h%??Qw^U6A}KP{-s+okmzApj z{BpML{^QQ0fap)&qL~^hWUFnrF$@E(j&{&l2{E0_eu>?$i}Y5X;bQV4018l26i_43 zYHJ^v!E~X!*)&vxFAN<4sEbe%!%7Jyr*pkwj#3Nx=(2+LCq-qny~9|Bw^wh*`>k{8 zQ?LVW&DwIrzRG6TP0_?*1;tY>^byOJdoSZGJH#Bt8Z2el-a{%2O!xRCqHg)Gw0B<4 zzG{(EoCkmvL(7%FM@E5NgOmayN>!NIk?mT5kl`v&U$cWYuoo9zdzNCqY=)+irv9zG zRgO<@G2?(b;H5KUl#wOx;?mSsPfz2<6LHs;w^I-y(>58$*H*@0mCmO?KcJ*xVlTtV zQ9PgG4TUxy!t3hv_E!>IR7~4nMK7EZINf}VKs*ZBesm`Y0ZDz*q6+l)-iqn(l| z-%3KiQFRB!-xh>x&Eish?6QJA%^3g;yA)XLU=MpMJcQ>67d-KaQ5M`O{c(iQIQ5EF zhl5Ul5=*Q%yk?C#Cw`7k0nshB8EqfZ-+_Fweq$btCz5FlQ)Luyl0&&D@mNhYhUDar z;EpB9!qW)fv*i3#gAzF3cX)Z$LaHSL``D@F-HAXdC4@xEq4byyDV_G~8>A#8AclK{ zBp%j_h`bo#gB_W7TrbQnrUO0L&i9A0`_`VG?iM-`P0fo&6b3Pv1;wyBB(gE3W+_n- zWO^VlDd(3Z@7;6xL8xLn6JOj(ijMx8%X-byh^o-C*cqF-)Ct-!CY#x?vEb^+dqD=|NoC?4BtI^ z&dy!@P#$XHOBP3uZw%D;LID9y!TPEl;Lyl0Fl66d*~DUD!Qd*E1pt@0EpN*EEzvu* z^P0+fy^&&=L6IFeTx@1-5B6?x7WqppiLRIY|CaxvIAQruZZ5cZnu2nR6#cU4`yCs&K ziz1LbT@!ZT8uMA9=?m?55(AEL8rLwf^q%IXY|3OV+2Kh75!4r%XM;Y)uGA)>>-3V0 z$=yf&P|MSVYdhW0xL?EhM&*Rs0n@5h6giTiRPkPJ5!cLV;4^ttC4i>9Myn$N@E2{0 zU1J%ZUe=l3k%+;nW~gI$3!3K>4otFl; zyPX8q7d zsH#-7GoCI+SsN|#vEnZVTbpNC)FihA6iY4gMLt-IJgk2e{mZfQa?OW)lVa!Ve83Tr z%P&!#Z&awIUTE-ZeqkJcU4(f*;K}*fEuYL|=q>imkFTFy0O+APDLVK$U)n#wZT3WG8LGm?k zm?>M{n;JKVEaQ@4pi*-__MgM=gVacxeKEj1*AnH zlX|L2YMaoJW!l~57d(F-OmNuk*Z6A8&RQ;bx8}=bS_$~Q|2hgo!=YNjcZ7E0z%|Ke z1aeqW%pTE$uQfyqd6U65>A1%)IsDn$5>(7X6wMO_>hp@e!6Yd&Cx_fJVN{@MmhnEZ z8genRARlFn2?d{7K~{96uqbXeCj@5HEW$6iRh#9-*x-WwtucoD*NMoCyw5WxMEb-H ziQ|pIJiE}C9C(zY2S4cP5tu@tZ)Y=O1i9uF!#umy84?(yFMm$JXi=W{!~&-0lT~al zFfD_$jR@)W%9X6&0|$S9N*fL;cQUZ&i>kH47#RAYwc<|%hw90?kxN$o6W>uVlCrqY zapwmCMI)0ZGMtLXr*IIubVwg)WNC?%Yrmy-M}oZ7E3y0(B#OXB( z-AveDx*0IiWSXQHpSWVaXJi>qOSFlXYcM)Ic3?;$;gJy}9P4m{`~o4%)SR#P6#&+9OV(sZqm^a^VThe6mz`G zoJrKQiMVo_^c`H%FKIZ6Mvq-nt&%3H++-RW(_PbJ5Xcf)wF+e(R~%AiJ04Qz4;YEP z8%nKuYz1jG*Vn;)x?@yU&F3PmbLwN+VxHpZ^yyM9sbjih+wzVeo?N$S<64yIBgYnJ z#8Bs~yCkMy=j=Nz{AthWc0S)6XMxbWY&b669o@k@dKZQiYn+Al(e}7fMkj_N$ND>L z#N6KuCb~SST&b)A*)k|3rPF59HVzZ z{b`x54VYu{ayRsUe5YMS3qtQ`{Ta{-yfZY-$T`1r_7A6dX0G4AGY4j_8Lh(^UPdZc z6n!BcI)iWsMjoWwC(LY0I*&O(DV@g};Fw;sf47(hPuFc~FZVYD@mjl0Nn$5*um)Ea z`gGrXjb}u#V~Y*L49Cb2`yBi75c?GS4EqQ`7fkO?ZzH!IqwVN-+iY_hcAiaqqz#cs zO<>Is!}nmJD}%;Hy`1nXhQXEIB;rh4J-Tp0uTpcpU7cvq!L8bb{`izuPgk`@jh##L zLVLiVwtVPsbB(Jkt=^e#X7P#RKkcivKUq;WK{lu(oE=MdKAE~3ryU%f9NKZ6>dPrq zh%Fr)&TUi8I#Qx-o6VxalE-ViYsF>I?j0?6Po28n+#45bR>CzdHT(myW*_t z3=oKM+_6LRS1g#EkAKefuj`ml=}E^yM-}sn!OJ z_M6Z%I@bjdwP~{-O%TW0j)4%EI*#QK8k&yH5X)MQkr1sqaj|3@L-v<98*dxl^rMns zmmdh+T!s~)Z+UNV!-Ky^ef6z%qdSl~V;wyPeUnNFT{CS78@CAEb7#{u6^LT2j|5Hy zhME?9$9*&WFRh-iOR_InFB{)Kv?|}ZpM>EET6UP>2wI8UjW6%qe>?X1YFTS%cgSp{ z79Fvdy%l7>F+GtZ5dzv7I~lcSZHH(HwzPB7?JpKtaFCsxIBg% zgPQ>s;TF^?G&9ObSNi-Dd_H(5T9>OO`A#0{9xc>C$TebISi3aA<-dSFmTa zaz3g;-G_6WbME-wJdrfGW+0F_4HUvdX|s+CjsXy!lo#y>hvsMP=e`-VYv@;WC6-(1 z1T|?}TKYAHTczEs^rPsryz3L_le{AnQ`@}D&a1)duY8PG1zmUDa9F)t5L+Qp23I0i zB*V4t@$Ss~^PMZ58LsnN7G1PhUt8o`#Z?n`3=a&)&n%3Dv!1Em?StL4T@!Sp?0ubc z6XaKVhlevyCEO>EJ=pVdB_H=OsR_h`XCP5qnHf6IBK zH{TlOTyGWnw-oSt^nAo(@9XS)$1N~3;yTT_JrZi#1JUD&aUeg@Iy+)^u5++2Kij&( zx&HmMSOscWd&ql=CnH}{+zwAz2noLp(sLA1Us~ixYcXG1U)^G4hE^gC^6iRCysF2G zBrlGl9`>H696$m!Oh5%$T} z#nz>7R~&@yJUtgZ*;!}!0+;K^PI8YI_rDi!E^aT>ct|%cXwCO2w+RfGzpAF*D4jRl0j0Uu*`{t6yr=tq!|vnm8OOXAyaU_0_2bzO*(wDnId|E|r^nUzZ~`?u z(6L(ANf7N6uhL$uj_$pIg{+il{DF64o?KA6z`Ohpu9>!zjPU(OajuN5sGubN=dEP=1+jFJ{;M=gC%dah*<&FEn)d58<-imm;V#gThXt>+u({RH3LptWh%JUVO& zw39RAX)Ek*WuOnxO=V49i8L(nDg5~<69w6Q^TT~8k; zFJ)^HKRpgSll5eG`NK0!^U0CAZ>35bw$m^n<8jUEr^ zWV&I(B~-3#u0tLKUb@tJT~(6CH|D58eU zd-2!7EtR{*$h+2EG8}&dxbDa{IU&}yHiJ+QW0?HS}7I;8?MRwS#n>?s1VRtw= z%i{VLswTUBx3A7O-eN-~!h66g!WD&MhotY^AzWZ) z3-AC|bQZ^OSdFaBm&h>w&Tf?AUUN+vs_SG#Y)T9*YKQ@JrV}CgAXxvt-ZoMk9%4G7 z5;GB@kdAnx&2V*57I>Ui=LlK9)Ij`!F z<#rum1%x;LeMRtBj{^6tY^pnM9n_;Sqs6I{vAw(-Lxt}0`aNmu9o!rI3KG<;1k0Th zTm%Kl&};Goy*V)iqS_I2!X41uB5G``|8m(Of(I{{)HWclDxXNPWJFXk!HK?Rfcd28 z4>f4^Rg(H1sUHsIF8uyEU0~1D7dSoB+xZ=&ZotolpsMl}9ZWRGua(vX(QPRN7(Y-q z{!Y_BW^Dk_0Tgi#!lrvz;jy`?{=k}JEj%wZs)cVc8_mY!5u`^rbqLJB4CbS_0#{|9 zJGXjfgw7E%vSRYV6GwEuDywerwe8{ZRNjgKo?;vDj?Gg_1l-&ULY0%9Al9m8eWo38 z4;VeYr9r8Xc@bwVtwM-!iH=etE4xMyi0(|D~N?*d?M;5Y>;GdBN`s0b#u;mvo;ig6@AUZ}( zCf|H<08g~b#3$DRZ0H z0tj~`*6e z#ASZg>PAX_hKjGabHr@mZgV5Y$8yx^G zePQ@G?PSG_bq>YFaFFattxcDe8e*VWWr)zi7WqjLjY%C%p&Fd`zTjoEt8$`J)fm;% zkk(M{PO+oH^L3~=`4*(SRY;z& z4)o{3h18t&=xH0Na?MyRKB}(_1L;w+c}{-!!Q~WKJYbxz=|5_>3&s#RMIJeUzz%M#n~3sqguqirVkv=7~KiifI(g zlnex2JTZJm(>7Q7p2lPI2_%^>I6_Oiid!e#9((@sQnO`HqQ*EcAqtkoB}z@o9O4w8 ziN6wX|CnV+*<&r)Aj-6`<%tRgDL6KE%0;-(Eo1Uti>z&vCD zRhuzYo1r$4gsL*pr|Nc`KCu02KuMn{W295)=2ter1NcWv=CU#@3!GC#YNE?bX!I=x zd|>*i5Yvj5(K2I>%(tg&d43MTGyoQxOF*-2a3|;-vxS!u5iE5n1bb|kZ+j_N-zlE?xl34|h*29pW{MU*TbK^d@cIy$4O@~5`{e~21oJ*&Y|jAx z7UzW)vE+F@ueli{zse^$|7TiRmXY?SIrKklI*;tGzWev9{PTQ6q&PMBTT7l&VsrGG%-J!9WRi3x!_davdO zXyBthe@13YX(d zOL?RAmHX_gI`s~E7xEh%la5L5bC7)sHI$X=69YxuIYwTvH5@J?it%UR?lFop7;^yc zr^vYafTslhx&A|h6 zOp2hLtWKI|5_w>HEI*v?X31OE{c&iQ%~EYNo6&>;GD5nl#cjgM!dfq689C<*27Zn% zhTVi%9f=+_HZwZ;N{W6Di+ug0vLd~*@gQn@Da2Vl?=>qm@S~g^HouW(xsAte6q>^n zJQK(?Pq&@HW7ki`VT86XlBe18;({|lHOvxG4RimND1pRd7vd{mhY2d)M9pD_ml-d} zVfie&K8Lt+Hy;C@aM^WSYnv1#`ojz9^%c1dUXga-WV0ygO!=rWC2qRBTWm-CQP!=%^yrb_5BO0k~$!^3m3ky z(DYaum$@xu=3NMr;;z|+yjPJhVG+{qWGKGMJ*$& zVHM{Qy+;vzv+gUFbKVQFT=qD0%8MLZ{2;Qr0vzmJBn#Z#?L>oy(0ANULiUQ{lK=U`DsFE zi2ltvUUflSzqxh5_{fhKzv8a1hU1A1Sg3#4tmdV10SO#VK6iKIVya{+RFE(N${){* zL+Z)q5*wPv%#3F-vC(exp)FN;z6>a!6NDDXRQHCf)-;S?;hng^=uJ<%%c`G9gQA$7 zR=BXg4ukrM3x$NLY8Lc^qqmgRiH1zjR4ML?qi-qhUeUbg^@}8L6!(YH=qgGnB%dpd zsU^3m-2$X5E1F8A&&m$ili%|a4AjjTTcyWUMQ8NsynD|P%pOGk(kxj#4nE@;30vLAik8OpiPf4XdP{FIc{)rSMZM)pz(|y+hJbMx|`X zp15xv<}dG65XM(^%I#VzOs|X>^pm;3zy6J&>F0DDBv;HuarhNN2fo9!F^%WIdLfKt>l@{yn*$}?uKz_F_5MeoM29o# zW6+r2%kUg?SPhAwyYIHXwfDwnGqW7Dj?9NrQ9pn@oNg(5$W*Js*eG|jmlTgCC@fT*)!mhGuy(Pw3zwv`s6}kyE zkQES3#KwYc^mmx99>TAAHpyae1|x&jD=MGsGhs;kHkEEEV`xvaiaxU0h}mtwSPK>7 zZ1lyn-dpqB2;*#!+q|BkYRkSWzaxEWw17Vi+B@wgM>p$5Rwh_qb~@J7ksS544zpdH zn|q2aPsBj7g zvSPF+*$G)WX?)-YCK|L4(sE&v6oe*GuiF=n1I6auF1XITgvWezai;AFr#= z3MPcY(+?Gu>xX?!Gp{c(+fd5c+ni!4!+7NmWF zq6w--3~x(=`4vorq~$PRYDUBodvEtjAwyVFxN|b-DTZX!2$j0Sw{@eiQSg1xeYTaW z>n`tM&Ck&vagScICnG;Oj79nl)mEZlV1jN6Ta86ndRC@;;ZWV2V)hc_C+%f%r?t%) z{bXy6=vrosb9w~>F8Yxl_mIu|h6ff%b?I~wN0>6=*piz2VLs`fUrL$i1(I7)cx3Ax zNN9ryRB$X?h+k!yncF!N#7e0jr3{(xGn{<1wT%Uf!edmTj-z)?nYVBzU5D>l?i#Qh zx@_o%b*?=10crzT7JOd?salZ@qm^{wtp_$;KO(!QjjQM(?lY97ukJmHq7YS1a+!3| zXSHa;$4+5BG;Q*0RpUkm1L@$rWVq@1*_qpOY4SS1kJ*qgJYvg5Xy&Q!la#kTYQj#a zh7O3OH2;}AdJPiEz9p5@HiRQ8OCmgJ0Q{7VJqXR+zgUB7(>Ft6rE!_-G^CY{9pZxaF~ zPO(tSYm>CkesCOi!qvB>)|rlf#%WkJVJJYXu}gS~Z5r0Vf6sPf;;190hoyXTBOT(} zd0~q*w3d1UrpXITgBiy3cw0o_a|KIsy%@>*5yt3HW)gmt5$E#Nnx(foQHL_*!-(WU zv!xol1Fm$;Y^0@BGKQ2|nnGGcbwZ|rgP`dUuyCpvmUOdPJBERM02(@I6Jahm5>4bW zKm}ddFyJ3uSsx&Su51XfMi*u*jE}KkCd>x+uRc!z4yTR?2!WtA8wTNCpT`WBQI|&z zmr^e**U^=R22RYf;K&8B4DZ2CM{RfKCy*Ifw6T{HJUPYbG}?T z! zt~`G<0A|+F5SX{^A9Ki1YwhU}%U6IZ)B1tGj&l-9J5KpHjT@;8q%=D=PxoWZzMy2T zuocno=rtveuzgkX%KSt;`hy|*=yz5#ZVz1j)MjuBEPl+&AuZrj1pCXjh>f3j>xHePbC${A@zM z0#Urn%$^MS5myc-VThy4(K=+C6Ypb4B_(#6$9JtnZeJ+e zyMxq(UT1m)o_>#C^;Dn`c$-x(Ybf^+&{5goxSSxqHMW{?^xGaQ- zZWPvCDQ3TBc(ldxwsT!hDAC+i-9|W*E*m$rvJ|nXJFjrYe^GcSu%WS1HP&LmhO@lc zf}?%8DKu_7qmVN{21GnG$N$X_>Cx zAeJQKg6$r^d~tyGFfNntuu*sn20g4?ZID_MMjIxA+js9*<-H4mt(OCgz#chTI(JuO zh26X2t#@iT%$pzTMti^9SbOR>X@}P)VrlE>y^kR_Pt7jOJ2NLJq91u%p4a>|Qf{!@ z?joX5`ScBMn+*U1bC3GS22h(lBGxUql3}Zt=R|Ma6PqPQ)pnhq08mdXY@DRk26d%JVDUvUsnaa;WWNf3I_Q4klZo362QmzK-lWDp2B=Y1B zDLdl6SU&Jdl1?4#w1PU2Y_kj%Vqp5Z!Fa-9<*kszD(=I;8w|#jpo-M`;vvF7V4HvJ zNQIgEPsUYeHuTDjrmCP0bqEbwwq(#QiTVT})W$vw;cor7LBk~odN#z}LcU?c-GaU$ z=6Giq3|+k*4vVeZl|v@98ptI1j6-k$K2zat;oZRF5=45GAjFFDO#oYke6kQ6!aZ6L z973MKakp@8!a2GS_B=Vd==Wk*uie5hSFRt!Fjub;!xZXw@lkTk2d*UEf8+Wg?J2BW zd!zV|1KmY@QV_19o^5frAa2?@x@h;l>*Sn+m}}RUVT>)i{Ky8z16QIx=?GWh&#<@z zNJ>Sq2v;Fj8td0vVYSV>zQ_g+1E|Q`mIH4jJ*&VcQJ+eLtJr5Z+?=pyd0aoiy-vI5 zAA?V8*JOiFtJi^Hgmt@PVT294)M146yFti;<^xcqe*M5w62Ea^DY4%$u$0tq8i*wP z4nQD`coxSMfWMjG@Zs9iuzQ9c%;tCp8QkRXA=}f({Uq93wtW^26Lc6Llz9LCBJ547 z-LvJOLGvzlSg-lO2+?N;!i?Cv9IgPyO{=X3#-79awIs6t2ryRk-GIY~Z||#RcQvfn zVt`Qm-4|B?~x8T22E@!Lx8 z`&4au!@V!voBuD1@Y~8V^ru<-KzUX9tzRdIe(?$OQQk)MUoJvERdvz+iyGVMPYu^)EMJB?ODT{ z(scv7QI;dlq^X6$kE#&anYLi(mm+b6kU2?~a2#2NBXWK?MJ>0F6$S2!{bmIMU-UOf z?8Oy(2uSQvTTL{98OkZz!k*Te)}d|lH0$Fuw5qO2^gKiAs@IsCA%sdbYcysP^0jqq zo9L>zN-Za-=<1!48#+B}6=oCDRb|?blx5Wo146>(KNg~Geq&eu%J zu*g5P3gf?|#D=u(b>)cgLQF`TkXmMo)G5-c!U7tj$GbGQAx#*Ov%!hcfff0}G~uAQ z!>$cx2O?VRZWXm*030DZ2Ah#*gksymf?1JcYf<;6MM)qglbp~Cn2F^KL#F@K5j+&x z%@%G!o+u-k;bUO_jZEeOBMluAzwfl$-OH?L3j^s}z3%oPkWe}y!2kU)7L8mZsZfci zrC?RbDdOTH_Epcd~l@`HY#&)Oy~AiV~hA32HaZXI?aU-5mi^Lg|hY7eeC>-DIe99q9Cc zdE1ZWou6Issk^n;bnp0C*9MM#%R7ODeQ>?~w84KWN2i>{0LS5ojBz;EB;kGc!)aUa zMzq0pyNtS=JOvB;y9I58df@>JBaybqBK5XA&z_RVXFpyY zkZYML%Qo*RXfngBBdFAo)ND9=VbrjtJs}}VqLc;;D@M`O#1=C_AguS-0MBL5`@rQFC zaGyo*3C+0%yBGfr|EJ_v-{Y?k10sZPWMdmhI#q$L?99kLN$@<%G*J>9DJ1u=Mx31V z^Tc8Vr1q6-$|_(jM86!F6~`r>|NgjebSHT8RMWXciP^x^Pfa_UjpmiM2veI4;x2LY zMsZfzAQ-Hzor`N#-ND&_AHY?JYsW*3vlT?&eG=f^1|sWI*pFnWb5#iq`(n&J5*APO z=Bo6XPEuB1g3tcqH$G`trca2_?fkBuI~h+>Ht}rR;D3IY3nX&+1XhUd@tR?zzh_gL z0&0rL2NRcOW19lW*osu=5GCRsnIc>QZ0As5$2O@J<(U#)fGz0SU&Wg~gUeXXG9Y8A`=SUcgrZU))5Rt&Ue8l^39d&Vp{HFF2Z>Z4IUjjBfa!H5RW89is=x!+3JXU$&P(}v-35fcP_Ly48>OMK*L`(tvcv|I2Ui-e6Q1_5c}ubXR$u$U8rOF}xeS4uR%{xBluchrCvc z64U~&X#(h3?hMmQ-%l=XP$=KhL}_+oPh``5y76q!I8s0FH=$dlIHlj$&!}% zI=){H8qcAn@pW??0@1;0cxRSIl@}FF6u%B^z+_L!uNl=}dh4AQt9*RFHTwWG+gPf* z6fq%ME9TxIIslptoa6k;6%KyZnNu#bN0S>htFV8^_W|g|KRQVNG*C1L0Vye(7@j*sbWUb2 zAey4`H2*-4+uykuManK+`l{I77%@{cWOjH&gf-iE4me&GW|TDCh=4n-3$Q%LamxLM z(B}UYVOw-PPxpY*7Ud)7I&*!h_l84yh21f7)nn5|`2K*1qcM<+<4u36n zC;3tlLpa=tw4w4_-AZ^D@no*PRK)3b!Qlgr1=^?Hnxt=R(`57GDLa_C?v;7 zL@ExXveC(4Y)78lBCl!%?JFYDQ7BR!jZh1=9JTj z*rWBq?FVAQM()8gqIxu}2^^5McXC8>TMP|}F;JBU^}<%Kbu;2FP&S9h!7g{_!k(|P zx%nTpGg4oG6Ix#i=LBC=4@$xZ6;vX}{W^xkEOT&(|%CFEHcckp;TeN7< z(GBF6e_V+S(h|9GHQDb8lH=L9HLnSQO$NH8xX^btp_gChl0Cj?30h<~Y~_3FbGrtl zxGZ5lq5Q|k$S+}?pM}l~NKnJ>rLs# zuJ_U05bUbHD7eA#Bk6_O1##?9?AqBYyG4xjt&5^;5vd0I#;^6Y7x>@U&8fJ>3_xEe zJoP~oB-|ji%D<#Opz#xd1j~=w@3JsUyadpqcafF{Uyq{iLey!$gyEw4kW&QdkGSu0 zw-SE<{`JY;0b`F_5tI31fZbJLiht3BBp`?-d68NkI4M#Hgu?>{8L1FJShNIxG{#*n?d8fm(7S##REbv|2eZ8xQbU$_cS4^G-KEW z@keuLBrh6Pbi)BoW>sscEL81;RzsXRNo$GZzf{IaoT=8R%A@Q|nHQ*`@qv4kjw-ma za(_uiq;7#6<#45R_5u$~WPIV~w*_C=`&O*_;|1t@l#vqxV)XsqLIcq3>`mi|c{;JNKnUPyGC z0DfhoG zp}F?C?$N(!Zpex{AV6U}$64HleQ%k zDY|~)iE(VudE`W#1cS~(1TymB&4&_sA@26?MSOK;w%d5}3N?8ug<6=_d8*99#!uqoRt$*7XB)-$*_D%F=->OY;EXg`!24X(dvzaIA3R}^il zcPW`x7&dt=;5B^6q)u!5kYDc~_0z*oCi|vl;-GH#Cx0_EeL$QL3IuW9l3>#N1XR9Z z8HZ)}=kKL3Dt-{G^>Q%kexRF%clYAnl22gx27v8N*NA?AEk!IFU=(2(y#WPDAmOL< zFeHJom;QT@Ho*WK29PCL5^nqLLYHcGS`K#IUf(p4#W6|~=L011GDP#zM9U;jTn4=> z`iMG3esl;%iv_mCTQ3Kn&xz8gu+9jmH19* z7eo1#KqPw~SY-&p?MeGW3x>YX&&;iI6~E8{z39}n=Qa@1cIPU2%>q3!YBa5td{X*Q zrFK?@m`eb*Rd$1%B)#U!p^o1D0-}g+?{T_e+thv8^(-UOk4d$s%rOq^O&5XfgXoVB zz)DYHEi(OHv5nt6uHHcI_TWw@5*2>o986)npVDcl(kTL6fv7pdCc-lSBquZx^s~^P zGRhc}2rgt+i8?Z2j!+#C3T%NXlM>R8YXMr3$ZSx_iq0;H&?|mwutFXc05WIJ8FhNh z^hqpCAsmx<_*1Jkuq&Bk+kBnl;nlYa``*`!E9Mhvi?U!N`{0w97=L<@Mou#j@YM1hnp6l=~hm9EmCY))&1#3uA}4xW?L zCa8aooRi2VM0yUrCFGRB@QnsiU*e^xVV-s)c++r$<)m zUO&e@I4kONUpZN)Sd+cIC}?2yU@d;M5q>=$dgL)MM{FWyJbI`tt?oVc_{{Y1t)$Q0 zuAHZ?XO=M<#)OrcyLf;(|~@KnidW?2p}De z629vJiN~P3VZ)^PM60|JLtT<)RP?|q0#xVZ=mox}c0uks29*~qe+IN5q-!U$Z<$(H zeFUUN1hiN~J{wxihXzoH+HC;wVe+G$YS%&T~Sc9ZCw~O!=N-Bg?J&WB`RHXd+U|4w9zhnHc+|Gx9hUAFVq; zSsQ_>_>Ip+4~Q%wK+=1LZNEHcJ_9fGg;U+AT8QQm19uY=%A+#HD{v?@wp>%k z6Z(o_n}QvtfXZG*!V8$rSow{xe@|p7M$bQOu+KVlOy%_zeKw1q-TAU1iX9;>c?P*e zO{bagkL>g#&}sx}*K7pwW9J%^r9vy25%<{FOQa3kJ@!&^|NS~}V~!617c37+@_-FJ zg+g$2Kd=*sN-ZGiFXqdL!Sza|KOo)@9_74bMJ_SS_TAMPm7FB?GukpM-8AF`E<0L88sBKL?i@t)|z1&1G0fIth8 zz#W}nkM7m&Ld{F^AHwE=(Ou=Cu(1GvB_aVBIsr7r(%Qq9=wYg9e3d88TzYl`vS`}~ zaix=?4ecC!ea3FV>Ee1U`$xec;hZwzNaZzck_vdC=tQEU>aVt+J6TyPbL!RPtU_C>7**vMxO~c7?!`93o-ah| z$Y&UW%s4LdhQ$POnSqQJ97)d*$yQ;DzAdfXZP6KD;#|Xp=KQY#sAvMlfl+W~imHj5 z#fdr#-`})Fbe5{9SK^0c1|fl0Xwq?YB3YL{ja4udV~*%j-WrXkKCM-V zj6*90S^)@%LyVoE4`Q7}ed5`>@`A<>j5#Tvs11tmB-j*viu?nP5ztpzX5}v&P3rH= ziui9K_Oa_&yu0oZ+gE{u$PfHh>hF}7gXhuiLxd5DyU+veR}#QMj77@_RVBTz-1(UP zjQE{;L)Zsgr}|g&(D?T3*WEL#$d`X~if=*io&1Bvt67^)m)!D5_uS;2oihgf{1Y`W zU-93CQppD{v7&1#=uc6_)8}yVlW_V4HQ3xNWO7!uzF>4f!HiZZ{ey}nnkQW{U`QwfXMtsGCLDHTVYD5OMZ zQnR2Ym2{;#SAY*_OU!|di%&FA3cvG9%#BPWr$hj}j)}|>9~xK$GXu1$BZq3WLmJda z6Q5{eB+14&NAn|7^i=8!pOYjCrxT&(H~`TP^~{QGr3a%bqbcPyV2<8}3buKuqnk;i zjszy*yn<=e#nkf$yJODoiFYj@f0;$HN_dGdDCI{Jl8O((#;n~7nI*PzCX!-k?hl;C zyk5iW1fQs34l$Aj?`X!9UIoUOUs+6AKceb{XOofu1$BVZ;tDlxDyzhVvTIw2`l zcIy75$uUWj3}(gEDj7u=N_lFY+e>$J&2p*|S8Wpg6%C@Snzp!s!gT_Lx3YTpdpJ>~Q!Q!=aorOJdPtGk{PWH;r z8&w19;hJ#KD?g|`7|Deq@9IZv0b|zS!cBt388w)!DmHnsT`vv8->)`#ZOgee=d$K% zS7h3D)x=u^tukVRHInDh5g)B&!oSbI^Ci8X&Xu~QJLxlTTA?bb$q@CJ{7bTlnh2&q zhWB|DV6XGuwg3k>g1(I$k!LVU^3E&Yvz%3YqDF4=X~;-Y??%iG@Qtqp5`F4 zhi_WLr@I+jji6S?;1R8#2_^|^P1Lp9Zj^U*X>i68IGqezV0e5ggHTx<-#>>LB_rmV zG3{P?q-t9)sXUpr!Q#KK~c2Hcs zC0TdbkA#;O<9G#~mBm-T^|uJ|K3R;{ffr7BH2sK+N5#6fJ<~fP=2|7U_HK0V2*4|Y zqX}|&xPux0D)bWpDxsMy+5Re*_nSA88<#f{%0~r^TH>V^E(McWvRW&h_q(uxhcAZM zOLoFUm&xw@TSKKUpX|*a>btkZ{SdPOx-OyHHEKlr$Z7IFxAc6Gy_7_Kv{e%8Oi@wi ziKA?U2~%s2Be!&&6Yh*@Q1^_#vgE}ocp^q9_m(VLOW`ehB5}7Q9#w~k9bP15mX;-l zSwO9m!4q973mhe9OS({*AMs(!#8nQBoj)^o)SD#4ScDiM`$Otbh7g~!5IUlr`UPLq z9dQE^L{M(jGJgrgJQ1+8)VIPjGs0~H`rwoGn67op2AnR|-rp16v2-M6yWt3U+v#WB-y`oIC;9Q5 zn9aGdnTy>%@^JoU%BDR8=g7|aH>%|5Cp12jHQa@+a&f$saE) zY;%q4_~J$1gx51OVh58tp#Yxj7umtFd^y^^1Vg6x~evHwy?@chj03dm!q`D5D<0fEFi;`+P-@VC# z@Cr#UD9LyTdh`&O^!10AVWdZ7y=0*Tq%FJfu~(2NLvG0u>tKn;cNke#>;lA*edh0B zlNgnBhq1b!zh7LVf*oQuKgkPS8 zgVmxS81AwEb?NYT##Auz33b4ng-9*~jHO|fQ9T1BqS3uZDFXqg0jx$>8`85;%w9tq zwzz@JUQHWZz435oQLRsUjoM9G8&2QKYNx0v`tO=}o_U5;P*d>2LQ|Z_n#-KVx>UMF zyOg#KLaPJ~`DUYcL5z#v!#sSP(3%0W3J(B(E;_Du4T@QgM~vK}cog-L)?JB5;>Z$X z1o)CzGgp`RyphH@!zJlr@t<+`5jh1b0$26xi0UQwt@(6<)mp>>!x#y*~NAnZW zWv;g=K!z2%uK@ETzwEqSnfvrQr@je!6P2^#v(;vbkmS?pwC%Hf zS3ZOc0Ji@d-mxon{=~ppsz(1cmUu>3<7FmJR9E07a}ytXaR2y7A35iE?rQ6yuM%1-owlSU%Bn1EdmT{n$t2u%-fH;KNAmW zjmmA9^GCTFDLaUa$EO;R>tCS{(e~)`(u|+X!WhCaTdUnBO{+~N=w8-4?(0&*7uM!U zXNx2>S9(8F9@d@`(^ljXXFS+z*?t>ZO-0+W)S9SLH@!XGOW)c@+)I} z3}xbsdEyLcYUObcFCWa&c}x$>8>dEbOlW3m7smWE32(qnD*r4)+$($7zZ+>|3cx|| z&c1Ym9vQH~cTF`}EY}kGcN6m340&vOs^E*e`*#*ImFGLB@P55e=Umv4+ttN9omsYS zT)mx_#QJBw4DEOPOc^N~1%bVdzl>i9HLm{K2 zK79WJ8f8)vWs)jo(qwG8o&WGdV{CPGAk~{kLk3(8=)C&xH_IR#B-`2MH#}XQ6N^d9 zJDc^-^^ZG^kUO_opBhs?VI1UJ^7nT)Yo|2!3b*d;&+?IEYZr|=E@k12732BH(IT>Q zC6Kx_`{KG$Ds93j49V&OKUw3+Yf0n!-#{3vw7=Qgf4MlhA;LSE^I%qH3&v%N#$^h{ zWs1aQO2p|3#wF#9(C3a+<&0GIVSZ|&CZU*~*rpbC!#X{x&vfbr2ERGgsQBWupD^^; z%4~<8LLlKwxB+|@$(sz4SJ2l6T!t8$Iw_k{J}AD>=$ptzt%=?cEN94*Agkajt)Qyv z4-bn{W;8N(v>1CEO`Gq41I8OO&4}Hf94<-McgZuFE!`ou$_PmBhpva0W8+&t6WKke z-)v?Cdc?mGaXyW#ALMIi1p<@bj%S3vfw|B1h2=kKPKv*SfM2lUAMFUmzR~9%uYV_g z@vTkBQ~u4KHT4M?g)Bbne&JIIpA?aO=D5sXX<%57(InM|!`8lKg87+bQ@)xr=QWQU z6p3v4ZY0(KXEoDwkqUFp&aS#_X=VAPA6WqNnsL2Fm`N zn(66`O$w#|9#%Q>;d?y@Ku9yxjhkrRq$F|~tl>G`v=0|j$c(Z)_0dq%OnmjJlJ2^O zN*`CB)7aDvC9%I^YbV%sc)PnW^c^+uY=+IFYe9dcG6~~i!{7y>!iPflgMB*~G2?k^ z*^>$f?fd+7Bo&Dy0o%h3{M|x=#*AyhIK>3&h$oUe!USu|8Pab(45@M8_DhXNyiaRb zq-Ht}NCMAjr-1~8o_i=@J`QY}3*TQIZ}mof7}RZ;3F+&6B$xr$J&2neDRiGnX)#Vd z4-c#$#)uhfCsi1nt0>+e+Jdy7DO1LUS1!wOg3t+9K5j5N&A8PFUh_Cr+J*Bd?mpUV zL~K}T&w-YNfm1DZ8JA{s8?St%8?Ss+BAV?$dRXf&(+IEiN<+TX2xJi#$D+jurSfz| z28X+8#y{GIb+a~;e`iIA1()X(beNudwKikQ9(8^-+S@tKNI-X&Q*fCJe!eoA#5sGP zl5d|=jDbr|Ib|Q#d&?oY>xxrCz~Nu*8 zHzXeJGz=ad17s#11GG0T0~A$iR>-Lc68~TO#C^8!u`{i?g^mV)5|~i7%eMh7a^#?B ze|WhO%E!LG-w%D&8hR~s3p@J*YTd%FgmDg*=W>^M>EEyq;4(yw8QZQPYY8RUAQWPO z6h;Dw=gu5>CYL@tAKmqne6A)}t$gi}qZ{}BfTX6hO-O z!<{JU`Mcg>Aa2a zvMc5aD+Z7?(}=qzM7D*n%r_AfnugQg=bZ=w|Oe3&hJWb?`6 zqC!MDu;Zx3b&*X)6D-B~l(tLc4VgO8ikijT5c;NubiZboEHSO=?n76TU)$f7X|;dG zCRo0Y^U7fHZ2MImbmiQSDd;-i}GuAeT7pjaz@sxio2TVMxpGq$@ z3hjJ8jXcIF4+c)e^9h6U8%pPG2GJx!TCNLfPb!Ci*M> zjDY8QT{Lei@HW<&Lf`gzTF29K+X|8yU|WQ89&K;ySpRSD>Qn9?&w!M3D0kAPft=02 zvWS;R4OZ$NKW6eC>ltRe;XjFRx;~`}5UQ&-KzP&xUhz=uUSrBhy=lekwdV&FK2_6< zQirMlE9&WO_hqHq(h*h9pSWgTzOUqO0y-bGja zoT4jO%iXDB_A6k^>#02WE9^*wP{ecdzr+uoJjV=6i!P5;R@DL)^Vx4t z?e1Ql`NwN?z8CB3ywACOS!<^uAxjb`1ytuG(OVbK1^sN9z|mHHO%vG*@`x?xibvNu z6C8OH9Jv!5%Brp~i;m56Hdhcg3kbWV>${~qJEfR%?L51s?K`EOKg(|E`%dZmZfSO( zGD4rSKwvR`a4~*haaJM2hLiIgpHT5eg7Xw#F!+8$|7N{hq9;7ukS4`1>gNu#+=0Cr z#E-;bl!zd{S%gKe3%mf=aKp-fhG^LO{(hA{TDoSCTXBUUxQ==wM9l|vtT8@q=AR1) zq$^FkZ!l!#ZpWe59hN>C&4W}1uQmugm97CR^x4L`_cDmS#w6{>4%d1dJ6rP>O;mTM z4fqzRvgL4mC28pE!s+CSj3Pg(M>F(DJ5V;-LzK+<^@;QIkx}1FN`|Bj{QZ@6pZD4}~+&;hT@#PVsoS#F-q^|9hP$Z~N z-(gKrz#cZBx!P@hFpXAPk(+(qKf`9~%Xp8Hrn>Eu; zm%Rd2IQ-8W(-S;A_6r@#6c2Iw2T~PVCKK%}dOSGnJYnvyuF>bZ>-X5#x-?hW{9jk! zFX!tH=#J5=5EKt;NVkyq&z!Gp&5Op*TQfG}V%A};Hm!dz{Z>+HCPR2uTZ<)RZ25ixyis;dx|ZIOh*&WDZ@`TBuh zoHv5d;WAoe;Impxm{XntHYg(I&6t4qLHjqI$Q)(j2>S3@XHDLNmjM#FM9h8A0gd7k z%;QAF{Y*zgU{6Wj-k~t53#eOEPr!tk@*ps~2(4lLz|S*ejUn`iL+dcND6m1~CLPe# zbwjH4$QPTx+dx-9&k<<5?7wlN5Teurv(|$k`kJAd^WIi)d{Tw<@}?ANK_nfiPrfvK zI#ZM;8k?_-pKE+_#dGY;fxQjs&#y~mz|Y1C90+H%)Bb&Ap08V^pkzUq%XwaTdII?G zL$oec&P>a0RIsBG|K#t6gUm%Gep_H$e&Jim@e+J|%XJ-2%$X2>1FC17&TG6C|i z>RXy4pWa)A;gk6qz7%sGPu+6&>j|4^XI+Ou_|3w;Zm|@{*YjN4qzZHF-2!^eud+|9 z-EWFW?W$c;QCo=_6Q5a`t=2VJ3b@E=4SWe^(6jW;9c-v~w9XSt&jbWB%h7*j#Iv3g zAA)(+ebCa1CW_)(X{GhKnD0bKINY;BU)ZM`x81+3`gPa=`aIls4SzKgi-yaNsu_-2 zpF+zYO?hAuHhcD!=x|x^e=)(^ukobG8S~bNaKzT3f*D&-(~m1jX+~3z-z_Ms75LO4 z!^KOn%BbZk)=@{rEuJ`NW@g2)nYYOlVb!5erZiG%FXb+q=#Irbp3rG#vyXr`h_M&M z7#pq8Wy}bzCPt4PIRm!jFpQyf6J2LaeyUE4Cd&z}uEo_=DyuX(Asa&!S6rNsj;c^- zx;UPVvKEJ3Tr|XD$>FT7TQJOL!q>IWYd+aC8_QFm+y){EpiTfwjE!t@WYzvf!H?kd zpsf=qI3@P*T4wo?sTHb)Hmx2daknYDKyvMjQUf9v=A@&WbtBJmSApOB?TIT9|$2KG(;m529L6k$ewEk*LIyUuY? z@Gk033dsn14;z+{$Y1hGjDjM&M*4_*+A2`EqYmj1`!11;LjRj4t=MIK=U~@1ks>kD ztD*s)3vkqEkq?c5DW)2|axj~62Bb`L72hHWx zm%yz;(7o-<;Gumc-fQ5>@2C135y5}ND1D(PL`fp-0jx!iXm)g7r)H1niP&_ugQa|8_f6X6#U*!qlWZn4ID%L9BBEZA?O# z%XCD2Ov*pye`SnHjG5zn#q2P{olHbAkMsJs6`NolsAGM(bcNT(;-hlAS7rFS9FL zb}DzyU&(4U(Yb1+p}{%ZaDIO7Gn_9wIZM74V{R@VH6t!LOTRYF;uJ`<6Ozyt-EU-7 zu))yD4>-IN6jjBVeutVJ0Wo|MqQDTw4|5P57-$e3C>Yff>#ynsnjlp&9IBc%lY(fi zx_<_$Cmdzj3UW@Wq0ldOTChD-PrMe*S`I(A!DJw)a5@M8WfQQZ3M~X>>5A{Xqa>(O zR4)9)z^-d#m>o8XIu^>Z28vThMg?$Z&_Y*SzcpVUTaxiOIco9*^jw&x1VJ#-EAn{Z7SUjh_Y~HSJX{xunktjVe=OXIP|86-LF|??r)+OlkZlkK zco7Xl5N^=OPaBm1l$55*Fa5`(u%yyMEva;K*ijp_13#n8`n90Si&RqVMwQdGXW|DQ zo&thRtp{XY;6|2HyC>CS6Rr-HPN|1yUiLyK$TDaJJc(8fw^8MWM<{md(SsMx@k@(x z3(~xF(y~xr>pX@1t+3L^qF8^8#s_Cc=(b2uVlbol@Fr0(rA7wTuC&v?c}Z#4rcuSs zlMZcbRx;R?S!p*jO2ti`1Z`{bXO%-~m+xnl;b(PSGWeNIY4;hk^u{wv<>eO%T9!pY z-?vFY9|TV64UsstS85zIfo(xweWc2ZBnjG=-OnpF4%&A>GB}1wY1ioIM{Xo&{6BjU zFevEDW>wn#{`q+N=l{%pHmUq<`q`s=vyyu+z@#W?jFu*eOO4v8Qsqdyl(s?1eHB2q z4meb$Ng`9DmabIUs!`IkEsQrRy!-hsHBAzm8g;80wN<6cl6I+ejnb-l;aykKm?=$C zr5g2mg-Vllsh4qK-8ewZ(@c7>(X~lQ$J5N}e;SHE4ekGFD1X!>O)Ao4?5nY_@hGD$ zZ>>r>TxME?TU}pNyl_dL3DbX*dxObq_A*rLZ67M2$}I^Qa~<4(JJ5`1Hv3@%aYlt} z_xt`%ED{;bC{-YRawKiaDY{d{PT#no!EyAa^-h|`z|lCpuYM3aK4Az8*F8nC@~-7l z>HC1d(-DNCDG}AFVqnKZa-i`J-dB4KU!CT}b@$nV<)Mtuqw+^xERtSGP03aJqCMNo zmUMm1F4X(Npz7~V^>|NFB>3iT8}1H!dvzuBk(WXE&P~nwLSgFs*d8!`@r^poWMC&J z(XUPI>h>l}@}*|GKebyR`F2%V%1RTbO}^8;lm8QM=tKTZ25|N%Vm9A;0LDJz+2etZ zER0q`%Qcc*ce~-_1o;Ta%e>o3ffRtq5?le3C+>jd13SVA+h^IFcL~;ICX~GRi8POML z4P*oGWMFOoLLq10Pm>;{-=ja6VB)gcIZhO|>Ut9}x`GC~K=n{|#r=}WE8pUa$6)L5k@Z!Q08l@HG&akuZ zD#qbMB>*ItmWjY&(FbSY@9iuCE_cViys zEaSG={#mw6+hM!&BI}`Ef^4M3^1Vto{u!uMv5NbmLDBIsUYgwnsH|}$ZOoKcxgs@- zuUS&p>dK0gD|DxkGpe$FNRS)=F-RPbFkH@d)zlRBwkgW3ZC2!n`RhLxnc9rlAhlU zDK(B+`i|{4+Sp;Z&SD<b1IJ9cejT^DT)`vp-3HqPM z&W^4x>&VY>v;5;k{Wr&sf`OxfjmeMw?(`q*OJ%aYE4CQsP&QDX@X7~OsYQl>mQ5wh zKviX}Wp6>8hAx?fT)?e|$Wg3Ca&SG5{h7oqkDH?1-YkrK=c9n~+NRAxl|5otSU+@t`)*lNoRy^Nars0I~ zWk`alKrB$enPIh2LbeNsY#c@dYu28~e2K7_W$Di^m9JPTG^3SEs3v{v?Ka`tx=`tC z$Nikzrvj62bnTkGC&s~xu-GZUR*vB0zgBiV+>>G~48iMRoj~ihAEyX{VO=ZMoSKi< zvd%d!sVk9_VLs!kP_uMVa%pLT-BFff%~Cr{dK6k|?NtN3yK+w?U)#c(Yer)E7?2g| zG~{3hWjB~>j1949V4sJy1Bi5yx?*w49`+5nf<-{=Sa{QG9zuyx>+lY0!q>^S20c}7 zv#{TnQD6lgn6^fgj<*$69?T@B-9?g}S|Xm|Hdt~5H?c&m8-uy?$5z(f-mILQ!NO$K`=}iX2T#|~h zayC=6?}R=hX(e!Bq6-e(7SS$6_5D#v<369|!&Fo^dl-8Eo|uHvWg`uNT#ho;;<;k5 z8RhoSY4rLmF;CLl{&)*c!a;c>jI&89zqxB5xG#0$OP|>NhWfceDc<(6kh8VZn(DHl zPsfqCwfM1Cc(mc;n18Mxv97f9GosWPP}*Kc9Iwb7*&~WZzLi!~Ju81f*J^g)drhgy z3ne{23WnXlkU&n0DC)PL*5d@_QN7tnRESw<9~|D71FIQd{Hv&uHL|!cnFRB=S*mC7 zMM)x-6x~y?1=XTwko+kZUN)1={kxe4CR%!D{OP^qQLSm2IXU&@m!piuQK%m?NY2Es z5?qMH2%xcU^#5&uw0#i>KA==3;VJ>d1q+k(9rjcFXBwbQIbuyYNNU$VEkKw83A<); za7fGV)&@}M+R^Dmw3G#6ayGF6OiVSi=v@nFmWt&yDF9!?M~aDLJ%h#V!QsP-O0Xar`;`Hqx)H*xfYzJ z$Na3{g}{HFEIds!=om8_T1 zv_sLX(gMn1}*tt)J~QEW$D09p066_n?+1sj$-n6KtplRk%-^zJ^aTK1QTN7 zCKht|U;>rG;z@1GSb;F=K5Y*-?P4ftKpmZtYWlbNP%~CP#4@yh(JEp30rjU+vBHTS ze+bq@S!#q4elu1bNd5yZQjiuI-S08Rqk9@W%%d(6+K{Mj(ov2SuC=D;K|*BMe74m% zl~ZTa6GG37v>aiwyFNxeCfeFf%Y`82L$(CDcr@+fBYaobRs?vFE&tv4?QdB+kpVs{ z?hp=j$oy_IDCUiW=or`2tNc7nwRL{xinf^Hp0NeVUimuf%LpTIvdr9m#^pb=55`m9 zicMc-2=v)&{O4hZ1~r&PQ_BY;_Z9TzB0H##imz?Pdy+Acm_2c|VvlRU*n-^bUQcfje6I0N>nxrkO^ccRcIM%?+_= z1qjl4XevIW5D2RuB}$O6(&W)mm*IueGA{r*S2IY&iGM)&So0TABP%n1ML4bFL;4$d z46p{(VJ0)u*TS%QS7_XvNds_{p42?Jlw(xdhI|1(aU72r^*dYw3Fl~BhgiI=2p=g% zEG*qyi89_e{U{di5Q?z=rAH!#yp;BRXFchm!kl*TwUhpO56pMk-my!WVD%T}a0aV$4x~|G+EwT31>f@ppX>AT^|ipS ziG6QSBJjy%wx3uzz-=PwoOx;m{;+Gf68p(k02>y!&4W24=5YRv@Em*1Z`M%o3<(LjuSM18P<3!f||Ko+h^H(V|1_Ke??+kd?&7n>8)12G`*_ zptIj2-$G02e+*jXVz<|0$_x=jU_}Ou%Pqp;8@A5k) zaGObfFw|bW5aDVWjzY!byAqKi0XvNl?cb2abE+{8L!nMIo~ixvjccge6@H7>9i5CXOShe17;Q2-fW&>y|E z^*?3RM}M#a7$Gm(1O-Zd7wAG9VIByibHT{pw0@K`XNarjM>HWUt0)_vbHR+~B#}+(V31iH zAW>Z`9euRk_cdogYRvB_``Jv1e1mRBI9H+e|H$4`EA#^r3FK*#+({FIonA)aed5FK z(`Sx(E;`e|?$AezZ76PrDB487o4cAL|8>(|sB<9%^7gml%-i3*Cm^oD0P_rLi##H9 zQl)nvF80e^2b-rVv=8DC(Qc5g-V>NWyHACo)u**YB^i3w)2WH84Lega^7rHGY5iZ! zZs@{(yMJWWoDCd?+2ADXEmR)4Ic%gkqo-_^q_<- z{3j#nahj~IpgSioUb%6EKxYwI;qoy_lD8kARqNVIVUJaS?qGXG>nd#db9adiVGZ)t zwtdO0+F@zJ_S^%E6AlsSnP^{w5@m;-t(e25WGqsL&_ZU5*3MB=cRRl)-r5pmpBnZq zm!cUrtWh0wV0PO=a9T!Vu~#tFp{sew<~nqEu+Ynj8tH;3YyM$wEH53GRh~E6Fi}E< zKy7hk!`dNBZDa5ojZyU|_#3iBV#sP&aJV!F(caQUxEKzm_f|5e6xDT35;a?Lv%(%% zaZaZ1UNId^bEvYmZ!n5xhP)hphi`1>_YT6d@!9{4)-3<@DAt4F=WKN@O`Jrr zah^XM3T4xKCM3x)9X$H+g1eGw_yjUNwx%~bIi<9)h%*{PSO;j7!P0p(&)m^Mg|r)O z(lH-}p(ujHz&FjNF^i@#1+hDn848!y4JKxsQ2pP)dhKDFEi#F$YE3|9RU*M+5P89Q zNLl=N8sN+GZ_GBxbgkMA(4Qrh{vh2Wy5GUaMiz7#ktXr?y)^Up2}Lk2KHWhA+G8M` zr(y-;r%^gUm0=>?)u=R~v5 zO{-n-W+fhcH|Ef93J!}b<9m_CDOJGbrNkxajSl`Fz^9q2!s-`=Zsq z((F6*cf1g^x472kyK<|71di|=OIlKUX&E#jG=_%y$HZvV*F)RiPqn+8p0)Gjv-zCJ zsRUc^Dg5UHWS5B+BYo0P`X0_dv^@F3bLy$aK!99@gym8eQeI$HHu0Xx&4SQtSs;`mgPM3h2&L> zaP-2V{ZtPE`IONvPt!U)s(Ky`FWcI@%;GJss?lGJa2}6mfwUJacgvv5XFaxpZ4+}; zt>P*bsw>Qv9(z|n5gvtoBE!7K02xZkEsV&U!Ze(Be+^$}3)8r2_;C80*K=WwDp?en z4x9btz@LrZl-`?xAVcsbxpE<`{%vnv`(3eXgU`_0H8t!bJzYq|C1g>@Hf4G*)1iJu zip3+bHe6XN7p|_s7dN^orjB&mM_2GE(LV4LD3;q$nE07@Fw6s5+N`YECk6>bWa7u+ z20u1onNz7%Lup8E2t6SrZ>H^NgK)|E3gn_+N-C-Z^8c>~#LsX@q*L%`v$T_f(cW+~)2+U9lL2Rw#}0`C-nF z>idEQh8^+XjN>row>sxV|Al_LoH(qI=O8{k?8kg~WDl3@kU-oIK;8P=S1;Lt7HlW6 zYZUjQt@t8?%8wuR9c3@_k%^d1e;6Mm?V#WaA3@3#hK6*QK!3x@BEXIrmB_LfDJ?MM>C zcf??KER}DM;VFSm*7kWO@I1=nV3yzW@_-7(A|Tn z->_kM78zRw6$5h0N%hjuA(-@kG{ea1Z9Sqhh6tZZS7Ho8jFpFsoiMK&K|hStVOFE} zHg$anVXI?@AmOPw3-%bJ84sH5>ZgknFwBit4rypA)0e_&AP&da4{vwtxW9se{{H@( zQuH{7Hzv@uFJ<&MX@vPfRYrS)Z7C(V{N5yjI4#`B-YTrUXak}*wb^nBtLj@F42w9) zeQ)l1dYicW|KjW|+v*CNr9lG0Ex1E)4esvl?gZJmy9H+x+}(n^yTjhNI|O&v;6BWp zGat_L;kb|S0yL=NpvhB1$JjnlBs}f+_u*OO0OCp3S&CQ2&`(0i=KMA}@VwQAoG^ z=|VC!%&&f5Z-=<#&jF9$a$DR|zVg?Gu!ze*Xpb6Rvct5IxMbZ+d<4qd`Ryft3hkGy z-`9dhDl`6f6zX9uJqt(llHu9bknLpV*B519P9%ROqz_WeTtqNa$hHu0=f?OkhxxTc z`ITD{_A&B{VD=aVeC~#@GyT9JN`z}>&^tC{1gnbp2wmIjFygI%4Oq<#?ITG1wL;0M z(2e0w+yV)I1FwaTAqt>6Ln=)9I*&lrM(m};aq zPrJFo3C!5`29B076)Lm-T2c7_$H>XNydjtLS)Om7jaBsjM|p~VzTa&AqdpB>R>d&| zY}zyl>8(zZAY=kl{Qf%W&LqsL5+wF3^v%De^(T5r=wwv^Mx^U$g+f23!|o}O_?h>U zNd_D}x~{pK!Q%78R$3K4Qvweg4J$n#PrFJGr=BKc13zJn#}0BZ20+oR80}&1OK9Cg z1;g&I%ZTSV&)1~wvOIp^^kt5!)X)hDdHHQD})j5YuWul>0V`48!a8m*Kw5uyaZ{hfP9 z0ngBESw3UCz>;i$(${i_9FfE{eS7e4KARaG2**jIdA~C1bU*+j6}MYf+FMDS3lO8Qw6_lJzD*`3oy>9_Fq_^5^Sk|jkSXUJ6U9q$XjE$<6) z)gD3Msi%)3&0d3{{7_g>zy7ZteDo!v2@bv_TnPsGGdR{|tRI`yc94%je&q z-Xr>GFvINzoeVZ8x1vALH(T9HBB#$t=zV^`V}oa9+TLabQr6bLawmVD2EgZ)dTKu} zQPc|NuVN=roUNi7(K5w3Rz%)F_Rbq4L4@!2toLdG5YoA=KX{c2&Sy18x&15E#nnOu zhlUsLA`rpJ#r5DZuZagYs`_}M+r&`pU=i|_Ka!8zpSb15>+n!dCs zFddlC;I>xq;L5$#4bxGgMpi2!7WgA3_=&vJ8QggEeeRoE5VN{&kzCJqaEsW34xZ2( z2J5l1h(2)|@>7~;K#f~FYIu01A|4j9j~okh6!gsV;Jd4>aa(VkS5kBB#tf;5< zAN_&cWo`X4pPAn$F;MnG)G-pFcauUG?6<1(9J3ITOP3T}F(Et7Ih6!ToDiM+-c%?amj;pb{imP3} z0e{F^YEB{8qodq>1z1EpJOnjy;%o!+MV>Y-Mpz`y*hcgYmaraAaFX8q8D($hRK3``Fsm@JY(sJ#6@&*|j6b%>u zHoyQz{#P)|#%SnId?h^nWV!(KodboAih1NyEqWMOLA#JPG zE!M~Ztv5q$Qg0>Vxl6i@{HF-qsiM9nAgH1h)`8;M+XsnEqRnTOfTgMsZc@Ch)&-`kl|FS)9#rP z`Q=5sWM}!kpOBSCvPWY?(WG#)6urWGZvHGsg20-bpni$vvK^O|hgC&-*#7M+3e?=O zn%Pw{ie>3Evj&dB=oJ|Y&&K-Z*WB%3d%$uVj6>n7L^9_6*nVegcjp|hQP5t_=@#_yHA_Eyc(Sdz zZ@d*`8M5z>QZN8R$Erl3$yNbwkcylJ6+G$Ds-4k^^^5Uw&dtp{C-(LUo|Jqtkat6S~ypa`w?CYXUgS~#Unos`J&Z2q{6!AEtp!qoO|Fff+ynJ3r@L(jfi)cAc0bz z@&&R=6<2deaK#6UZ--a@f7(!$EVHmrXQ(~t+$>Sg-%}_GNVseo<&K0XX*X!gw2uh4 zjqfy4+sPJk`Fs|M#(}P;nQK?^NEqhFgj|AT>`}Td%7|}v=#=K0#)%tjW}POgohG^u zQM9K;B)7AhSM!^qiYGNPzYwS{Jc7be$vF*vUqRGG;}raU5;XC{t=kVD_Q@L8e}9xWzy#>Rluv!joKWo{aX@Q2rx& z--tQ${rCPnN$VvzjD5sGdUiEnY=q2YhO7EF4y+>M&JS5}CRB!qWPyxxzC|7R;)ei1 zA?^l*a*E6NKnS}EQt=NYp;=sNFKOqTJ-(3l{|GzBSzPz4_+-80VIUwl|Mw9@&C1Tv z79eH`Ftu?JF*A1jRBtI*{wwV~Tm4gw5y5;%S#MTuF3Kl^gR@*vWt2m6piQtWkWsjX z21PO{wj{b6cXa$+H+j^diU>!2hwx9j9&a@H2A4!-*E8w&c^p{raOsjn=!@;vJ{&Mk z8q6Fo9#MM`_Cv0nEP{wHfvj;=^E=^GvWnR`cXn^`LUSW({*nS(KPy8Ld|B(ccqqr> zA}od$EAF5)J|0E^Gkm1%1=oEMk$(!ZoH$Vh0bg~I#44-(%S3mA7#Go0cnciCfbLsm z_0Wb38TCC__LmW1M9xw(99^W3^&Ag|=`aS6H!LJnPJk76XoB57y)_yhv_|PGdas=K zu&$_lLl(>IW1r_X6UV4kct))tzs+c@PwxRPDF1zaPq5U23YQy!Q(ki|%+-%&IJOcl zHe}-j9b)b@4b>@m3NN|fAPdr7zupV8FChgR%s6@hIxkj1>lk?jeh)av90nnGU*zbM z=qs^|BM%d-1+*`IRaKnL0nk3Pg-M|OZ;Y~w?G1}cIG9p?*iT^-l)UyXz9_UuNT#(< z2lA*efYRdP3=`w*5o?ait+-4Wr8$nq+t66~{J0wT`J^=XycFp*lYc+FE;bklnW$Wb z%r1YgL|N3pn7YbhE{AQj5Ieg1nOk;BM^7?^2bP14__@fh1k_;UO+Y(%s^K5k!rQ+& zfiX?mdY~y5Ni)U-ZMl8d(tU=Zo2Zn>+l+tD_iA`eHzBSK@_FW+mmjaAXP3RtJ**9Q z$ts+N+H;dcf#x@RkcyfRtOywD6g`PKI$TPxSWchSGAl`qbrJ)h9-l?I>x1D&dHuVG z_(!Jx43`zokjaiyxryCo+f^$rWNJ*xjdj+Uu04GQiO;9Mt?J+R^G8xPQ$(jUwTaS4 zq2pJ9cB&{^`S-O4dHo4IK`~5?d{)ps@Bbm9Oh~3LUVXw};1m8d|2zDpY#mIDZC(Bg z@J0U(cp!Fj(!M65XNmrgs#-(gcrv=-i9dqsGM-uX)Bwl7oE>VxuXGBn;xe}ru>UvQ z>yt#`Nm&%kEfjlPx*a9~@2_vy7`+slJC>sT!t>&6y14Dlj~4bkYd>@@5%oZtNIx28 zldWSu4*=?MeKS2m5!Rq2vI%|3bnv1?fr{5`>|>v{&xguJ3I^1e!H2!bu5@qZbXjS% zx)N=_EY_`)-)>mN!!RhLZuESo74~xa_90o6et{{NfkXQn?oz$(n_Hw z<&tqCY6XrsrY&}O?U|7b$V^EoEPl89>dk|oAExM)+KcoF?6;c(`KT`PbMxM!m}O;) zWH089n{L9#ICKZ`6<}a+pOq#mV#sCJMo#G&FP8K3&Hi#Q_fLBm{`J-1mDnC&`7Mo9 zfYe3ZCOven-ig||^;JN*xvgPRplm9SrJR$pY4r-wXsm`|!Ni1(gHMo2 zn%$jXU&Um;l;N@`t2m!I&v{QhszuXYLopA{dPKZVEm5w33(mZ0{uuG*Q#m|6VE3Z( z)P~8}_ia1*Ya(OaW}emykK7Lt?TgW+qQHK4n-ef&Q>3KkTI>;UuTsyk3ty#le2W$j zv6;y8b&RlYnOpo+a3}ptu)Q0)dajXb7z%rEozHPGB$378}wZTg<2BDQRzb_S3D&JD(drMG1CuHbm^l% zOmUK26MGc(ZntV2&$Q#)&@rf2 ziS(X^_#i4%cDmQ>%>zXH;pfviMz^tScaE) z(28GWt72bXihg2I_B#^*zBh$E)GruOz0p-M7>~Ehh=(6Yi$Jn*ABi;xSj#pu8v*dU%@H!;6ufCn0tCVWa*k4{9}Cu?b%&VY$t_S-V)GJS@Ol<7k0QaQx| z)?l&YcX6r|IScK1*1Q`?{er)SZPZ*i!k{~x?@NNDOJYYD&I(SGa!Hw3;$(<2w~-SD zD(E+uePNYM@uvzNr~{@W6oH=WHao?A7aF4izCr<83dN@D`3fQJ3`{Jfy>z0?DI@(b zVb);c813V9j(`7PM%xfrAeYb})5Vp@5~T--pt>DSP^VTQX6Vrt8JBTpCLR>ueCs6~ z0;2cTJ$8nb>9UU_DfbH$&AJ0JY|O54^540sP8Kh{5N_PUSA~ve92a+!< z2m$U|3?edf=$$v|lPj`*ol3Ntp?KpN0Q#DHOUOzWImg(m106H)Rx0E{UZJx(>SifA zF}1#*VPwM9Ugr|HNS@~oUxS!2U^&d*4;H#-v2hE=to6W5B2*;i+8BrUr*8owi822X zND6Or55&dRJrL>u;NJtauxRRgra5hdB1UQ85F7KKfJ~#Bpr45J;x->UeKoI{dH^o5 zlL9L56e`#r;{k?l@>Jp~uDmrNeIH_2P-!&(4ozE$Gzb1R;D}V3<0vgZB+yK5=KsUk zD+$hRh$J!b;bnc;vW;{-@T%lNwyI@e4qk9*l+L+tQU2g>{@p!iiJK*2YC6XbGBLyd zF}JMU;Dd2T^p5?(PWA$|Egb2AziL=HxMEnxgMs4dz!z$Fq0Psm$;}+S9_`bnf$V{Q z9?a){v9i8{ycGKD$1GB{cj)>@_=NqEO-MzoLF&W5oO1K)C6}5~mzfAng!`7ZpRig; znt6v?>?SY4+kYPVg{BGbIUa55yh9YYwTIpa=-y1Yl?g7Y_FOD$Gvv9sgZJn!@a7QH zzO~elXJagn>%HLjv~^c6)ZG5 zR(pMLgysPZ2Jk|7VG8I$s|)rohs~stM-agJVseE+%I6Ac!v9sN7JPW=6w- ze;pgEsGuLE*Mg_YRVqsMZe=k`0{mok{?)1t#?&WkwG_6FSo#ShI3){eD{I!Bt6hg1 z9Qy~$GZtnQq@wq1Ki-S9_Y_x?2N4Os+@zDRJHD9~2u*XBCl40w)ML(Xc{_5fuXii>b@T6qCM$42dq=Ddh`@|qf<)ND z;oX_8i6lYBr&~Y(YHyOOZLGn18N61OuayToSN`Pew<}Pb#=K0=di-jW%U!S>#i+D4^_7)5HQjV{=^MJGOGR{!oFFLFn% zo`?~5Z1T1_U@tGYWlbUa}maqL$Qx{3%?b^kVg8a#vXMf868@^xwD*E;gT9`aD zZ_TASG5)|0x^4%osADC4$ydX*18^9J@7I>Ohjj{>2DEeyjjDM)Q>3PRbxyYl%{|=( zuG_dyAB`^yMEHV0K6vaAgnjjx883}rEIJFP9UNzBcf4KB`}Lz5T3R)g8n&N4m&8X* zN+iz2HSN{Jzh|B0dDL;yc_)QRHm%hAg?IEe3n#zuQA!t(ESgLd)@8Bg!`Rnqgqga^ zD&zrM%*40bzky+n>daQXj^;n{BPJ2fK zd_Wlsg^r{Fh1_+1$@n3u;aP&mCZkjRjK|k*S(fj&h8xw`C=Q}*s+uX4aA1tpMm9Gs z$h*DP1rj%8258eb+u6@|!zhq2i?u_#vT4*N7s87UHhV60F-)hXoY_ni*G^VM<^60D z8h94UI{{TAhiAXtIMdV8HUc;~T*e!R7|WKBsOBMp?)|g;jhT}k6DgA)g#QSOMO({M zVH$**41PQPW}re~)f6=7tR^u%Jl~mJrp-)T0UAfvBUor^J^Qfgob($HdZvfJB3F3Z z1?dRCotwszKWXgZ`ViK%bNh5svk*&1VVuuQ)u0N6Zdqh?A>iZ&ghET4J7Qtxh^aRBIrDo~=gPaJd7P-RQg)Bj6p6re2+-aBgfcwyKr7+vOOoOB6FEtqe0rqxgI;DUN?mT)f8@B+XxLQd zN)=FBX+KY&T?&3$`(Wj`QN?jon5^4eBc9JQTszWIC5#*hFt>H0-!H zN;94`(<(psv(3yjI%>dtq)#(Fz&w4JV4LDBexy~wxz31j5Q-H#c2vDNe$EaRbDEIt z$tzk@9!xyxHh(LtnEJpOoW+J?ERof1)5=+<_6QjOuXpM)I^Vajmr1 zh;oXd;!dBNL}I~{;ZUV$ZJ4Iq1*N4$GBC_I@fJ!1r-_pzeZrgb9*PNKlE9^9D|3M_ zu;RSSu{n)9zfu}Ll_Gu@B_i~ii+9(2tK#;;B{2lbq+pJ^WiX^8IR}NAUt0LiDR4kb z#0WRwE=h#iExU^fEMa0co4%ZwVBNV+=c_(giF0KGCBpils_a^uTahn|@a;T}wj>3y zd2Tq*tcE6vatM`TI*>`qr>?V9M7Tiy-!cSbghEP=_Hecm3y^SD*NcexY_qWV3}w3{ z*4}4&gUHj|(LMG()543o3H?0FD~1O=>>gW3r5{vmTXM0^*AkZ<=E@n)ErM4MR=Qjk zW!8L1Z|7(u$?M6qWWAq<6L%Slzo5Er1**mtJd=)V8oJMod5!MD`*f@+Z7)-4ZF$c<5mKv&3o#asV2dOU;8M#m%g{N6 zGXUZ$g~QcNV=DXk%S40qW6tX%Wa?nJMtL{lmUe6BSxGtn7;x_Blv((6qcM$O+2V8U za_kJ8)?7^*_waS(Tx zQ@@vyM;TT0Qm#(itsg^Kv0z5P7dfkO-{JVi{{ig5m_0E5VmKsJYQXp9JlFRWEEl!n z?{r|Eq3FB_R~XKLH`L_6>gurr_a1yWyw7|w=+ARAS|rnswf6vHLHu`UZllpS5pO#A zAdAP!FMKTrV$-*6L6H*2PC0dJR(|?DcSp3;Lv@O$iOtK}0y5?_p5vIX$#vC}KiPAf zJ>>BlBT;(yc$jH6W^iyujs%N8PF4Y%K-r!(tONi>Y5SIeZeEmYvU5O(%HmMCF!s9Q z!o~_^arflwl^GV@@-H|+VAbl~?=BsQ7%eRPzlo5fIy?CjKd06hv`kJ*|3b@joi;{N zm3}(J#g8DdaZU=V`QQ8VmR!`KsVcNd-=9#{Gy4q(xCOi{VJs5(H_&Jk*|cUq)1fR9 zy4eC<1jJ|mTo@RTt!I6s?HH~DUwx72V3TM(E42J8GgF_K4|qWP!AGm>t~4WA50hSI?LI{94$#Lkr^Y=$eJ0c`s+g8xw6kPzWgqH}y%!ChV~fhm z66KiSAqpNNIr=u1@Cpy{*zk$6P)%o9B?YUJ{%>Qm%%|XE?CRhw4X}0mlzuq=Tlz`*f25zGkB0SnJDoo% z<-a3Z%FpvFXH(Jw#DiKAAW?DAw+D_{8-q_7|E{CI@^(M&1XJY?!U_hEjCz`PkhP>) zCLW*V+z9o!j9B@=uZ{XUYy9H@T9nqJn$8JbGv!0tGR1!1zoX! znu}ZjZ-TXOG+9Ff{3o1r4{vsM^;-v0WxUuIFiZs1mjPovYw|%?MO12%GyGKjBWehC zYsa(ylk_JiUiArK(E@4O_~r8F(PdtVU>pb5+;fs>1qm4z`m6%4mF1JvEt@hymaxT0 zshI?HqanJNg1-dx%BJJNu1LJV**vLjUD(7F+Nma}zR$#Hnmh-`?lg$;iv5u`u~5D)DSB0Xoa>Y0+|QE_F@CwnEannN>!vAB_9^SQ6YhZEJG z!?)^${!!_dD^r9oJ(%*ypdOn#7aEFpC`s@}C=w6#xiVlLXZQ_IP2w*4`17;5Yh}(8 zvDXeNYx*+aX86ZHTQO)%18QGbmHD#=#VvnSoOQs8|FyxHkCe^+@}O)+;QLm5-D zoA*2S#yE{fN)Q#6Kczh>=$@POK!O; z3*$Fj>5S%Lo*cPGafaPY!x&k~80p(7-2dm@ZEcW<*XFh=f@m%D?LSb&{P#E;|MTxx z@VUWE|NjL=s-H5(e<3DWQ_llK1M^*x)pf;HmMQ#ukgSbWqRcAok05kRN?eBGJoKpM zjkMyD^XU=!tn}8c0g@e(D~%;G3BV8RsdpNu+{9_BIpbQU!{)=6`@1u?kJpz6Hi*=p z#c{%_q50ciVQ>eD(}XgCcD#Ip*%Ppx#LP(g4TSWMX{6~B3+hO$xYaGDj;ps&6&EgZ z6_@x5bI!IGFTjt|y5kkevi*6eF}I8KOim>c31>L)w0e{!cen}=k%e%f-GU>yqgrl7 zs@W$UmoX)_tn)i&tWBD5#@Y=DPah+-<%}KAmj~SCh{r8tc{?XwySSmC+(H7{ ztUf)uNo($~7Q8_~fNmhb18R>g>-JIU$Jj2`Qdy&IrZJTs%1~V#pLgMo0dN4<-*#!; zh9kP^qMM-wv?hbB<{8V*^&*ZW=d>MONKVhlyl47TqGhJh_Cmw!oAzW36H?kjoJ0(y zE-F0U!LB@OzG{}ro!q+ce&ZJsy0uj?O5MBNi zu4xS4AngGUc(PL{DhjmC0ul4mc7Pn8YrmEUO1*Dd>fB>LsJ2EG;#OPJY~io-H2mG0 z#D;EYN#ITEmOUw;MGC4uzPc5OS3;ar`g&M`bXZScBN>4jiEqEd2JGuShr?t2TM!2c z_N!c-0k~I|b1UM1IKVh_z!cFmaOyS_8d`C1wk_GwV*pz0S2*Sx`n!Efzjk0_-JYFR zp>>sC)wA+O+xUjT+T^Wzg@e4#dRYp?=?KYAK-XqcCbEj?N*ulb>>Vr6jQMm3M;MoI z?9hXGzzVdn+#B*Q9%7Qevt`WTr63ZRh14QL76SfxPa`h_IHBp=$L2d_3PI5ftF#Sb zx0}qj*uaGKZxZYWt%^tKxMeWrzZ@29-Lqvi)>E_&DdlV>QEkjbXuuR4iC+bJ=veck z=jh1W%d*PqM$&nsvySTub6{z%`lZNNvYIw?xUcG9swh-2d}l%+=l@LuGIx$Um=yn}&^={* zIDv=98~Knq+KbiYiJT59HoC-Mgb^*3<96d| zhHjxep~0t3)F|Azurbx}#iu_NA=@a6WW8+0SIN>>sjUQGau9-6ibosYIq0P$^$@ocT1K@|q2bG2aCofc^b(1wtyr7V@#fIouQfQf&6M#H z-lO0o1!E$D**^}~23lca$LK~y&=v=0HOk4Ge<=L(^3mNA&PWZ;Nfk)qimwHd8NjHG zIpRCel5xr`sQXKdFs33EDQ4tUP7td6BYv|gupl;LI^a- zt{C8b4%w%E{u7gq3?U!iWLmZvZyn!;m-}M5DJ7)XlCZR#5Px*$9H^PTxqY12X@N@63($@DXuyT ztpC#ww6stf>g}!Tj@e)gESDJLF6LOoACTW9aDSAPvp2AAKn-#HAvTMB*3jm>Hj1Xq7;!^0pnRw?s(Y>f z_x2;MM@1>x^6cVb%D7Gm!%JiG_)3h$isr0fyz5*{`dz~L`8kX203T){`}`>P;`kg5 zULpN2S9YNHTGbyBG4hPB)>;tFJv2yn+0m76S73Ves?v^Bq#X%-AtiTVVVtGBZ8 z6ORla?<(B&Tu@z#fsgp_z_s;adNp%(VI+FbmforxPq(DTcETa|d`n4b`w|JUinTG` z!6l2V>jRU-#0MM8R0b(Cm=zvsJLzV3>!Y}zVQfH-gXpn5MdXgYknq+vv=(VSxAG1j zyl$*Btkxo5Pp!%ED10OvRMCIe0YKOpFvqR!Vr^^Qs%o}eHdd9c#x09WEaz3?+LGHJ zIq#!XVq$bl=^xSC2RViN0l;AArE&`#DoV^?e4yiR+Vhyzw(%okw%w7ha>bgJ{i5zD zG~8ryy0SK;FBu4C?%6T~Ix=ye_d^o1v-Z<5BxmDXN8nePtUY&UysmnXO&}vr~f7`q1N?^WiK#%T)uyl3+qAtgJ;x7&TiP zISshe){9ZdtIWaL#>W64>W)~Y${2~^T35umR9``)t{|7%9AyhSSckuQ8$2tL7A0W$ zC^m;LNEfD#f_##mMM~=_3QqKt{XU32XXE)?dT|Wtv7Qv?b!G#r;hSZUrZe42gNQGO z$u;`#wGgPZJ;#9N?lt5RChyQ$nVI5=uX(Mb`kfkoU%bFdVWlKW5-Zoj*M5=?c{u7d zAIP*l<^rpp=g^86_YZ0v;GNJ^vFR|1wd~wb^ls@%mxjzO*8wh2d|C!?u9W>%7@y2$yXr-j0Pr6^6+ePo)3sJW$P zIs7Z#D?0h5z*u3$S^}4SLgzE!XRC}{Ui{SoVM^Xu<9CY~!Q5$^F^E*pN55A~8EY^1 zx&9xA^%qsO>RoA3WwzmQ8~eq5 zsiFs~0X*i%hLfZaO4Y>_?}v7sMXIW+v*|m@+`6r1SB`++1lZJi1^VHK4lRId5FJx8 zOhXgMB4+8tn;+^)MNE`95u#@`a?@5d3#~Q4fjr<6BJe|an+VV3gQ0)B0`7j{Ft0HL zJ3){!Ct41PHDuaGE+35~)k-E`sgugwkn0{b@;6v6@qs!}z#9G?Y zi;!j@u~LqP&67Le21yO(S1U6cQSn5I4iZVVx5Fx~ zn~(c_z8wDIX}1<=(3x^BNz(54+oP&rc?_{nkoXGqX9QbpKCF_dQ0h6g0qQmn;dg$h z*1^lvYv%VTk=N)H|HHZ`CBnX*;|~q{JoKS{PC}gZX$e%xD}!pmXxUd>C;k2h8X}PC zqhJx-5)Y6>IRSPYrCNC)wdQa-K<<&0UDE4|&<=wU!4=Mm5m0mroqfIfThzU@Bd=d|B?%P&n@T48-6k!tN)tKp}-7SdH~de<0H3nThnbk%|rG3bMMG zigJyx#!tHC@~x#H`py_1EL+SPQd-Cw<3vv=4g^lxW%6p%0(R9@Tosbmm=i6PYu;v> zEkuzEUL$tH1KBUHDNZ+nW7K0`5((k2I${8|c_+vGf=j<=c3JG(D%1qb=p1r!cn5Zj@^~amc+mMB zenyAW8j<{@Uv@|7I~*gVd{clX1rfe?2|dBS&J0lr_dn^B)RW0~qQ|`A{LgoA5z%|d z{HF`c>~p;MKUjA^U0DCc;m8B*EnF@Ci^2JSr;I0mf&r|Ln408$WOvSRC>V5DBx#uZ zIAFoDQ+$nfxbK!*)-W)mjy;7_=e)c^13$H5jjJ)qFe@;n!opE^NJbVk^>*v91I}DP zAG6W3*7e`})xdW7a^c1Ha_PWi2;&H`8KM&A4UJ5PKhr<$9hAGnlBoB0IbbAG0%m|_ zkSL6abzUl;4M7yCrIM9WUd^lx&!fJmvvw_S&Pv4*c@=?lycTT0@O#p??8tpGQqkVc znU)3#x;)}XYfN6*QY}(TtTy?GMqc|Vu4Xee?|Kxct;V0SW#Bo|i!C()hFOYDVPp{B zv3_MQ^4O1#s9;{N-Up@O~* zh)1v=nuFbFS`u`su@-;={9&Vsr#sucpHRMoR)@>%?)x4h-61f8N4rCX#bt^UN=L5` zT;-h*=sq$k|80pQhyB>=Ymo|gA!?XDhcXPUyJTS;?mp(ET>G)M5Jw@Od)D<@Bj57 z3pe|d;cZR39{r2%qR+1!$&exPI8uGUmhQUz64tRM=*6sWeQFvzs#|N(Fz-!yAowUx zUS6K6cvnrGNlcA=H`s;zx~^|8PB4{_M9A4SXglTvKhi*ERZxd6?jZO`?TQ==m2}c^ z)ju>}m8~nV=cT!7M2+V+DH5~36qcsSr}3D$v*E%n3{GGEpZ zSWsUp&OJLiSY=jLKp-|P%`Af9XR_)EiYjamf|kKRa84lBbQGQa0$p6Fj*(Irj3B+< z{P%9LrB_5Hup&Q14T(>S&uGT&>(rRpH&Rkgs}+L3!s6_0@V`TH2lIn+%RC8{d^aWe zyF(L_Q_y0NU!Z_-@p z$jim!J?F}=1O}@%r$gi#P3i_~y~h=FoqxIucL1HDu$Jxo3Wr*S_~yZhq)|&(?Ll1X zo#8E|kD4=rQAng7x^kKulema5xm=-#+7=X!-4aljNE7YxO|5#)mIbKQ2It5Z6B`%Z z3S0#}>(A0=re^L`vg;+ry_0ZWgZL@9^!ta$;&CY~mNI-36IK_VDbI<~oxWY)U3Hjt=!az8iyX(m%dx{yH* z4|i9r@R5(bc%G1m4FDtW+Au~)*U632;5cFH9@X_TmS4J zW?6ypU^t9*K-aP&%H;1Eld&f}#iJWr#jENlU+?2@q2`HCXGkyE*iYhGESO(|2HhSh zyXFKE2K9uw;5!xQd-7X4!db&lyI*l)uZg@lz0{eT zt(Nn42BL9GLjMSPx)LQ>pZb)x<(ZG`OTG_%^6q>dTO3;jtQRaL4zfn6&EJLR1oRk=sNLHvjL> zQd8Z}RYVvFzi5-jp46U8GP^Eq$32?sUikg4G= ziR0OpgQ<^+VW)+cwIP>Ce>tk+lD@tBE`)l}X#Zns37Y5OpI&_BI8nV@$;z>wZq2ct zpY<-6!SI%ysrRNU#Pcq%lHrq4k{Fv~EByP6;8!1%YuKOIi{R(?g=uuJv1V(*#j?oN z>i*%0H%x$4wvtRB_?ED^+vztbrx(mF2$TKFfHP%u%_Ri%FKGj04N2(d<3%s7TrufW z(ZX6$>-QmV{>PT>+bn@t7a0V^H~asi$N#fWDj2(3{#R#g(ue^9xp+xOhLJgs}3SGMc9N4~->^KBcW6>-caO3uB8232 zv27>BQ~n>u4!xIO@r-|#tzM#r+^qfh(JkS1b^@a0@Y)tO^i+wYz68M-^%7Of1S-Z2 zLP|>=r3mpHG_n%jJ`+eGr|*YU!t1)edB!^W*$4Yxua=dvass{3Hhm#w>+u~n>q=BXIf|U- zFlV?46Nt|FiLfUsg!c@F_*$|=67$4ps!+nb8T_sNFx5)n-{c-U38_H?ze3> zKqN*QacOuKxpAu^D4?ou1_MW1@I^Z_Vj-Mj^0tQ~{zQFDWu0OX3b#QE9c3ga2NM^? zV$=~kOW|QDfz;hU97>Yxmf5_jaN)GV0xB9}2L2E?ulFCC<@MKfB)Yos+SRG#ZGK#_ z-U2>>ckd7~Hu?Va$AALdd^rFv;;v;hfq*e|I)mH_V??}tHUtKdGL;yQ{Ope(m-C@_ z9xqUS4%w?(+xEqH7W+e}0;BM1-$F9-7+%X*P;aX4+Aq;5jP)|VwTFlC z-h|+iV8?{(G>>}|7ssd0;4BlKuv5;Ux2G2aiA_q+5>}a0yG3YfthwUPYHG<@oLIIa zpJx<TAcTQX`yenga@SAs6MBn#2&TPR@#xPrw?ADdB&y!$ZBiGs+HB1kTkm(JK*&E z$}F!H`O*G2(Y-{D|Xx;sxHk#4GOoUV~*53;H{-U@U+Nsh%X&sSr z+ zy!n|4zFqIz^TDczw*;`KHi(|`2)+g8ZG1AKV#&-i8;x^;AOriB(+9i(oujBO+f57B zyW$LDFR;eHJHf{>r!KeNJQJ6o6WFT{<69P^^hui_u3rY*KZ<`67i{I$X}LUVB@^ka z<|~c$5%6Xz2F<{(Zez8z9|%t$bYPq-u8=}af4hL@!$2Y?r9#OyWTVk5)Ww+@bR>3I zP>%X1m3188VD^aJEp}8%@Od4jTvF9D(;y*}@Cr(lB=Rm>x+!F8H-tpS(Cv@PHaZ;Z z`5S7LLv%C#GyE4D?X{lTR(}a@a=(1|@wISiRlR~wXF>r@L5NHxq`{sCm(S^PI_h>M zid1cmz|B$IOnCN@zQ|ZHw#j{D$p%+MvL&=Dq-c5}310(Uld4vD?MY}>Y- z9c#z7ZA_d@CN?Ivt%)a|32uJ(-0xQ1^T+wBc2&PvYgMoA-K*d3>gRcNR?7Kveqfwu zt?6#R{#h!5&0NzTB`gy+>uA!%GOtKWpUD<(@Gw}fb6q@5OQ3jWycE93yK8QY zcaMuw-Y8aKzGgfM#+wAPFLsGKDJYu!!}xB?2EJ*|8-)o0L!m*P^nswPL)SY-#*SSS zOSB|rM>+CJ^wji#o6Uv2uL6UddZ+P5B<2+9t^Q;6hcK=U9)^R1(G0pinLWX5E`?&wEXr)1S9;V; zFtb_p;&F8rmK3pLKWW)xY+PrsVzX`Ff+9`F@^JdZa6Izb}{@>7r|p>hrPO}7!l zlF?jWBeRPdzn?>>9Vcm1mR(7TpW6GL(c#YbqT95BFlV`rZ+%$-Rv$SJznUJaxZn(# zD_N(~1S*R0;XIBZ9oAe)h5nGjR5pk1knv6E{BP^IWy|OIUs#jA#!X+NTOqR9F^l3f+n&u7+c6tV@R3 zjB%#UM)kZ7XzDaT)wfmRF5bMJA4+4+a^P3FIxM9y1hi=xS{pnw+ygdZ1d$lIYaW8} zN_q0I4tH$}hyfOMPLF)aO3!9J-XR$4PJ|Df0?AL9^M=MZ68IX3Z7ck)U@b2bV(G!C zu>8phy9Z)kfJplRj@@Vv3v7SNI}c*)XgDPUC6E+*orRwuN1Yi{F*Qwt)nQ{Sm&ZK5 zo!g$?#;}>H@-ycPtpj~fg%o_x89_O+fwaET<<8f)GQVbxXuyOtD|GeXk)3iM2|F@M zH_m`(qLcW%D(mvFn#9bo6|XTphTv8U#wpDe!zrOVxzdFa6B)QQ&3OMXj2*qe&G{)d z^)~EHeyZ-1A!TUv9^om$Mo2bnng&A@h7vX4YL7>PW9R7Niq6PY%B;|uMOuwYs`QC2EW8`~v4+9Ly_ zD4lPYuzYwD@N1G{EAm;ur7sSJG#~Tl2=Lws6IPL?XL*;f>Y3YT+hbIPI-`;(dbv*= z@q0ck-`%%#vF^Cs>*{+{{xCbf)#`=KGw)R3V#Q9?4c`VWdMQGTwC=7M1%Ux>%sEL@ zC#TAdY5C998&&&iJO?pYyi^F!OG+XQ>hXBB&Ix&U8r;o-!)#~zl*uY)>J@W5KV9Ln zJm#tO;}^2lXgUJjk2SK^p(aD6$?wE!ikZukt^-5{!zEEuD9ey#1)ldd3xYLeZ|t6= zJnu`*tH+Zvvag5frYV2M=*=mQwHY8}gq0zfeAMPP*Dz1EYkfQHcItDyOHT))Vs zi+mWY2a+<~gnjr(y0<3vf50JDOXtt_WI;Cn6vm+Z>%XIG)hJ3EwW*#Z)L@|L%*@^M z3Q2hT?o^TUy(#+A+DjkXk{7oa^fx>BNLv_YJnC8U&t}mo1<}2FTO2K zpQmexOMxLB(JTHGMhWD*N zekshX5P3?bMt-?X-MPRtb38Scdi&I=q23z>k?#1WUmfkQelH2;Hn(ob#FMtyxY|pW z8jelHeJ9T_d{&uCYGyT`W@pjkvg)HWvwYycC)tt3Gk%iKBHg!S;I?f&56rUa7)c*pcsg~V z#HW%s>H;3~khn{^&fp3-lxprMm6OYz3coK9JjMM6-<_{{kPF!sYiEQFU6Vw$C7XH+ z?B#0gpiEhY1Bk34fq#=pnpO(+NT1%Rh8*_l!oD?aUSum+Ul)*k=mt*;fC{_z2{%G2 z)s~r+g@XBZqunJampBpQ3j2{vZ21W7kGQVQr*`J^40$7%2C{NgYj5;VEWS}uG=?i2 zuJqZh^xajbv%vOobHe7;y5xEgR$LUw29g~06z=yZ!>HQI`(pBIT9y$9&nV*x=2hP% zi4h~aqC|2LhgU^1Qxi+!3li=Ve^}s)gQ6qN!Xis+U|tgZUSd{)+v=Ho;G4O{qy|!x zmZ7)TLtDk4gqu&C!kI0m9m51oeFYFL+6QVJT?i1PH)1sORS6JdH$b)R`;IOkJ9AfI zc#0b2{;IfnM-_uPXevk6f(CZ#MR5X+TfV4CLZ#AiFu8uP@;RbWF%n!DC|2S?7>puZ z>V;bNEaYPqsMI1b`aSfln(P}rLD1~N{yATlm#Esa!rw&dT}&utH0gpYB5pJ5iqS;e z5hZm@0m(GJ3<0)|W!OA=@zt>I3yx9Me=ILy#rE;V7i2q+jjl_8%q{D)-`pNTgFkb` zkNq*Kd=!coFhk%^T&uR^qwBX|&(qc>xwCv_1vIYI=Tm3q7xBZC_#>6FD9qaJa<-vy zm~0~TkSjcpD_jue&k5!Canly~(gvj{eJ_(Wzzxsl<$1FZvRM-;Ct<>hvbB~_C`iAZ z0uU5HuPShWEC@0&^{fUxQ#8h4hVwgYojTnDKd$lLkO{vKk45zAf2cZO{b58{m$G4+ z=S44>%OQx+B2#WovX@wK6Q2$1KIIr?`$rJcHaT~XdgHssdqPUlu!0LD-WQs7UA76W z^{nX3AsEqQNvI{FZ&=`MFl&@MY>X+Uk1wT%uHi(k!L3-}tuRZHJ4}ipqmQSUgr#*Z z3GPb%=80j^4?Kh784?YRM&Rzxc45eaAdoHM9?)1rTy`PoG(`Y7F#s;Sbilm_JsS;M zm<1k!C(ml$q^FLCPG7|er`0JfpPksneiM&qdbbf7tB{T~7?m+-ba!JulFy6SO-d>L2!EolgJV^_;n;2DqR@#a@wYsgUx}T-+%d{JG5x)0esOjH z`pbo<4|((JcUT30;;}&SDFfsQ#z#=y8PfeS!HFN10mCX_8PmZm*n_Ua zl6L!2Q~&L#YfP`C$;KCV;l44Q*nnu!jqPaR&|G3_j0~wDn9wH${#RvGg7Oe2FD%Xg zN7r((hLBQ;J@ZC{f{315!tF;vUE|=6eX5$+gdvn$_&3BL0G!cC!7ct%#HuTA zcL>G4VqI{@Jkrg=(+jZ?JjuS^3onR$EAl%lKZABqF@r`_KA52!JO5%|T;TdT-s{6+ z?A$4jdFSl-?W`m2HIKPZOY(kDhiT_-+ z!VB?vldYStU|(1t1XG8%<1prL!U>u%E(b9;w$=9O()N|tvO9B;jZLB7g0pWq ztct_88)>}8de+5Fkrxr%zTj8wiFS+3(10Drf~zClJ|`W{v%y;vv;q9_5mEARs64N{Fj7>w_`VS zTLd+vm=N7L4%#1}9r_%{`+x#`#Kh0VQpCIXM8G##hSP$S94T}Se(&Pv#sz&R}QUx$KiG++|jQ)Z%C)|ADjh*!@c)S zyY)-4j3wF*5aP8g08)i{J9ltJ)bzcrdcVbK`Xm?6OC9H$0c%y z3ha2PHk*zwcZ6P6w{CP$t7`16b2SY974NRen6I+n>4hWTuFbS>BG)Ow0iSUp?I}S$ z-%ZnrzxbDniO<;i=&dHT4yJ%|Mnv+le^CR4unf3|R|A8rD&&&&JA~rPP!8PFt$`^h z1@8IQz!(()_awiH65yU?4NQW%&@KHk#CKJpTmEGTXBDAa>aXHU<6efi`O=6r!AQOe zvSo-uHKE&e*%gS)c^UeYDZW~@7QbCEX$rV2_f^Fm-i)eM9)iF$oHdHh4L@?h* z&0!Uwv+pUAAqb;(4V+%eBZ#4RzzVS`kB<(BITO+!?fDd=D51GE0mg@{ib+5bADvpb z!8~vfu8FL$B&g7b6k@`?jEDoP5#Vofw8MoF%Ad!qAr{RFQ4^6pNBJwXd=RP;Pz9y)(_a2)h^z|p&_Y7|v34Zy3P z?_H`|gryxnmzujF3>Ysd3^9oMd%Ma!WKXRWep_x8+PWPY5sQISR$dX>Ix={dG7M!~ zT}`UXXH?Kh%EX05$uL%n{^i9E_2`Kvt#3jrEANv{YNw=>(MLxwV>$_K6=DNym{G{+ zJ3vl+HALfkIHYZCJgMW?mH+Yfhyym9sAYHx%1G-e09^@?=Rou_0+}QyNPQaQPzd!PfLp*uFRQ1N=}0AYqyTIHLR(WIZE@fh3@K&2Q%SeQLtAqp z&yCQ_dMIU{lS!{A0Kg>3^Wx8XQYIdZG9qk7e_mIBo)f){J`m2GBQaX$ysmxv@#+h_yuGRK-V!P)VVKu8IDYn5hVZ^4S8;fUM7-CN<;$y zMnIlxqL;18Chd>{fT@t@Oz34DUkVujmH@vB5*+U>(^?cxy1Av zI5guXME4u|X@=}i{uE+7+`FcDnaFqWjgS<182k>C5evrj2QTi$uzwx{@&Hx|0#CGL zry^m@)q$;#2H}SY7UdJocV7LcyYJYmHMp|J&cfH0yW~5NhU+*HaQVNzL)7_#pK78r zDXO<>4UZN7YW7ZB=(-O8GAV3zr2$>M_|P$@qQyFhLnH2{t-MnA<-2m z2+uL!zjj}x`$D8edcs`72rH`vw}fbL9lg=)&68`z*CEbb8b?`$MMer?PR8j~{#kyA{h2@Vu(H27Ok(Z&)j zXF)TrB0MrM-!jIn36D6gFNvysZO`<7i&<14$J@p=a1@lRBbQ<%Vr>1rfnTeZ+&(%E zpvX=xJ-e{T5gJhB@rsX5@yL)HhF~3~pnerKV_Q{;$+c)-1_oMestGS3XZ0{PEAW^*0 ziQ6%Vy-~uGET0W~=6KitaT2GN1k0$YMaSf3mN;pMQXZew z8(ByULqPMua5+JaObg^N#>_JkvrZg<$xBFx0ar26P;y^@OXz6HojV-y7pfS>$~qaZ zj15Xh7XjB(;;L-MzIJF!={SG@ZI&3yJoaLFZ~ULef-+RUI5cnxSK`ue6y1r-UrCiY z@{_yf=V}#GyVtUgtQ}LjH#jFU@l)SQ6jQYIDPP%AM+BWxkCw4z0|$p!?YU)*9FvbK z75sZFzl=|^y_^|GBh<2ii79WwRIfu4sokSrx8tS0WhLSonWubOr5~x zXBn?k`o>G9pk%-NU7?<^XH4-Q9$xKpNa-FGp2!?a@z0h``IMLah)#Kv50$kF;!hK^ z5Lf#4s4b^H@o%2nrwJ)xtefFZ9(mf73`-=qo{xe>>mfU>)V=3LHl0n!%)0zDZH`w?d>Tf3l3B zX;K;(lv)OL&S0kvyf3G}yWBa`Z}5NVFi&*5N%lG>1h$n+qt74AGVXNBnDhUB{Q(=1 z$w0xJg8B8Q*zQ%O$$y-Yq&g!Jb4vQ(nn4K%9(=XOI>AC2;Tiogz_^+OF-a+8S2k=9 z(Uvt$?v)jQ56)2zUX=pRrCSGhy09xU=z)#PCb8RGGg#*CQsc;j&tC{{$d`OdoPEat zU$1<@EBq%;Xp#CfG?w--ySaaZGNcVI2xt8BW#m~MK2fyzsqB^I@d|Vh7gQ@fV~O_} zPsEL2&M|G$ox&VUSPlQD%#JqIilJpfJ#u*V)q#57_zq!G2N`jw&y)n7DMP%AAxE5M zPg&(8_~upPLrMJ={d1u54{~M(UsHAGQl-}mAA9xSco}_6LVxzCEY^ZDwU~w0nf8Uwc~81w+FWl0Hjh=+(W={AXC5&Ln@ zTH2?q`UiC1F*+May#_{+Pdw^Z6Dj*x0PrgL#BOat94-R7A7Vbo4Vp%*>wEEEn1hb6W z6~p+rC8zz^5jQNovGw$L4F1w?!bDZvSCKxIMa0!gYpgnrOUPy-Cs2`M>a&!zl5lQ8 zyCLbWF8!m4h~r5Wa?P=jA!7l4yljfWCR84fk%1z>p)g-WS8b(H{ZS48>A3;y#1D6Y?-~b_&b0sI-uT(L-8N?cv`z? zgU3&3W~!X$h_gL1Zz@8$7m7q%r2RC-W(yH3oK{ojD}py!AR@I!^ku{v=$(G^E{*$F z;iX*6I@Pif@4BRo02B1O12~h6V-h`4aDkctoD2bC264!I%G2f^)r<3S;x9zd&RST5 zO7w+@0s6_Jkb)iX$66rBT1_tPk1$36KeaQhTMLe^4=mtjh@kR#)MTmh&iN)!9b&;%AmffyClGI9K z-MSA&k!qN&Bfk2T7w$(R(y3saC;3}JUHsNYRSWRPa&61Z;fk-Mo;^ng_eC9;6Vh4T z{SVLH8T^Blq?wJ$`g;Bgsx4sjOjndX&Usy?+eLW~W&Nw0Q?G$@Z)ooKx!g?Gd-fh* zD4s9z`_T!5AC>L2w(Gqn@P2vAzip-4`A?~jWBSE6qi4t}W8F{a@B6oi3)d(M*^sj> zGM=*)Ii`@9vJ}NS_)v%C^Q`*(FrjK}br~}e^$WhYMV!zHvQ)Rd8t@`A=BgQ^ra`uX z1x$+l)e901Nt3s3)r70^skcV9?7~cn13YE$Z+bZ~yE2Qn`se;oe-`1kl-|UW)^;01 zIp1&-=|pD-v?C~?J!l8T#n=sHRpLeRD?=3cB1mKj4Q`rj(Sy}W#*nQRB z;OUkswv;Jl6C8ej4muNZdRHdlzfS37q2y!A{%j+1_Wx$>A$#Hz)YmLm0^ZzAA8p!4 zpDp)ml3oj_rNzeqNj}7M<+DlQLnA71?T>q-X&3C(eFOHAC8$VGn%qN*K{AQTPF;nm z#-EHl>-$amc7@vx>p-vNCUmALZCm-iinO{f<6z}Y6Z2d{CPOK#c)_K{L^-m_!;twZ z6#m>PC4GBNbXNG>NQe3=BK@ITY6E6fE-2V@A)pZu^ZuITIqz8)%nq;$(vAC^jJRbm zKsf8Ce{z`)vPqXHZYg1~73-oG6T@kKLiZ4%Ktqo`v1ax|IcC3EMEhHF|4s5h6JoBbkWhZfi^{T8A#zHh*R)IcrZyF zLIAFQQUt^kU~Y#iz*`*Q!!bs zQKVg94~GwG#pJdWXZJK0)k4t_?b)>RhZWFUUT|6klwaz^-^pouj3``Ib zy1rdUC{DA5Z3O^EZiiPpVk$|oiIaUU*X^$ z?K0};zBH-J$7UGTncc#@fCiiP!8UKxsS6zK@-nX@fNC9_)p5kG&1~{=jPpzl_PR8! z>mkH{S5KBaFT+%!aujA|Z=oHVo@s{z``1`F28ISRKTynFiC!|GM(9Ij*~FLjx=HP8 zFuR|Vr>3KM>?@0ee}5icmmSbCa$Ht@mV?9Nw&uW0b$lYhZ^=D7KAp0{$d(i=-kHs} zEQ|jkSXfd~Y;%94j)h#BJJup82m?TdSrPFhhZ!3UZ92bOv)O%^>wi#j@!%AEGsrQq z>Tj*C3L&Fg*NsO7`aVRT!FaCLogb?Zt#YM8%M&GM5?(ieTvEse$)R1t%{WXWgens=D{e4 zMp)^8PC$Zto=*&m{4DjiWHC88nL=8c&p;bEtRXM4s$7=J`G;KTRz;Gs$kir5Pb`d6gR_4^|GEu+Q9A@&UEV3B6b6e;K_(9jIEm}vk&R{I8 zP^C?as(Ojy1b{xeo#*MZEl>qt42lZ@qYs{pqFXhCEA{ULmzfX7C&`O>YYkCTj z{1B^-zth;1u2%P;rMSAHKbFz-As4w(?5gXUDiDm$QqvD^bBiaFLfU6*V1PsN@j;2& z&u44IB5iD20pzs~yxWjxvMpr(U`A&eL;DxFM`5ne3*{whiM3-fZkJpYB}R-FR)sJ$YSFA8C0}#A9OP{-#Gc zZ($cuz)~buqOq!a;IOVHmVD?eQ<4E4cW>*ESu&&g83ex~Kb>{a%Wu>`2r(nK{`9B^ zFlDbtOBnM0H0b)nHxISVstqv3nIq0@@K@2{IQCuFkwog6t+&w@rY}(kwDFPQDD{`y zD+)8ttrPLMD?R>%srmBN884SR6afuIe;RiE0rUWYqe_GA44PGf5Brt1o0?Ulqctl> z>b3M9SB!#-4IVP{+^uRt?mH_uUmH*US0AK8euPAvvruV^m*uK|B74EqaF}tG< zo^Jx0_hhsTA#v{`bx9ERLmAXxDYB~ckOucqXu=|x z<|1dkB4@174Lq9;49+H+t>z2Yh^io_(j37`IwlP)wn&mjIj7^mTQdzO-+N&)xmy7cfbusW1Yo z`w!z$SIt-xi`I!>0H@ZqpE#%1zMna#*14ZL=jgv3!g${R=jhSj^a0QFG&g<>0l)wh zDec=^_#IC$l5bkK#rH3e`nhxPGX;`3^%*w<%g6k&rr4Cs&Ytu(*n<2*Mjn2UTVk_g zf=HaR#ySIURDqU}x2sD}G;er8L%Y?M=*t=pA0a_#5#lG29pyGtKz;5Fw_K)N$920Y zFMZ|(`=dVB$It&p#9cdN@J{_j=n(Q1rSSaE5z7CIm6dd|wso?kWdE-KrT#x@fxn38 zD=@Vt!Ld-8=xH${j++g-aa8MysG*{{x?c{O^V3Ewal9)fNE9DBUSgt0hH;G*-$*`? z4zthEG3nQ(ausGTvu_Me^Eh^c0zcsQ;ECJGL#UBtiKcB#v!245Ckz=d6Nuax8hL&> zPTd(0gHG&P={7=In6P`A5AQA!#bei81}`z;aPZS+WG`quTFFP|n#_N!tK>K6=;syJ zHrih4RM`7kw$Or)F)(yDlo}qW!{2Cw=gNCkCU7dTpQSkd)89;(f&lFw`cF!;mUrk& zqbNxN4R`5f@9uaH)ban zRd&ddhyvFVH^wvu5SwRFmB5)&EZ#)Yv&Ww&Wkw=|Y*^b()5}6D4HtKgI|fNbR^@|O zO5tkBm4)~|Ih(YZ-jDWudbxj{OnS1r)dXRTCO{-%T7KK=#dtjm>hESeXWA7P$YO`Z zRd*S4K+e)WA4b`-c#cOu z-nT@n z%IcJX!wVG>0-{wIT*`K?^$U6}!DqGT0p@uKtfBg4McMlM_`OdOjm5Y)l02f6zp`z^ zGIyuww$L|_tj&3=zrnYXE3|TLF;)Dhn1xQQH0s8Z2jqptH3@rE^)kyGui0Y(Nsleu z+EBbhO`A~(EJrD7UCGE~+lG><@m7s_dy7{3zj4ZEpQ102R%d+?t-(D5j8}fq(!jIx z9{4K57Jh3tT*(z9bm`)_#JOHF$+9aU-LmiC@1AqNOO^$wQEVQs$bQ!PXRI7KK={Qv zJvAhZIK@2So8mSsW`ZQ7jfUbMz`>j(PZW=l=Nv8v*6Il&j36ZVQ^)C+2%Q-C69r=Y zaGqTXy$pxti=On$PEWuV`u^L{ivs^S{rtrR^!9}%`~O)S{8#ds|4ZmiDgKoO!qd(2 zzs6p^hW&rWo{+eHdzz%2ubir?$|h8o%B`+Md6Wi&e{j-^Ygc|6)s<7r&&NB4ho9g3 zNTY-2he`Gl*>~2pRP+#&6s@j*<@wF5XXpOAU+p0IcG9>J!VQTDsTn>ulhmG{!aTY4 zs4#@J#n%2n&r{#*Vkk7r5J7I->NxvIXhbyor$*ZyQhd(Ou-ulGCG~2sowYl&q{zLa z#Cc9u$}U{fgH&v-#03eY6PVk#2h7%|3fOj6s68sxz%mq`JitOLj(5URePC^!&CNJx zVtt@-3o5sosLqvjlA4PZhI&UA>PHolsC)Io1&=yP4~UI}-2 zQw$mUISmDq6w{)|bPigo{pHeViTenmXSEcea7owHE=2d&MH~$fnZ+7ctWo?iE->eE(fN}>c7>oh zKziVQ1AJd#WjbZ#Vwr!*0DzvhWij4P+pzf7A2+-3WT%JB;U>dTrZm=%x(@tQajBKvN3tqL7v!&4g0mcWFh?w&?@y6~h{z!yiSR3JA3;fAIi8LrY*zx% zg*S)(4n8OpcS3R3rVcpy8%Np(yHJa*EGB+g8xhTi^1tSIMZ^0AAn%A>{rho+$s?3y z7O!pc@mrSS_oaDUFn%S9bxLA8sn-!-ZWZVM#Oxr$fXdFR#ISXX_X*`>(DQdAIrZ|7 z!gPLC-~DT*N90CYv1cT%Fc8W@UHZ=_Sd=p^QpX|bf>T~2>Z9S_UH*615Goov7nQX> zH3N;j(O@a|#3kf}NAG1~V$*?$4M6~(;0WuVKZ&LLyZ8T$Wu z9#j5e(K7Y0b$0r%;S-;6p|7EdIl4Ra_>F+q2@Hx$5()-YWk`POfSaCQlsz~hjcYGT zd`Of-)U?b}x5834LsB=x(l!H#$R*q2w|?apBu4TV;_uv|UhI7q6-gG#snE^etF{$k zzo&H$o{wHPBvHITc`-yY475trL`aC(e-uLHAxR?qxR(jgZ^_sBKMVrfv_qBUB@lZ)cJ z7(%I+*i{_&qT(avJzXouMOmO{Zm#}@!j|-Xn$t6b2m3uj?Qygh#*{U-$}Pu5v6{Y~ zo+4zlgZZB#F%*mqEmzN6yhjXt%ZDT}l2TeK*;+F49}2`;QS5m8mPb;F3zzrhi{|hY zaZf7YwL$=X`r`tPwIK@C8mCNc-F9Nz`+si%?1gs=EMZK*k?t26r@caXl=jw0PW6nODpk-2snU zJLRAbk){1a$RAniY|NK8=6G9pWwO-1VM3;#dn(~#+3JtKSxvOOBJ(h)Rz^a&J_Q2k zD|w3Ta@3kTf@l|rbO?^B%eF133>vNYn9S+(_wVhRU;Dqw+!HdndHg7?C8~F8-IgS)^Ac@#7iRG;BNEMXyLj|w_EA=OJ0kMe&l-x`Xlrm@!fPr^$prCeebl~0?|Q7 z)UF-Xh2MxX#%FMP$0Vx&@*g+$c^M$c}R?|P^l644v7#ZgwWv=2lmkwXZ zH>#dIQf<&a|5YI1GAfiTZllD!Pf}@2r<@qYM&B6Nlu>hVpi$)p%BndcCY7z@QpDkxk$fSNzk{)S zi$JHqE0;pfz>9c*DJ5ixLwfi$W0;IHs^j!BO?M6cFp4vccg^`b!s|RR`y%4V57iKqIq z=y)pcT6R7Aelj(hfML;{dIHFROu0C*rny8?}W|#hkrXPX)8X ziu%J&Qr5CHPraYfM5o8ydSk8yN(86*?Q~>hr#sn()4~I6{tMSV-ZQVWKTbVoiSE{S z^Z8&*pswJ|@Fy|TYO6%4ich%Ti*^WCF-oU5K~5ZI$i;5)*{u0(;mtDd4fK#I<)l?5 z`1E9URMNTeolXK)zqlVP9O`_;;V(Ff&%m{GRYFdb zdqHu)wjA3{vK>xeq{zOzbl3_26r^=gTfW{;e}r%e-Ri^zBeWE>XwGZC!m4~C{Ts#~ zJY`fSuVdj-*cru)xIqn7%ayBv%s?|PiHrLRX*8-JM!@aa59-t(3&Dj5U>ef%w-bRAJ8zF@of1kRv63I}_Ok<{T8Zp)xrS z9Ugp4uQxYIut4*bl5w+XjH>rGkn=6AYtWbE)C_CA{6jp6G z1bD*nA80f{Zq)7*;eC1e75pBxnB*WU$ZDud@G2Yd*|~ z+HC6zn8Gv(!kKH2s}2FDYtAod4S{{p6t{bP%X0!FmdS+|$)a}}0t=;=i{f%f$dX#ffZN3y=H;zs#KQ2w z*#8Y)K4@;Duz2n6(a!#pcR{m{XBcWlYoBzaX>1);L_vp$&M2eXBn6mQhR&8eJ5A67 zrq2^BPVWR$`iqELN<#6(({wssYk?uutL$fZ$6Q0QHUvOO4?stD=h#lXlAkLV;&+Eez{7>HeX_06WYD83Bajs969^o~+8d)xTHL%+v zMSUV&b_L`e%cHWxFGV!(oKzvcvV;}TlMa>!RUE+X$ivbg1@Ib9k5rpgrlvHO1>c5< z!OR$=+K>kObxJYnb(k;C6wK^=2zSJc#t&C6f?o`kXpmpjzHZ?61_-SUrr_Br-6euzB&N~WQu)L50WkdEivD!y;uJ+H? z9T4MguhYgXA$oqd`lXW;&PoYeVEBDaB&zYBw3z%|X^YGj-3ug6w#Zr(Krl`@=HQ>r zKqG^OUl?ylDm=Aj-k|MZ{C93fuRl@>r;XZel12~uPVZF=h9V2g*4Q&uybSn!BdwN; zv@0LFBYdt_t5IUk@yaguNiL8Lp)|0uEcH~GYorCkl~`}JF+oG>29QQqE1lvltBX@c z={qVm=9wthZW@QXcX&{RSjB%7{0ww1FSbeY1tw=3e_lf%PZsz@U^ z0;wz>x(4;x@v8^a)e{}`Cg@9xbJw<8#g9j?_E%iw#EQNT{T_mb!g4MD`^G;e1Ma!REa9>9u`20sKDrI2u6wU z*q3t6{+$Kf<>2{jxcp6rd^U4=(#@aZJEezN{hXo=PdwKMCw(POtlEM2W*;~o6S8qDQlnE0=o<}rkKU??13Is@I zZAm)C?p!Ph0+J^d#!SB(O_?`D@;$1S&dO1lOPy#+CUa+B;okE^gwLowKq=<*(U~6o z`(8C+RLU=@#+;@Z+$~IL&>C|1djfjFe-@$5ml z!kl=WIVH;rQ&VxKAR%z(kf+=nXsVTcB+aa-dW2;zs>F*Q=^cw^>UhR>{8F5%>D#x;PXo=eN;{ZEfcNnQpIRp}Y5hIRIbbjGgX`|HQJD1_ zeQp@6N~WCSl99OnE4I$x(DN%0o*$(7cez>{uG#k3bpj1NS)S&ppXhKy0q@i^*Ldq~ za>e*P5wEOslV}sjopI9AYpnZ?9=%!bMgxyH?d89=kX5ag@m&9xT<_dEl%W z9N0P3al=j)vPQG48dX`O%)z_ze8bWkAW7Bng|8*?=37-TyHah9k{v5udm+t;+Fx;h zHVe#Z+h~_g5sKkaFngx!zGJ)01#L55G+J!$D@o~u`OVW&n^&Us;W+M3LPz5x7XZ+C zif%wi&>LsDYvU3c~$Fki_8>BM$vwK(Qe<^p; z+YO5DICmDcs5;lxG*1Ty+@Fh=os&eK@s0v|?~Il3Djh669l6|z!?2Mhd@0(N>-XtD zcq34JfLbjDEK)-ui@ZSeXUU;sx7&G}PBCQSI1t0}Ua_(pZyH9>9$@L-8ewuihJLHx zv@=EgOzPJdJ>!6#M-h_#Tmtb{c#lr3zAFc)37IbNkCMZ%_*yv4d_-pUZ!Cvn(api) zws;MP%Gwt{FfDbWztvCz)fhi*c%W@Wc4R1U%Xpp2F`wpz)|5$xPy@i(fH8fA5dh-> z*q$g=AfEXHM;2vT55c1DZv@WxNz}4K9ff0!0etsw>Qr=Q0)p@=STKBv7IKQ>T<_n! z*`)DK=6Ec-(#(a0STM@L<iqa^jd%n=i3~680qPL{$Ky1F7&r;1asDT2eYu| zF;s|?AqQR3-R4ugv<$&#E11U(ptHw_%LS7=QQvq5-Nl}hN{X1#LAAfxS{Kp}Dd8AFC zf{d5v);yqtSZb514pDC4GI{a`DZo1v4xo>l+(Yke)y%%Tye{YtQ?SJPw5nJo<1!s6 zFq;?H>HV@lX2&=I&SFn0xD@7F3mLp;G?s0;t}Wj18L^z+Xd+eKDQ_e77@&{{#MpiO z)wsEf?X!ay`uKJt?faKSxl~JIY_wwR_JMO|O0wh|w_r-O9s=ou;FMlajP&V?j$a;^ zZ;JTGqCsClieF4u^N|v%w7d{OLkaA1ixRvZ?WDb>8x8)=bUA-vvE8^zzI6@0?T=;z z72bbV2B%j|$*T!_J=esx9P(Ja(j~>#GnEJ7&}AI*s`eg0=^R1sM3=uf7Y=21SoyU&PS3Tdi> zQ=G;oU#UPY`3z!b-3aPIaF_IYl<}-Cd;|Rl$ar zB0QyL9U=#b(9WkKUf#m#QXEGg$}UlPN2q*cZQc;xO^9~m$*@pnu3IGki?p{6imTh! zeiK|8cMtCF9-QFr*0{R`4bZqd2^QSl-7UDgySv-v-S6J#+`a!e-@WJSs_rVfC{`8q ztU1P-%92;%rk-OgZopp^0AQ(=Pj< zd5p4-WCjWZ9yqz9_RkoWUp`UrowT`)XLz=sr#-LMyuaMzSs2j@!XK+`Ttg;tpuGHFqGoW-TtyU82Aff%NNtqF59frFqdaOR=APiB} zh_5D%4z8^_wRaD8OS*U=h0isxA@i!QciQe02IrQjlYeIDx%ntJr^4mN6z5d?TBActSQ+m_OUT2 zA`-b^X#i1)Mn7CA$hgj0 z4KCj{oJSW9Rf|Q{pm8yiLauepnbxEmLLpbGtl`K6Xm{lpNq3o@cfEw!fbe*RM_LWZ zZ2T;A`>Ym)D;==Ra9D&EqF@m3Oe*9#76LR#<`E49mKKNt;?wEwaV2CZo71tTrFV#E zxpjPH)Mwqo*WMJd5C$qo^8ICl4$F0qlWJ%t!8zm1hYEkKWStGgoJed4R2THCmh&dH z4cOmm@ZbIUam9Gf?O#l|L`q1|39b>W$BWiWY z5+1NU!L_}{9wy{P9bylaMS;tww#L#mSl6N?KG=R9eNYhLp{TKL@W3%@XEWuDr5TA8HoJWKcaO9303`^!5z!}RY@!1 zqyk&Y4AH?RlS530Bp%|EwGlvHS&tXOiKxbXLfll~3u`nl6{;WeQ?+=nh$yZC_%M{F z0Hriw)0a8V!1M(Z;h`JSh-xz<^&K-(e~VUY2>(pM2bCge%(!Q9f1JtphueLC@b@7+ z8!yApnJMEE<@KSygU}0Em#Lo&dZ0rZzjy7=n9};K`2?8E>PND_ZYW<6Y^hQmABZOCb~_tX%;%O`7k2LC5&usY>Bpwqr;j=D zKVBpspLULBj3ys!4QC4@CljEfkvXINKV!@poxa-`+F3J#|HmGv_J)UI;>UCh>0=*H zSEfY$%|>hEp6JT(h-G<9qr24wLqb1?s~xjbAK)PzPg zn#M0`UE-obT2-oc-Jb&De{!)Z9-7{JultG$*6t@X-_#C_^S{dSd!MJn42{H0-AOy{ zx1C?D?CYMrZdU|%fOCbMZ<~M3@u$FGW@9BYd!)}`Z(>j9&&-^KClqnY1mdhQ2Z_`3 z6Ar-DQiYUgz$Rv?7AN!floqxCN(f#}7wvC=%eV}w6g_hEST{?lh~em^<)MN{+(GQC z{$yGhwM7~Mu0c8Vtm(6|XCC5RvrWn=LrIOmpUuant4)S$95n^QYF(_>RuTKM{E0R2 zD_(Sl3I#O7K)o59CC4sz2qStCLq)!?T{?b-ZDDfO1|hu7>aL|#O{m=FqmXPvZ?Ibi zvB_zh9uC(1n2_44e4#b~g76mbdW$1eWaeZ#Z86WO6cz|a;6PZxx;=x^u~(A!E-bk4kF2caF}V zD3x}nt7}w9=GG>-Fy?1Eu{%vE3*ui>#6wcny*?Pw_A!=YxA^H;I2@L<`?q-{$~W`N z;utRpVLb=HkV~bZ+zD;V8zM^2EDEYY6os%S6@19Vn`Uw^e){R0F1jtW+O>itY+$ zsrDTLzo*>2>B%=iqf5itfg$^+?z0j!Tt}+mv(^y4?#iO_eE)EOw%F<76<@=xS5ix# zbr%C>ku**57LyST127HPX7=2z+^lUM5ogBh!^m1|b!Zdy zDBI)=n}Iy)57Dv8n@vaN3SLLyFk&jx9WJ+>l_HqbR-AynfylClE$wij5hNlBiNYzbZtvJk;k`@rYG^ESuIeLP0>#3jE_*=FNZ3|vC3sazz5HC!UP zs2ee*h)Cd|0by>v+HpQ5BWGhl!v5hAFjTaDG6)P>Y%GJZFCRbnjrA1$f1?PPz-ryT9RcX`T}2%pK( z7JZv$%YVnnMFXcy=j%j_kqFG)9pSH(nfIoOuCyc!9kFdXNf~G!A#7T4CraI`;-8-U z$n>sVb|I_Z|9r>H*Gs(dIm7n%tV0#g;tvTf?_BO_oMY?u=&tVoGoQY|Vco=YeI^g2 z@lm5KO1PB}uvgdVXY7SwiW3R{H8#A1va;B9TMtxxQ6%xh?v60Mk>5y!ZDJJPJSU(L z36y{6z#69Lz*^$&NX1N1sryG!T+KyWEJenS+w7bJPz)y87q00m=r!~xrS;#J{NLyf zpV8NUYf$tbCWqv5eu=L#`k5K~ph$ym+zz?`L6knhVRQn-G<+~EBjzC^<;Ad{VXWg4 z?OD5r?taI2k*9N!N%ur@^_LTY$vMUjT!fTVUfLsfN#_Zd!S zM&$3;FXJ7bR>aBSh+aOA9v|iWVbycN7KU7%NmqsP<*C8zhv=zw zw&ZTkvbDV1Oqz=z0r)~NQvqdYLX5(MY&2XF@qV2isHR$}-745vHe1*)tDSD=NcAXi zYMIVX;_XGLF>{Hmn5(eo*wo_WOX*S=4h1uh+Go*LooF;`>RTO(M`|mQZD1uQ_~VSk z*_SQum_`D*b#Wtx%z|VHWqiP}a8hVu7+`aU0oR9H9nbIsv~YR@U_GE|drlms!_62k zfZfI@(?{ouFi*W{>p{MnuLW)WD#1Xj8==H*MsfBZ=;wu7>$3?OYTr|u8^uiA zuw`uI4R{1fn=X){w^wXL9rUQA^V;k#FQH(05>aUgW#lK{xkjbFRGCgj_0Z$i8nU?v7$S!2kbO|#92Gjr=7}17siql`egqlv3ZK2yF9JhYQ@4Z$*j^8yz z_kO3BK?q|s?!%`;9HftMM2iya5QPSv4{v@16+Tk)Q}jNd8uFh5g3>1|<{ZBLAr%xe zLUL`ItS<5aSboUi4ANG&u)*_?H=4HjL)=8JdDsH~X!E?rw+C!I=jf2}pTVjm@|&KQ z_^==6PUSDOuE2B|G7Zikt~;EWL{PVjdQ)ADE?_x6H_>bhUqgm zX?ln>bYL?`TavZ4GGNmTEyxpI5hj~9bPfQ;MDlyW{v(V-abyG=WG|nR6)3xc3+-j2zCGJM{NIM(UQ(4x)U$AlZ<|tdgdR8C5gsMrmyMphy>d}|iA_S6X1XKRgaU|@#!zjsogGpvbJRxyh zaZxAnNWdS?lIwWgTSM<&m;g!iCSE_heYcdIU_BJ;V#I@ABp0ewEiG{6y!aA#iWhA& znhI*%7(%#ie0|R(unp4j{OYE$D0&8~AFK3vg*k$$-#rigCE8@7&gu%f!RBti0qN zuw;4>6#k)tt)CeGxZi<`eVyW1Ts`F7=X2T{`FVXke^2x&sp^*m6gXxzJ~x0x1^jer z3N1@fjw;Y~$yI`CJsxOomlu$qqdH*yP<~}n^@quPiH43L&M8O!T&wm8S%R_ zM!9fIC2tw@jMa5iq-leVpG+TNACcXuuz>O0eFr*UvU7FKGoor%-KDMRXHuZClh`xD z-%c^WcFZe66EMbROvLl$H;NsMZ#3QH89=vXipcn7hRuCv2a$~-#^;h0Cxdc~X{(*G z*BF2kv`FYG{%Bu|E>1YjDfRA`?D_MTva%@FZao4iDPu4>0p+ec(io>^ zN38}}*%;L1ciEj8HsdMTayi5R-NZpuFI>b+5;v?oy-bJH| z`*^?2(2*?aKSEt+AV~9A++fsx3W8K0gQWE(|NNFY7h-`xRLHs~vxvRM-}7@%2;bLq zE>YTmTdc%>NK}w$bOe=1G(J9}Unm21LM_1PO40Td!>WwvVn};er^lcv)0`~WH0gTP zI54;EFrtlIVC65;#Eo)IVqVk=sb>`)5dOW2qW(!s{=Yop$L62Q${uG*AGF);zfdU0VYDydReYhA6}=s6xBI@8ENO06EMg3&0s;~}>Ks=7LUzW4 zN@JUTAUj34;S-f$j-!D50^y4{Z|Ajj)|BIjiYv(unls%W@BnLui%yvzL+C^ z<|9SzAOI5X-^k97KQ8vU-P2mv1JcLKmG|IG|^b-tliw32y_gk&JdIY16q>y7yp zFat$7p~*s{srb1}T~u#cU)e8y-TrJF7z@2nMY^!{nL|*bG!=FjD%{)R7@i>mz(4>i zN6CKJh*3gQ*xwL%x!{3^)`&G5gvbPoG%-=MM1W z{ON!D%N4$fko{{xR{h&u4xR_^5_{hR%}B4L^&66?Pz)VTvJMhW60IWzFucG(*D`wY zaX($k8<0esXRp61_VY^TwN5R`x|-dMwe4qko{gQH3$FWuxr1&o*?udEe3d}+2gFB> z3HCbqPyKGBuZD()0ms5Uceql(5lV^o!^FItiLr*CpWhtuWI5rmw z$@-qD4Lo;JWC9qwJ_tl>uZ#`Idaf^GT$WzIjoneuQ;JMX7H{T9an!Opt9vOY%#Avf zh+=nfPjj?=59%LuX8_4LTO7=Nm_vdz2=H-)SD4Jn(q+`%k(aEj)vG86F=uaPL_NbO zLzj3cyEV2PHh2gq)y>yUS-N*ls9rA8N$#VqSBt`+L|BC!g#i75mCb~JUt}6#CI^D! z2LMLyjA z?jL-SFT2)g$@LKy;dN7MNinI#TtQT4b6j2CTAKHC%1?^P#r)xbTQvqZ8{BK=t1z8N*2 zT91~w23OE#?D~lbXUD1&`vu1FM38b^kOnixZqzl8T#>=iRJDypl=Si?o0ptVe#9H~7%@6S> zlbF2NGmfX^m;*NHBBHQrQKMjk$xspVNu!mAV&O|rhL9r!B9rvEUUkt%fjiVg4TUfN z?|RfS>Q2U+{7*)cb|8s+SRT3H_669p2^HS%2_e@l2qQtJ$2aUteIGa;B4(*B8VkzE zPGZeLtN~|@^aqF_SdWk+kEmREa#wNkAnw*LY2SYx3uIKc<}Q{@lL(lD+BcHx7TQHY z$|jJg#)=wU<|iFu;8A)}Ye)C+&$h8RV%i?Y?|V-&t#Frd?g<$KUQcdp%2ZDqBtfjnpf*p*-KzqGme@66>g7NT(w+_dXMP5OIVo z9ZCNwHJGF+3u$~NMBuMVg9Oa@D0Vk-(xSaY6M|R`62j9Hx)N1EVWmyOln<0ZC0_71 zL!qAMMX;_(Oj&4>(@ByPfG3xMJfde8I_NN9q>>FoT0)udN}VT8G9I8F$h%{61KGXS zOw%y1jBP*fj#4Xp_Y>}!>vuvATS^oYk07!$CtTi*KI;_$&!~P%nGPM0BG?s>-+<7CNSM&)86wEfJCO+1sVl`j=pVi@OO; z6UP*KG|$EtP}Y@*Iu9meNvJb={GVWZF7!PTd#&1*8eJqVP|!=_K3=VY{kxv)2VQ2| z9$Ufw><|_z$^E!Ha?`+QP zA4GN%P&mJj8x>hV6}G>^@efk28KJ=ht)I@Wx!DAllB{AY2TIWe2A1-H9*EKg)Q>TI zdHcD9xvcQzhA~t&8`Yy?#i@I@*!-^KgALkA$-BSS)l-? z3T}qs$e6WmVj3^2`v>pO`U|k}5U%9GDV>P=2ME$RRQEhU3}KWqs)Q3M_Fhx z*+&@=B@Jt)@AHAGb(v3j;GQ%{O2#1Z84~7(G~G4JGJWvS9lQI`8+T5Q%t3K+^*7Qe zcX-Ct?kr8kC8WFs`iOnj$xe;Jy#uwMP0@hLr!MLq$1KdGjpbYRbrTMfm4>nNXlg^O zIOUu6WxeVT-Nbf?zWl*>5I*jC4N|!xW0IVT=6k}6@eu>m>O<8m?sl8@B?h#Y5U)PJ zf)|7>UmKL$#g=)ej*EW4Pw{fEkk2V@l@%dyvdtMA6~mmNaCu%l`W53bW9OoOIPFC*@iPq-DS=y(F%RTrn&4^{}CT`kK-SmC-l}Or7)$hNWFPTCizg$Q7uE zJ4sSl>^F>vTy9Qq9ea{FiV7)r6siiJh!{rYl%I1mcJlrgc``yIMWb_39s@x7RKns{ z+MF`Pv>%oCzZp)`vgci(&&0DVt)*|pza`+Vq;DH%jY-n8)1d9=x93SOu!j=GBANOgAcdKeIh3cg-WZO_v-?1B4(oSSFuYPc1dxJQla)B6vJ_gUBA+`V$IJm&wvCM{JYXCcR2<-ZG9>9@=q*m9I1yPY z&CS4iOiJq+<-|>|`!z^8h@2 z6a9c^)gq_(o;0_f+5{)}87<3qz1ZRF5-vTPk?Sy-4BpFMBd8ydhSx6m6`TxJ-DzWT zt;{vO3h%jXKey@o$<=nqPi@H5uS|KlNZ$$Y&(UAds$aS@ZKDt3oLJ8Ce=(R8rmsP0PsKn|L)TT&KTp&gVpj=mk%ZP7**-*@w^T@3Y2cU51Vu0BWcj?i-M=YB*GaW$|o zUJ`CT6izl_Jciy=<}^h3T|x{{!n@OAVaoq(H8J)M+O7#~P2Bbt7}pkm!{Tmdi)nCV zd7Jw93AVz~tE{r&BM=w6&BWLze0v%4;}^Z=cj!rvpYa8$cFOS2gH7#le!llRmm>UVCYOuy?m0{7T}z0Ze7iUz1big?9V6GGsTc?Kl$munL$RSaGeyLr(sbz5RB$<)umB)u8U4 z!I#yoRb8_x3x(qC)kR28j&uvL<}qUhRorFg07del-2FczVN?nOs~F8{cKEgTSVTL_ zjGi6pJNPD!AHqB`JEl^bz;HjtiB236NoK5&qhcW*@?0AG5Dt9tZa0y%W^#BhM=Q15QQLqL6C$psIPDbNS;0As)K``7Sj&OA2}7nWyfa5=RQSJ2!{ zH#I65NONh^R17(Gg0x0LjoSA_;BUCcr0Jg?g>QV-z1mnLWMEGaa&5c}p}j5Hn3qQ~ zRR@T(#)EVQ;K=v&TYnU0Jzs?!&F^+ah>$q>><+NiJCflDc(eN3N~^xQHXdUJfxzUa z4f%#Ji=}#At3=r*X4lYVhn{&aVSZUh^(KodF*B=4YSYl)^IHkev3Le!D>Y4C-D5lE zYJw@!P?J8Rji(A^9!TuMPF{*-X=szgok^is8R=o5vb9{aQVqIp2F4~O>EYyHjNY6- z@j5mYo_marw;vt%tre$+v&V|&5{aKe)7p_a6neQ8g*sE^U>sNIs4`o0`QVPA8d87u z3WWgnc?7DTc*q970$C!++y)Hrt&C_tYetAi5J+#U207sOhjKbU@yoS}NxNf@Bv*=W zCLg=c$!!DHKZBx=oathFL})jS;4;}ZEc7mAC@%@1UM#!aiXJ%%A33QTHM{8HGIBNo z;qxdLj7~l)95xe97HGwYB1Kbj-I{P?+PysAw}RAlrN|t6N!5JLO_2qwv>ds zW#Meq?8E){sob;tld0Y7{O4)i!~NZ88fClmAl;}Q3jO729!mWgsULp%+tEJw`SW7D z=yX+Jyy$i5tG+O=`ex%K*f-)vt8C-Im2>pEh4t5BJS%S+4B!QT>X*e|b-(9+5!6i{ESyl4lh@5IDi+j>(^SeWQ*B-@!J=m5 zrju-1Ea9MLrX&#&ONK% zm1WRxg`=^V&$Y2jh~y5r441^GijRl#q9y!4O}xXXGDo8_=Jn!4eGh}?YdI5t{ASp& z(Yo~H32Q%UM5>J@dzCv?K6Mg%%X>SdJ=K0Z9@| zbxn;IyE2Zg9SA@NIKZd07#9MHs`?NNQtFwzBI=Y z9~s=UwRQoHMCi;$!eW(kkn-k9S&a<3DCI?(?p!M6p^Xg2=Smf%#1?!@9AhFKkE2Pq z63<{%Z61th6>S*^Oip!BZ=N{rE;HS!V<>glL@?cvT{>oHosDSGeI5;T`{}?Ykptf{ zIw;s&IU2Y;I{2)c;=CDPy3?bSH83(bkSFZRL7IsP$8Xl(_66NzF~U=f=B63vF<<3? zfc1*MXhMHlxAN12`}r4j^V%h~#_HrEg3TF>dTX zsEP9E;XfogaV`BqR|Rh!+IzF<>xq5Pv}c$kVCuwd#+f5-7Ba%FRtjH#pZr`l#xpab zH8mP!s>zOpH#^Y(pldB0$%4FjsYk4H+XU@eVLkqVzrHv%ISWM3}~ zxrkouxm^zCg+AE^e6c1ie%^#}CltQG1#R+cfD!euJiy^@U}^Yaa)muj<~X3@2PhN! zJN*uQ8pb@L&sl&eTY#l?AT8~lCYJLCf-(9buD~7J^Og=^8GyGV;T19RX2=G~&OB#+ z<)03nAxiJ%=%GHb=8Dus(q3@o3gAaFtB&5FyCY4r!2#RXpy+8z;~n5W8i$^6SFB&bY^&a&8W!0aS2-}wsz(Dot%VNi)8Y8*Yc>Ry`zEZG;g)S0 zgfmZ>8`tm9`3yX9To=}Yplx_J9hQ?XK&N=_Q?|hcC%AkzjDh>7tQ$DbGVWsn@OqU* zpDGsiyG!oi+*kFW?G~0dWS<=_l3u;smwi}Ujn+S(e?Z;uPl$S+?=m;RgTV!y6FMcL z4lAb}zIf3+7d{#keBY}ix^N>JK*WDvV3i$n(_GuHWhQM^8N^InTnr|mE*!RBwzO~5^ z9-sE*W9Iw%F=F8PKaLmvCZYd(yd@d;KQ}p*bgll%u&G%zj(0YSubn$DX1A=yz>-2? ztE0Nj@vE&92b;s9OlAJrd=|7QTjV={rSGLs2_tX={gBhkYo!$i>(4MUHqvG`#(!_` z`|{!gV}R4($P`m;u=L@lAN@Sav@AKO%q-R+Uk&71IMrEIMHV#|Y2bBAunMyAV@>J8RluypWie+i(- zvaC!jy_z|aL_`Zpw`#l-7xNEbcju5Psoj$-09ekGWm-0BP#&n;#k88>w}9V%40G%6 z<`tHZnl5!Q6?8h{k_5J1MQT^3nF zj-*|Ub>UtJ^W6@A0^iQd1iwy7^ihpVCBvP>Wt0xKy$rb1z1?};BMH@pfO6kc9thVn z)p2jR4P}d3!*|!gG5HP~_APxC1}tl?(2$G-92%Rj7K(!4#~ zX+(}K(xg*7knE+o zu<6OYtw!w>e$tuI7;k%CKK?aqTWrjkzZv3*Jvzby$vhC|6=f~)oXdf+9upK3_wfI& zyXkW{_LvXd`FvPf+5TtUDO=dsTbqcOn;2O+2^oLHCjFN|U&ZDlH3`|Lo}S-Rg<32& z?21ICoc`vkVk|D&RIjAc%a?qp*V;DQrM_cbC(p7s$`14FIP)!}3ke*v3K-@Y63-zM zS69;vGd)+|x2HSsPKtVjUhFWRiR!>%RVo5<_l??9hU5&|glc_A7IdN6dzHa9g+6Ae zlpASWrm02{dO+UlYk!t~w_7&QX|~EU%lXt&o6D{QUG0?ZdvZ1t8IiPnkUaL)ob73; zwy{pKRFIFtciqAQrl?xKVGEru2$Am)Kzs_jqDkj3bJC=7RfcfNY5?bHbm>pf}le*FQfdXq!928*L1z zBTaU2;BufWkdJcf#PuPho(RF0O*E>A8{C!n4i+qm@;<0 z-L69;64M}IWq2lVth{^|wW+FN(3-Nt=;_B7N3s!o{LOw8TN^xX(wav|c<$|OSo5TZ zPbGr}2;Z$^Z>Ye0nPEJ^Y^T3ve66buauglSuZVCbD~nGE$wgSn8(~cu;P;S^-!a(| zAVi+TCKPYf24zi~BpBBEfd9L~E8r(HO+FNE@nPTlU#_g2|6ExUbU#c7*aPnc$5eRf zf0+(0ZI09uNV5BX^m3=g0UA4FU^p{ef=>->lIuwyTv{*t;blc5vAjMBCR}pok+2wM z%gV_=x4vY&U*A}-`+6;dGX=EZ{B1g5?qu4Aw)rp90YS^~KTHQ$y{1LD5HF*KWMG7k zU96j~VhYXUF^hY)p|nH+^@`($$T;AdXd+BFSK3~w%MABRcT!H$Tqr%AX*b4f<1sYq za|uCc6hX0OlF}9AuGkBPn2-_JRKK_ar$4gliCyORdzlK&j);w;2}QzzNZ9OyfiLG6hiF8~Xvqgu0RK(=Q-yuN;Qp-Nhv{Gr znIXn4ErU==6yHep#9ve2K%+=^Mqn`F+|HYB0#U4g`WnizQw>hKIx^f}8USNAV5g-n{X*p6hg;5Nil6PKEQg;&EN7N zUfxekp+#VT9l8{bs{_N72$gA!&(Uay1OBufyJz+|P$W^SkX5Sb%3&RvGN7$*xf!7b z5`{lohS7fXn2O>ZfnkwOT;mh>cw2QOVt{Z&oA5;XAgR$3PPvDIa8ZIv2b2JS zDb*cSPRAUM=_ZQ^cU?UiPGd(HDRrGoMZ46{^<@5+&j>hSyLZP3SsB-nKj?PFcdiW* zX^YlbbAHwukJxuy3Z|#!7i;n9$;~QReSj3(K+hFP4|4q#FN!@tLF%%NA=AP5`s^6! z^v{uFU}ij8%+hJuSapev8Is;=oUjD*iYl+$6G+(_L8Iicwb`=p4LB5UZQ^(gXULj_ zb>F`>JfeG(_3Hsdvi1&tX!K&5PXxXBka%w?kM*+S2HG;|WD|Id{ZRUb#Mkz-*26xq zRpjO-hGYuc%$jKA5o~zqH0Pf5CqO5!C4&aLhYFh%1ZgcbGkDx6#M>jQ!aAcIHq%~x z4ck_`(50=h$D7i0Z#onk8Eih%q* zpndBkm^3zcVTsv#7g_rk>6~Q0W0#Wt+G7MfWqfcn`97;Gh4^$K?$P0y0bSi%H`iJI z5`ss@?~cT-+EC|Lh<{&r_YNcvDn43@`;Rxv|J+*qXDH)84KtCl(w1OC=%t)SX%47^ zbbLSH)k!$~DMQGopwprn95^FI_qKZeZ;jhGfW3oA`asI(rOH1TGiedo%K&79-ss*0s8b z!)&K6ZcS10b!ge>99Y-HFEoqzp#WXqc{eSL${t)SpQUvg#Il8omdHcdTJ$0y zw-YiybhjVKTN`l9u(*o)!n@|a9Y~Sg5AX9s@Q=HxCQ9C4x9%eU^_bI|ljD-zdI#ZW zjm}j%wp_pg#nge3#zjCqy$+%H6f7iCT2$M>KMId}ubc%n%){~QKiqBw-K%Iq7D>b{ z_h?eci}1P;Jjtvx-W8jRuf_Ldg%Sif zEGs4N@`5EQn!&-xRr;0+@jwICt+8SD_T-E34poO0)#jwt1e<7y)gNTDHU3YFU|61P zIpVo1`RfSymm0;^IMqBk&MNPu;|{M19;fUmE-y)bA7>!n_3~ix+(PK&arw(}S9^$m zGOP2;LkuT;LC^C09#qs}W{iCnirju>Qt~t>kGusafpW>`YT(LoO3Yb@rQjnJ{8iSjY08AK4*clwy zWfiO`vSCa=B?zZ-iP4bd9@kDyTp=A$X61*hB(24O?JffcWgI9xmERDp&~DK<>W< z9yG$>7Os=dY>t;m_Y}(v2199hkQ$#6v4^9SclGPa{!cHm zBf#R&CX^paZI~n)2o8xx%H;%5x?D~zH(;W&(k``TjYy!`efrjAoz$2^F$Rnfy6+|2 zrBCoU0O%MD4s5!T=|0PQ@8s7iQddl#ius14BF^SfCN0~2^i6RCm{%_An`gL4xgPTV z9y1BVJ+DviY)(l>mRI)N_0p@FX4pC(ZIfwe1M1r)38J>tJWEOS=4By4%nq>O_nPj8 zjvM11Y=Z9XvL9)NRAOmnnj8&I;y=44qi>?JzQdh1L5IGKQ=mv*(Ig3PLRIfGV9ZDg z`#4$`2|0|I`36JJ!#XPq;C?W4m<{my59yYEZc4-T_>eBb21$C<^fc*T(lsO+d4lSZ zIyJgr{ad=~6UBq(?A>4#x+;UTjZ(Zl?C5AStV+c-t+$W?ABD#g`w9A>C>mY1uT~&$ zBEv1_3ignvjIDOX=!v_KTJHBXx=OV_m{vtdYk3DnfbzP-({${R$VoV&^(Jzv_LsRx zkV!zFnZ+^fSVpVPX=9ok-(e$8i4@g9OJFFM2Yh@=Sew-ipR6yvkptS{HQv8VH>SGR z8x!HIy`E})_d>tLcyHHyMDiR{%Y#AmAD=KNkdiu3r>M5OH!O!3MRZ( zBU2rLwiyNPs2COg&NFAzU7sr3vmvzu6qm0+X3T~LS5n+UmVk;GA}gf=dsnh%&sQj} zVz&Yl*!FpL0TZ^EL6V9t0IwQE&6013o3$hqg&GD@O@~|z0CoNhrSvnPLudCw(Non_ z^|h^vM9oLb*DpFzFTEWNTkB8_ZB~d9<}@`-0xh!a88C!n=U7g61KG_%Y)Lw}EHf#F z=FHtE#g^~biY;wx2mO3$#G5iW*Hu3@hRBE|U&Ge25OMPdT*C>%jne}AK-nQpe5_r( zrJ_%*%O2&%kEPz^K+XJA=V@5IVJsW1UIWbTreWi>NE-j+BcC}Q{3(QVCVDY5j`Z0w zp)wE;&ak3oRgo<)GdGmePJ)SSypX za2HT9{>AZRjGI|E6h~Ga`NndMlapt`_&VVM0Qt}Bp)j7VMko|YXCx?$rUNZ0a#pwd z?%IUSh#wC(lJ(dHF=)@i1HLO&0;WK`6drGaqPF$NgwF2x3c(B%RBed5Isz&B;j|cj zYCylk7d5xgh$Si`G>#hT=1%J*G*gPzK(OOJ)E7`5nrM7pK`^{XaD>f*92LA}Y+F{l zd&KprA!T|E89gt3iFa1W#8`{!ab&P+zb!NvDvyay1VeofEFaj7#3>S_YDfM}vCeQf;Py?K)7j2^Nu4n)SEEqlRb8!wgU$SIv&_Te-NMr}!)qKc zjbp0j&uiR@c5c`hcWB$^vkO6;$p_V#*c4yMJ=4t z`nfCjvXI+bupCF@10k`(INLSIa+IFc9@@EMgUX5Y){H39B!I-ORE4d-ZihLAK6|{JTn9oTl`<>84mVGpG8XDZQHh1*|u%lRjX{< zwr$(CZQG}Mcb^k?_l>yc_KwK-e!joH%$)g*Imh@^mj!nruZ>Ar4;K>l5p}sTsek;O zNN2M_?i+IOsxVsm}Fk(LhpFz7{$DAjyt z9eiEV+hj!#Z#A3r!0@hA!(l%?c1=hAvJ3w$Dx6wOkuQTyONx1==9$uyOH~wBPgv8L zNk_ZiAgbBjHh^pvLwqCM)sxap%;WR{lZ@M|AhiJoek_R;hTbe{EQ`=I-N>$nM4)+2 z^xmzezG?6*31aG{t$H91hI(%y)=?6ZFmQ6^`H*p=Ja>?=XO{U2^H|2_ViV~GXWxu5 ztF#XNd|>qQEiYh~5HhrYQh=z%)2be?bDaS?-ejxEI<)nAP+yq2KFxP!n`eG)*hFmF z3e8k^Vtl%XEel1s1VEA_{M-BW;# zQ-(AQ75h}0pn?N<8o@Y#fqQtlU%`<*y`Z>tp|wWp7tnKC?u9mqC7V`;>LggRvAf5B zGnk&Y^hHa>GwB>4cB?3MG>Qf*{=5fYNV~JLeu;pouJP6y7li-=#Ki*==IO}y&z~hZ zCtidmJM1a|lS|Jir&y&_@(C%C5**sCyWOFL2vFOjmvZ4#c+>>7E3CdfTw zo0!9T=fV^s2yvSnbfCFXzpKvXph=jaxtj|y$xO=PeUnR z=X|j^QMNMt%(PYTk-;r=Qk84zB!J+((W`9PMtzbqq0_U&EN|BywqPnt(rWoaD(M#_ zV&`17+56t?&;+JWQ{?{k^x^jmLaK+2)6qN&F&2!i!J?{kc#&Ac7%*#Pk{LcVg$Q^1 zsb+1BbP=POH~S>%$YpE@2BQYwY#{1;h4jMy!;`DHx___8c#Dcv#O4YlWvDus#Qj~d zpj7~Ht5|DrV@NH6^{pM&c0cS5Q}j_NYz5v2+RiHDO^D3u=&MXh+JK1T*SmtY*-_>| z_aQT3P8woNn~1FQ@2Y;1$LW{qmj{>%5qRg_W3D)A_Yc7C1D(F=8;c@c?S`mV@s6U* zKkW6ljti0cAjc+hLbGHPU@m)}^y;FnP!bqn!LINhyH+M^E1y-onafxP)dwqK@ z&qY({o)MNRB^Eb1DM@Q@n>i8%-?6Ua0SL-2wYA^ce52>7`x_Ty(CY%*;}tPW;B=hd zI+uL8-y5jvxTXUD(vEOxk3=DO6~#v*SiS-;)FcTt!21Xyk)#YPvDTZ$e*KMmP*Z4c zarKQkK{+9-$JS*N45vX6?jD{VS88JT+!4~D1sOTRZ?R=_;Z#1{1R=G}kYOoSQb98E z+>}C!5xyedKF!*`j1YE`F1{wpc#i5R6K%4H{bHYiD!0{A%?v^3Tuo>XeRAIQHCvR$eb%6Iwi?{+NId{C_-_;6Pl za%Tl%1>e%_&!S`~_Kq&=+q{RA%JFUA(NKd-kELLpMeXAF${2?tU(v>25-m5u-u zU;j4AIkJJ-V){b|-2UfufaQPF0WFz-ap}`5c|$E_KE)4pr)DxGK^j%OxJQe4U>Z82 zzDNOdXHW}?A}v3k|APnqp&w2sgppw)S}|lkO>j=T9UnAoclmJt`WfYPLmN@0vof3= zrb8}k`agR0@a8VVjSx~R?4Ys{ANf}sI^^KKEI0C3lx(6|&M2RRrAJm=xvlnL zGaHmxWARbgD)CpOtpXiXlObMGTQy67`w;7ozODYFZ!1+5c+2=3Z^Xj)JD&TLsTa>X zxi%!Q6){xOLsblHc(jhV$a}vwJ76s(H65xLa_-ov#2Q`|+%6m#OFzUs1|( zrE==RO3j=RFYC$wFMaz`2;Qadzu@%uX9kPr27VnE#bXGK6Ku5MkTr;}EVMXW=tv)T zP;IwKLDT6E-6|!v|3L(dj@tl(d0)RyCJSbx!y7n+WgH4bnWkQNQtr`{;#Y@zKq1gu z1YI_@=!|1n&wkkST1l*mZK83IMM*&kX~BX8@i8HYX^lT?%|tUD<26~D*iWdT-oy`^ zmY;LNQ2WuhAIwg)rE~9*7V7FiIHp58jJxps6?AOhKL3FTHs~#1;WRXV5JAGBAF+kn zF=Ej72A6}S1Iwe~o^f7TUeW~2Q2YtCCMtkzo z^RpY+x1{)s6~g-2j7d`4SzUho+qc@^&!49ef5F~r3PE{6>|wmc>ZYviXSZB|=O3nh zTD1?nPhQ{&BWEKWuRhX zKi?E^d|IwA5*UULoEAhxLl5PmM^6U5YjXqCOP4h1B&+1L+<-}pOo*lwGiQr#07bY7 zkWl)vvWJ2n>0cO!hBL$dMQVH``UWCvw! zWxt$oK7#)2B9*6I{sGH3kY#GGvce!Ul}KUPQ?+%ltw>N9If3Z_UAaH!st%i zhd}2A<|(oQ&G@t&WUCqJ6~@6(DnM?805yjwM#Pscg)1w7yp~5$^)$ggqPLGes9P7W z&~xzbZ(Lr85flH(h^}<(o>LZEjQbXeZ`2WGI7}@iGSo~IJ9`v6-jN$VTV@^tiMuYM zKcy6@v=h&h*&jWN29nr~g#nft0PBuuE5;JSmUHeALTm5{T)EF?y4(WfWT27AT4WL< zAO9v)ViV9?7W`ZW@;?SSEdSAV_;F-1wK4qXWl*WCp`f9Jrp4Ke-M5Q?C#qh%pq`fT zD>p|LoSz&uT#Ae(ge0U5y!ap?#-9|F%A|WQMi=R>FvOuw@+s`-{A8}x`pVs zxk-kYbXOzowo#?cbv*Ca>m%#0>wc&nVAfy}e^j2JClP&}0m!@-XiXQDEpl+g!xM>6ddGLST6!pu!lg*Gs!LB>)}F0l3PJJB zEa-p?eef*_T%jhIu#iY}+NlyFqLmnHGgC7cU>@VP#^kc0_^#&h81fdJOparX0PD6- z7kgvzTKVYsjt(7#xuAMM%8gdj^pLj&YI$QVYH8c6PFW>$bpV<}>sXx_TfN9ZGoxo} z<#>#Yl>|aI3Ne%+S}n9KcQ$=<6s*ObBWcOY@l_ENJ^J ze6>qc3D|#-I7B4-e}P0dD3q3fB~-{HP^4(XhmBTrCWX{-w?EsX&-I%)P(dy4ugHHr74xlgZ?6)!dg z1c`YHa^r^yjl(M`tw|FnBea9BF3n?D8wBM9VwaPgtQVB0FV|n2BTxW2$tQ6$7Gtfs#$4$|jdU*pW}7+N`8fYY_Q4imU4k zdwGmTcy(+aN@YR_$8U*;Rdku|!{*q0 z0wpE`$|8IOgsA?^#J>#b+-*aD@+=wf_MEead`2mMnn(_wymNP4{Y*lf<&j{fkl!d5is$Y^5b8*fkeOm8AiX7i>*%YS?@RtcuWBN}F;uj6ID|QBIzEF;qK+N`5S0^i~sngL8pJ z%4P7-X=F4MPNYGvG#;oaR6hI${_k4Di_iTi;!g`}Xq?rR!+(%^=M`u1tF?B{2$Yy8pe@2@w|zYZz*{*l;>;(Tt;jg)pCD&C}CtqgNoYYz&V(<%?e1 zVaLy{S9efCn{6-9S9)4)apn@zczHqFjMhP8ixvEKH&r+Q4BiV(vOn-+FC~mr$iSz8 zn%CP2WueTQ#889Whng~HE8gd#;nK09IH)`4NK%8F!AX@KRPUms!_q0o-HMj|WpnNd zdJXZrd15XpLeqwEjoEjrqEn4-JdwcU$ku@z-N0H|x4`>r>?%A9Y~#vslNjZ>xsTn@ zwzsqY;WOO1SG|mDr6!E>C`e#@CNG^eQ>ormVv`ky6+`TZb4laIQ0USU)VISUN6O`| z@5a=)sR>t42qHD7`CzAJH}=7Ti){{;?#bg)$G6HQABwWu_>nbN<2P$|*BVhr7v{>cn=pp7r~Co(K-a7RtWfqyk=s6Xjrs(_qq8@7tKn zSOwdZ1ASk#0JQ&|WN;5vBaLB6G}9?pH9729erqq!YJm*v=`BcS@;55I$SVT1jx6L2 zI`b1AkJ#9{&5XV9UCPcjq_~00KBKXI zPj|Ugb;Y8fhCcyz9oIl!Qq&{IE08&<9A&A-W%$V0gp1(vgR`&#vFO@K7^|w0mJ_7$ zah67Z=-m?|7SV=1g=r}Sszu%bUP(9$kr}PbWa6Ko%%K6p$?IrB0t^D?hel3J`x z84Ef^*VyN#uKk_c2-i+Y)?AMp^oyV`g9|#v*DMM;yI|K`MH+5N)+n*6%?Qb7793>p zqeucp8&^ef5g$QLTQ=!;A4c{k`4p@ue2I}1!Vl6AtEv4FtEIW!$o^k8cq~JQi!-fBSth!II-lxFTm;4geg?esW zy!4K}(Su-teW*!2zZ96>@PuC=G{C#EkTZEN!GpR@U5zh^rZ}02IpZxtgc|c`?7*k? zGnNt;xzc}XS@m<;PMXz?SXPNBCr?6)T2QqIH#;kp8_{o4tVj9HcTVtR{81LF{P?%m z+JxG-@8eHnJSq6EUtIrDaVhZQ?d$Nbr`EqpOeL#-xQTnyxT%3b7T}4l?_Nlq)bOvNe2R)iw`BBM3<+JWB>@+q%eJ2bmT5PxyW3+G=gm& zWOP=Q&S>S)?Uu5BwWCyJuaXwjTFwb*KG~!>ZMMXbvSF~X3n7%`4PSXE5_ zS#-sGp`{|Mtw2vsIL5c*p*7g>PwB_QY9Ty`>8gNNyWC)&rKgeB zs^`{LU%dF>jPCoo=VMdZIZXQbV~c9kC|7LeHsrfC_@;%tY-E~OCLG~l1c$m zf6fU>e_*H4`%Zy!!#BOsWRkv~_qHrGSzyPg#>M#-c%QWpHSwAo7A*@0#>(~ys4z-P ztJ;cBr^s-Ybi|CUrCZz_J6MHHJWXHW&O25K0xPN)D%jt#$G~zJxCfTZ~m@WHb0S*(eC`-5zlT~ z8@K6b{+5QH9~zF4lDPUh^W$&{5CoU(!t@&@6y%2f))iHoAdAbtxcx?JkCOYR6aBzO zQ`?UFy~<_RXwMK9=02Mi$Ng&79A6N!q(}yDjy6|On(hIrwkHDgNKjWA*qDGiYuEg5 zHSiIquiHLp_ZNhZNh$aU#RR4ul$oY*P)7a2845%M&HNjb1DOF12JV+qmGU~(E%=py z_tK47u|GrosOl53e4=Ccg2urH!77SclW4V&GxeN#tPCWpbj<5*g2cjh`-~FddTH-6 z`4T7dS3cb)IN(( zy#KvsvzWP1mHK(BenS3V&0PPzX8Xr+^3QW*Qdvu3UHHe$m3Fnt_7^BBE1c;(Qxg=K zXMvcx?HpTSF1>FkIAhVIKU^OfSg1Hd>PN!Y-zM6JTt=yJLy}CM$K3AX=uGMBssMUi zMsk6Z2fjJ(=c=hrkEbeSpO4Qom0t>~l7xOG0Vxq|2vD2T4cJnROzovK6+DcN+4%HU zYehPGAt+(vW<;@ZF-f;DhCy<}R%JnjZe67wK}TnpWmlF~>`iNTQWBLMNkUjf2E6zu z^rCI`pZePC#%MGPf)w;oT!(w`8T=rqM2_Ppe6;@VT=PxFYe~CqWru9(l~zvl14CUHb?fwt(M4=w2BeIoAbZK5QKgvcR*{vlM1glS|dgrqX(wo6Rtz)iuh4+6yYx4^AuD+l;9#sz&Wj zB3>~`oDN^i()b^^8u#_OP}lKI4wQC3+;227ZhU0gw+=h}qrVrfbmAN^Awt2ir zJ+s3p9{^nX_Pd{5H7yAv^|hRI=2^)-TH512`mrxW-qdnvo!YJ%G&fV22ZOj8@`u={ zy&f1HuYQqp9G+%?_LBw>kRhI(_sj>pNAE~ry9V7H5~jfD)_J^`xtw&CW4G|P*n)|i zq7P%&T?1N%W|`elQFQ+$FXR@boh^(AF;PZGp3aDi1}CgO*zZG=y$el7lfM%Ks3v<& zpyQFhi=zwUMKD3ip7VH4o~U%MN&FOez%qLE|oS(J+a4vQZnYj4bamOeu?&uZn z>e&2%$#6d=bApj;0lVA{Afm>v=6eM<20sSQBuyqmMmvMd4-^3M`;71(&r3Y=CvN@O z%_l#}8HT@O2U2*k8|-nd*V(lP83IjQ+E~Nd!ifImcZ9r{g{vr#Dx`ogTR)GZ<$q@?e33`fU19&(jS> zMkmAn3_wC@C7SpD;q4bME~F8geQ3evXc#qsJBEfzZTYJgv>VT0NaoI^y<2rH3hz3O z#G;Q@qPT88$4^lh5Dr3<+7clb)Ft4)7x?#qVe+ru0hxFiK?T7O5~)gP=NP!~qHvaK zw{>0wreL%rU=ZnVH;jh`=nZ|eMPI@z68Qm}N+ojVfNAb6O-BQG`4-{A{ZMu{k}~L^ z3;UG=!8~ffFRoSfLCJ|d zfZF}rzY?TJX4<^4!%N>#e{r^SKEGYMn_B6zK@x&M_7?2wGl?T+?dW=K5mWj3HidqD zp1K!c)`xHLD2i$nF4nbiB^I!Bfhwo3_{(wjtVR=!P+;uS@G|_}cE(qR#B~nmENn*ZS)oM&uPT_iw2{;l-Ep?msoX{*RyL|D>ij zvojWoT;Q`gDHf>ZBX4ARquS>0ON!ÂkO{yk;0?GzW9vc%A*A!PSDwahu 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�iY!3blRyzco8TD}t84g+i??ys!x-M-ERKBO zk>?r0$I;zVAB{rM@ezBB1G8{$ms++*IAh%<+qKI}<>#6dZs7GC<8&SlMtES9@G#jM zeP^_ScApHKnnFSuSeyV-Ge~wo5VF9(^kHG~7Y)z(BCJ2ZrQ|Ho;{8<}?ph>4#vip+ zN>Zr8m1Rrboi9Fxn%*gzH|0`n;|gi{$et8Lrl|Qfe(@Ef+s-v_sBlH9B1DYW#KUs| zS!~I~@IMz~Fn@d|1={7A?Px{QRT_9x3VXEj*Zyvd+&F5KM=xG_zify3C6C$5n#C(b zkm6Q{(ZDI48=KIMUoqq4VhXNA0OlQ1^lQSs81cmbe1@u+5@8>_n+UhJ1x@?m5g$fb z^6ZNjQ3gKdC8TMOs^ z>7CR)yit#^e7i5nar%X&3HAL`>0qqcp`*lmkr9Zr<4FnkL@N`fNU>70)~2VAXFXLk ztvt0n^?y~_6t&C)L&PhZm)F-PvYVe9OS<0Wz7%|$W;hx$F3AlNR{zDX-MII>c+H%6 z?eIS2h!KF+B7ac}{Ph0$iiVmmp1WM%L6V+Fj?0%mtIV^G5>e4^VICno*vQ>9I!yQJ zkioLW3?8}sy(+21fC|yP$F;7@FCPGnVS6{t#bg1YRA5AbnUQhb`UVVaPx647iqf&{ zt&Wu%t$|cLY?-Mq*BSHH)9~40^Q}_e^a%ISYD=COr7sw{z*MF}G^oBrPn2l)Sx+L} z5-dOc%TOVJ z+b8wrD_l>7=DAc1i+1o}El8V5`6)+D=u-|afh<*x1*0U21?e=S!45CF%ZDabW4}$M zcU6K-%n=GXCH)bhlsa}DS)Q^TmlwpUR=Cxyj3*M51vC#e7oja1FWktc1Mn9_ZS5+@ zTCjRG1L_rAS}G#&A@Ud9x&q-_lM#wsfaL=9w4yR_d0_Bu&@w-*Rcpbuz|l{jtDj4& zMzXe&MM@G~tYpc@H8*on)Fs4Z_}IIYI{kRkL0e_}5E`LqbLc?>B<*|x!H`#xuuJS8 zoP#H)hkvYt9mhPK7Z=((Te?DP)=9nn^W*@$pcUxkvciG~hLMfwg1^`5ag*Y&NQdfw z3Og{{Qu#o~xFANa4Zzs;BJGbm$26tfddc>URze zPb{cMuP_Z?1mYKpCKEuXC!<`}15Hbml~iT}D3SW>Izf#Z+=Jom9)}VD(Sf$$e6td1 z7c>A-Bqcv<`=(V?CtQ7WgDv8;k;!bIQ}y5GQdriW8+bE)aDZ z25dx0q)I(nO^mseElAC5SSC+mF@0304NhkSp2i*Zq%7I?S#zWjS7k+K(I?^I8TdE> zgFkQp5@I_E{dh8^xMHuHdMvYW={_yhI#tWf9PR+3r*NynJBB=?v~)0Eh)rvPeLv2| zH18#yqj>AW5qzMkt!lg@e=EZ~AmzS(y@2A4$x^fYcFA2o##}gIOfJ`{$gMT8uJ5iG!E%Kfl9e$bj?RGJ5T=`izRUJ6CM6KnE?emx|gY zJaL{6>(ZcfVRo}P86&JJR_h!Y%N3LB6 z23bp)76i4^9BMaX^Bv5p9fAHmEce505E$Ar7N1zxizjjB?G89-J4;%tPTbyZ*nA-U zDx0Wdr#o@7;BpI|$+gBzsY|TH89oA`SYw7ekPM)ZpH+v80ppw)9g zr%_V>bZ_l+fV${kG$eUh`K!1}-sK7rP@-@H%oe-oYgpCj<_X~g9^xX{EBliCrrJz2 zVCm28Y+wwbKYL`M#G5!Ur~gHg5_SP+T5D#HaQzLK|CP*RHb*1jeNiD=ia+SdRgEpG z7vMaE?N`+EkxaCydG_*a4DYiQLj1m?bH^-b8B=z{C^D@gL~jmPkkQsx(W zPf)Dcyp^GtSTa%cf5KC0={^VemUVQM zBSg1J54>vut{!GEH)RhWZvm+M!mxaVB>^n2>M%LnVPOjiPOpM6C*BnwX#Z$A*e4u9 z{084b=I1pYh{tN`Yn!Y2Ll{)hJ$itC7BJsaM5~d{$AN(Y-_=9G1Q~fJC`btq0fzE9 zvD~vF28h|4iE0|p4}RHDENK5SDqrEtBH}m_TTSO-d<4NmEg>!l%bG#UgG3}dZ$9Ly0IvI^iAp;w7eT1rcD*F=HfgxRqNtrkw;xtNd=C_-f-TeY!*P35F zgS5E5ub%Nq@%sI7qjdvvI@FVIE>IDOD28bRx7Ey&v?#Om1UI#$B9XrSG7|McS9+}n~k6^y^(&7B&4?@jEdAq6YgmJ!)(=ABTFd(e1 zXlxI(95KH4dbw+0*-u1Ts)p}D>}3m}}4S*u0*93%LbCarex z_zAn)j7453XeWAm2O+@}DcvaoHP5b+Jajfuuq?Gbo;d z!^PMOq2fTPV8~nlz@W_jEOV5Ll|IB}>8Euz@UXKVAg|IJ*;I!KTt13@C78|CqGq-F zsa#tT`%w6(5zAskh&SosyF?J|w8_5*?ie8`3l_a~TSjAj?nE&;kTx;;5GB?L`j|qK zvq1&-p#cfvNbK2H3(T8XH7SG+yhHKmbvR_dWH&;O&Sb#~NSRQEEHV}BlSzUcLP@NG z?Aux8CeFAbJq9`?Q{B}b-dgzzHJeQk#}8QXRLr0cw(i6fB(QnPx6(whzgDZnXX5t z2MjZ=m)5H7$Tb)fB;mQhxkpJ)`=7yX>nIiMGK;G4sXi49zu2D-T5GzuQ1%F{KQor= zib05~oU}%Q2Alva$uhD1gtHIY%arCuRP|i>{Q_u zZF(lF>U~_PE9F)lO1h(%Xub&tRJ>F5B@Jky?#kCq@xVJ(4QlC@J3y?(o!L%fG!=8O zwTkrWhgxji-UXcRv?Kf+sdB1J4JEEZNwCVwom{NL9@n|U@VUs*1sA%*@mPsD&d=Ik zJg?EAPvb(;wks}+-GP|un?FBlseRw*N25F=WZ9~@d_obNoF&oIq5>c&mM4=JOCaEN za<5;w{C^W9S{rz4=S&@|8VJ2~9w>*O4}V970@Kbi_Y$c}bJ=OBvyNbTIkv}wy%Etq zXt7wmR;1qCnT!AJ)b3EOQ#FU02D?FRNWeB}Z2=ezazumZ+E(U`$FkT@@tsM>f{!&= ztV?qK^5*oYcL3w-HP2KhH0Z6=-*r>+O_un{rldDS+wQM6Iue`vwoi(Nw{w|FY1MR1 zD>0V^F^m!lwJW`zup6Smas^xbYP5XhG^ArY+3*~0xXn}um}J@pb1r5@#*^<PbS4HiG)kbZWPY%evZqL_@(b7uN)B9%4v80}wTGD%$* z)5>@hM+w^&Xa88l;y$w)yH)9|8yP-`*p6bl8!m8&I_Q4{9cgV90osRE% zBt|UwM{4tje5{t$(F^O}pyt=O$A1(bYcI(;#TqrU{xowUfB1>eFz&|5hOHJKe%8)X z_=CQTBJ@OpMzlE{4$Ap*FB=Ri<=tD_&Js9a92otj*?&dB*AjFH@g6QiGEQY$&Za;n z(VU?(WE>c-u6{*#CF_jxO!m*C%UD%Grx*@SP0$;36~2rQrdADWNcbWs6#)>YL!O0j zMYC`QSi~1z|AJvK1Ys*X*al zg6Ut-YzKLgkK(0So_7C&7U>kN5svREvvq1iILEH}vwM?#y+IavN2~w(m>D?jio8=5 z`0@h?f4YP+P;}Z)26D^f9m+4C@B%hHw=fV8c@htN7*nb~1N)N~X;CaL z@MnmO5AN5H581JQqu?d*yk47*%7BDQJ;Alnc;v@8rjHKl9&;^T1}xD}cBA*ArF|H- z{npgsmff5Ce|{e#rA$S_EvWy7TmLsx-&P3`KJ_j1n!)|?gZ4i;-_`yPQeUG5?W(#2 z__AjnCrui~U>89`fo6mY_)V;cVkZKUjs?PugdKlAaYzQ&J&9wn{lf|9w^La@>s>7q zVIvky6bO5b-nOo;{qjVaT3MrR6D8C4zFoccTZJq8u-E6`yTgvh%|C%5?4 z(t~dv8U91zn&)gBE+|FtMF(X~L_-T$U<4m>3KpzI&MPVCbxvH>qi>5-R18l5(dtd{ z@6j?;HqhzXSEOgcEiq(`1cR`?n2bMX!C8zquq)(s!GvA?6Q#jo!ub6*dYDimii{OA zh)I2b6Ch#!83?3@=|GqLEzw`X{Bl*s5;gh$!9Vx>SNJQxV~la~J}5yLQKuJ9ydqF) z-gf!2glWhOrc`oBdXf~HwEB4 z!c2OSN@>}zZ2f>N8t_bj`Zl!R{@AHBz)V}V!cT(4zVrj{&yByM-sBVvcwax2sX|gt zEQDH|rdZE&Cq=Iv8!U!A7rU;!64+E2nSc zI8OnMB`7L?L7XGCNp{tKrTFPPq=yJ5k|#8{#V&0&9V!Z(^-nLer{OPq6{adME52#BeO~aB1CRiK-=RE5^iqQ1 z+Tf~3&QnLQN5+n+5f;6kw(YDD$u315#zT|7-GaBQmB+6?E{+L;Ba!3Gr7~!`krQJK z3-ub{q3u4a2f|QIE>0!9ff^+_y_vr&TK*L4N7$h0Mj0q)2pE!|X^^DVraf*DN@*lj z^0j7A?ohJrh-Q*vUPKF4MZspFeZcgY7tC=bEb3%EiCo5^{f%LDtm-%Pu&ex85#)B| zetf+9X1}aWx`lCQ*wmlSDhw7=zw=l}gi2o8V9a-|>WFz=dcaQI!bomPw#Y5Bt^bVh5kB?YJ-@OkcwG@Lv;a|QUilO%#P83!IdPtuG@i?(y>mIkegMx zvo70%DAmKGrI94FBpw{H1S|r;$BHd2Xd%!jf zX?WnKBCA6QDMRNCvXCO@Tb4#16gh9#^+fQ=_S7GMZS29>8O?pm?3lOI$G+d-Sk&e! zU(O`1VGF<*ib(TZKC~YiG_F}zEe+lHbG}F}=dmYNowBr#4*qL6PjjSZ3gqH1Ehffk zYY+d0Sfz;{%=AJGc~_a^zFI)w^))@zUro(HW}070w;J6eu#-ED)s=LVj>TQ2wP`rJ6jhW!Y2Wj4-*oHEHNepy(#-Y}X7zd>_yc2r!E8Z56?UaUU3i6-hq*>R5 z9F3XI6hItZ`@!%J>}dYbW?SIbMfKs<-O`I6ovlLTdJQZK?)KO>u%ejYKVcrLL;t|pnT7vl7}Jo+Yg?gg_MpEel5#dB zJ9Up=iv;`opEMz&B$&-*#LeOGi*w;}rr`-;@K`+|v&MI{Yd;jvOeEHE%&~bHH-T=v zKw{8VP%M_%IV1`Uwyli~;O$+PSWe0%tRyNhmp5TFeX5-!(4WPk|7)bn2d1!#7z3=X zk1hXCX|jiw2EVFjY}ptf>{*(p*flVJ)L^`J}~uXs;h@M@j|G2|pMUpoAvdGBD!1 z&2fS>!k!H{pA+OU&5Pk%_^Ljm5u}bJ@1(jz#%J}1N*XK@(K_(Wp}`;h(K{vKUVZ0e z-_N=tO(B!Sn}>{6&zAD|+?pmO68kN`8QbdJdAudJ=b3XRjTRPiK%nLK?eO>Qbv=I` zrWKi(eu?{$VV*PPQ^>YYjO19^)RPRv(HdGdEg+zxdKvHocP#B6alcZi@48OkTAN7t zPiI<)dmcoX(GJ4_w4nCHnL77rp4YBb7AMGH3KyR2+~(x)bK@VG3W;y6+zlnUEHUQmN?p~497AfmA1|swpWKB;e$_s%IE}(PFopjDa=F!rTn^?dRqV~5B`AuVJH=@wZ#9tfc_;q&e2Y|;koEyVX zp7@i7Pbn#Px^Ga<(^g^cP07nV({tO`R1S4*KCr}6jO7E$5PjK*jUa&Az}7B&uwMo0 zV8-{bJBaNyo#C34@g1fAQsze!12`7=8l9o=mgYruPvXFlo%T|kjtz%*+>SmEkY#ORj; zTAGmgJ6xeB#&@|TWi3VI2@3E@^bVxZlSrvMol;*IjRCmS4u|8!)w=tAgNOQst{cL^ z`3_!7ri$a4v(q1SMUI~;C#9-oV^Z#nCX!M_TKSn^Qo!9+UOqO`LL6`*^WAqB7IcC7 zkD(R^wH>4Mzh?EJMb_Ge zys;5+WjE~3(r`uC>Vdq`6>-Ja4)J1)dJU>KGSr?&;R?Gw0{V)L2m|SkG$T*ksuDdq zM77$9`u{#Y{jHVl?W-fH3MM!k(F|H%&Xj!x$yb(_z7nf1h-3$%q zz0oSr&4_i4KQ6_P>Ke*?a#qH(y6LwE<%*YcXn(}*>+#0Ew7>gF|LRXc)I#AO)OZzz zy2SMIEkhhAD+J4naQ3B-Jt^uAy)kF#MWc9Ft3IG{;_t=4yi4)r+i6TpFBAFVn3rWz zk2V=q3S?%=Euvk=5x18Ak@X8MF6Qwy{AxmV4;i(iNDnPidD?7Gm`PA}pHe50Rp=4k zxRJ6cyjMsTS;cH;bZ%}R>sUtFpY$Ffe@_Q3{HA_3;`4*Y(y^}_Mgz!kI_j5pkJ7?Z zXuTd!W*IH%?Fub>;6YI!QuQs--;oh4?>L)-1&B zm_$%Nevp3a#{LtbrJ{(Dt*w;3yMxVtlQBSzGmr1Y?>{~Vl8GcaQ3R{Z5xXYIMzazk zxqRvD&ejF)gcKw)`72i=+PI?#36?*W$?J4H&9-I+pv@s5Y>KH6-NW!(t1w0e0(U7c zul)v!-jpxX(X?7Hk#N~Vb90k9FV|f++dF#Oei~nImk&Rl_h6I8s?K4vI_y7nKPqsF1j&K2(l-%f9GXI@{fL-Te`>fS11;a3 z!!WI-qp>kLY76fAhBYO*G?uBEtTCoSE8y;-C{963PdL=_YD^4?=%mgFY z4Kv%p3-C-hG8u13loVN~<4*Yz3|)p@7R!}nW}$3j)j{}TC8>$v)V7Qck&&2oseH8t z=8$UZ`uz)3nm62v4YNx_OC6{{=x-~aQCc+8;BcM%MrvYf7`lwg2o!@dohms=Nn*~B z-D;#fKrcMeIh zHo|{t@jH7jrl6{SBC}6w#4bDu45;{+0SR4DkZF`5t)o57Zy`xwvLjXNCno*-Mf;V}rQsz>e%RT+~X#%U?sF6hO9cuD}Aw@?mU8Y^e zP$CAs(@GxQxxvXzcrd{mg+UGLLW6?yld}?qIW(U1!j0k1s;%=ph#-h_I^}cZ~shIi0$s3T8|6=qM_yI!IKl&$Bha7|AkTM_%yx6cdJagO zPIGfV&<8!NOd*Z$|Y6i<<7JT0srNLTdx0pwi+_L2&Qbt;z#_A(>e zd;U@dZef;^Mq%D!p6ZOJlBjl>;(DlAP(&jP5mDJLuEEN|Y+;++(a-XB2WNMP2WF(`bj*!Zcp?SdYBEv<_uuXk9z!(Z=>{UZPTP~D$I zYa_SMQE2vPK;F;i_|Bdfj@Wr4#Q8bA-+I=f~+AB$BURk?b?@Akzh2 z09ei9!1S{2`K4fU#RkWw%Vu*0d>53VideK6$O)br{v;TS^}DT%^`6qS=3sg039LxH zdZ;K7^lk3?O8o)~e>&EGP1n8J7jx(3g~O*sA=x`%8jbOIDm6))(au?uISLJ2PY_v` zQgj9i3kL2ggzxJbfA*QL|73mkVfAW5GRgNEmnrlL7@V)JsIgvxaMa;)Db^tP_`*LC zpHWph;v?~hxY3&MX*cToZ8!a8CfS`yYcc3Lw~ez>**XhcYqx3pquV6&#-Qj?f)w9m z1}>CuF4J7-KAS^&kO~!W^@N5JNNk2t-R!Mt^16}+wBaC$(~6r_9>r=rC`w$hV&(&r#?!>Zm6g~Rn4rEu+6_7ub zQ8-ar0MIL4h%(^3pS$^@eSx#q?q9k4Z_+_gn=UA`|hKG2=lg(Q~%;0 z4e`3t?9N8wZcW0O@w^TxL_d>H*;%_Ie+RG9fF)KvPCORNP%*{N?=!?}S|Ph6Uu*Z{ zWbFRKMVLHzmUQZN@b}_$JW*N2?uZ^h#^#j%N2t>oZgSY5#Va40bIbYmgmO*aNNc1z zo8V%={FgaYvj26=Og5U!u(K``6{Zew zWIOX2j|lIlpn!V|C962%@wuOtC0UQ;xFhbHAzQ9iyn#iJGK4Y-?g*phI(!I$;erZ# z-zko|cAQ_MQ2IlBg9;o~gx9DXyZ*?b#GPm2K>fIQo5u8!nOm3V&T#Y|`9<`Pz#h3p zhC3Q(8Xq6L%&!2FI%0~wISr(3S&_w{_S{hEK~CPFT8Sdq*H{~T70jGjL!V{tJGP$! z%&Xz!W_*@=&XeGGHXkDqErkA2J6vz5!#8)3+BEGGFRi%w-6pkka67HXC$~Kb;@f;| z^TV}rbcWX%M=^TpTWhoMhjiPaAirGOzaAO>=e)7$G_?Qo8!?(g_|G_8F?AznD$jo4}8ts-~Yhy`Fez(3f%D1n_IvNlL+#7g=grM8kkv2);c}sxU~a&Z zrD1r6I{CC4(4BSZII?6K=n`puy4iXVnsIzLkZhu@o3X?tGW0!EOcRAlnifZHhF4I> znqx0hmQx>6-Vbfb+cdBX5T5O&FQ>9_V1GM7E+)!Rml4B=c2QsSJ&M zFNuYNgQm3h^Hn$;I)Ab{E#FDjk^9c+dK%_^`~`H90|FUQnlw^db4xn#QYtufy0SxR^Bu!SDUvAZC&!rM*fk*+-k(*CH9gt zQSYM11XTdbLw1?ifP)-rXXBk%z%`U(jQjf6SkKDo(Z7(~HhTP298u&`O~wT(BjLy| zT*gy*M8&vByD^oDR6%LER8GVoxjxOvCqZ9%#Y=n+vPPDF;+vHfI^r@43@!t-CTBU3 z)}2||hm^Y`glBR|Hbjb+Vb9GVQRlnmqQ8SO=Yp$A1SL*51r4s@Xid@l3yMb?Y2`4E zFF5ioGxvb`>KXjaU*Ib_q6C+u6?+!JWE-nWUF3N);3V`Ys>O|dTPA#Xeqz@B8yTiW zni7Gam3G1S)WFN1*nv|!74n+ONWXz#TDu5Q4BIR!M9M8U**eQySmoS zDNE*?YGiYC>?vRJWfJzi)|T?r8Ud$-yQ;D=vLtp?2)5==j3yT`?V~1vzh;s-D?Kom zR>n$CV1kSh%3ZOQTU4K~uL!&#`L>6bOeA~wtGjb!oaD5c9F6l}+$6=*S#jyBAQ7>e z9Xf`1$H*Biy@i|KjuW!EOH8ZZSo*WKGyUqn&m~?6(?x8Cx^3`vPt{4%zYE!NrcDm( z(>$59TGa2X`kA^7GF+F!z==^JZ4`kP{OO6=Ste6r)$5sGVw(q|^(V~u)MZ`C+ckfF zT7+~vd7e3x7(}_7rZN&rJkgl)?>+{Ll&z^-{qd5%88#gPzr8r>N{ zt*#iwyfBgv1Wxa}C&8+soVo_?LRXhYguF%4+uHJ3$=@kE(^Oq&->Qu)n@ImnH}mgx z{sxE`Mct*L>GSdZQb785>=eBW*ojo$){!)$RB~3Di17=!5pz#wc1)K-upo-X0kO11 z(TtQG)K~Ah)z0EQGS>zu#>I$X|Lh{nO@6eCbK8N4YS4){ z=JTlEW8ig#wd2s`3L9ZOx4a}8rxfk86~Xn=K6@-?imUp~Q&fg6Uha!`d6s z<~vb~sxe^4y)0s=0M&1HiS)cB`iPA%E72LTZF3s41iryZqAii=30YNB4|1|Xtq(2ccJ>5gU&One&AKCC6E#Z&xxWiBI z&pUoH{1=aP3jGu?!!H*&cz_r9QNfdLOZI#M_Q7nP=G1@%n6VK#yegtMolJrya0A}cwL_f zOBxosg^qvScl z(9(|+@wDNHpqW4zlaClN%kmw@d6CDrCUxleQ_^agq~8KP052e&6a+5gkS;@6f3oy2e_e%jxEYsrgU(H z>03aH7|Z(~ViRNJ74$4?wRT9jmA_DD;R!MOc%cQ5urTL(s5g5MBC6i-B%w_e_8RM< zTAQlFsetJoN^Eo=TpDuw0B+OGd+;>lp%=b9qmC_q3da&Z(%iD5Ad3|VPy*LvucE(d zNk7FqWJ5JcYHqiJv0$|i_p;D)BSK#B3W#Sg4#NqJTj`$*VDKPnz9Rl&n9y^ z?^BLZr^*jCeae01vNLH9W9LJD^=2CSv;YQeNNoj7;Mgv`NA8Cp{RSULiQA;<`_XWP z)uCq1m8mpBxZKr|B@|ibFWgX;X1nDgJAHT+w)-9j8E^a-)gr{W_doMDR2Dj8A~%LV zhU7+RI6~rd=v+J7AdZA2rj>Ns`PnuGqFWp03Hu$rkTRQj#29YroJQ59Scdiu6vYBB z7EeW7-BjSKaAM3!SP2FoVmwZ-dOK&%xKeTje##hpqK_DGKABeP&rGZ zuJZC1wq=B(w%#)3TjUWc#9NmRmd9^U&Z>Z~EozDi2OwOmDA{$F50r|8$}xs^wM!h7 zv2wKJXs;DClm|$&`iE{Q4#bJdCXAPyTyUm+fhW0jKcitMnDqv(ESz5Tn}4sK4G=)ylaqq*LdY#{DAjN&tRqvsix0Fa@V>cK~j+LAHC`^ zDyh^QJy$3ztUjZRp&c2bgo9j{{`g;H{80(zdh7Q`rtF*S_>Vp`@@5_i#@7Eo*rAK| zg8uI-RnJ08LJST5Zfsdp55v*LQ&p%M1RHGt$~YK_g%&jWa=N;y38qzUeR$hrfn2Vx z`OIj6#mX#2GwHEe&U?pW{ZaacrYAbW&%yjR-x$c-BVy{#$Me*?-;U3Y$H#Mm1->Uz zzxEzte-JUWK7fA`rJQy0D;!%TF%?6uG7^9nPKqWMS21oX%Hh22x6VOBiJ1J0%t3*sC6D6kYgHWMFL&dnFide>~ zV#oBDs!B^BAyRXDCn|0ii|H4mtnq zGp{H$29)*}DvE`gCUq&y3-Kxp!T{0^U_g=>hza2-$1&W-P$*&4T<>wJOsmDiWoNIh zLJFk1fli1M<)Y{Tq)aLi+IW!_RD6f9+*HXw%j8-vXKRE+2UD192bVx-U_Be@tgWGK z>WpU39^Tb#;@-uYjNnR9Ky09u0#-~~HA&y;gu5{=NUPHte$HUFJD0+MVMw5F&9;=I z*p#idQaZJ4S+*5*Gba-q%a$!IaE)Ul+>-;?%E``?`jlZBT>Nv>!TyA!qjt$Pq_5Wv zw{})r;zm|N%R@pl5XyF(*vnWo=r6$;!nQgoFK;+q-4-bc+A~$>qnMgQbZHugMcd2` zTcSX#-JqA}4#rorSbwaN?VjlmRk}}D3ehCYGvgNM?zgXltVUm8t?CCfj?0r2CgLKwXzSv6NMKBNGjKW7raAq{8NMiXmu=aaA1-be66df- zqx2Z$$9VDIhPb|m}yPDuN8**7Zg$%Km52cQ^C-_SS zH#RG{WH}_e)*FYS(G(hCIGO5R#Gm$;tJuSrS*rV!FcDJ&JV%+psPc4@Tg1?+yaK5W zA<3sRh+C<3M)Ir&C^?uIpXdZ80lv&fp^+dhMv>w!P{7T`P$YY$j*{$S>MZheX*?Js zV-~4^d?8<%DkjN|w%6^WYR!{KpL7q%Y(GMWmQ(GL-LF&3+988CEfw5=u{4hUP{M2v zv`dz80^&~c#gyZoSDzZrbjyxRba+i3IbJErMj}CzlXWLXPeP-f3|5(SL)4X=I{wNCy{FO!hZLg+&vaNwT z2o3a0sg6B(cc$vLF;AN7{LSLZ8GEbD;wLnf3$Lu`uJ-7^qsb4)Jf_{KH~YQiNmtw& z8gt_@=k|b`0iSWr5cV*x7Y|HaPV&DBQ>rdfv{o9lh}#qgpRYf}NTnM=hW^cf!i*ov ztGSo(5FLoLr){R2a?~QQ$=QJH4?ce1?3oc@P(+MSLq>QA&>x_-$MNF0NHG2RvXZm? z>5Gz==%_sMt?>#ODch=KGkm<}@G2+5CpZ!dT2DH6n16>`c99;jidII8z>(jm$*u;u z`~F3oRcfIqBt1aJXidmYxUg+&9QRDu+b>aHoUrDn zIdE||xRN8|d^Cu^6U#=uT}uZKg&El%IZM}Ke9icxq--ZKf8^vn6uvbB#O*3^oHbGJ zm;t7lmwK_ZaKuB;C3JcKSKMQ_+*%A(|lAuvOZvH^iZ7p^g;ze){5+k@|*( zE{<>E_P^ZvK?}s+iF`;BrZb?k?K^R=yFn);#p3I%gq1SdFpHbgGDN8mh8MhlA zME39qd}W8>RYm!R@k)1p9P+XjtItm35?SNZ)NC8Et7vLjJgW_^9vmJ1_)SCa!!k^c$rq_g;zHs|cFi)tJ_pM;})R*5L26_%4;12t>R3YLf9RQn)o zCm&cM;H710;nK(TEPU-M=1zVKw4(D~bwFdHwi`txNqF1bu06K2qs(hQld_%lNVe@; z5{5E!E(!jYs#e`0#>J+!8+oQ`?`)Knz+80h9z#OZHLN#8K4;ev>*f!%Mncr> z%%fHWHRj3{eXZJFk|u8?8Edp!%s#Uas2+e$9p=0>H}(7vE493?Zy>Ta3(~S7z`7xj zK7mHbf&^}!YXa)U;8sIBVcV&?>Xzdp=T>%iKj+u%xs>)y=m`i2O5h1}H|S&Dqty4Q zh@?0}_^%i|{J>~XSxJt>qn|l8uRBgHKS+y*4P-)u z?jBy_w4cZW(r9m~iLL6v@o6ILrpFn?$sWCX!2)JE8=2wgHgD@3 zw>@yn@IY(x;cU$EJ?cGYzF8t^Z`wS;8`zleOHs4x-bir9zXkvyqw4>)Yh<^lBP7j+ zQCQAOEP}Ke;bYfB#fS#mG$8Ugfx7Q8W=80DIZ|jlG1LxGKJVkM-(gAdMj$XnA%!$3 zR11}@2GY+(+B@;-eL4&a73`BUiN14?P}_^t$<=UYYUwBi{6cQ=-KV}JPyEcXqKu78 zh*tkM@GC>NnLDm5T&&0w4fEDjT$qz*W)=a};iqp_-e3T1yT~9A_BQ+h42M^kdzfU} zJHzv|inz>|Hs-x5JG^+o^S3(UHh4t#W5(Ub+9BObC%~1eE*s5QLPK4x?CuQ}lc3Hy z@U?`s*BN`qnLz%a%j(0k5Td#u`v=7CC=m#ts5#t(3&qt$AR3Qxd>n&|Rjg$sP`b_0 zeNJ0Ck?s+~B5wv^M)Ube$py)M`3X9XvXMqC?-nNS0sHJ+0GwSc$^|?LB zn03k*HHv`d6k>Se75wVYlOCPd z%=Kg~iWQHQ!|YT%O{7n@7sTu=<(VCkmR%Rr(C%FDGx&9C^#!`i+T$ReO13e^UN$;f z#Nn|0zWsUK)@$+a{Sf?z&fN@QrD6?Xej$Vmn6@1S`hpzY1$IPrEmy>zrZ@|&%8a>5 zYR;lb*K@QPZZDvftlqTC2yiVQAX(fsIAYIJ(6KqYHg6E7y+{RBsR^T&Z`OP8?24ns zF)ad?N^VPY!QByT!vnIS!9Cl2m7q)RUVppI*3+N@qFHLprHM+TPta6GG?7uH%$V;@dR;PA1 zybaEEhH8V zb6Qwb$?TYrI-2i1x(3Lc0<1o?ZBd|J4jb(??cou*+_`NNL+T%iL|9_F+$>Cxu2zZt z?z96^5>RISYE3k$0-;cb+0j?_yw6b3j?R5>CFW<9I=>XBonxByd3&2m<|V*6V077Q zZsI|&>|p_3;_Vjb z;iOt^ zL7M{bvgn+Ymgz``wc$`J^OS~0ZJYwBis@uk8>Yy-$Ac{^C4-ho;?2fL?Rbnt0==IVp?V*YKzAx${v`jH+$Yv1ry9F$HO7Qlai$ zsCEBzFr{ANWTH2EQl+(8P}<}&IAUqiU#=X?Qtbvf6l_Dw9e>^ZJNcQiJXyV=uhyvn z+;AjVo0e|n5Z!MY&kg#Ofv{7%kLOA8#sX`WgQ2DPgt(8kU9-zay-lMN1CRdv%I`Lu zaFk&7P>g%I4CzwQ&SomZg;?$>fM48mO3Qq?+A)dld=Iq|B;d|~p`Zvp6ez!R`c>e}b3NqascYvxuybIprCDC4Tg@4Wbmx8Tpj zE-pyJX}4zJ21<8oyd%c^K5B#VWnQkf)LV;prxi{bruZ$#%o-hnGmZ-7uh_lvEpRrA z_;VAgTX%`aSq7~H#i-QxoHU9DZ`u8tK+31^hplGg^whsDz>s%YpZ|&p4;DvKIOSet z)KxN+$gr#h*;a+yT%%pVewIeU=E7QBM%$L=s^8K1X036{yf8l54;jm4QFG4C)7MY1 zm&}>FtArE^*}MR#WL#Vjyt=H!X}bNC0M-;GTlMukz{%9Ek~~0b6bL{|Ic;0lThRky zqBfP=`^~v>f=(7<(}98CX$xC^)|jZ;u$wB@RjuT&2&>x^KTCn`=RPfU>H|N1 z*;u$@mz-?OBGMY^@nRi(c!dhGv!{dJJMn9~qKC<$?W1O|4cj;FX6HmlUjOl}i+SA} zgP58;e@w!!*$xC=!4o8J&jr2hhtBI}IH56GOG=pS5F#heGx%i_lm<7)Z}679 zE>nwh1McD0drD56F8Z}x!w?Sds5=gE?N2COv*UQLvr$ygkmfpB^ZiSsRln~& zWyPPS$@3@#2qN0z_J2!1l=T1L4;f*k`Ezd} zJNqZoBJLVw|3i%RNnQUgFqwtuD=YyK?Ih?Map29;qg}rw{$6o} zR{Q?+F%VpdLfZEt{!P0GE+X|ydl1kSjt{;?arR%{X{T$PG6p^lxn;NVlLz{dQt@?& z25jhRvBaOrghnF8gksX69fP~4VB)V91GI_rVKlriDck0l74>%#ALB)XBYAh24A*ua z=)Vps#2~l#xNgbm5A5bnKv$eAHq|jx&X4XE4{|+ZievemPjUa7 zg&AeLY<2t|W=OtSSL*-Z+FV7|`M=90TQuH%&@9mX!?vbu*+GLHE26|YQpkynqJ(vt z5cit|m>*vrrm<@em5UOoMEI^h9G& zXtvu?BiMFGapV#9c8m>rb(O3ezG<{~ZSIq|>&i-$#mbaAwTWU`E_OHMjaq~95OuYB z{qFq)`mo%LquY!VI&D>+ov_51!iphXtxALZ&{O#do(4mKSCF?q#gh_Jg~KWh4>nu1 zL{eb+Ra08>bgQcmVM~=mc&}X5s$xWs-F_!nCQt_F>@CBEJACf9y`2jr42tDdkroNX zH%RFZKJI=OXU7@xAw7eqlfeKy2nDn6H;*{Lf%f{O?P1QfSqFX84xHVp-UGE%QcQA# zzqa+zYiKrm{(BvGl|eG{*mD-@EF2N04o?6^AS?_w%?Zw7L#g8@Oult-rdIjyei-7K7eJYw3sOHj57e&Op!;bLoN`7(Z`EupbD@mi! zbgWNe)GaggeL{u?*v$^QE9eAEeH=iOGv0%GLQ8XhD;kf?Yc+ldr z2#;bW-YVL=?(ch?i?)p$d$wwqFkR|2n+ku9u|gfbWZ5H+aZzP)N@sXm$CX{=OyrB=MSBH8hC_<$&Z(gvia(> z1OMv!ts*@ipp+1mEuYM*@=gr^R@lMfsspMkmtrJc37VUL4RAF-zxOM+>guH|4s zXZf7o46S0JQ~Q$++Io$yt3B^5W@Vex75&~q)Dr@US6Z+erQwP^lU&V!nvOn&G%I5`_QRr~NFzx%Lvkl<7iq zULU9@`Z_Bc)OZ{D!vsrz+Ny_J9BlJ#l4EU;o)5FrRL>85!`H3k#+YkNK?D1^6GjH5 zsvcc^iVZ!P;tb8)8Hh`tnWI)}qh)2W=Io=DYb1;dH4p7`D4iG^xs&G5VNO-LA9vY$ z%%8k8nk5gN#^Jp%!;AdL-Ifuk-y-?}p%oG{$@uUJYJz`Wyg;Ew0ndW=F?Nz`wq{5# zn(zq5W%42ZrnlMtg_}H5O1wC7{E%)iypK5+yPN$hnAYmJ6|H!s>VWNJ+zPIBA4DI_ zH?k#Z6qYP)=7Fk%KQOAeMX@#6T2wehe}9ahPxT~2F=r~qqM-L1%BarkXZxV<{f&P4 zE0f+ZCU8Mhx=?69VYa&|gGTv4uIApHWV;a)5X zK@Y@H7)hEV?j2O94zHs)7zlM>auW#gY_!HzDhaQ%)X5&MyY2i3LGfP+Fa?UFS2_>z@&Pidi_^!WNi*A% z@I!1~8a$kx9h%@CWn5uMDCtV;x=@D9`tW$8SS7g@&edcID z69?0;4ATXHy%`}S#vxH(KbucUfjEodBGlJ`2mewe2KBf5Fu#eQ4`rP7s$GV!%D(?? z)+BA5m?rpM_Zxh-&(Qn_bIZ4*!{xu_YAI?L|7Fws2me!eADa+Hog_s)ft1%cs%Dwc z8dP~5iB5>NrEZ)V-X?9!)!n#Y=lx&v3FUWt!-31c^4#xTKN0UViU6t4Nw5D4o5$DN z%TwNu+9CNu*apr{y2t!9qrtSNKu529TplFd^{fyG4_*y0p@9bu(Y@_Kcaiz=JHF6u ztx=anToHDiSVr1+b`4X-$r`e`Fi~77*fK*VIR2v<&w>ivw%hz?)m3UkNvS)Ng@nR= zpOn%IX5FdOn9PYD?{f7?JTtO*;a|9*7!V2OSUgloAt>Wm-j{NtTZZY8e|8C=oqwR#7uyAS5E(XqeN+|A(@7h!Q1i zw=_@Mwr$&)CvDrd?aY(5ZQHhO+qUh_yQ;gY?j8L-i4~)m#fNwA{cOc%Yn+>#D=CAk6bd*K#%ERYONvmq))Ol^1fOe4i*vvu$ZP|YLPPvX#rd$Xm1<#EM`U=7<)v;)aU}ez4UH|1Ds%y0PFc|v?depv5)N)pY0a~2Je%sy!-yggJw1$%Wg3+EF4AUvy!L<%MnmWU1eN%hu% z4rn&cm|Uyqm{UkDi;!U%g#L2f{p=eKR#z6iAX|h}wP$dP>(ke>y^mD^hzIDif9%!d zT)6I5V`bZGWOEnzPJ_3Srjln-*IyYe!Pg#Po%D|v+>}#Q>9G}^$B1NAhIT8hPLCW$ zE)~)t&AYE*`e|Rn=CGmGByCmSFM`8owTmWoD#BEegALw6-+~UodjWN)q|N(nUUJUQ zW<@8X-15%nxGPX5zPh66r=k0s2iMaxM)lagb@4P=!5VkoDC)im{CeDE0Xzvv5^Kj9 z+e|C1v*J0C1t|yL;rVQ}3&z8G);Ma=ZP6=OOO@N}2GFXUYtD^3i`z>a89dL~#1%e@ z>-*gW8(GYTELBTpJw;}g0Y2LA(j=5sx^(Z)sXKt^*GNnF?rh$4$7DMGM`XGL-)!wV zyG}miv8FnDr)&qNbFZ`QNJe}?08&H&fV>1U-A6!@ugLVsSEd59i6S?QiNi4nPZ;Ba zbEg$XCB|i+H|#yx)18B(v?4!*GLyScn0QQ}hOI?yA#weTl*GP&8;u{CPYC35GTc;8 zdnCZCxF-UUxlqe0V9tv9F|Ey;33&Q7LT}M^Q`t`$pm{zH)lGB8_(smc#>%v{(ujW> zcE!JN)`vVppxm&;ClS2C(Ck{O{-yDZLNDJH`AzOZbTh_cctzQgGY8w=X@hr*Rn2M; zy=C*=_IXGF@s32PlB=wAIR9PJ-u!ryOMU>YS8j-dkN3l>TK^xmqF#O1Jepq?Q2PIm zvY7vi+&iUe?uadl;iD0vsu5$Xeiw%>#afqeS#4x3;E#mIkW8|M5NEWPWNc*Ee`$5& zaX2?=Vxkg45J=?*jCef&e@%o9uwO3Z61Pvzd$0HkRhIA8Zpx!^HGWal4<=D`mYx0L zvHfz^;`#G-!}o*IYv{%l2J1vRYn+Rv30$A8J1sr}EwBMuc&3@+h_c{HwYV+2Hc#=K zkH>|GPH%_i0%>#|=tHVYVluSAr7BtAL)*Ch=LdEd`?qGkn&dQ_Q?Z+x zgIa-B;x8hG5fVBxePDo)I~E5(0rdbyjTzGtZ`oYhv=njNzyJid!ES(?lAdkDH4TVg z;8bJ>DaT?`_NbQFt{~tG+mZJmohn)p)-XGgo0p)Ryn?KXbqV{u4tNK}bvPHD>vJ58r z5PBQ~!@@D)Ll4tdrF|nPCJf4rZuaaYLl)3!=P1!%QJN|J>eR7H?1mYYn3gK`AvZRcNK z!yZ+Tk4(Rr1E@;eE+D-8?&ZA>)e?C{Ufj6kt$5f4jrNtN2m`VpK-& zx~DnC0b2Td z1UzHt9^L9dUbcQ3O=fyIqB!2n2gb#`N7^bVE8ABY3!6yMt2grEFD&607SmhyCC>+! zHI}8fW}o90C3yrAsppra3Z*m)b^p$zjilSklOURiTm;~C2gXq4(Lh$~gotR?yuUkZ za2Y6Jw%TcoR82}%jY4^Bj*HwH{iQdIG$68EI(w+QRm<(pI%n%q0bo=6!NtkuT#QSN z`G0_68<9xO%{5Se<5*?Um+~>H$j$Ox=m|wk+?{Aw74@ZXCe1Dd8Wi{2O!-)yoD>-w zg!(sDT0F_hR+|gNRm({NuJ{8ML0nUJQqFMDi$SSgW1h-8@g-Ku!`*JKFjQ1-sa3@R zXf}XyY|_)s_dQs;$K#TjS*k5|(OmTbZ20wpY;mt#&0SGfD{ZTODQ}kxfPzYx#dX-- z{Vhs`fi?Rme`nnO%@w9ou#F#8ykd$T8KG)>6w!Uax=g`cw)uH3-+uSl7b$wK=Cj}} zCA*5o*B$YC;q2_b*gDvlaWvi2Om|lieZuDK482&`efN*M{(>Z<2cBE(^kB|1 z(7S`}L2p+-x!9R~fn=evwFeUFdck!;hc8rRb_N$L?h3pr34DPZDNn5)zdkow-FQH2 zQ{exR)q;gE_!D)KV;?8&iX+>1(rPn;lH7S~E$9*dqMs0lE!!#gwafipHu08jKO@pE z_SG=+H)JdGLTd@v+?I1rm za1Y%A4b+e2YM znP2hGM4N)xNg|>vSPXDP$(eJ!grrV`ygos?Y!)u87SlH6Z=61ghG)8V8BeO$2{o zkqfS|*{?F+NaEi*`g|Cm*A+uWdPlWs7n10z@-f7jYlpJgStg(4+_y0uZ6k< zngE2wToryHVH_pDBGJYI4Z@oYmHdr5YC%&5Sv~pfY0iOTeML!4k@3gV>ZCd)^;Ge( z_!2=@&2-)qas~W)%ZgJ$R#lOKB-#D6ITc9a+|s7%DRo zuZfTs1!BhZrlqMvjKpk)tx;26H(`pXNZN;V^Nxb*l5mX1e(4! zT7P!LO!XDHN<)-qxYufPQzHRpy?}7bI{91~SD5)rdu@@z0)=iq+Yggv^0auXw5Tx| zotk~nO|e_|q=!;PVKf`W(k1GOk%cDgEP`N*+Nk`_ z6;iGz1kkpA)#Y||VK__W443g=(H}WGBduFem~Me6GYUv%dkNvo-S_&>n4wu18~IT zQW>u*aqt&Hg2r~`in7xeaf-^FiyzAaW4y#qf5wQTVhi54uFbb7Ge)9D&F5$H7n-vI zkA@Ehs*EQ(u!^?W8aERYd*+i2Ak_m zKCxc6e**HH`&RBQjvtC+_N1(0+xv-F{W!1ud9GqQ&BHbJ;;(xs0A7tJhgAULDrLPl zXhEQ?k*IH@Ve4>p2_&gD`lvShT_TiJAf3p~Bmah|5o%A~qq9tKpFx99CUJn9cD{vR z+XItu`xzw>@Vw`DDdg^R8nY&ea#=LQ$u87pp6yk1!;Gyky`|0?r|PB(JTa?ECXYcR zY5j74FWD=0d$E5HKHI?N3wmc#6QI-Gz+nEJ@hWI&(cA(Fcwbc|sIl08yEao$TU#V* zV41zQqf(h4YX@9NxM+(fcmG2x3YsE;%D6++A@v-0VK_q3=#seL44fv+*L&MxE(Qt4 zE%Eh868{H{;yWL-B*ZZi{2dtN*JZgjJ9K9Yzq7OIf_Xt&_w9KMym>+H88V}%D8?y& zUrV%!O#A*yQUgfFRW7C{dDd7pw2+>h4-vl_C0+eHYl8J!gy>M>il_1wGb1(N28*Oug4Xx6!;A=Trz*;ULyvOc3RZ2=5ev{ zTs4rx!~JYPFIb@u;(MeMUz&hcEnGISKi36$@30a_U(92$c}QRqxs~{36msnnxlVi9 zon-uHgtNS{#@j(~ck&3xY17V(S!}VZBd>+015d=g78ajWkqvkWZo5!v*H&^(hd7BT zU@ZBlHOQ|@65h}MBLP{u;R_D(E57~wUM~L=E4iY$iLjO9|L!4;P(?mL`SGr$zvK*+ zo2v|?87!TEv_Z0#97+ez&jX00l}A9z!U;Ckb1}(ELlK)7N=R=cHBTs(wwy1XVfI#4 zbSbKHe>7fy`~rKtIpw%IJJ_}j(MHz3&BV1oo_5XI@xJ-^aeuJ>vvIcq{$C!V!hFys zK>HDCGHA&MFU6N%!0ZT;`cxy$zyo44lLfI0nfDYMWAGK!;x)7N!VU?1#FOgog{#vP z8%{^Xl^n1$I8|t=8h~=Hy#QAci9@$J$#V%Q^wtZoO8f9w<{4%{G*4;+wV!mIkGP4s z3n%`Cg{D`bUQur{$<$5Obo-<5abO)}6lA)R*PjXyR=T0|ORS3~ZbAG?uIJJ*HpJ6X zr#nj)m%4El%H@4jfFW$j-)&KRTT?-#K7)efgA=8N(Q_4Fv+y7Id7aJ>*d2kN@^Isg zMZ2$^s22O%@F zmoHr&DsXYgp@)$Z&pu@{y9g6mYJ@2vf2 zby5A){UObTeMxvnZB*q#n2O%95;EL?`$2&MS(l^vuKk)821mV#GVy zxRAxNC1cut=}G27B-ybBRvWP8(V^3NV9cH7SS^B0H$#)?bdapIxQsIc4OMR5Rho-t zs{!(*bT!Jx52f7_-n8a|v${7r=n>4Z+14a7e!W7%79pO=DJER!5+$_OGG1nSiK21e zEH&N+?%+eoEB>yjc@5x7HCrp!%lJ0N!Ja7BC=+i(&B z1yf;hU&8*}-XRlIfOA&}XLQ{eN?@F&8^4sAsLCL-r~+dE&sD^eM|(nI%Y0a-yf(a> z>?g@SA<|LF2m@`Ix+2nn@OGDKw2VE7qP_}y3t$Qlt#sOK0g$DxyPMVgC^9_c4m^ay z>;e!gW$BCP6&Y9Ywl#c#+nn-g1Hipyp!y6eF{YvfoqQ_m%g`{JAC-@wHrbfH-sabZ zAn?E#=0jtwhLG7;!tpT^|5ax|<)$%YdaK?ZmPksk%|K;zLy0L@he6%gNVvy4A&&A9 z?{5m6A3?K|vs7m3c3FI)2E>t5*@O9rFG7|2R^qi%{j}2S1Qww@rW~i%@o42;Xao9?LocS`+)Sx-4A(1knUh~ zX}PdqBCb<;c$c<$!ZIXEI$}^qW9!Q)eWjqCJ^htr1X7zB4v{+wdwHNjOxGT(FLIh` zt{VVrXl&Wq%gpOHgY?^+tV76cc%1NOXJuj0CyfX{WhAIG! zr*)z9<4RtbAx9Y|c5c#-nOC}%Y--?i+42ZQR`u^94H1W#H>5(^mnk2nd{B=VBp^P*j{(FdNVhKxB4{p@5U`SL3S3Qx=WldEinewS-j-_O z;Ef2T0jW1fol>p!*L_?QxG}q98qcv(5le4^ZF;;c#1r9~{YR@%A2GNcCEb`lCDBl{ z8gHIq58-IEJ_Dgr6y|kL%AZm+S>8l-2jza&aw?AHGN-O=-XC{o;1A;kgmrJ0P~40* zi<=X|J2_3{hPqLc%ix2NH6YDJt8WV6+B3lBe&Z4H*h3cM4d7;r`vRipi~Di(MZx%j zW*54|JhN|yD+**s91{X~>xRqeSyE`wSV^d%ft-`NFbwWM+QnhAMnWikBA){M?ByAU;GXI^!(UEqe-_v0%q}u9l!`hKbc*S z%V-b6(T@IZ4my%$9O?!G?Q<`(U@AN*squCrasf{c8*o>YE4wbZ2U<_z=dKsWKf9B2 zUxFvNM@qFP-R9J7NS`A3^6Jf4}_z~ZFl_evFjF(Idlk|W2=3;eLReL{nrKyZ4; ze`ghO@si+lRk#f(_+<~+-fF6+o{+2EjNS8u?CiZ1w#2pWj6@tJIX6cB_~l|^1f#(J z33{QUXvS7tRZ7>G8Y-)8gQGX?#BAd2xTI@vlH{~x46mGb}UnIk0*9IWa@ z4p6eEQXmy6)yVPHDc;row{~$Ma}OiI(cM!3|LM1r75i89i3%~ z3sJZ4b9~iuHMm}P%{bn0H#{7k{T9u&`r}26=F-Jf24Vl=Wc2$$pH|80j85bCQUo;>glzAF&3%#(Z?=6nG| zoi+?#CvIW2yo%kkYTI@LX|YI=SrZU;92@rJUJS;7YFLjY8s$on*(J>6=54ftNWqxq zzS&gS@9@aU(%2ml*KD{vsiqPbvO72KVzN`E_KK86hwNZXF25cjuKfL?cBjQ2lNOO+ zhA1C{RH9;Qf@;*b3A&Y-ZYAkeaj1<;5mP?Nsr9Yc`As%Mg$uFu!{vpuBYr>Sz`qqm zrhzxZuiE!fW|u+Z>1;NgHnq|~;3e^@=|Crz42@lV`w~uC zPyPf??R<5*U79JO8#ol}U&~An38!Q>vBi^;1)V_g=&Ih+%@eH7(JDs{g9d6j!KZbT zUtcr1xi%fGK%b=`q+Ilkkq%1h1>r_CsLacg}JbMCrAIJ&zcnDz&)w^zK7| ztGuBR*;!9co@d0I;0st6)Z^@sa5Cjocad@zuh9%QXu}6Cfo+4R+XY*_F}>&wg3;NP zoD_)gyC2LxBQKd`8CHn97eMM-iW)sThu6}CkF0Le`itE2+781f93x#{>-s>e2%6NA zo|H=g9K8e>I*E4@fuKH%RtT)_U_3^OeE|14>C4LF7Yycb_dJ&BlbE(TQp(EYA^0|o}e&KF4pc|UOcu}$c?l(?6Q3VIGi44OD%t*O~MkR@Ocv#*wALtT5;Of z?fOS$T?8!uS3osN+1eH9Hwj-Xoj|&!5ZVYy2y7-=SzbIcNpg;aC$p<;B~;!#dbcwcF91I}L8|qEJIRrHy{gGK*?q z#lUoeF62Nz9TRd?DxiDH@e@ut{Whfu1MD?u2UyZw`pF!nDi1zHuM|oUec>`xpbydj zMQBx>+my`&ZY#G7g>cXmD)|EI-_-P5zHxcf0rSw>r-0XJTkbk1Y_l-Gx9Tp4cx(iR z6rpXqZ-jok+8KbVGjbpdVHVN+0<6g`>p-CFKaEP^xN!9A#}V6RK^$h`l)r7vW((x@ z(|ztlg46Ko5#HN~!`^*;p2Jy33eTM>*vOHtnIRv|R0o~=yObsvGR|CD%GQp|R$Epx zT&=-`18O|`9sYZnJfzCL1YTbfi#)h&U63_U>eGEg0-!56oiW0}mO!v3f~Po5U)+$5 z_z(&(O-1Om$UkW9N)x-F183Rjvet=lPe5QTb{PbC35yC!{&H4jLT-fepUn>3XQ8E8 zNQ8(L%+%0|q(9;v>S%MQHIny-Q1*9*M4$F+82Z6&d8AqE zD4v}A-Mp33AP-sQ<`;iGl=-_BPh)kT0gI!rm?p80dUiN3_s-{Li+n5UrOwtYX2IKR zL=zcwu?dIh$8TdNzHTUt4ReK*`5-ks6e+ZM#gQ;H54AR>^A>OrGiZAn;fv1_F6gD^ zvBr0{cB`V53~MG!882ZjO_Db485e;z&T_u}{9+2r@mP8HUS?&{JAH7WWgbS2sbHoe zqwC_}^-^(yNnzTqw>uk#emYIs$}L2@-O$n1$>KNa%=YaPuJ6GoZJ{T<#7BQUniGdC z-;Eu&n3tv+QM*L-92Z#yqwZc(6=}qfIlGDx@xwTY5I}1Erj4exxNBC#^aZG-)`F<- z_-bhW@^>9ZH*@QC_QMSV&)pyzBp-h)aq{`_g;W1seEUzvupfL!kJUUV*4Q8aG5v8+ z?AgaL+-5n>XGrm+rX>_yCh`PYc;w}h-C2?h_0iqs(7u$6Isx{MOUS?Q$f8;j}|gR?WHST&~w76O@i>cf{6lN1tb?2@=ND1{J_HRgaSdf2obL3frl5GG=1ZP; zUYtjgK(KH=ClG}o>fG3B!U;Wu<)rA!%JBL{<38P_#;`O;(~#HPfJ{QJyn93rWU9u6 z)FMW_v{gC$KJZ%zxD`CS8-~D|H90a{Tj{4n*huuSB_syp|G*s$sl=Fg>Yr)22Hlqi z%ob0@sjP`MNdkj60+K4*KEhJ6bFSa&1RLKt&IF@FJs1RuYOi!)46XdJ#LtrG;6${z z-K87BAs+1B>|!X<(!@GpC5Zt#KI0H#J!J(o@5}=BuX`+@e!>(8+_ECL&TacVrx>0KYgsj1&5Nd^x zTIh~5FmE3a2qSo*2!l~Q1!kxr5U2;SOs|!?R&H-4T_MitLU~+hRka=QM}QD+nUOlx z>^ju&!UQj#(#^I`1h7`@#;Tt#|Yg za$sD&DAE53y8G@Aq$#0hAE<&;Ii#jS`&_}A4zpf@oD-8^UQcraa8#n>O>1v%OY? zNw^(L+^kgiElZnKTvKA6bYB7Hq@;@Bxm4blC6SZs70WaTYg#IXl5`UR!tlEgZeT;^{%*yA-$YRI=zqO<`h|COd zmbF-#@$2=rr7XQpd4%3Ia*p6?Vsw& zYgt!*w_1hMi`F3a!N%$&#dFt^VZrQq<7&uJHUXt;2SZW0UQ!P1VhoiT75Q8gHO?pS zMGcPRdBRoyRd$#~NGy?KZIKD+Xxu!`vEKs>7AjV2()bayd|kyrQ&PMlk;bEg4xVJd z0PDC(3|K{OQW^s1d577l(no{cvhNJt5%p{5b&oo+PJefA@p z9m(`SCR=@cGlZ~Ny$c)7H5A*xIb*-F#J1YLsQ(QB5E;d76Lzn_xjkghw*6Nn9vm9% z!Ga9L)tvQkAY+u9Zl87Fycm%{bDqa7!Jo~s6U5e7jT~0p0hK-1Ib_j@o47xapTM?N zPP`vB;R^evmkVP&teUD>@{9AwsqtB=B`)Nnb%~odMW-&R}S8Ry6onSb7j=Z=tafiPx`fOL$q0s?dJ$muI zxim;3(f#p9(7BoZDhyqkOdMD$qG%9ldreHniG ztt|=z=!uj=lvcVDH?RA4j<(&+a9R_KMrCgs>+Kf^v~~0X+aa-(M9>(XiI1R&H}O9D z;PuJf4Z-H?Z*Yo9+hUi!!)`E>V=XgOk+l@!{~*KWLkWy%w|4&fFh8y>@TzO~sW5Dt zgVH3V`@u5udm+`JH=cMrN{5rY#UA;E_^r##hvzk&k~(kBl{qx=salVc4&KgEXKY~y z_i}6%ns}O*Ul9i|kNGPQIQ`C*J6O2RqdRyh`b+<$3CAqdkeRkV9e1`TC{s2CD3uvb zlZ)pcOemSSyN8)YCzd+dVdoi)^ES1P8HA;cqFBEfEyAotuL+Gv5_#m5g+uMU7IEGn z5X9xT55Ndo>dZvLO*GtA6<$iqq}Hg;#Ir7;6FCa1^Fr||>6!(G!8DeKMV58mLC|zi zv+`z7+U;etkIH$5$zmqoM;j-IV9ix+LImp%Ssi1?ZENJn@Knm_h<71S8ILqpwac0G zEy`7(=@8%b7mIg^gi;fh88I8xCL?zJ`OCngsz<`ldsh(PMJG(s1vPl1c&{Dz*8S(< zOq=-U2Lalb@RVNzjVcBBTqXcyl^*$y94)5&uN^SdwBa3nGVt>6PmVqTxRkA5$w?vp zot8ZzhO9>v*9NJhC4IS!R4_$6%mSVpC$#0?6RLZzCE|wb3qsr&Ekh3h5eG#~oJf%v zD>ouIyL0Qhj?^!5rl~gtmC2twfyN#6&P?kbsRCI6(5`dZB!5L~^mdfGu6MPon`Rb}2-ICm{h zM0m*(Xe@Yof5j8bXx?#P2D4aHN7o>Kx&XOwiXws|u#})CNr|pqpd_7A{ui6ypVuqk z5&yizUd{|XR^YPeB%T2K-c7`giR1h*bsvC{dsc$fl8ou57u0FChrGQu!Nw-5HEP?{ zfDJbns+C?Qs$w(MK6<~$2thxwAhHe+xmJL!nYHsDJ-?Hz9gLzJg^wZ0qTFm#zqP<+ z`))e3&JCr?MTZBl?PKN;PvJusu!xA=j)&}QiL$2zIqkSi3RKdQs3}@8t zSCVS+9sgb0aLB^zDMlv#MyA#c21vO7lF_9ik}P$q6QLXAnW7tW)I%TTrmlA4@QI1Q zcjwUID*b=Bn8X4Al?YIm;xmkQ?z_Gju-Ge~lwEg{^#W zkQ_2m9pi<(u$Kjy@)XL3r6O=uX5e`#o6Dl^3o+K{xm)bdNG^yF*#1!;;G7aGH-_kg z?%26$7x>wEStqCEAKW%3L#;u|yDH70*R2zFfp7L)6(czFTN`=sUk=B87;*B{%;#>X z2EtM%F#M1SBtf|f$0X)22lnFure{KkF^n>DanKPC$TliEgB&1ar!la)vUSHQ3EIdw zgyH8vknZgjc9Z#GVkskEugZlLVuMnJ6>6!J@xwQ`xKt!IfIBonE(wjiL>2&4DKqYc z#N_K37&POQ@?ZZW+Fo+9Ne>GD=MNs~e>On+byZtgN!c3eTm8RyBMnbIrK6;utg*lh zscvv!z`zh8_|XVp6nG>Z0^mqeKSXfQLk4l1c)u~J%(ekRYwx_LuVPA-qTFE%>!ElE zF%(N0wHBMIX6GvFwI-XEjVl+|4V$XJ&NFYJkJph%k$**8n4RjN9W)<)c6OPZIfLKS-dHZ7IvV4X98e!cv%>F$Q_R zFk}NmNbGULWb6uLFu39U{Q-VOrgv~R`UA99zFat?il{HV|J*UmN;=o72!;FG1+bxC zzW_C&`P1`hC%`o2omzD*FbXwsKv1W&N*CK9(vNXl!~OnX8I!v96Rwg$n%@y*N`5#! zO<31Oxb zi6HUBH!2yfzO#;RNCjqnt@r*;081%bt;!xG!@mEFaMbRd{hzugAf296qpW@ptuen| zurLs{rf9bQ%fs+%q-0jqhz^7dXe*W5{5X2cQebeTt1n8jC6Z#g{(Ax{_g!vse^#ng zGlIw#e$a92!1S4kTG?`|fSF#@pen>G#~)tCO#aF&oMQ>wP$o!CCTiI2YIt}w2Cu#G zXIRUUOJ{N|5ZH%A74d;JcV!?@M-u8F@Mil%#!MXFbZzBa5;1a_YjE$~v~Ac+X1k_- zmR45xr^^uuh98pc+Oih#0>t>3?Zx1a_S@$nhUj_#r1-l#x|F6N3) zpN6FiI#&mmqiE6wLBOeA+Wyt<&J-c9Zxg1&KIv9rjWoIoW~H3qjn!OBKuw^&D?cq* zRo`n5zc#@=nav@X$d-Zu=-QhZ>|OS^uV!poWAoOKioxK`E8dDJQnwuV&KyDNIk@+H zo>7<8*bT*yaF8b|NVq-yVp9<7+wP>ilHToqJPysGLtCKmDOCKJxQcGrvUcBAkZC#- zmC!+js7b>EHQ~V2x*cl;bAbWRp60ujmo#0%CEUpO*NO2IXO2Dn32x&u4i&!}p@g!} z4&g=O<{@v#0!_C zFvZm-4V0VvOa(Oduq0?SxfdASgE`V`C_(^0L|8B#o9i=!N2R6)8OL#Hf5j{9hja&9 zV-p=)^@RIH;RElV94#Hy*KYDzr0@kxESS#E>6<_t0KRIzs;`*S4tT zi6z+lkgC3nL;~pNLvWI-NN$5>%FV?5BE*!Dt}qe z)474(GDMI14%otccJ$xe;swZeD;mvrPED=Da;uRh(N7zBh<(bI9s1&H-Mg+J<@IfU z@@<|Do8+eoPE_zwd}91i4P__PnGeMxk!564elvVq>>>pv7?dG+1H5K3n6lcX)9loQ zE~&?d8&a^qKthhEKD|CVMC;8A;{>*@E^7+Wg5@#u-*{Q^YeV`KrfE!a_3UhmxoX)w4=q%+9OUfWJi_EFb>3gV2kqoT~axib_LWGl! zhs0rs8`V_|ug6A4T`FuC*DYE_HcFh3NN}po8SOK$DEAOvij|XCTW4q}unaXwL$+?> zSvArm%P5+a^Pf&CGT#QyL`_=xCt>;{6bEP&(mLp z^4;G{vv$O+q@xntA;m%tr)2KCyy}@X-3P9!pJre3DSUaHxp!%2qqBVqEqMx5_`<9! zt0n7Q$=&4SobCbxU)_MTn}1GZeXwkBW&R=0a{upQQ!Z@0sytC$j4ANsRo9SNKSoe} zos=+*$D(<(Q>gz2@|zh{!?EK~rEZ*SvWQVE|C#C{EkDP6vj;YaJC@R79?LpH9Sda! zfw2Bupys;5b+Q=Ol|-CVhgf?+tsVZE0RtC%U$u%;6nL^Zl*$d%m=?Zmcj>7lVPffk z458M$I{5Sp8+m)2&AuPgB%@Mi#2AH_Agvo$kM1rwseA%56xuS{yMst z>Eez3KZM9x%E#L?&(yc6LJF7Nux*D^{kyV^N;uaGx9@^o&33Bo48EZFKDvt*8$g&{4P4&oELZs{e%~59rVdn zIqe^bJ#QdTPkEck+A{Bx0%7JE7xMVYsE*UAD8|oM)&bxFHmR+aX0m1@@h))?G>J+Q z9g6!p#`IsvSh=+55G-jEUIqhuT{^ndlzQ^zfB?MBp=8tXX}3e@Xt#FffQPC?Zzut( z>i2>mp)Pmp!fX#4(B$e9F-q^ekOfcP)Wc^Vz*37ZW0-s>n}+i=ksroBoP!@W-6^QZ zE&(5PwCE0Fi4&v#iL^!&l%li=km0a3@NwZ_3jKgx0G5(aM28hY}kjaLav`dJ`gh4L~XEyC2s!}bY%V$n>TO%r`Ns=ztCs|-_SpX~MZqQm@ zhzB_Qc)&)p27gc&zwoh~&~1Mz{~4=~&mV6f>WYNst3=wt4>K5z(S$F>;7_r_@Zpx2 z`!CLdnFpX>;WNf8)cWbLg>k?c95NtJT;XfL1q4{ak#faQgdjNiF$~CC`K}+AFhmzr z@bSMKyTv;qiOXQ58j1L2Y?U$jJ+}K9edV)n@*iT0s`nvm&e{R9u{a$ZS85itYX5yp zc5dm4&fCm*`eQ3p*MSuybhlK{{O%B=XB$w}@4e;L-rTF>+Xc0AI%qz(%%G)4{u1Cu zK;?lRq9t{K0`}`RiqOA%_r$zN_1=#Pdd7%(8i)@Vsde+ttb>GX*bd#7j>hM`Xxea^T8deDaGoE-e=1)OD@0@%o3zK!S}%{7`gbVKl^g^^&pzZ@rQmIA^+a5 zG%#X{*;Nu;-f6#En@eo_WevpKKj*0|ui04BM90i8W-g{-;(Io9iJlUw%9M9RyejL< zC(c_#e-J#-M@jXqYulWEUaB`U7{7on*RX^9S;`Dm!N;TG_`G1}s1$)Ye``nesT{ac zo4Io*!5tyx4noBi#)|F>(KUebiK%*JTEBy+-baU;V^?FwK+uS^RvLL}YK>;y_plg& zae}ca#Ii>cU8h}-$vFFClP9?O)*YsK=DjI`x99Q>bZrMSkX0?!9n-H}eb>5?6yvGY zU|(ZNaP3$%^i^%rZQB<>3+1WBb|Am<>(uc;jp@+oMXI*BbnY7aur=(tC~;FD3qy5F z{o%NeKrAWx;;DGyP(DL(BzINmUWE6L{76sax^01dg4J|^^@eaa`cj~VQIYVew z3l|B=E=*s`jAW);M>;4{O;4$`((x!_c+wOXSIiBUC2)hZ+$^cpKhIRW%@+7Fe-n+! zU&zdn*@v8#OQ2YpmZPAv_mME<7)A|q6gJPqQHbzlv@GKqxjJ0FtFKS6EPIYklTTlK zTMH4Un|J3tG!sdLtA+SVq=gUwH7!D%TL#mYnQbgxii%eV>fJh>W|ut zYY}aX%50S!RI+b`21U|b(FO?ZW}=S>E@Bo{-9ZDU_bGq9TC`(ERFVrn6RZ^HWVO5h zLA@DLi**id7B)8}>vx$qyM*!ee(a8{mQKq^&novj<(wMj6|=yjEt@<#VMX(cv=5sg z=u-Y+sh;g+x}=_Q81jwI>F#6saZlXS#D1l->&5#Qgl13E9d$7qw3SJnv;X0Edb}n0 zN(*~{gWU(_hCy}<8S*Lr8E5NzpnbpAF*FCbVlX=6|JTD~3l+yNxE}++RglOqRHL3>X7&P#s z#qn2Mx=ry+#W^Ad`3f)Z#M0Hs5Z(~i&!;^Kx~)bVQXjG>KN~e7#~Qp$ytWbuhns09 zR{Qe1k{SqM9lL5ExNtG8BdiF^o?R>~j=941Xa=A>LeKxe{dZOBF-eRM@mGmH_%*ry zM{2aHnfd?M@lmDv;i{#K@@*48CPiA(D861OZVux;Yn1NvS2C^;c|Nw;k6VIFTDtr+ zYi!IYo$E#BrfY$in>yEwzXFh!07PCM7&*wmM58R|9WwmpMB{tE<{RW0Et&R(*VQDR z)tFIxBB|1Idg~?g>$SV#W$j_xcgF*(7xt4Ulrix`o?ut7C^*)5WMF<4hYi8;*A7P7 zPr;*)Id9)z%tAV#jiBmktdL$EJgyDFw0FHcJ3p^#q??1XuoY!gVAvh)f)ru?A0YSu#&O>QPOVd7` zJTecV39EMecb$GzMKVXjhvD!9&~T$y}7}|10a0qWKJb(jp;>53yKb& zD8{2*fM9J>%EHFn`pUE2IfU%`%3G5_c0KWwcMlY9*L-^cnGiT5f#pk#Tyj{ z5It{4J;-IDe^$*WVpc~&(Nl#n! z2uKaw6IJL96sAIrJzd#?FrX`wRV*_r$ z$tg-;e6LvtDht0CYRuamhu_QtPkYnovd_?!K3864W%j=Ko(c{&o@?R7$N?s%T1e5o zorK6hdjj;!nY=l$J)-Vz;9I^#zdq|1iQli(p`;PtF0DH9gzKcbmPsWn3&9;#gSa=| z9(TsH+O9$G4P(e zoxjHuQ}c1>-^+G8wU0A}Lagvq0));$tqQO)F|3RH%GxdXQVv*dd-nz|f1kMdVm0Ur zqBBfoM6@y?w~B`jQuCAD`{Le3XK|4bKQXCDjcZt=gXShUhtm>F&9_bbQ%$|4#e4$H zII5uUN=^g4mO_6Ndqe_(GnY&>#FekbYVKA#DAbuuRl2xc?3|i^N$MAzbouj_6C>$4 zR#df$kX}|-Mr}`qI5WPTO!Yzr0_2La zkLldIr+U?SN{5e7gr5Y zi>I{WIwf*3Z|n&=o8ooi+)aUlhk~JOgNDtNIrRY^E%W=|>|JV}nYj$Xdq~WcpyoJo zrEEXGMHg5q+I-pomb_@&CM^<2_VJJ2I7hm3fbh zdaau)IyIdLD7Osi9zn-EZoM(#^e-iV0+wA<%EBBfXD%M%Ml^Ar4wtb0oz0o;&M>+E zhp~6;t}JTTb*o~`*tTsa729@Z#kN&(W^CKGRTbN;*tT6e>zuVuJ8OMT7 zy6+2$i{|%g!?P5%P-k*{{tG_uQ9WN$rU68|H}oDC^gqjm;Hg6IqLw52M^ncqKK!Xp z&z(P{JN%TMWh2`^?4rtMMyHq+4;?&GR+JlOE6X3I3wqz)LGxNDq>#D0l5&=Jf>F8s zvw$J(EUQX^ln^%Ah}Gjg^xpz;y&yI?+)$nhg~RPG)9?&wb#}m zwwPBtT(rQ3X9hn>!G&##cfwla4EY7W_W(1&kat?OPiO+atfGI_c&D0<8_#5)NtJl| z6*0eJa<0IpqLSD;;!z;=$s>unmCJCFt^U#+q@+e8@U)Iyn?HQvWirNbJpzi*7xotK z|0^Rp^kLVI@s$yM{K|;3{s+X1(iia}W@`5TD`=?J82>Me*gt(3KrqV>F{L+TIt$b| zC2L)>a8e{$NHJ06>%~zAShB=)ZZ_ejt0(VyeNFubmwEAv@?*{)sWc7F(f=zFW2CzKe?(%5q3t7y z{g%T`Z3(kHq91u*A~9r9dQNR|yE!!sNw(;KXFY5LizMWfS%~!fhm?j2a`>1MDkc*< z$HjUaQq14_GxUPCxbu+u=G^#Sn`4*3kyjh=8>fU|7*W~yEI0be5zYe0YSaQ&x5DUr zcfKdHxsVBJL)_)Io)M+iiepG8cHVYvrgUp_ZY6TXW8P_6uT^Dy!IqNSuIsk%-Z;GP zg$l#FUGr{Lfv4#7n^;4H=U71h2%uusdSJK)d`|ogJt8xEIl8Ngt#-+vLqpO(m0pJ? zz1h>y<0OKJaQvhjd_)%Z>t_DJn8eCz3RW_7;!OT?%4>WB1b9;m+#MO~ z;&gT_3S)TeE%u8NI4rRfRH#!h72HHb!FI{yu^TVy;6C$zuae znsh<%m0_9J$LKq`xKIk4fy}Fsqw(ZYLybD^ud|R5$=TU%p(LN_vf5-1KQ3^h!tU2u z%xj<6oTzR9vP%Nb~uX0R&7>Q!)L9%)DD=k75!`N`}34ZFh)EHQ#ulU3!( zj-#SX7hRoVlqLJ9Z6_+t1;n~Aw2Q`Gz@Eu_0j6KVbCJ`=1M2!=fPNe4!iCtmj4i4g zvKAP)(2~xZhFm?TJj8G;k~ejz5I{>-lo{a>x3c>n?p}xnsAll|VUV&xn+ecV0QpZjgA1M|?{rz*=r)iJmv3l=h z3#4+UQ|3+)+n%u|F!jS3qEku&b}Ujc(0%z$j4LI-eW=qBo^GJpTThd`DQfPD z2$-q?%L7YkwSHl{Tfg%>(^K+oX?Ar>_Av3xBLEZb2{dC2m|B(yBixaDMF~|59q_#C zQ7U_630-omNeg$={6z1rR#c^)iu(YPJ1&X)tj`k=UrK(jWZd;z@69+f6uR6c{C-iy z-V?w@L-R-1V{Ld@wsN}`_5)e#9+mA<=Q_|3P0IuN%8t&nr(oaPV~Z&YM+dUuRZKC& zXCh7!OE#iFa7KyAAQ3M@L`e`PVpsIl4_(YJ(63L^%^$6cN7J*950KPI>_QJia3>1w z^ZuL4B>>ecdc92n)GiF${gR9ND*fw9m&ouGwkOvihj}siPbSh!8rQdKI`EEMFes}I zD63XVt5!yxy#*JlGNuS4)$c26-#9UT$-fxweb)+Ayh%rLOJj%mjDgs}%c!LwXCv%7 zyyrFZUr*xcE~?}8X$0hU>KVSn|IY`kM@9>s<`+&~_EiJK@gE#AV(NBIrq1>@Zl)$` zo(}(=*8D0RQ$!O+{>MP9Id)U=%f1}WgCQ1e0889QNvR1vID%vdX}q2WdRV`E6X&Be ziV{u&^&u1FpU5(0Fs-B0w>N%qer|8(_r+U2olP&>e;c|cjo@AQ%DFm%MFV_eGM7UJ zBXca#A>E^0yZ^|qp$-<<@mY%~9&KVki0%bjW^R%Pm6#$jk8(pj$qg$|q!fndNeioq zv#Eu~Abf_N^_c6tzMqCNcae%#(iyy!&^5$lKQKh*8;(OTN3Ojfr^qZ+pf|BL{nKRf ztg$@GoQXk%WWk`C9nB-k`0KoeAwKLywj{$N!LQTc6FHz&vg%D6VV9-ipfiY*W!mQU z%X{3B^CPea`I4buI{xtcp7}5ZxyK52Q6>ETK*nT^e7HuF2)T4~ooVs3rco%7DFz|T6 zis2-|%RwI%pUmJ5vaqEKqzh+P*%ss&N+(%HAlkSCcL}mwcGU~Lkr|Hcxk%S7(EBa$ zvVc#UmPd=fnjVSaiz5z~$Xe_TaF5~i;m9VlKmG37tg(1^lZqn8vd}F9p-nLF-d+Mg zP#wt3XE0tRJ+rTd;~LhiHi{dW(K)Q4dCG6-)#b8$mqdhX+X^o^rtI^zw2K1gx#A0T z5gMiy8nj_hL%2P@DI6;TA0yyM?Vssxl?sN3U(`m(ky1eIF&*6-I>cv!V20$W@WF^9 z>DYg+Au*fyqpVI5Mv-+`k^KqvEqk0RvB)bykyw7qae*JP2JiCEp!>f=*N76Wj(cy6Ds-ppg_(e}Zz z{z=~XK~9EIWDt!tTLJ3!z9Ti8VBH#d5ay-)1N)zU>TQN`FBjyuZ$W_n(99t2;b3EF zZ28~CfYln7&S;XzzGOrRlcdIw=lJB*S-dt7!EwJPfKk1_Y!G=!1AjCaAl>$PX;zu_ zQa;@TNvYG9iX1$r(E6#-ZWK2AP*X%!_{^MJl$gIhoN)=0?J$qa#< zX2oC_DV6;Q&u5D8`}$@u072H=jP@UY6)uO?$t=q=eypb|f~}>p$adCYmBSY#8KO9uuW$o z;$RPDf(a}IUQED8wHO=Gxq6m-*n(dfF#%I#$G8~OS$)^C$h>cHLaWkgWQxek*baNlcqm#FdP+n4-((+JbyP2-@t$ z+oj^#L9Grk%gj9GfbSB#X!KLk{wZffsd@^1IsyRb&c#6aVwTS8Of%S0qn`@lsS$FL zK-hZ${n~zT-LbkqGiDZQa3UVioS8Arx6UzKOsg2n`%$%9*0!n4iXY7gkRMWExTO{Q z7Bp;47Y~eei3?T&Ih>Wi9|F@py0h-()r2mS-Tf(ky5Hqwo3|(3jXVZ#4sofn#+P3& z??;Z&q18_Z5iXCHuCQ?yD`mic{pnROQgMqg*w(#mm@FF1+~pe^9dP7LMe(u}kK2Y0 zznpCh=;TdK6RLR;mOKWl9I z2O~fxaT6}V8ZB^*jhN>h=`afZwBjxHwBnETaC{?7cHS*zm~%G%9w_jack`#F{;K-# z9Bzf_7PQqtrT)5;0wlr!EDsT1(av3zTrUm;O=a1qAJ~Udov>;9Y0zs3UKeBUT2QYZd%TdC1wN z_s!WGXRbj-nO+#C2~^>^IibB|oiXe4dcaKOB&XSQK^fM3)|no@LFie0AG#svSynps zgZG8F&y{QdK0ozcpFC-geEYbp-HxP$WNM){i!j*Gr1`YI52d#W=URhEv>nPs*u!{d zge8emef6;8p1g|oFsu<4X)b) zYRQ)AUZDwZ#j8#C)+9-@C39Qr+vDg8*Mt9 z?Q;F?OVOFU*67~JA3&AmI0C!PS+hPLcgdG9t*Vdf*mUyG<9bev9Qs4}X*iC>ul#&# zGRqS`y0f&NpUX-@#;+|rmsw~!W|_arFfnaK5f#old^Z|VMYXZI}?e2$39c2Yfso7NRL+G z5bwgG-W+sG+%%@Sp#;`_^8xmqiMQL{2wg~TFL~AqcfBdSnINy=Q#Ww;?GN0aOL|jB zYh#%kcyK~~PRU)R-=Q5#V??38wl{UYlVO&TN@W~Wl;@IE_8U#!A&JGLJ3^S zkd*F7broh9ix%`X>LNsJ@7wr9TM zWLK0qT3P&TJsVYFUGVXo%#G%gZ_bfc3Ep7R`d`y7-@EVdj~MMnY!*64jWpAxOEv2r z6KSrO*{sD%+J5MsRF+0@l$~lkYB0ul z%QE85@>P?sg@^GB%MoyVRAshXSB!Tt+K_||?DWdL{GhiMZv?=%hLPCM+c|J1&C&tg zC`0rZWN!W@+r!V&TB7qY_era5>n7K1;6lSp?AT+vV%6MHb`hm2yBCJZkQC?1ESO10 z0Q%i!8z;|_5@Uqb8jjNt(3nZ2VU=KV601%>TV@qvW~LA=g-yAVo5^uK+L)vK&lv}x z*ZQqwKfRr@XLrJ4F%emB(qx3YhbYS#^Z;SN;cD89%Y4$GnUu%^Qwm4uF==nQ3jvA8 ziz@xUbfRW80~qpai8VOrKGwE+Rj^R82WckO9hAbGM}rm>akAEPJC3b0dBn-0ddV@8-V({-Ume?cwtBlAKFY&q5 zG2uSaA=~5HkNx*}tqY9__8z*mb$ic#b=KBG#cLRtGLw=|)nRA!cDB+UwE?ngw$+!= zE#PQ~TB|9C&OLG`YPs=Fo5+rX_25!(BXHkCF5TWL_rF?b)atuRzIIDjr&e<-Fp6FU zMKoJc$w;*ArA_fE+lE#uHM>&Q6keF(m-X^o+IfQ`G`L{SI?8LmcQt6FT@^<^Ir}G_ zKG1SJ1}j!o%!UeWLspPvg{nyUdB%4NIT^y+64lV*rM?_+Ydg&&=+J>dQG0SxP(?n^ zIFwBYYk&2>`{NKPd%0pblGZnP$0^9V+}taZpom&UV&|vU(l{2p`W?Ru{&0Qe9?jiu z&;8_k6^dg;z#~kH4ro*-`I;#LtuOjthLU zIix)d!=!#%1B%N(*TV?j5og;_*d2p6A{$+1sojxw_&YZXxrZH3`JJ*5j~u=$ZUgy8 z|6bDY2b!}eNSbNpw`0vevl*hdGFErE!q)C`94t}1L)Oxr)9=(i<85>Vrp4V|?W0R_ z6@KbxE!`k>mzSRig)fLn-$HHD@0e*6ihVefbbBHUr+L}83e+G5UH-CI}jDMSxC5?X-=3Qh}DpKf^I5TZCS1==O z=R|T`$0=zx(h^#}Q+6h9z$T`DZOG-VY{x_)mFbA#AP0XH>0nrrkIEe6mr)~aMLa)4 zzo#26#6}-&{*`x2h#N9AyUg;QdhxsRoSeu^HS~h~gYXDl3j&H4npr#whAL5a1OpeM=s0oM7apH? zMAIRDMF>Jc>) zGm6QZfKZq_b4a7l%z}N}&1w|FePpOLz&5)nQL*L4q5>{$={}b8mYueY!>{bKi53@8 zIZx#Y?BZ=9?(z-5)`S{%@$tD11oV~UG=}C;aQMR-7U(!XvJwG=j&*v##UWWxiAZwM z;RqjVndx(0U_?Inj_0$|w|!E%SJN_DCMpm#%}GEJS}6iAkN3Xv>mus_F?4KjhWZVo zO?YUyE)r;(Rkmi8X_}7NpY!uWRJ(sEbm8wxn+M~{{mvfxaWGM3oumXfE{G=)8xQu@2bOp6*vT79+6`jigs;1Q+G(TpwYYJKi* zb)`fCxM~im4;ks+H#;EpxXBya%e8t4X}mc2N`L~aJ}cs`h9*O6#$Uf|D@RkEdRD6) z%h|?eCngr0jc4*8a;rA$UuP|tWW0=GBt$8WcwRIXAz)6aK0TddBWKDu!!uv(`G$90 zbVjRGWrz+f+4=^_oItzRH_yw_=rm zlmdMNiDNjBI`V@#>iV5YAr5LiwY@YC{sB9-=T*S=JZ3|lc?k)v$3 zaP)$4hC2LlQTjQjvM{@47yQN(N9Ygyf(s5@V~qrd=tT}e6Gwib?C9tCDO)JgK-H9h0ATwn!sjnDu zjsFhPB@nPrr|QExpcVlc&%`HKTIaPXXu9AV81J%!j<-<}4KLalJ2C!KXHMz4F82*p zdoGwQ0bO)fQXxTlIKdJ$$iQGr#46vpBf~PwHl@ATH)GPq=@rs0bKi|q;YV7;Bd##d z!WJog&@AWl-c8AUU8bK-{jmM+E^3?x?Tpc_v*+$gZ5a;+``gX6K`H54w<6ATHsRVE zt`Fm6hHDj8wvh&>UzSqz57A-9Qo`S3rHiC=tbMXTZI+H^H7)?ES`7#XcG<}hoPYM#fry+PmpC1KLNek<{&q3&yw zT88z)C2vo?RNrBkH`=M@k*WnQl52!<$raod)V-1DgNszA(6`1NRhJELc1b1F8AnUY zegDZ3jsJ2;7juR}7bACt@D9TiAG~*omGgawLBuJtG&dwi|N z?NZd+Odz~PVUNYI?t;_R4rW&@HP8h`2HI?9lyi@GEljiui6!L+QodUw`bSh&ac&d~ zK5%*u+dI2QX{-0*Tz|dy6U6uTZQz{sRUkRsyCVL2;pd-5aOr6~lkn=pzwjGqy~r$_ z0;NFD98nFI2bLt1QrxbXT;=I$bd6w5t>_)c_pB*pkv60qEOySWeTL-Lyck9~2%YW# z!&~Vem4-X=8Q)+2#y#C&p8S?i;8a_xu9T5dvVvlIstwzRh-mPkuh- z@xd7Zd1azOiFGm`5;wBMb|S}nB8Ma(Kq9P+A})^N zj&Pc&z8i!j5+9tPQr-~J;8Qn7Ye-+t`mYbVV!`>!M%xIr!so>Mb=~=j=ZSAi;OYH# z+Fj_|N(9q-T`yxVNk1%>Xb3R$qoQVjo&jAIgN=PVmR3hh)0oA7;8^tofuT@2@spjb zZ@XfiG(&xQ`=P~5d&MdkJrZ*v#l15=NDtNyN0yik9g&tSLdedt<2M<1S!fk@zly2= z!LnTQMtIY(Yc{a3RXy!QhCGYCk|DP?p)LvNo5IXnP(iahBK{qY0)12~^ZrkFjbm{fR?&gB>KQ`Nj}hVMBK$LeJ@;H$>YLFu%|Tj;XkUi=$}7 zAR54Hl`b=Ksv##2JBJ7mm#%{-`JNniIwek%lT@cLTO zG=oT^;{EZ)Ogvut@LkzuepLGML*zz%RdqX z=y;r?*T!t(Sfsk4_5bF3$;^5~t#A~9bot1vq%5)^r61yV(rJSR*9s9;F8LkfIJ53h$a73Jf&-h+(BD%ZTUa}_=wnaGHXQ&H7e08oa zGI>qalPj0Yt{hdz-(~9;QfA|D57;Mq4MLMg%TdSG78BA;heS2j)wtScqdwjriHx*Z z?n)r(RU?DNY2jvQ3lS~=vLYp8t(@}xCS~cCTR5>=s}4hFReZem2}Fl+QRY1LdSW|m z1+p+oY5Yu~-|nJt@9FA+{*|a|u3Ws1X<>gE;?Ul?X$zsdU09~lGQ`7U%qYT%?@{b5 z%}k{-tq`z%BbnDL@p>V&De#T2Ct|zEa7k$g*SP}{Q58m&kWHv{i=4qE&aP~6V_2(h zF716`m`R1HW~f9V9fwh(hoLNp;b1?00T6D!qRfptgJZ1VGS3&Ozd=l#<6>GGGgK-GAQi85gvc_>k)@Es`j$RzQFR7kQ{ zO9jmN?$+dY{QJ|M1Z67|h}QHOaJCyZ^BpgqeuR=K6gsPQ!D9UIC5M zWv61C`sntAt9=+bB(W7n7G?6F2ykf+zBkoeM~WSS&^btbrN`I7ZO`NE0-a)s*JIg( z6s&1E*n%9(`oRc;m>q3XlCwRIN}t(ER0TB}t7uHs@o*!JSHCY<_?oo?Tw)zi?#(`h z+Dd##X&1`ivSYiTv8p`4N0(sJ^?uAD$mlOuH1fBNT+m z@>2YaopBx}hzVtd1w4ey(zxyF`B#)0YI0xaIia8dR@mNmdW^_cWvzWD$>!}G9+@$Do zUYm(IPvl1e>yMNz>w~5>7;}&bxAxm7wMrMV3R}V_oZ?q`TM2Q27ozSSElUWg?M*s3|Lt$y(?M&_O{u4~GCZ_vKZ{(Ce$D%|Hm zjAhbwikSDRlnGDJy{*@Z2_a2+yAKv zZ<^wLa#WR4m`qD_>l;N`B&rK`r6UBMW74HAk{c>xG`B=KkAnUVYy+<}Td9-^b1*S| zFg1g3Qi5MsB=Zo#x;rT{~U$S?q*jC$TSN(xnPR;=!(iOnaU-Exv$q`A6q8E+8d zO*jX{q)!|Xj0%i} zGMKy+k}rgxn~QyIHj#6=YF~uE@&qSn&5hr9>gHLgkAOZU#8Bi; z$&p5Y>y4&ufi35ldZEXHpQPPl856(QJpC+(51G}+sfs1{aKryk&cZ*?WH#07)~u#M#(NK z>+DoDIkP`D!P9|4G;jM=de(ic>JS^@2dDzwx8k605K5b8-vJh9r&QqtduI$#Gf3!? zW$&W)Iz@U>A{6Skh(=C^@LNT=qY6oRbCX0$gW6(uyD??Pio-98O}_fa4qfdg#1-I6 zNHCC$(r(4Z%{)WT1=_T2WK;N?gM_1)%gjmdN-$9TKv{^p5Tc9egd{#{gQeG&p?Ss~ zHUNfMl`nVqdZa*~HBu!v2-c~i+HiX=VV0N@p1z)|RqR@!{25RJ0##wq@amKu@1JYu zxWHT*0|=}aac236WRKm*vm3Lebet351qy-{%DJP5VFAUgJfYdBk-6$O!CHWqK&LO63<5GgJgrL>g*}eJ9k8vkfDj`vpeZm4PW8SY z+|*;e;7j^c+F_F0bXz&6DP+ zUqfR2*PFg!wfU$*1G26kDA4x5IKCh zPRrR*^)n?3&)FRCEFPS4sBS21O>#|4M#_#Sq6iy}?B7SCbp_t`x8KvZmaM;tY5n0S z;gH4J+WZ;an5WA5U~{tF*9pc`0%GFBbdBP0BqzgX;MPZ7kGD8YS%PiBxKJ&z2^N#y z?LA$Q@@iVh9uDtj%r9ll;J(9ol%z942}frr#5oe5CS<}}7n_@FoGP;9H3cVOs4L!& zyJ%F3QK!yqSdSwOp4C0e7Zl;j-`{OZNv=`3mOSmoC|9ZLt8C_571e*q0CzIqj!O%gOD0E`Ozz(mGC zmmepOj)MLPmqM1O4hvU{dTue7$)dMv7_Fc=LOG~b^jgAb(1aabKIT~<$&aUqEQ^#- znwZyL41|CrZ&)^SikF~{vYf-dpBE^B4&h!uF}kI#j;9o2!81YzT@7MfB2$ek@y|}M z{wV&rR?QGl)N5wH1i4lR4t8kf4ItL!k+d|LLCV)>2VgYmm4486iTvv%x5c_45`z&a zB8ed=^5(i6nzlGfql5ois(j-qw1%)mWecc~nS!XX;z1j++LtqepE*x`#!!YeQEehS z#xri6;Y8bPkJ#|^dDqt|Ptmd}UiT|+T`azT;M|2XDE_Eq*QChSdf}M#BeQ*B`1prd z+b(GIk76=7Y;xEx?}U?b&;k6yp4bZ#__Vhzzdq@J0}gSxnXb#t-x$$*UC)16>KhVz z?dZNqe26q>NQhMZQ;xV~F=b6Eyf^ukwxyGZ+%=2zLneMjk`_bOXs_nJjH>RH5>@>g z&=zP$!}V_QecT(Sou0}ft)2Y0)D#eRN>69)ETY}`465FLC{a`23$-WkZ>4yfr+8cK z8%mTi;&;ho4bE`O^)UE0qS`&~&uEl)Xry{%32i3*Rh}W!Br?0Cr2@Ie`r<2?sJJAM9Pxut+9c(ScnRhaA6&H%LA7XdTeH$26}IL3F!S zjE4)H2R^AH7nnN`y~uw=SYykeh9lq|dh))B_5{ayINMPFsK3Sf{q3L3KmWT8AzD1F z!5c3W{=z@b6IfF|(=1!g6LRrbbG;+r4+l5P7WHcVnGA~2oZb|ka>xx?;D0%$4tifDP}Ff-!kgN=|ztG>(^ zf@y9&9?r}S{t{je8%tGv~rY?tdYIB=7KnW%{Ug@9M;gagwyV) z|5Z<^1nij%BKY0fef-4kQ5VP_HESdU%ZVKshk~QL*w*(K zJD6ARI_GOcUclO=9Ec>GUJeRX(CqdzBwrgtb35^7qfuASLqxTDMnaO`P} zJILHgYO7n!CJ2(w&Maq3Df)!=KFU+5bohvD>}fPRFliyow1hZ#-Tm{2wr&jWJh&SQ zzPI3w#snl(Ip*jx)IX=|UPTEnm$#{L1%r2wI=iD0xn@5Yi|jefL3B!cdkDeys=M7oBbQ7V*ZG}+~k%t<&Wl~#6!!p!ia1hnvh8QH) z)TPWGWR+?U&gaJXpBjVu6k49ERIsjhN$quSEj7xHXB7MST{S zIQ%Gtl1I%5$aW=$r72w8sU@FEHcPz@$Aqok{)wfzLDsl;IhhQ@;|-bY36-V=glv+& z{$@MiA}X&eGd2-3i>j;kLzne=Ea=woDV3_xjYKfOOn5O@lbPa!K7ueo?5w9;Ja&W=wL;?O0C89 z{_hD@A!HsI6|BlVn8w>MqL}IDSvJXz9CzfSaO8Y{&0dvbvj=_vBGDwv-@(w^!gHQzAqT(aFYj0o zF(u|T-95l+IL)#{!tIDUx1 z_X|#6UdIJzUo+QBkPz=85;%(CFgx3b8QgC1Mq#-17UJ?#?l^jY0p|=*)euW936C;D z1nuELYV-T12>9&xJu}dl_3AlE*XaE6HzPZaZOb)<^%$akGU$Q`#*i&tQ2r)c9&X{} zpt77WEOw8tWK5KR=i9e+I6QES7zL5GM-_W$bC;@qP4X_dS`@1|r!VtLQ{&HC%in9i z-DOh|6bI?Hr9&6FD7pqme;wYgt*wGvGh8E@mJ}n#4&$X^gFS%|r^Tp*vdfNU=e6RV z$h(k;l$t1oX)U}2Tv^0UutV!Zv04G4VP68m=2&tcK<>cGybR8 z3uL;TA2;4!l*x~X@v%3NzSL`sVi~b1WK~Qqj@JxyUgmlG+m>b&Zp>qAEg+W<-40(U zN3>ZbIr_HGlQ*n?$ZutW!z+t>JT0t71?+RmULo@LZ~w@nY^_|MBfz~l^{hht`(tt6 z$#=}3DbyHG5yech@=-S_pt}w>ITQ@b`>*yLi}~%)-p9&5@cKR%Sg1Kw4MK@gcyycD zJq5nc(eEsCvrDr}mN)7E^9@C5qvn6EYl&8vP$3nbHs>X4G3RhNBT1wzlZT3GF3pb$@A`y5H2++f5Ph7H@ZsAs zQ0Rbok^_}ABf*NOEO9TZ;Br*I3*gTXXu$^V#UXOnkz&_9ZX%*WRT*e-&UmH{$;X9H zs(_qlYpk^qYMo#7E427$V2&L1M)PQPvv~}6S)__RpnwM6(2HH~aIUO{~8dRdKtqho&E2GQ5yo zO@?nZkSe~fL29#MtYNjGLPn#X6@<7cXc=$U9OltY37V9$l4pGksf6v#5m=#&DSQ>C zc0Q$-x|z)2uva#vsnzPwY9p^PQjiGt!n2B$9lHS9t)s4KxkRp=S(Lnre^1i<$%lly zycOYmaq##u*!*f#awmP?*gT9RQkt2adJ@-$yF9b$=BeSW$t&ta#L>3y-ReZ3*rl<{ zdnlyMgmH?0iAeR7OMioYsaRkoO=Q%oTCOu)L0_ZPmCJYoNMT9$V64otr#8XOp>PE6 zr|4hOE6u6*^z90oiuYj5k;K(#$sML@fuU>M`_(J>h4k1$k5y@a@_HdX@0(HM@u4FA{9* znKA1U@7JZ+3~fzZ77ur^XQ8i=q_fstn7lv#zKxII4<3qjqoR*`WdeVNb$zNxYPMu6 zdO~iubF5-I=zVQ~aFysGB>2Nmu&B#x617IyQ$S#yAsX#Br!iM#Cq}+W9snHrT)x8V zJRTchzrU)Hnw#y}IY96nmxF$WJ04kDFN_xM<)gJr*5$}{uU9xEQoNg2KDAuI68);2`a?t^7&(0cE%vBjjuz6RB%FZ3 z3&(=I|DfYVTRiX{^2d_4Jb2j>%#?un6q>K_6cS;y@W z%yL(O!>fA6?HTpyD%Jz0`INbXJ;w~V-v|V=kkIE^HLd$Nc>)?>6GZ|0x!966>; zy|ZA0u7&A&FOye#L zchyrt6Ul%Sjl>OKhKV{%y=NKe!1A`P{JG?%;EdxKL9{}vdenEiNI`{&k3o-wlF1$2 z(Lq0aO;s{(aWv?-q{Iyad%om_p9$#D5u>kT@d>N#(-aR5G0n#C7G@vB4Y(7H5j3Q_ zXgn(Ww>%q49F`O0UMA&^-r)SYJ?N@~>@v4%o5Jixa!8;|eT|X?4i^0gQSP*&t*)gFCf$K3JC*xe$n66_mdgDO67h^Tn%4@ki4#xd6nCe8zE;Xji z&B+6ep#N}>7rQFs%nR)fq90#^fZ|o1bC?$qujUoELt*xV^(rsZuiwul`|tyjpb4yy2%FX@ysD zh@vd6?&=Fr?nJLl8TiOU6ZEySHdYw|-XkvQ+nM*JqmS zLt2)pkHJW>tJTud-BLm^OO9Q+(BRg~A|1TKaZOynY54S%iQtxxm>er{o1 z6euovFBft{63oRr`MrV~ITW4im4L^;tso}WYSA1?E$O(51fQKA7FpuSJP6s)98&WA z_smO=ZNk5)(Z5;qp}>smK>j}s{O>aC_C%p`Km4*Qi2MNh!eaKO1}wmKL93OZ=Rx`X zw;qz;Jdx^flBXk7EHw9dmK3J3pr)G7PX1cNQ1nZQ;Tv=!>%mldB?CJ-YZC_bbrl6IuqPzHf6p!St#Rh5#rNekJ*cG@6_F*#5p6w*p9YBP(@cGaF=iNI1hVArIL2=Y ziHBobOJT!jW^I^C{KMHh9}Y-f%OaIO7vm;#d+N)09% z*O4M5qPqJ(jJ;!XW&zu@I}_WsZ95ZN6Wg}0*v3q3+qP|9v2B}^oqO;1-Br)?>8@I} ze!{AAbsycGNQ;pEC*g~Se=3qnWNw{zeX}v0=EsY&_EiN;<6VczqA~HEVuF4&b`opP z+>ruKpRKakT%vU8z+S=H!Uef7;_xqm?7-WGVo(dC9p43e(s&ag}qY@TkF|UO#zdPl-jNDcHvc6st59LhZiFHwN?+ zp};faD6(>la~;$aWv@m7l=(67Vb=OUvy(@d_A4~?_-v^RrWA`bt$H;{{E-A60u>j! zG*y0WF^n7P*vB-}RAcID6m`~-Jsd~dOl(%jw7MWO9sbei<%k$I(mTw?_Mu(ae8aZ$ z)De6K5Mi-@2pXXd_|f?gLZ`;H`A#$teVdEV=*aloP;sT1>6pQ8Stne3wn=>%nzwGb z^&>o3i05TKEUP=uio#3j3OG7H%>TO1sPHwQ4<|^}Ur^*rA}vSBjf=Y)a-R*tkGHH6 z{9aA;934^Gki3jD*aB69#}gb_;s0C63HQDsx}Xq|;cB}_Lc_Kis_lI5MfB@xSu-a^ zVdKxtWr!=kgR};Dk}|yIvK)L_;j9g7LTAbPp4HhN+x zbwT)5wp($h54nSN&TkhYcJGW9Y+9zh z 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
K%F-$Y>;9B37_ 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 lZ4v2 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 diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.1.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..1ebc7e363e4f4e3f9ffd98986aa915f61893d81c GIT binary patch literal 14743 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

@Cw~QC#fy|?t3fdi?2uf#F?ty7xd*8xMFmV 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 literal 0 HcmV?d00001 From 31ea4548d71e9737afbe57660ebf765e2a90c48c Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 11 Mar 2020 09:46:27 +0100 Subject: [PATCH 0082/1191] DATAES-744 - Updated changelog. --- src/main/resources/changelog.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index b91d31b28..fbed7803f 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,21 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.M4 (2020-03-11) +---------------------------------------- +* DATAES-759 - Update to Elasticsearch 7.6.1. +* DATAES-758 - fix documentation for @Query annotation. +* DATAES-754 - Completion field deserialization is failing due to class cast error. +* DATAES-753 - Reactive Elasticsearch repository: Bulk update fails on empty entity list. +* DATAES-749 - Introduce SearchPage as return type for repository methods. +* DATAES-747 - ElasticsearchConfigurationSupport does not set customConversions into the MappingElasticsearchConverter. +* DATAES-746 - Add store converters to convert binary data to base64 encoded strings. +* DATAES-745 - Consolidate Operations API. +* DATAES-744 - Release 4.0 M4 (Neumann). +* DATAES-741 - Tests fail due to Elasticsearch cluster 'blocks' on nearly-full file-systems. +* DATAES-282 - Remove all low-level reflection based field inspection from MappingBuilder in favor of PersistentProperty inspections. + + Changes in version 3.2.5.RELEASE (2020-02-26) --------------------------------------------- * DATAES-752 - Upgrade to Elasticsearch 6.8.6. @@ -1030,3 +1045,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 3a528c7039431dd1340fbbc8cc937c51f9c41bb8 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 11 Mar 2020 09:46:29 +0100 Subject: [PATCH 0083/1191] DATAES-744 - Prepare 4.0 M4 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 3119d320a..89d081cc3 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M4 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.1 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.M4 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index a6d2b5d5b..1b0c300e4 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 M3 +Spring Data Elasticsearch 4.0 M4 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -11,3 +11,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 8a6f56a89ea6bdb9867c16f60135414247456a54 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 11 Mar 2020 09:47:07 +0100 Subject: [PATCH 0084/1191] DATAES-744 - Release version 4.0 M4 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89d081cc3..e858f0940 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.M4 org.springframework.data.build From 9e81d39194e252a166d5503ff4eb8462eb18d106 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 11 Mar 2020 09:57:42 +0100 Subject: [PATCH 0085/1191] DATAES-744 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e858f0940..89d081cc3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.M4 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From ab0c6a8f66dd30726656b9c51a3ccc664a41bfae Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Wed, 11 Mar 2020 09:57:43 +0100 Subject: [PATCH 0086/1191] DATAES-744 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 89d081cc3..3119d320a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.M4 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.1 2.9.1 - 2.3.0.M4 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -355,8 +355,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 0b0c8027a341891175062d4399fc51aac2f4cb34 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 11 Mar 2020 12:34:56 +0100 Subject: [PATCH 0087/1191] DATAES-751 - Introduce ClientCallback for the rest client. Original PR: #401 --- .../elasticsearch/ElasticsearchException.java | 2 + .../UncategorizedElasticsearchException.java | 28 +++ .../core/DefaultIndexOperations.java | 105 +++------- .../ElasticsearchExceptionTranslator.java | 17 +- .../core/ElasticsearchRestTemplate.java | 196 ++++++++---------- .../core/ElasticsearchTemplate.java | 1 - .../core/ReactiveElasticsearchTemplate.java | 27 ++- .../AbstractElasticsearchRepository.java | 5 +- ...eNestedElasticsearchRepositoriesTests.java | 14 ++ .../core/ElasticsearchRestTemplateTests.java | 5 +- .../elasticsearch/core/LogEntityTests.java | 8 +- .../core/LogEntityTransportTests.java | 7 + .../ReactiveElasticsearchTemplateTests.java | 4 +- ...ImmutableElasticsearchRepositoryTests.java | 7 + .../SimpleElasticsearchRepositoryTests.java | 4 +- 15 files changed, 229 insertions(+), 201 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java diff --git a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java index 8559cab62..aed85fa99 100644 --- a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java @@ -25,7 +25,9 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @deprecated since 4.0, use {@link org.springframework.dao.UncategorizedDataAccessException} */ +@Deprecated public class ElasticsearchException extends RuntimeException { @Nullable private Map failedDocuments; diff --git a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java new file mode 100644 index 000000000..70696b86f --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java @@ -0,0 +1,28 @@ +/* + * Copyright 2020 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; + +import org.springframework.dao.UncategorizedDataAccessException; + +/** + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class UncategorizedElasticsearchException extends UncategorizedDataAccessException { + public UncategorizedElasticsearchException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 9a7225195..a3ca8c694 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -33,14 +33,12 @@ import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.Response; import org.elasticsearch.client.RestClient; -import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.core.client.support.AliasData; -import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; @@ -60,29 +58,22 @@ */ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { - private RestHighLevelClient client; + private ElasticsearchRestTemplate restTemplate; - public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter, - Class boundClass) { - super(elasticsearchConverter, boundClass); - this.client = client; + public DefaultIndexOperations(ElasticsearchRestTemplate restTemplate, Class boundClass) { + super(restTemplate.getElasticsearchConverter(), boundClass); + this.restTemplate = restTemplate; } - public DefaultIndexOperations(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter, - IndexCoordinates boundIndex) { - super(elasticsearchConverter, boundIndex); - this.client = client; + public DefaultIndexOperations(ElasticsearchRestTemplate restTemplate, IndexCoordinates boundIndex) { + super(restTemplate.getElasticsearchConverter(), boundIndex); + this.restTemplate = restTemplate; } @Override protected boolean doCreate(String indexName, @Nullable Document settings) { CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); - try { - return client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException( - "Error for creating index: " + indexName + ", client: " + client.getLowLevelClient().getNodes(), e); - } + return restTemplate.execute(client -> client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged()); } @Override @@ -92,11 +83,7 @@ protected boolean doDelete(String indexName) { if (doExists(indexName)) { DeleteIndexRequest request = new DeleteIndexRequest(indexName); - try { - return client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Error while deleting index request: " + request.toString(), e); - } + return restTemplate.execute(client -> client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged()); } return false; } @@ -104,11 +91,7 @@ protected boolean doDelete(String indexName) { @Override protected boolean doExists(String indexName) { GetIndexRequest request = new GetIndexRequest(indexName); - try { - return client.indices().exists(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error while for indexExists request: " + request.toString(), e); - } + return restTemplate.execute(client -> client.indices().exists(request, RequestOptions.DEFAULT)); } @Override @@ -117,11 +100,8 @@ protected boolean doPutMapping(IndexCoordinates index, Document mapping) { Assert.notNull(index, "No index defined for putMapping()"); PutMappingRequest request = requestFactory.putMappingRequest(index, mapping); - try { - return client.indices().putMapping(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("Failed to put mapping for " + index.getIndexName(), e); - } + return restTemplate + .execute(client -> client.indices().putMapping(request, RequestOptions.DEFAULT).isAcknowledged()); } @Override @@ -129,24 +109,19 @@ protected Map doGetMapping(IndexCoordinates index) { Assert.notNull(index, "No index defined for getMapping()"); - RestClient restClient = client.getLowLevelClient(); - try { + return restTemplate.execute(client -> { + RestClient restClient = client.getLowLevelClient(); Request request = new Request("GET", '/' + index.getIndexName() + "/_mapping"); Response response = restClient.performRequest(request); return convertMappingResponse(EntityUtils.toString(response.getEntity())); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName(), e); - } + }); } @Override protected boolean doAddAlias(AliasQuery query, IndexCoordinates index) { IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); - try { - return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException("failed to update aliases with request: " + request, e); - } + return restTemplate + .execute(client -> client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged()); } @Override @@ -156,29 +131,23 @@ protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { Assert.notNull(query.getAliasName(), "No alias defined"); IndicesAliasesRequest indicesAliasesRequest = requestFactory.indicesRemoveAliasesRequest(query, index); - try { - return client.indices().updateAliases(indicesAliasesRequest, RequestOptions.DEFAULT).isAcknowledged(); - } catch (IOException e) { - throw new ElasticsearchException( - "failed to update aliases with indicesRemoveAliasesRequest: " + indicesAliasesRequest, e); - } + return restTemplate.execute( + client -> client.indices().updateAliases(indicesAliasesRequest, RequestOptions.DEFAULT).isAcknowledged()); } @Override protected List doQueryForAlias(String indexName) { List aliases = null; - RestClient restClient = client.getLowLevelClient(); - Response response; - String aliasResponse; + return restTemplate.execute(client -> { + RestClient restClient = client.getLowLevelClient(); + Response response; + String aliasResponse; - try { response = restClient.performRequest(new Request("GET", '/' + indexName + "/_alias/*")); aliasResponse = EntityUtils.toString(response.getEntity()); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + indexName, e); - } - return convertAliasResponse(aliasResponse); + return convertAliasResponse(aliasResponse); + }); } @Override @@ -190,14 +159,11 @@ protected Map doGetSettings(String indexName, boolean includeDef .indices(indexName) // .includeDefaults(includeDefaults); - try { - GetSettingsResponse response = client.indices() // - .getSettings(request, RequestOptions.DEFAULT); + // + GetSettingsResponse response = restTemplate.execute(client -> client.indices() // + .getSettings(request, RequestOptions.DEFAULT)); - return convertSettingsResponseToMap(response, indexName); - } catch (IOException e) { - throw new ElasticsearchException("failed to get settings for index: " + indexName, e); - } + return convertSettingsResponseToMap(response, indexName); } @Override @@ -205,11 +171,8 @@ protected void doRefresh(IndexCoordinates index) { Assert.notNull(index, "No index defined for refresh()"); - try { - client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("failed to refresh index: " + index, e); - } + restTemplate + .execute(client -> client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT)); } // region Helper methods @@ -225,7 +188,7 @@ private Map convertMappingResponse(String mappingResponse) { return result; } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + mappingResponse, e); + throw new UncategorizedElasticsearchException("Could not map alias response : " + mappingResponse, e); } } @@ -261,7 +224,7 @@ private List convertAliasResponse(String aliasResponse) { } return aliasMetaDataList; } catch (IOException e) { - throw new ElasticsearchException("Could not map alias response : " + aliasResponse, e); + throw new UncategorizedElasticsearchException("Could not map alias response : " + aliasResponse, e); } } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index 512238103..f4aeb1c00 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -16,21 +16,25 @@ package org.springframework.data.elasticsearch.core; -import java.net.ConnectException; +import java.io.IOException; import java.util.List; import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.common.ValidationException; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.elasticsearch.NoSuchIndexException; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** * @author Christoph Strobl + * @author Peter-Josef Meisch * @since 3.2 */ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator { @@ -46,9 +50,15 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return new NoSuchIndexException(ObjectUtils.nullSafeToString(elasticsearchException.getMetadata("es.index")), ex); } + return new UncategorizedElasticsearchException(ex.getMessage(), ex); } - if (ex.getCause() instanceof ConnectException) { + if (ex instanceof ValidationException) { + return new DataIntegrityViolationException(ex.getMessage(), ex); + } + + Throwable cause = ex.getCause(); + if (cause instanceof IOException) { return new DataAccessResourceFailureException(ex.getMessage(), ex); } @@ -60,8 +70,9 @@ private boolean indexAvailable(ElasticsearchException ex) { List metadata = ex.getMetadata("es.index_uuid"); if (metadata == null) { if (ex instanceof ElasticsearchStatusException) { - return StringUtils.hasText(ObjectUtils.nullSafeToString(((ElasticsearchStatusException) ex).getIndex())); + return StringUtils.hasText(ObjectUtils.nullSafeToString(ex.getIndex())); } + return false; } return !CollectionUtils.contains(metadata.iterator(), "_na_"); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 26e617a58..b7b014420 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.util.List; -import java.util.Optional; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; @@ -40,7 +39,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.data.domain.Pageable; -import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -90,25 +88,29 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { private RestHighLevelClient client; + private ElasticsearchExceptionTranslator exceptionTranslator; // region Initialization public ElasticsearchRestTemplate(RestHighLevelClient client) { - this.client = client; - initialize(client, createElasticsearchConverter()); - } - public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { + Assert.notNull(client, "Client must not be null!"); + this.client = client; - initialize(client, elasticsearchConverter); + this.exceptionTranslator = new ElasticsearchExceptionTranslator(); + + initialize(createElasticsearchConverter()); } - private void initialize(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { + public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter) { Assert.notNull(client, "Client must not be null!"); this.client = client; + this.exceptionTranslator = new ElasticsearchExceptionTranslator(); + initialize(elasticsearchConverter); } + // endregion // region IndexOperations @@ -117,7 +119,7 @@ public IndexOperations indexOps(Class clazz) { Assert.notNull(clazz, "clazz must not be null"); - return new DefaultIndexOperations(client, elasticsearchConverter, clazz); + return new DefaultIndexOperations(this, clazz); } @Override @@ -125,7 +127,7 @@ public IndexOperations indexOps(IndexCoordinates index) { Assert.notNull(index, "index must not be null"); - return new DefaultIndexOperations(client, elasticsearchConverter, index); + return new DefaultIndexOperations(this, index); } // endregion @@ -133,29 +135,21 @@ public IndexOperations indexOps(IndexCoordinates index) { @Override public String index(IndexQuery query, IndexCoordinates index) { IndexRequest request = requestFactory.indexRequest(query, index); - try { - String documentId = client.index(request, RequestOptions.DEFAULT).getId(); - - // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); - } - return documentId; - } catch (IOException e) { - throw new ElasticsearchException("Error while index for request: " + request.toString(), e); + String documentId = execute(client -> client.index(request, RequestOptions.DEFAULT).getId()); + + // We should call this because we are not going through a mapper. + if (query.getObject() != null) { + setPersistentEntityId(query.getObject(), documentId); } + return documentId; } @Override @Nullable public T get(String id, Class clazz, IndexCoordinates index) { GetRequest request = requestFactory.getRequest(id, index); - try { - GetResponse response = client.get(request, RequestOptions.DEFAULT); - return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); - } catch (IOException e) { - throw new ElasticsearchException("Error while getting for request: " + request.toString(), e); - } + GetResponse response = execute(client -> client.get(request, RequestOptions.DEFAULT)); + return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); } @Override @@ -165,22 +159,14 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) Assert.notEmpty(query.getIds(), "No Id define for Query"); MultiGetRequest request = requestFactory.multiGetRequest(query, index); - try { - MultiGetResponse result = client.mget(request, RequestOptions.DEFAULT); - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); - } catch (IOException e) { - throw new ElasticsearchException("Error while multiget for request: " + request.toString(), e); - } + MultiGetResponse result = execute(client -> client.mget(request, RequestOptions.DEFAULT)); + return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); } @Override protected boolean doExists(String id, IndexCoordinates index) { GetRequest request = requestFactory.getRequest(id, index); - try { - return client.get(request, RequestOptions.DEFAULT).isExists(); - } catch (IOException e) { - throw new ElasticsearchException("Error while getting for request: " + request.toString(), e); - } + return execute(client -> client.get(request, RequestOptions.DEFAULT).isExists()); } @Override @@ -208,53 +194,33 @@ public String delete(String id, IndexCoordinates index) { Assert.notNull(index, "index must not be null"); DeleteRequest request = new DeleteRequest(index.getIndexName(), elasticsearchConverter.convertId(id)); - try { - return client.delete(request, RequestOptions.DEFAULT).getId(); - } catch (IOException e) { - throw new ElasticsearchException("Error while deleting item request: " + request.toString(), e); - } + return execute(client -> client.delete(request, RequestOptions.DEFAULT).getId()); } @Override public void delete(Query query, Class clazz, IndexCoordinates index) { DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(query, clazz, index); - try { - client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for delete request: " + deleteByQueryRequest.toString(), e); - } + execute(client -> client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT)); } @Override @Deprecated public void delete(DeleteQuery deleteQuery, IndexCoordinates index) { DeleteByQueryRequest deleteByQueryRequest = requestFactory.deleteByQueryRequest(deleteQuery, index); - try { - client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for delete request: " + deleteByQueryRequest.toString(), e); - } + execute(client -> client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT)); } @Override public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { UpdateRequest request = requestFactory.updateRequest(query, index); - try { - org.elasticsearch.action.update.UpdateResponse updateResponse = client.update(request, RequestOptions.DEFAULT); - UpdateResponse.Result result = UpdateResponse.Result.valueOf(updateResponse.getResult().name()); - return new UpdateResponse(result); - } catch (IOException e) { - throw new ElasticsearchException("Error while update for request: " + request.toString(), e); - } + UpdateResponse.Result result = UpdateResponse.Result + .valueOf(execute(client -> client.update(request, RequestOptions.DEFAULT)).getResult().name()); + return new UpdateResponse(result); } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); - try { - return checkForBulkOperationFailure(client.bulk(bulkRequest, RequestOptions.DEFAULT)); - } catch (IOException e) { - throw new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e); - } + return checkForBulkOperationFailure(execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); } // endregion @@ -272,22 +238,14 @@ public long count(Query query, @Nullable Class clazz, IndexCoordinates index) searchRequest.source().size(0); - try { - return SearchHitsUtil.getTotalCount(client.search(searchRequest, RequestOptions.DEFAULT).getHits()); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } + return SearchHitsUtil + .getTotalCount(execute(client -> client.search(searchRequest, RequestOptions.DEFAULT).getHits())); } @Override public SearchHits search(Query query, Class clazz, IndexCoordinates index) { SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); - SearchResponse response; - try { - response = client.search(searchRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + searchRequest.toString(), e); - } + SearchResponse response = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); return elasticsearchConverter.read(clazz, SearchDocumentResponse.from(response)); } @@ -299,13 +257,8 @@ public ScrolledPage> searchScrollStart(long scrollTimeInMillis, SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); searchRequest.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - - try { - SearchResponse result = client.search(searchRequest, RequestOptions.DEFAULT); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(result), clazz, null); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + searchRequest.toString(), e); - } + SearchResponse result = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); + return elasticsearchConverter.mapResults(SearchDocumentResponse.from(result), clazz, null); } @Override @@ -313,12 +266,7 @@ public ScrolledPage> searchScrollContinue(@Nullable String scro Class clazz) { SearchScrollRequest request = new SearchScrollRequest(scrollId); request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - SearchResponse response; - try { - response = client.searchScroll(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + request.toString(), e); - } + SearchResponse response = execute(client -> client.searchScroll(request, RequestOptions.DEFAULT)); return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, Pageable.unpaged()); } @@ -326,11 +274,7 @@ public ScrolledPage> searchScrollContinue(@Nullable String scro public void searchScrollClear(String scrollId) { ClearScrollRequest request = new ClearScrollRequest(); request.addScrollId(scrollId); - try { - client.clearScroll(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request with scroll: " + request.toString(), e); - } + execute(client -> client.clearScroll(request, RequestOptions.DEFAULT)); } @Override @@ -339,26 +283,66 @@ public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.suggest(suggestion); searchRequest.source(sourceBuilder); - - try { - return client.search(searchRequest, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Could not execute search request : " + searchRequest.toString(), e); - } - + return execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); } @Override protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request) { - MultiSearchResponse response; - try { - response = client.multiSearch(request, RequestOptions.DEFAULT); - } catch (IOException e) { - throw new ElasticsearchException("Error for search request: " + request.toString(), e); - } + MultiSearchResponse response = execute(client -> client.multiSearch(request, RequestOptions.DEFAULT)); MultiSearchResponse.Item[] items = response.getResponses(); Assert.isTrue(items.length == request.requests().size(), "Response should has same length with queries"); return items; } // endregion + + // region clientcallback + /** + * Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on + * {@link RestHighLevelClient}. + * + * @since 4.0 + */ + @FunctionalInterface + interface ClientCallback { + T doWithClient(RestHighLevelClient client) throws IOException; + } + + /** + * Execute a callback with the {@link RestHighLevelClient} + * + * @param callback the callback to execute, must not be {@literal null} + * @param the type returned from the callback + * @return the callback result + * @since 4.0 + */ + public T execute(ClientCallback callback) { + + Assert.notNull(callback, "callback must not be null"); + + try { + return callback.doWithClient(client); + } catch (IOException | RuntimeException e) { + throw translateException(e); + } + } + + /** + * translates an Exception if possible. Exceptions that are no {@link RuntimeException}s are wrapped in a + * RuntimeException + * + * @param exception the Exception to map + * @return the potentially translated RuntimeException. + * @since 4.0 + */ + private RuntimeException translateException(Exception exception) { + + RuntimeException runtimeException = exception instanceof RuntimeException ? (RuntimeException) exception + : new RuntimeException(exception.getMessage(), exception); + RuntimeException potentiallyTranslatedException = exceptionTranslator + .translateExceptionIfPossible(runtimeException); + + return potentiallyTranslatedException != null ? potentiallyTranslatedException : runtimeException; + } + + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 848ed4dc2..4042c32e6 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.core; import java.util.List; -import java.util.Optional; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.bulk.BulkRequestBuilder; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 32123cda2..b0ed7c877 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -792,15 +792,6 @@ public ElasticsearchPersistentEntity getPersistentEntityFor(@Nullable Class met createIndex(); putMapping(); } - } catch (ElasticsearchException exception) { - LOGGER.warn("Cannot create index: {}", exception.getDetailedMessage()); + } catch (Exception exception) { + LOGGER.warn("Cannot create index: {}", exception.getMessage()); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java index 86790a25e..8f5972663 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTests.java @@ -24,6 +24,8 @@ import java.lang.Double; import java.lang.Long; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; @@ -34,6 +36,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -56,6 +59,17 @@ public class EnableNestedElasticsearchRepositoriesTests { static class Config {} @Autowired(required = false) private SampleRepository nestedRepository; + @Autowired ElasticsearchOperations operations; + + @BeforeEach + void setUp() { + operations.indexOps(SampleEntity.class).delete(); + } + + @AfterEach + void tearDown() { + operations.indexOps(SampleEntity.class).delete(); + } @Test public void hasNestedRepository() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 0abe01445..d3654b964 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -22,9 +22,9 @@ import lombok.Builder; import lombok.Data; -import org.elasticsearch.ElasticsearchStatusException; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.query.UpdateQuery; @@ -57,7 +57,8 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document .create(); UpdateQuery updateQuery = UpdateQuery.builder(randomNumeric(5)).withDocument(document).build(); - assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(ElasticsearchStatusException.class); + assertThatThrownBy(() -> operations.update(updateQuery, index)) + .isInstanceOf(UncategorizedElasticsearchException.class); } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 1b816daeb..b2b468e8d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -26,13 +26,13 @@ import java.util.Arrays; import java.util.Date; -import org.elasticsearch.ElasticsearchException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.dao.DataAccessException; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; @@ -102,6 +102,10 @@ public void shouldIndexGivenLogEntityWithIPFieldType() { assertThat(entities).isNotNull().hasSize(1); } + protected Class invalidIpExceptionClass() { + return DataAccessException.class; + } + @Test // DATAES-66 public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { @@ -110,7 +114,7 @@ public void shouldThrowExceptionWhenInvalidIPGivenForSearchQuery() { assertThatThrownBy(() -> { SearchHits entities = operations.search(searchQuery, LogEntity.class, index); - }).isInstanceOf(ElasticsearchException.class); + }).isInstanceOf(invalidIpExceptionClass()); } @Test // DATAES-66 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java index 9e7cf811d..0ea128ff9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTransportTests.java @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.core; +import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.ElasticsearchSecurityException; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; @@ -28,4 +30,9 @@ public class LogEntityTransportTests extends LogEntityTests { @Configuration @Import({ ElasticsearchTemplateConfiguration.class }) static class Config {} + + @Override + protected Class invalidIpExceptionClass() { + return ElasticsearchException.class; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 02d0e60c2..34649fe32 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -39,7 +39,6 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.junit.jupiter.api.AfterEach; @@ -52,6 +51,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.TestUtils; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; @@ -436,7 +436,7 @@ public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGiven template.search(queryWithInvalidPreference, SampleEntity.class) // .as(StepVerifier::create) // - .expectError(ElasticsearchStatusException.class).verify(); + .expectError(UncategorizedElasticsearchException.class).verify(); } @Test // DATAES-504 diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index 74e6308a1..319830044 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -22,6 +22,7 @@ import java.util.Optional; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -64,6 +65,12 @@ public void before() { indexOperations.refresh(); } + @AfterEach + void tearDown() { + IndexOperations indexOperations = operations.indexOps(ImmutableEntity.class); + indexOperations.delete(); + } + @Test // DATAES-281 public void shouldSaveAndFindImmutableDocument() { diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 54b943f4d..e8d6e6cfe 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -32,13 +32,13 @@ import java.util.List; import java.util.Optional; -import org.elasticsearch.action.ActionRequestValidationException; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.Page; @@ -148,7 +148,7 @@ public void throwExceptionWhenTryingToInsertWithVersionButWithoutId() { sampleEntity.setVersion(System.currentTimeMillis()); // when - assertThatThrownBy(() -> repository.save(sampleEntity)).isInstanceOf(ActionRequestValidationException.class); + assertThatThrownBy(() -> repository.save(sampleEntity)).isInstanceOf(DataIntegrityViolationException.class); } @Test From 300eb313ddd39de826435df4d50a1d2b6d6581b4 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 11 Mar 2020 18:39:11 +0100 Subject: [PATCH 0088/1191] DATAES-68 - Add support for auditing annotations. Original PR: #400 --- src/main/asciidoc/index.adoc | 2 + .../reference/elasticsearch-auditing.adoc | 68 +++++++ ...ticsearchAuditingBeanDefinitionParser.java | 109 +++++++++++ .../ElasticsearchAuditingRegistrar.java | 181 ++++++++++++++++++ .../config/EnableElasticsearchAuditing.java | 70 +++++++ .../core/AbstractElasticsearchTemplate.java | 61 +++++- .../core/ElasticsearchRestTemplate.java | 11 +- .../core/ElasticsearchTemplate.java | 12 +- .../core/ReactiveElasticsearchTemplate.java | 46 ++++- .../elasticsearch/core/SearchHitSupport.java | 4 +- .../MappingElasticsearchConverter.java | 18 +- .../core/event/AuditingEntityCallback.java | 56 ++++++ .../event/BeforeConvertCallback.java} | 26 ++- .../event/ReactiveAuditingEntityCallback.java | 58 ++++++ .../event/ReactiveBeforeConvertCallback.java | 38 ++++ .../core/event/package-info.java | 6 + ...it5SampleReactiveRestClientBasedTests.java | 47 +++++ .../config/AuditingIntegrationTest.java | 142 ++++++++++++++ ...asticsearchAuditingRegistrarUnitTests.java | 50 +++++ ...sticsearchRestAuditingIntegrationTest.java | 41 ++++ ...earchTransportAuditingIntegrationTest.java | 41 ++++ .../ReactiveAuditingIntegrationTest.java | 160 ++++++++++++++++ .../event/AuditingEntityCallbackTests.java | 163 ++++++++++++++++ .../ElasticsearchOperationsCallbackTest.java | 100 ++++++++++ ...asticsearchRestOperationsCallbackTest.java | 27 +++ ...searchTransportOperationsCallbackTest.java | 27 +++ .../ReactiveAuditingEntityCallbackTests.java | 167 ++++++++++++++++ ...veElasticsearchOperationsCallbackTest.java | 115 +++++++++++ ...pleElasticsearchPersistentEntityTests.java | 5 +- ...lasticsearchRestTemplateConfiguration.java | 6 +- ...lasticsearchRestTemplateConfiguration.java | 51 +++++ 31 files changed, 1863 insertions(+), 45 deletions(-) create mode 100644 src/main/asciidoc/reference/elasticsearch-auditing.adoc create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingBeanDefinitionParser.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/EnableElasticsearchAuditing.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java rename src/main/java/org/springframework/data/elasticsearch/{support/ReactiveSupport.java => core/event/BeforeConvertCallback.java} (54%) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/package-info.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/JUnit5SampleReactiveRestClientBasedTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrarUnitTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchRestAuditingIntegrationTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchTransportAuditingIntegrationTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchRestOperationsCallbackTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchTransportOperationsCallbackTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ReactiveElasticsearchRestTemplateConfiguration.java diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 8d179a2ab..8ca2a67b6 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -24,6 +24,8 @@ include::reference/elasticsearch-clients.adoc[] include::reference/elasticsearch-object-mapping.adoc[] include::reference/elasticsearch-operations.adoc[] include::reference/elasticsearch-repositories.adoc[] +include::{spring-data-commons-docs}/auditing.adoc[] +include::reference/elasticsearch-auditing.adoc[] include::reference/elasticsearch-misc.adoc[] :leveloffset: -1 diff --git a/src/main/asciidoc/reference/elasticsearch-auditing.adoc b/src/main/asciidoc/reference/elasticsearch-auditing.adoc new file mode 100644 index 000000000..4b805cbdf --- /dev/null +++ b/src/main/asciidoc/reference/elasticsearch-auditing.adoc @@ -0,0 +1,68 @@ +[[elasticsearch.auditing]] +== Elasticsearch Auditing + +=== Preparing entities + +In order for the auditing code to be able to decide wether an entity instance is new, the entity must implement the `Persistable` interface which is defined as follows: + +[source,java] +---- +package org.springframework.data.domain; + +import org.springframework.lang.Nullable; + +public interface Persistable { + @Nullable + ID getId(); + + boolean isNew(); +} +---- + +As the existence of an Id is not a sufficient criterion to determine if an enitity is new in Elasticsearch, additional information is necessary. One way is to use the creation-relevant auditing fields for this decision: + +A `Person` entity might look as follows - omitting getter and setter methods for brevity: + +[source,java] +---- +@Document(indexName = "person") +public class Person implements Persistable { + @Id private Long id; + private String lastName; + private String firstName; + @Field(type = FieldType.Date, format = DateFormat.basic_date_time) + private Instant createdDate; + private String createdBy + @Field(type = FieldType.Date, format = DateFormat.basic_date_time) + private Instant lastModifiedDate; + private String lastModifiedBy; + + public Long getId() { <1> + return id; + } + + @Override + public boolean isNew() { + return id == null || (createdDate == null && createdBy == null); <2> + } +} +---- +<1> the getter also is the required implementation from the interface +<2> an object is new if it either has no `id` or none of fields containing creation attributes are set. + +=== Activating auditing + +After the entities have been set up and providing the `AuditorAware` the Auditing must be activated by setting the `@EnableElasticsearchAuditing` on a configuration class: + +[source,java] +---- +@Configuration +@EnableElasticsearchRepositories +@EnableElasticsearchAuditing +class MyConfiguration { + // configuration code +} +---- + +If your code contains more than one `AuditorAware` bean for different types, you must provide the name of the bean to use as an argument to the `auditorAwareRef` parameter of the + `@EnableElasticsearchAuditing` annotation. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingBeanDefinitionParser.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingBeanDefinitionParser.java new file mode 100644 index 000000000..92ba52477 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingBeanDefinitionParser.java @@ -0,0 +1,109 @@ +/* + * Copyright 2020 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.config; + +import static org.springframework.data.config.ParsingUtils.*; + +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.RootBeanDefinition; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.BeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.auditing.config.IsNewAwareAuditingHandlerBeanDefinitionParser; +import org.springframework.data.elasticsearch.core.event.AuditingEntityCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.repository.util.ReactiveWrappers; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; +import org.w3c.dom.Element; + +/** + * {@link BeanDefinitionParser} to register a {@link AuditingEntityCallback} to transparently set auditing information + * on an entity. + * + * @author Peter-Josef Meisch + */ +public class ElasticsearchAuditingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { + + private static String MAPPING_CONTEXT_BEAN_NAME = "simpleElasticsearchMappingContext"; + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#getBeanClass(org.w3c.dom.Element) + */ + @Override + protected Class getBeanClass(Element element) { + return AuditingEntityCallback.class; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractBeanDefinitionParser#shouldGenerateId() + */ + @Override + protected boolean shouldGenerateId() { + return true; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder) + */ + @Override + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + + String mappingContextRef = element.getAttribute("mapping-context-ref"); + + if (!StringUtils.hasText(mappingContextRef)) { + + BeanDefinitionRegistry registry = parserContext.getRegistry(); + + if (!registry.containsBeanDefinition(MAPPING_CONTEXT_BEAN_NAME)) { + registry.registerBeanDefinition(MAPPING_CONTEXT_BEAN_NAME, + new RootBeanDefinition(SimpleElasticsearchMappingContext.class)); + } + + mappingContextRef = MAPPING_CONTEXT_BEAN_NAME; + } + + IsNewAwareAuditingHandlerBeanDefinitionParser parser = new IsNewAwareAuditingHandlerBeanDefinitionParser( + mappingContextRef); + parser.parse(element, parserContext); + + AbstractBeanDefinition isNewAwareAuditingHandler = getObjectFactoryBeanDefinition(parser.getResolvedBeanName(), + parserContext.extractSource(element)); + builder.addConstructorArgValue(isNewAwareAuditingHandler); + + if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) { + registerReactiveAuditingEntityCallback(parserContext.getRegistry(), isNewAwareAuditingHandler, + parserContext.extractSource(element)); + } + } + + private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, + AbstractBeanDefinition isNewAwareAuditingHandler, @Nullable Object source) { + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class); + + builder.addConstructorArgValue(isNewAwareAuditingHandler); + builder.getRawBeanDefinition().setSource(source); + + registry.registerBeanDefinition(ReactiveAuditingEntityCallback.class.getName(), builder.getBeanDefinition()); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java new file mode 100644 index 000000000..1b9b765f2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java @@ -0,0 +1,181 @@ +/* + * Copyright 2020 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.config; + +import java.lang.annotation.Annotation; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport; +import org.springframework.data.auditing.config.AuditingConfiguration; +import org.springframework.data.config.ParsingUtils; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.event.AuditingEntityCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.mapping.context.MappingContext; +import org.springframework.data.repository.util.ReactiveWrappers; +import org.springframework.util.Assert; + +/** + * {@link ImportBeanDefinitionRegistrar} to enable {@link EnableElasticsearchAuditing} annotation. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +class ElasticsearchAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation() + */ + @Override + protected Class getAnnotation() { + return EnableElasticsearchAuditing.class; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName() + */ + @Override + protected String getAuditingHandlerBeanName() { + return "elasticsearchAuditingHandler"; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) + */ + @Override + public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { + + Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!"); + Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); + + super.registerBeanDefinitions(annotationMetadata, registry); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration) + */ + @Override + protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) { + + Assert.notNull(configuration, "AuditingConfiguration must not be null!"); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class); + + BeanDefinitionBuilder definition = BeanDefinitionBuilder + .genericBeanDefinition(ElasticsearchMappingContextLookup.class); + definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); + + builder.addConstructorArgValue(definition.getBeanDefinition()); + return configureDefaultAuditHandlerAttributes(configuration, builder); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry) + */ + @Override + protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition, + BeanDefinitionRegistry registry) { + + Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!"); + Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); + + BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder + .rootBeanDefinition(AuditingEntityCallback.class); + listenerBeanDefinitionBuilder + .addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry)); + + registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(), + AuditingEntityCallback.class.getName(), registry); + + if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) { + registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource()); + } + } + + private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) { + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class); + + builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry)); + builder.getRawBeanDefinition().setSource(source); + + registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(), + registry); + } + + /** + * Simple helper to be able to wire the {@link MappingContext} from a {@link MappingElasticsearchConverter} bean + * available in the application context. + * + * @author Oliver Gierke + */ + static class ElasticsearchMappingContextLookup implements + FactoryBean, ElasticsearchPersistentProperty>> { + + private final MappingElasticsearchConverter converter; + + /** + * Creates a new {@link ElasticsearchMappingContextLookup} for the given {@link MappingElasticsearchConverter}. + * + * @param converter must not be {@literal null}. + */ + public ElasticsearchMappingContextLookup(MappingElasticsearchConverter converter) { + this.converter = converter; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObject() + */ + @Override + public MappingContext, ElasticsearchPersistentProperty> getObject() + throws Exception { + return converter.getMappingContext(); + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#getObjectType() + */ + @Override + public Class getObjectType() { + return MappingContext.class; + } + + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.FactoryBean#isSingleton() + */ + @Override + public boolean isSingleton() { + return true; + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/config/EnableElasticsearchAuditing.java b/src/main/java/org/springframework/data/elasticsearch/config/EnableElasticsearchAuditing.java new file mode 100644 index 000000000..a2e6e9f7e --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/EnableElasticsearchAuditing.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020 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.config; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Import; +import org.springframework.data.auditing.DateTimeProvider; +import org.springframework.data.domain.AuditorAware; + +/** + * Annotation to enable auditing in Elasticsearch via annotation configuration. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(ElasticsearchAuditingRegistrar.class) +public @interface EnableElasticsearchAuditing { + + /** + * Configures the {@link AuditorAware} bean to be used to lookup the current principal. + * + * @return + */ + String auditorAwareRef() default ""; + + /** + * Configures whether the creation and modification dates are set. Defaults to {@literal true}. + * + * @return + */ + boolean setDates() default true; + + /** + * Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}. + * + * @return + */ + boolean modifyOnCreate() default true; + + /** + * Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be + * used for setting creation and modification dates. + * + * @return + */ + String dateTimeProviderRef() default ""; +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index c2bbb4173..553a68781 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -6,7 +6,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -23,6 +22,7 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; +import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -33,6 +33,7 @@ import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; @@ -49,6 +50,8 @@ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOper protected @Nullable ElasticsearchConverter elasticsearchConverter; protected @Nullable RequestFactory requestFactory; + private @Nullable EntityCallbacks entityCallbacks; + // region Initialization protected void initialize(ElasticsearchConverter elasticsearchConverter) { @@ -66,12 +69,33 @@ protected ElasticsearchConverter createElasticsearchConverter() { } @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + + if (entityCallbacks == null) { + setEntityCallbacks(EntityCallbacks.create(applicationContext)); + } if (elasticsearchConverter instanceof ApplicationContextAware) { - ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(context); + ((ApplicationContextAware) elasticsearchConverter).setApplicationContext(applicationContext); } } + + /** + * Set the {@link EntityCallbacks} instance to use when invoking {@link EntityCallbacks callbacks} like the + * {@link org.springframework.data.elasticsearch.core.event.BeforeConvertCallback}. + *

+ * Overrides potentially existing {@link EntityCallbacks}. + * + * @param entityCallbacks must not be {@literal null}. + * @throws IllegalArgumentException if the given instance is {@literal null}. + * @since 4.0 + */ + public void setEntityCallbacks(EntityCallbacks entityCallbacks) { + + Assert.notNull(entityCallbacks, "entityCallbacks must not be null"); + + this.entityCallbacks = entityCallbacks; + } // endregion // region DocumentOperations @@ -388,6 +412,37 @@ private IndexQuery getIndexQuery(T entity) { .withObject(entity) // .build(); } + // endregion + + // region callbacks + protected T maybeCallbackBeforeConvert(T entity) { + + if (entityCallbacks != null) { + return entityCallbacks.callback(BeforeConvertCallback.class, entity); + } + + return entity; + } + + protected void maybeCallbackBeforeConvertWithQuery(Object query) { + + if (query instanceof IndexQuery) { + IndexQuery indexQuery = (IndexQuery) query; + Object queryObject = indexQuery.getObject(); + + if (queryObject != null) { + queryObject = maybeCallbackBeforeConvert(queryObject); + indexQuery.setObject(queryObject); + } + } + } + + // this can be called with either a List or a List; these query classes + // don't have a common bas class, therefore the List argument + protected void maybeCallbackBeforeConvertWithQueries(List queries) { + queries.forEach(this::maybeCallbackBeforeConvertWithQuery); + } // endregion + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index b7b014420..147d66b7e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -37,6 +37,7 @@ import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -134,12 +135,16 @@ public IndexOperations indexOps(IndexCoordinates index) { // region DocumentOperations @Override public String index(IndexQuery query, IndexCoordinates index) { + + maybeCallbackBeforeConvertWithQuery(query); + IndexRequest request = requestFactory.indexRequest(query, index); String documentId = execute(client -> client.index(request, RequestOptions.DEFAULT).getId()); // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); + Object queryObject = query.getObject(); + if (queryObject != null) { + setPersistentEntityId(queryObject, documentId); } return documentId; } @@ -166,6 +171,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) @Override protected boolean doExists(String id, IndexCoordinates index) { GetRequest request = requestFactory.getRequest(id, index); + request.fetchSourceContext(FetchSourceContext.DO_NOT_FETCH_SOURCE); return execute(client -> client.get(request, RequestOptions.DEFAULT).isExists()); } @@ -219,6 +225,7 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + maybeCallbackBeforeConvertWithQueries(queries); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); return checkForBulkOperationFailure(execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 4042c32e6..d8ef07650 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -136,12 +136,18 @@ public void setSearchTimeout(String searchTimeout) { // region DocumentOperations @Override public String index(IndexQuery query, IndexCoordinates index) { + + maybeCallbackBeforeConvertWithQuery(query); + IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); String documentId = indexRequestBuilder.execute().actionGet().getId(); + // We should call this because we are not going through a mapper. - if (query.getObject() != null) { - setPersistentEntityId(query.getObject(), documentId); + Object queryObject = query.getObject(); + if (queryObject != null) { + setPersistentEntityId(queryObject, documentId); } + return documentId; } @@ -167,6 +173,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) @Override protected boolean doExists(String id, IndexCoordinates index) { GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, id, index); + getRequestBuilder.setFetchSource(false); return getRequestBuilder.execute().actionGet().isExists(); } @@ -223,6 +230,7 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + maybeCallbackBeforeConvertWithQueries(queries); BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); return checkForBulkOperationFailure(bulkRequest.execute().actionGet()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index b0ed7c877..519c06f0e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -56,6 +56,9 @@ import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.NoSuchIndexException; @@ -67,6 +70,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocument; +import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -78,6 +82,7 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; import org.springframework.lang.Nullable; @@ -93,7 +98,7 @@ * @author Aleksei Arsenev * @since 3.2 */ -public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations { +public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations, ApplicationContextAware { private static final Logger QUERY_LOGGER = LoggerFactory .getLogger("org.springframework.data.elasticsearch.core.QUERY"); @@ -108,6 +113,8 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera private @Nullable RefreshPolicy refreshPolicy = RefreshPolicy.IMMEDIATE; private @Nullable IndicesOptions indicesOptions = IndicesOptions.strictExpandOpenAndForbidClosedIgnoreThrottled(); + private @Nullable ReactiveEntityCallbacks entityCallbacks; + // region Initialization public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client) { this(client, new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext())); @@ -125,6 +132,31 @@ public ReactiveElasticsearchTemplate(ReactiveElasticsearchClient client, Elastic this.operations = new EntityOperations(this.mappingContext); this.requestFactory = new RequestFactory(converter); } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + + if (entityCallbacks == null) { + setEntityCallbacks(ReactiveEntityCallbacks.create(applicationContext)); + } + } + + /** + * Set the {@link ReactiveEntityCallbacks} instance to use when invoking {@link ReactiveEntityCallbacks callbacks} + * like the {@link ReactiveBeforeConvertCallback}. + *

+ * Overrides potentially existing {@link ReactiveEntityCallbacks}. + * + * @param entityCallbacks must not be {@literal null}. + * @throws IllegalArgumentException if the given instance is {@literal null}. + * @since 4.0 + */ + public void setEntityCallbacks(ReactiveEntityCallbacks entityCallbacks) { + + Assert.notNull(entityCallbacks, "EntityCallbacks must not be null!"); + + this.entityCallbacks = entityCallbacks; + } // endregion // region DocumentOperations @@ -289,7 +321,7 @@ protected Mono doExists(GetRequest request) { private Mono doIndex(Object value, AdaptibleEntity entity, IndexCoordinates index) { - return Mono.defer(() -> { + return maybeCallBeforeConvert(value).flatMap(it -> { IndexRequest request = getIndexRequest(value, entity, index); request = prepareIndexRequest(value, request); return doIndex(request); @@ -821,4 +853,14 @@ private RuntimeException translateException(Throwable throwable) { return potentiallyTranslatedException != null ? potentiallyTranslatedException : runtimeException; } + // region callbacks + protected Mono maybeCallBeforeConvert(T entity) { + + if (null != entityCallbacks) { + return entityCallbacks.callback(ReactiveBeforeConvertCallback.class, entity); + } + + return Mono.just(entity); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 842f9d39f..4947e62d1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -25,7 +25,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; -import org.springframework.data.elasticsearch.support.ReactiveSupport; +import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.lang.Nullable; /** @@ -78,7 +78,7 @@ public static Object unwrapSearchHits(Object result) { return unwrapSearchHits(searchHits.getSearchHits()); } - if (ReactiveSupport.isReactorAvailable()) { + if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) { if (result instanceof Flux) { Flux flux = (Flux) result; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index ab7cb01e6..28d74c2f6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,17 +15,8 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; import org.elasticsearch.search.aggregations.Aggregations; @@ -38,8 +29,6 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.convert.CustomConversions; -import org.springframework.data.convert.EntityInstantiator; -import org.springframework.data.convert.EntityInstantiators; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.ScriptedField; @@ -57,6 +46,8 @@ import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; +import org.springframework.data.mapping.model.EntityInstantiator; +import org.springframework.data.mapping.model.EntityInstantiators; import org.springframework.data.mapping.model.PersistentEntityParameterValueProvider; import org.springframework.data.mapping.model.PropertyValueProvider; import org.springframework.data.util.ClassTypeInformation; @@ -108,6 +99,7 @@ public MappingElasticsearchConverter( @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (mappingContext instanceof ApplicationContextAware) { ((ApplicationContextAware) mappingContext).setApplicationContext(applicationContext); } @@ -653,7 +645,7 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert collectionSource.map(it -> { if (it == null) { - //noinspection ReturnOfNull + // noinspection ReturnOfNull return null; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java new file mode 100644 index 000000000..779b32ba5 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java @@ -0,0 +1,56 @@ +/* + * Copyright 2020 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.event; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.core.Ordered; +import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.mapping.callback.EntityCallback; +import org.springframework.util.Assert; + +/** + * {@link EntityCallback} to populate auditing related fields on an entity about to be saved. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class AuditingEntityCallback implements BeforeConvertCallback, Ordered { + + private final ObjectFactory auditingHandlerFactory; + + /** + * Creates a new {@link AuditingEntityCallback} using the given {@link IsNewAwareAuditingHandler} provided by the + * given {@link ObjectFactory}. + * + * @param auditingHandlerFactory must not be {@literal null}. + */ + public AuditingEntityCallback(ObjectFactory auditingHandlerFactory) { + + Assert.notNull(auditingHandlerFactory, "IsNewAwareAuditingHandler must not be null!"); + + this.auditingHandlerFactory = auditingHandlerFactory; + } + + @Override + public Object onBeforeConvert(Object entity) { + return auditingHandlerFactory.getObject().markAudited(entity); + } + + @Override + public int getOrder() { + return 100; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java similarity index 54% rename from src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java rename to src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java index 205ec8e9f..85d50706f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/support/ReactiveSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java @@ -13,27 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.elasticsearch.support; +package org.springframework.data.elasticsearch.core.event; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.springframework.data.repository.util.ClassUtils; +import org.springframework.data.mapping.callback.EntityCallback; /** + * Callback being invoked before a domain object is converted to be persisted. + * * @author Peter-Josef Meisch * @since 4.0 */ -public final class ReactiveSupport { - private ReactiveSupport() {} +@FunctionalInterface +public interface BeforeConvertCallback extends EntityCallback { /** - * @return true if project reactor is on the classpath + * Callback method that will be invoked before an entity is persisted. Can return the same or a different instance of + * the domain entity class. + * + * @param entity the entity being converted + * @return the entity to be converted */ - public static boolean isReactorAvailable() { - AtomicBoolean available = new AtomicBoolean(false); - ClassUtils.ifPresent("reactor.core.publisher.Flux", null, aClass -> { - available.set(true); - }); - return available.get(); - } + T onBeforeConvert(T entity); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java new file mode 100644 index 000000000..4051d5f71 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java @@ -0,0 +1,58 @@ +/* + * Copyright 2020 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.event; + +import reactor.core.publisher.Mono; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.core.Ordered; +import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.mapping.callback.EntityCallback; +import org.springframework.util.Assert; + +/** + * {@link EntityCallback} to populate auditing related fields on an entity about to be saved. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +public class ReactiveAuditingEntityCallback implements ReactiveBeforeConvertCallback, Ordered { + + private final ObjectFactory auditingHandlerFactory; + + /** + * Creates a new {@link ReactiveAuditingEntityCallback} using the given {@link IsNewAwareAuditingHandler} provided by + * the given {@link ObjectFactory}. + * + * @param auditingHandlerFactory must not be {@literal null}. + */ + public ReactiveAuditingEntityCallback(ObjectFactory auditingHandlerFactory) { + + Assert.notNull(auditingHandlerFactory, "IsNewAwareAuditingHandler must not be null!"); + + this.auditingHandlerFactory = auditingHandlerFactory; + } + + @Override + public Mono onBeforeConvert(Object entity) { + return Mono.just(auditingHandlerFactory.getObject().markAudited(entity)); + } + + @Override + public int getOrder() { + return 100; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java new file mode 100644 index 000000000..e09b3ed25 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020 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.event; + +import org.reactivestreams.Publisher; +import org.springframework.data.mapping.callback.EntityCallback; + +/** + * Callback being invoked before a domain object is converted to be persisted. + * + * @author Peter-Josef Meisch + * @since 4.0 + */ +@FunctionalInterface +public interface ReactiveBeforeConvertCallback extends EntityCallback { + + /** + * Callback method that will be invoked before an entity is persisted. Can return the same or a different instance of + * the domain entity class. + * + * @param entity the entity being converted + * @return the entity to be converted + */ + Publisher onBeforeConvert(T entity); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/event/package-info.java new file mode 100644 index 000000000..a48d01eb0 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/package-info.java @@ -0,0 +1,6 @@ +/** + * classes and interfaces related to Spring Data Elasticsearch events and callbacks. + */ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package org.springframework.data.elasticsearch.core.event; diff --git a/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleReactiveRestClientBasedTests.java b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleReactiveRestClientBasedTests.java new file mode 100644 index 000000000..b7c3856f9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/JUnit5SampleReactiveRestClientBasedTests.java @@ -0,0 +1,47 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * class demonstrating the setup of a JUnit 5 test in Spring Data Elasticsearch that uses the reactive rest client. The + * ContextConfiguration must include the {@link ElasticsearchRestTemplateConfiguration} class. + * + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ReactiveElasticsearchRestTemplateConfiguration.class }) +@DisplayName("a sample JUnit 5 test with reactive rest client") +public class JUnit5SampleReactiveRestClientBasedTests { + + @Autowired private ReactiveElasticsearchOperations elasticsearchOperations; + + @Test + @DisplayName("should have a ReactiveElasticsearchOperations") + void shouldHaveARestTemplate() { + assertThat(elasticsearchOperations).isNotNull().isInstanceOf(ReactiveElasticsearchOperations.class); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java new file mode 100644 index 000000000..4c5f80d21 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java @@ -0,0 +1,142 @@ +/* + * Copyright 2020 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.config; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDateTime; +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Persistable; +import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.mapping.callback.EntityCallbacks; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + */ +public abstract class AuditingIntegrationTest { + + public static AuditorAware auditorProvider() { + return new AuditorAware() { + int count = 0; + + @Override + public Optional getCurrentAuditor() { + return Optional.of("Auditor " + (++count)); + } + }; + } + + @Autowired ApplicationContext applicationContext; + + @Test // DATAES-68 + void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { + SimpleElasticsearchMappingContext mappingContext = applicationContext + .getBean(SimpleElasticsearchMappingContext.class); + + mappingContext.getPersistentEntity(Entity.class); + + EntityCallbacks callbacks = EntityCallbacks.create(applicationContext); + + Entity entity = new Entity(); + entity.setId("1"); + entity = callbacks.callback(BeforeConvertCallback.class, entity); + + assertThat(entity.getCreated()).isNotNull(); + assertThat(entity.getModified()).isEqualTo(entity.created); + assertThat(entity.getCreatedBy()).isEqualTo("Auditor 1"); + assertThat(entity.getModifiedBy()).isEqualTo("Auditor 1"); + + Thread.sleep(10); + + entity = callbacks.callback(BeforeConvertCallback.class, entity); + + assertThat(entity.getCreated()).isNotNull(); + assertThat(entity.getModified()).isNotEqualTo(entity.created); + assertThat(entity.getCreatedBy()).isEqualTo("Auditor 1"); + assertThat(entity.getModifiedBy()).isEqualTo("Auditor 2"); + } + + static class Entity implements Persistable { + private @Nullable @Id String id; + private @Nullable @CreatedDate LocalDateTime created; + private @Nullable LocalDateTime modified; + private @Nullable @CreatedBy String createdBy; + private @Nullable @LastModifiedBy String modifiedBy; + + @Nullable + public String getId() { + return id; + } + + public void setId(@Nullable String id) { + this.id = id; + } + + @Nullable + public LocalDateTime getCreated() { + return created; + } + + public void setCreated(@Nullable LocalDateTime created) { + this.created = created; + } + + public void setModified(@Nullable LocalDateTime modified) { + this.modified = modified; + } + + @Nullable + @LastModifiedDate + public LocalDateTime getModified() { + return modified; + } + + @Nullable + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(@Nullable String createdBy) { + this.createdBy = createdBy; + } + + @Nullable + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(@Nullable String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + @Override + public boolean isNew() { + return id == null || (created == null && createdBy == null); + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrarUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrarUnitTests.java new file mode 100644 index 000000000..0b21105f6 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrarUnitTests.java @@ -0,0 +1,50 @@ +/* + * Copyright 2020 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.config; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.core.type.AnnotationMetadata; + +/** + * Unit tests for {@link ElasticsearchAuditingRegistrar}. + * + * @author Oliver Gierke + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +public class ElasticsearchAuditingRegistrarUnitTests { + + ElasticsearchAuditingRegistrar registrar = new ElasticsearchAuditingRegistrar(); + + @Mock AnnotationMetadata metadata; + @Mock BeanDefinitionRegistry registry; + + @Test // DATAES-68 + public void rejectsNullAnnotationMetadata() { + assertThatIllegalArgumentException().isThrownBy(() -> registrar.registerBeanDefinitions(null, registry)); + } + + @Test // DATAES-68 + public void rejectsNullBeanDefinitionRegistry() { + assertThatIllegalArgumentException().isThrownBy(() -> registrar.registerBeanDefinitions(metadata, null)); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchRestAuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchRestAuditingIntegrationTest.java new file mode 100644 index 000000000..99f0134e3 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchRestAuditingIntegrationTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ElasticsearchRestAuditingIntegrationTest.Config.class }) +public class ElasticsearchRestAuditingIntegrationTest extends AuditingIntegrationTest { + + @Import({ ElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchAuditing(auditorAwareRef = "auditorAware") + static class Config { + + @Bean + public AuditorAware auditorAware() { + return auditorProvider(); + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchTransportAuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchTransportAuditingIntegrationTest.java new file mode 100644 index 000000000..2526bbf03 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/ElasticsearchTransportAuditingIntegrationTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ElasticsearchTransportAuditingIntegrationTest.Config.class }) +public class ElasticsearchTransportAuditingIntegrationTest extends AuditingIntegrationTest { + + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchAuditing(auditorAwareRef = "auditorAware") + static class Config { + + @Bean + public AuditorAware auditorAware() { + return auditorProvider(); + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java new file mode 100644 index 000000000..a9bf3541c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2020 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.config; + +import static org.assertj.core.api.Assertions.*; + +import java.time.LocalDateTime; +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Persistable; +import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; +import org.springframework.lang.Nullable; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ReactiveAuditingIntegrationTest.Config.class }) +public class ReactiveAuditingIntegrationTest { + + public static AuditorAware auditorProvider() { + return new AuditorAware() { + int count = 0; + + @Override + public Optional getCurrentAuditor() { + return Optional.of("Auditor " + (++count)); + } + }; + } + + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class }) + @EnableElasticsearchAuditing(auditorAwareRef = "auditorAware") + static class Config { + + @Bean + public AuditorAware auditorAware() { + return auditorProvider(); + } + } + + @Autowired ApplicationContext applicationContext; + + @Test // DATAES-68 + void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { + SimpleElasticsearchMappingContext mappingContext = applicationContext + .getBean(SimpleElasticsearchMappingContext.class); + + mappingContext.getPersistentEntity(Entity.class); + + ReactiveEntityCallbacks callbacks = ReactiveEntityCallbacks.create(applicationContext); + + Entity entity = new Entity(); + entity.setId("1"); + entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity).block(); + + assertThat(entity.getCreated()).isNotNull(); + assertThat(entity.getModified()).isEqualTo(entity.created); + assertThat(entity.getCreatedBy()).isEqualTo("Auditor 1"); + assertThat(entity.getModifiedBy()).isEqualTo("Auditor 1"); + + Thread.sleep(10); + + entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity).block(); + + assertThat(entity.getCreated()).isNotNull(); + assertThat(entity.getModified()).isNotEqualTo(entity.created); + assertThat(entity.getCreatedBy()).isEqualTo("Auditor 1"); + assertThat(entity.getModifiedBy()).isEqualTo("Auditor 2"); + } + + static class Entity implements Persistable { + private @Nullable @Id String id; + private @Nullable @CreatedDate LocalDateTime created; + private @Nullable LocalDateTime modified; + private @Nullable @CreatedBy String createdBy; + private @Nullable @LastModifiedBy String modifiedBy; + + @Nullable + public String getId() { + return id; + } + + public void setId(@Nullable String id) { + this.id = id; + } + + @Nullable + public LocalDateTime getCreated() { + return created; + } + + public void setCreated(@Nullable LocalDateTime created) { + this.created = created; + } + + public void setModified(@Nullable LocalDateTime modified) { + this.modified = modified; + } + + @Nullable + @LastModifiedDate + public LocalDateTime getModified() { + return modified; + } + + @Nullable + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(@Nullable String createdBy) { + this.createdBy = createdBy; + } + + @Nullable + public String getModifiedBy() { + return modifiedBy; + } + + public void setModifiedBy(@Nullable String modifiedBy) { + this.modifiedBy = modifiedBy; + } + + @Override + public boolean isNew() { + return id == null || (created == null && createdBy == null); + } + + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java new file mode 100644 index 000000000..52dad6ea9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java @@ -0,0 +1,163 @@ +/* + * Copyright 2020 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.event; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.Ordered; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +class AuditingEntityCallbackTests { + + IsNewAwareAuditingHandler handler; + AuditingEntityCallback callback; + + @BeforeEach + void setUp() { + SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); + context.getPersistentEntity(Sample.class); + handler = spy(new IsNewAwareAuditingHandler(PersistentEntities.of(context))); + callback = new AuditingEntityCallback(() -> handler); + } + + @Test // DATAES-68 + void shouldThrowExceptionOnNullFactory() { + assertThatIllegalArgumentException().isThrownBy(() -> new AuditingEntityCallback(null)); + } + + @Test // DATAES-68 + void shouldHaveOrder100() { + assertThat(callback).isInstanceOf(Ordered.class); + assertThat(callback.getOrder()).isEqualTo(100); + } + + @Test // DATAES-68 + void shouldCallHandler() { + Sample entity = new Sample(); + entity.setId("42"); + callback.onBeforeConvert(entity); + + verify(handler).markAudited(eq(entity)); + } + + @Test // DATAES-68 + void shouldReturnObjectFromHandler() { + Sample sample1 = new Sample(); + sample1.setId("1"); + Sample sample2 = new Sample(); + sample2.setId("2"); + doReturn(sample2).when(handler).markAudited(any()); + + Sample result = (Sample) callback.onBeforeConvert(sample1); + + assertThat(result).isSameAs(sample2); + } + + static class Sample { + + @Nullable @Id String id; + @Nullable @CreatedDate LocalDateTime createdDate; + @Nullable @CreatedBy String createdBy; + @Nullable @LastModifiedDate LocalDateTime modified; + + @Nullable + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Nullable + public LocalDateTime getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(LocalDateTime createdDate) { + this.createdDate = createdDate; + } + + @Nullable + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(@Nullable String createdBy) { + this.createdBy = createdBy; + } + + @Nullable + public LocalDateTime getModified() { + return modified; + } + + public void setModified(LocalDateTime modified) { + this.modified = modified; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Sample sample = (Sample) o; + + if (id != null ? !id.equals(sample.id) : sample.id != null) + return false; + if (createdDate != null ? !createdDate.equals(sample.createdDate) : sample.createdDate != null) + return false; + if (createdBy != null ? !createdBy.equals(sample.createdBy) : sample.createdBy != null) + return false; + return modified != null ? modified.equals(sample.modified) : sample.modified == null; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0); + result = 31 * result + (createdBy != null ? createdBy.hashCode() : 0); + result = 31 * result + (modified != null ? modified.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "Sample{" + "id='" + id + '\'' + ", createdDate=" + createdDate + ", createdBy='" + createdBy + '\'' + + ", modified=" + modified + '}'; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java new file mode 100644 index 000000000..0637711c0 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2020 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.event; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.stereotype.Component; + +/** + * @author Peter-Josef Meisch + */ +abstract class ElasticsearchOperationsCallbackTest { + + @Autowired private ElasticsearchOperations operations; + + @Configuration + static class Config { + + @Component + static class SampleEntityBeforeConvertCallback implements BeforeConvertCallback { + @Override + public SampleEntity onBeforeConvert(SampleEntity entity) { + entity.setText("converted"); + return entity; + } + } + } + + @BeforeEach + void setUp() { + IndexOperations indexOps = operations.indexOps(SampleEntity.class); + indexOps.delete(); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(SampleEntity.class)); + } + + @AfterEach + void tearDown() { + IndexOperations indexOps = operations.indexOps(SampleEntity.class); + indexOps.delete(); + } + + @Test + void shouldCallBeforeConvertCallback() { + SampleEntity entity = new SampleEntity("1", "test"); + + SampleEntity saved = operations.save(entity); + + assertThat(saved.getText()).isEqualTo("converted"); + } + + @Document(indexName = "test-operations-callback") + static class SampleEntity { + @Id private String id; + private String text; + + public SampleEntity(String id, String text) { + this.id = id; + this.text = text; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchRestOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchRestOperationsCallbackTest.java new file mode 100644 index 000000000..f6c1170f9 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchRestOperationsCallbackTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.event; + +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class, ElasticsearchOperationsCallbackTest.Config.class }) +class ElasticsearchRestOperationsCallbackTest extends ElasticsearchOperationsCallbackTest {} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchTransportOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchTransportOperationsCallbackTest.java new file mode 100644 index 000000000..d05848e23 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchTransportOperationsCallbackTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020 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.event; + +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class, ElasticsearchOperationsCallbackTest.Config.class }) +class ElasticsearchTransportOperationsCallbackTest extends ElasticsearchOperationsCallbackTest {} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java new file mode 100644 index 000000000..4d15016c8 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java @@ -0,0 +1,167 @@ +/* + * Copyright 2020 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.event; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import reactor.test.StepVerifier; + +import java.time.LocalDateTime; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.core.Ordered; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.mapping.context.PersistentEntities; +import org.springframework.lang.Nullable; + +/** + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +class ReactiveAuditingEntityCallbackTests { + + IsNewAwareAuditingHandler handler; + ReactiveAuditingEntityCallback callback; + + @BeforeEach + void setUp() { + SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); + context.getPersistentEntity(Sample.class); + handler = spy(new IsNewAwareAuditingHandler(PersistentEntities.of(context))); + callback = new ReactiveAuditingEntityCallback(() -> handler); + } + + @Test // DATAES-68 + void shouldThrowExceptionOnNullFactory() { + assertThatIllegalArgumentException().isThrownBy(() -> new AuditingEntityCallback(null)); + } + + @Test // DATAES-68 + void shouldHaveOrder100() { + assertThat(callback).isInstanceOf(Ordered.class); + assertThat(callback.getOrder()).isEqualTo(100); + } + + @Test // DATAES-68 + void shouldCallHandler() { + Sample entity = new Sample(); + entity.setId("42"); + callback.onBeforeConvert(entity); + + verify(handler).markAudited(eq(entity)); + } + + @Test // DATAES-68 + void shouldReturnObjectFromHandler() { + Sample sample1 = new Sample(); + sample1.setId("1"); + Sample sample2 = new Sample(); + sample2.setId("2"); + doReturn(sample2).when(handler).markAudited(any()); + + callback.onBeforeConvert(sample1) // + .as(StepVerifier::create) // + .consumeNextWith(it -> { // + assertThat(it).isSameAs(sample2); // + }).verifyComplete(); + } + + static class Sample { + + @Nullable @Id String id; + @Nullable @CreatedDate LocalDateTime createdDate; + @Nullable @CreatedBy String createdBy; + @Nullable @LastModifiedDate LocalDateTime modified; + + @Nullable + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Nullable + public LocalDateTime getCreatedDate() { + return createdDate; + } + + public void setCreatedDate(LocalDateTime createdDate) { + this.createdDate = createdDate; + } + + @Nullable + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(@Nullable String createdBy) { + this.createdBy = createdBy; + } + + @Nullable + public LocalDateTime getModified() { + return modified; + } + + public void setModified(LocalDateTime modified) { + this.modified = modified; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Sample sample = (Sample) o; + + if (id != null ? !id.equals(sample.id) : sample.id != null) + return false; + if (createdDate != null ? !createdDate.equals(sample.createdDate) : sample.createdDate != null) + return false; + if (createdBy != null ? !createdBy.equals(sample.createdBy) : sample.createdBy != null) + return false; + return modified != null ? modified.equals(sample.modified) : sample.modified == null; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (createdDate != null ? createdDate.hashCode() : 0); + result = 31 * result + (createdBy != null ? createdBy.hashCode() : 0); + result = 31 * result + (modified != null ? modified.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "Sample{" + "id='" + id + '\'' + ", createdDate=" + createdDate + ", createdBy='" + createdBy + '\'' + + ", modified=" + modified + '}'; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java new file mode 100644 index 000000000..4ca299b7a --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java @@ -0,0 +1,115 @@ +/* + * Copyright 2020 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.event; + +import static org.assertj.core.api.Assertions.*; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.stereotype.Component; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ReactiveElasticsearchOperationsCallbackTest.Config.class }) +public class ReactiveElasticsearchOperationsCallbackTest { + + @Configuration + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class, ElasticsearchRestTemplateConfiguration.class }) + static class Config { + @Component + static class SampleEntityBeforeConvertCallback implements ReactiveBeforeConvertCallback { + @Override + public Mono onBeforeConvert(SampleEntity entity) { + entity.setText("reactive-converted"); + return Mono.just(entity); + } + } + + } + + @Autowired private ReactiveElasticsearchOperations operations; + @Autowired private ElasticsearchOperations nonreactiveOperations; + + @BeforeEach + void setUp() { + IndexOperations indexOps = nonreactiveOperations.indexOps(SampleEntity.class); + indexOps.create(); + indexOps.putMapping(indexOps.createMapping(SampleEntity.class)); + } + + @AfterEach + void tearDown() { + IndexOperations indexOps = nonreactiveOperations.indexOps(SampleEntity.class); + indexOps.delete(); + } + + @Test // DATES-68 + void shouldCallCallbackOnSave() { + SampleEntity sample = new SampleEntity("42", "initial"); + + operations.save(sample) // + .as(StepVerifier::create) // + .consumeNextWith(it -> { // + assertThat(it.text).isEqualTo("reactive-converted"); // + }) // + .verifyComplete(); + } + + @Document(indexName = "test-operations-reactive-callback") + static class SampleEntity { + @Id private String id; + private String text; + + public SampleEntity(String id, String text) { + this.id = id; + this.text = text; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index ec103ba56..8ca227615 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -104,7 +104,7 @@ private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasti } - private class EntityWithWrongVersionType { + private static class EntityWithWrongVersionType { @Nullable @Version private String version; @@ -118,7 +118,7 @@ public void setVersion(String version) { } } - private class EntityWithMultipleVersionField { + private static class EntityWithMultipleVersionField { @Nullable @Version private Long version1; @Nullable @Version private Long version2; @@ -143,7 +143,6 @@ public void setVersion2(Long version2) { } // DATAES-462 - static class TwoScoreProperties { @Score float first; diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java index e06f60bfd..d7085b24a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java @@ -27,16 +27,14 @@ /** * Configuration for Spring Data Elasticsearch using - * {@link org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate}. The required - * {@link ClusterConnectionInfo} bean must be provided by the testclass. + * {@link org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate}. * * @author Peter-Josef Meisch */ @Configuration public class ElasticsearchRestTemplateConfiguration extends AbstractElasticsearchConfiguration { - @Autowired - private ClusterConnectionInfo clusterConnectionInfo; + @Autowired private ClusterConnectionInfo clusterConnectionInfo; @Override @Bean diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ReactiveElasticsearchRestTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ReactiveElasticsearchRestTemplateConfiguration.java new file mode 100644 index 000000000..df8533c44 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ReactiveElasticsearchRestTemplateConfiguration.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 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.junit.jupiter; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.elasticsearch.client.ClientConfiguration; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients; +import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration; + +/** + * Configuration for Spring Data Elasticsearch Integration Tests using + * {@link org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations} + * + * @author Peter-Josef Meisch + */ +@Configuration +public class ReactiveElasticsearchRestTemplateConfiguration extends AbstractReactiveElasticsearchConfiguration { + + @Autowired private ClusterConnectionInfo clusterConnectionInfo; + + @Override + public ReactiveElasticsearchClient reactiveElasticsearchClient() { + String elasticsearchHostPort = clusterConnectionInfo.getHost() + ':' + clusterConnectionInfo.getHttpPort(); + + ClientConfiguration.TerminalClientConfigurationBuilder configurationBuilder = ClientConfiguration.builder() // + .connectedTo(elasticsearchHostPort); + + if (clusterConnectionInfo.isUseSsl()) { + configurationBuilder = ((ClientConfiguration.MaybeSecureClientConfigurationBuilder) configurationBuilder) + .usingSsl(); + } + + return ReactiveRestClients.create(configurationBuilder.build()); + + } +} From f103bdb9d81bef1ad58cee005fe4958bbda8f26e Mon Sep 17 00:00:00 2001 From: Sascha Woo Date: Wed, 18 Mar 2020 20:37:05 +0100 Subject: [PATCH 0089/1191] DATAES-764 - StreamQueries#streamResults does not clear scroll context when finished. Original PR: #406 --- .../data/elasticsearch/core/ScrolledPage.java | 4 +- .../elasticsearch/core/StreamQueries.java | 61 +++++++-------- .../elasticsearch/core/StreamQueriesTest.java | 77 +++++++++++++++++++ 3 files changed, 110 insertions(+), 32 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java index 1445e0e84..0e0d23158 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java @@ -7,9 +7,9 @@ /** * @author Artur Konczak * @author Peter-Josef Meisch + * @author Sascha Woo */ public interface ScrolledPage extends Page { - @Nullable - String getScrollId(); + String getScrollId(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index 784d1eeb8..62104b839 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -21,11 +21,13 @@ import java.util.function.Function; import org.springframework.data.util.CloseableIterator; +import org.springframework.util.Assert; /** * Utility to support streaming queries. * * @author Mark Paluch + * @author Sascha Woo * @since 3.2 */ abstract class StreamQueries { @@ -33,72 +35,71 @@ abstract class StreamQueries { /** * Stream query results using {@link ScrolledPage}. * - * @param page the initial page. - * @param continueFunction continuation function accepting the current scrollId. - * @param clearScroll cleanup function accepting the current scrollId. + * @param page the initial scrolled page. + * @param continueScrollFunction function to continue scrolling applies to the current scrollId. + * @param clearScrollConsumer consumer to clear the scroll context by accepting the current scrollId. * @param * @return the {@link CloseableIterator}. */ static CloseableIterator streamResults(ScrolledPage page, - Function> continueFunction, Consumer clearScroll) { + Function> continueScrollFunction, Consumer clearScrollConsumer) { - return new CloseableIterator() { + Assert.notNull(page, "page must not be null."); + Assert.notNull(page.getScrollId(), "scrollId must not be null."); + Assert.notNull(continueScrollFunction, "continueScrollFunction must not be null."); + Assert.notNull(clearScrollConsumer, "clearScrollConsumer must not be null."); - /** As we couldn't retrieve single result with scroll, store current hits. */ - private volatile Iterator currentHits = page.iterator(); + return new CloseableIterator() { - /** The scroll id. */ + // As we couldn't retrieve single result with scroll, store current hits. + private volatile Iterator scrollHits = page.iterator(); private volatile String scrollId = page.getScrollId(); - - /** If stream is finished (ie: cluster returns no results. */ - private volatile boolean finished = !currentHits.hasNext(); + private volatile boolean continueScroll = scrollHits.hasNext(); @Override public void close() { + try { - // Clear scroll on cluster only in case of error (cause elasticsearch auto clear scroll when it's done) - if (!finished && scrollId != null && currentHits != null && currentHits.hasNext()) { - clearScroll.accept(scrollId); - } + clearScrollConsumer.accept(scrollId); } finally { - currentHits = null; + scrollHits = null; scrollId = null; } } @Override public boolean hasNext() { - // Test if stream is finished - if (finished) { + + if (!continueScroll) { return false; } - // Test if it remains hits - if (currentHits == null || !currentHits.hasNext()) { - // Do a new request - ScrolledPage scroll = continueFunction.apply(scrollId); - // Save hits and scroll id - currentHits = scroll.iterator(); - finished = !currentHits.hasNext(); - scrollId = scroll.getScrollId(); + + if (!scrollHits.hasNext()) { + ScrolledPage nextPage = continueScrollFunction.apply(scrollId); + scrollHits = nextPage.iterator(); + scrollId = nextPage.getScrollId(); + continueScroll = scrollHits.hasNext(); } - return currentHits.hasNext(); + + return scrollHits.hasNext(); } @Override public T next() { if (hasNext()) { - return currentHits.next(); + return scrollHits.next(); } throw new NoSuchElementException(); } @Override public void remove() { - throw new UnsupportedOperationException("remove"); + throw new UnsupportedOperationException(); } }; } // utility constructor - private StreamQueries() {} + private StreamQueries() { + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java new file mode 100644 index 000000000..0508ee488 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.jupiter.api.Test; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; + +/** + * @author Sascha Woo + */ +public class StreamQueriesTest { + + @Test // DATAES-764 + public void shouldCallClearScrollOnIteratorClose() { + + // given + List results = new ArrayList<>(); + results.add("one"); + + ScrolledPage page = new ScrolledPageImpl("1234", results); + + AtomicBoolean clearScrollCalled = new AtomicBoolean(false); + + // when + CloseableIterator closeableIterator = StreamQueries.streamResults( // + page, // + scrollId -> new ScrolledPageImpl(scrollId, Collections.emptyList()), // + scrollId -> clearScrollCalled.set(true)); + + while (closeableIterator.hasNext()) { + closeableIterator.next(); + } + closeableIterator.close(); + + // then + assertThat(clearScrollCalled).isTrue(); + + } + + private static class ScrolledPageImpl extends PageImpl implements ScrolledPage { + + private String scrollId; + + public ScrolledPageImpl(String scrollId, List content) { + super(content); + this.scrollId = scrollId; + } + + @Override + @Nullable + public String getScrollId() { + return scrollId; + } + } +} From 745f9e9d796258c24a606d533de5c97c08bd1a68 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 20 Mar 2020 18:27:50 +0100 Subject: [PATCH 0090/1191] DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents. Original PR: #408 --- .../elasticsearch/core/RequestFactory.java | 10 +++++ .../core/RequestFactoryTests.java | 37 ++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index e54d5aa23..32192d32f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -84,6 +84,10 @@ * @since 4.0 */ class RequestFactory { + + // the default max result window size of Elasticsearch + static final Integer INDEX_MAX_RESULT_WINDOW = 10_000; + private final ElasticsearchConverter elasticsearchConverter; public RequestFactory(ElasticsearchConverter elasticsearchConverter) { @@ -557,6 +561,9 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz if (query.getPageable().isPaged()) { sourceBuilder.from((int) query.getPageable().getOffset()); sourceBuilder.size(query.getPageable().getPageSize()); + } else { + sourceBuilder.from(0); + sourceBuilder.size(INDEX_MAX_RESULT_WINDOW); } if (!query.getFields().isEmpty()) { @@ -720,6 +727,9 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli if (query.getPageable().isPaged()) { searchRequestBuilder.setFrom((int) query.getPageable().getOffset()); searchRequestBuilder.setSize(query.getPageable().getPageSize()); + } else { + searchRequestBuilder.setFrom(0); + searchRequestBuilder.setSize(INDEX_MAX_RESULT_WINDOW); } if (!query.getFields().isEmpty()) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index b2055ef8b..f7d0bb6da 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -16,16 +16,25 @@ package org.springframework.data.elasticsearch.core; import static org.assertj.core.api.Assertions.*; +import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.mockito.Mockito.*; import static org.skyscreamer.jsonassert.JSONAssert.*; import java.util.Collections; +import org.elasticsearch.action.search.SearchAction; import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.client.Client; import org.json.JSONException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.annotation.Id; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; @@ -35,18 +44,22 @@ import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch */ +@ExtendWith(MockitoExtension.class) class RequestFactoryTests { @Nullable private static RequestFactory requestFactory; @Nullable private static MappingElasticsearchConverter converter; - @BeforeAll + @Mock private Client client; + @BeforeAll static void setUpAll() { SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext(); mappingContext.setInitialEntitySet(Collections.singleton(Person.class)); @@ -118,6 +131,28 @@ void shouldAddRouting() throws JSONException { assertThat(searchRequest.routing()).isEqualTo(route); } + @Test // DATAES-765 + void shouldAddMaxQueryWindowForUnpagedToRequest() { + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(Pageable.unpaged()).build(); + + SearchRequest searchRequest = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + + assertThat(searchRequest.source().from()).isEqualTo(0); + assertThat(searchRequest.source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW); + } + + @Test // DATAES-765 + void shouldAddMaxQueryWindowForUnpagedToRequestBuilder() { + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(Pageable.unpaged()).build(); + + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, Person.class, + IndexCoordinates.of("persons")); + + assertThat(searchRequestBuilder.request().source().from()).isEqualTo(0); + assertThat(searchRequestBuilder.request().source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW); + } + static class Person { @Nullable @Id String id; @Nullable @Field(name = "last-name") String lastName; From a92970236c29a3c9e8ff1dba48742fb5e0d37e6a Mon Sep 17 00:00:00 2001 From: gsrinivas10 <44026152+gsrinivas10@users.noreply.github.com> Date: Sun, 22 Mar 2020 12:59:32 +0530 Subject: [PATCH 0091/1191] DATAES-763 - Allow map properties in entity with null values. Original PR: #405 --- .../MappingElasticsearchConverter.java | 11 +++- ...appingElasticsearchConverterUnitTests.java | 55 +++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 28d74c2f6..0d42274da 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -354,6 +354,11 @@ private R readCollectionValue(@Nullable List source, ElasticsearchPersist Collection target = createCollectionForValue(targetType, source.size()); for (Object value : source) { + + if(value == null) { + return null; + } + if (isSimpleType(value)) { target.add( @@ -386,8 +391,10 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe Map target = new LinkedHashMap<>(); for (Entry entry : source.entrySet()) { - - if (isSimpleType(entry.getValue())) { + + if(entry.getValue() == null) { + target.put(entry.getKey(),null); + } else if (isSimpleType(entry.getValue())) { target.put(entry.getKey(), readSimpleValue(entry.getValue(), targetType.isMap() ? targetType.getComponentType() : targetType)); } else { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 35a27b6a4..b3bb07cc1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -98,6 +98,7 @@ public class MappingElasticsearchConverterUnitTests { Document rifleAsMap; Document shotGunAsMap; Document bigBunsCafeAsMap; + Document notificationAsMap; @BeforeEach public void init() { @@ -193,6 +194,17 @@ public void init() { shotGunAsMap = Document.create(); shotGunAsMap.put("model", "Ithaca 37 Pump Shotgun"); shotGunAsMap.put("_class", ShotGun.class.getName()); + + notificationAsMap = Document.create(); + notificationAsMap.put("id",1L); + notificationAsMap.put("fromEmail","from@email.com"); + notificationAsMap.put("toEmail","to@email.com"); + Map data = new HashMap<>(); + data.put("documentType","abc"); + data.put("content",null); + notificationAsMap.put("params",data); + notificationAsMap.put("_class", + "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$Notification"); } @Test @@ -615,6 +627,40 @@ void shouldReadLocalDate() { assertThat(person.getBirthDate()).isEqualTo(LocalDate.of(2000, 8, 22)); assertThat(person.getGender()).isEqualTo(Gender.MAN); } + + @Test //DATAES-763 + void writeEntityWithMapDataType() { + + Notification notification = new Notification(); + notification.fromEmail="from@email.com"; + notification.toEmail="to@email.com"; + Map data = new HashMap<>(); + data.put("documentType","abc"); + data.put("content",null); + notification.params= data; + notification.id= 1L; + + Document document = Document.create(); + mappingElasticsearchConverter.write(notification,document); + assertThat(document).isEqualTo(notificationAsMap); + } + + @Test //DATAES-763 + void readEntityWithMapDataType() { + + Document document = Document.create(); + document.put("id",1L); + document.put("fromEmail","from@email.com"); + document.put("toEmail","to@email.com"); + Map data = new HashMap<>(); + data.put("documentType","abc"); + data.put("content",null); + document.put("params",data); + + Notification notification = mappingElasticsearchConverter.read(Notification.class,document); + assertThat(notification.params.get("documentType")).isEqualTo("abc"); + assertThat(notification.params.get("content")).isNull(); + } private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); @@ -748,6 +794,15 @@ static class Skynet { List objectList; Map objectMap; } + + @Data + static class Notification { + + Long id; + String fromEmail; + String toEmail; + Map params; + } @WritingConverter static class ShotGunToMapConverter implements Converter> { From db28d93676d6621ef0f9a46ee57935cf9dc869ac Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 22 Mar 2020 08:46:57 +0100 Subject: [PATCH 0092/1191] DATAES-763 - Polishing. --- .../MappingElasticsearchConverter.java | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 0d42274da..cf791fce1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,8 +15,17 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; import org.elasticsearch.search.aggregations.Aggregations; @@ -354,13 +363,10 @@ private R readCollectionValue(@Nullable List source, ElasticsearchPersist Collection target = createCollectionForValue(targetType, source.size()); for (Object value : source) { - - if(value == null) { - return null; - } - - if (isSimpleType(value)) { + if (value == null) { + target.add(null); + } else if (isSimpleType(value)) { target.add( readSimpleValue(value, targetType.getComponentType() != null ? targetType.getComponentType() : targetType)); } else { @@ -391,30 +397,32 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe Map target = new LinkedHashMap<>(); for (Entry entry : source.entrySet()) { - - if(entry.getValue() == null) { - target.put(entry.getKey(),null); - } else if (isSimpleType(entry.getValue())) { - target.put(entry.getKey(), - readSimpleValue(entry.getValue(), targetType.isMap() ? targetType.getComponentType() : targetType)); + + String entryKey = entry.getKey(); + Object entryValue = entry.getValue(); + + if (entryValue == null) { + target.put(entryKey, null); + } else if (isSimpleType(entryValue)) { + target.put(entryKey, + readSimpleValue(entryValue, targetType.isMap() ? targetType.getComponentType() : targetType)); } else { - ElasticsearchPersistentEntity targetEntity = computeGenericValueTypeForRead(property, entry.getValue()); + ElasticsearchPersistentEntity targetEntity = computeGenericValueTypeForRead(property, entryValue); if (targetEntity.getTypeInformation().isMap()) { - Map valueMap = (Map) entry.getValue(); + Map valueMap = (Map) entryValue; if (typeMapper.containsTypeInformation(valueMap)) { - target.put(entry.getKey(), readEntity(targetEntity, valueMap)); + target.put(entryKey, readEntity(targetEntity, valueMap)); } else { - target.put(entry.getKey(), readValue(valueMap, property, targetEntity.getTypeInformation())); + target.put(entryKey, readValue(valueMap, property, targetEntity.getTypeInformation())); } } else if (targetEntity.getTypeInformation().isCollectionLike()) { - target.put(entry.getKey(), - readValue(entry.getValue(), property, targetEntity.getTypeInformation().getActualType())); + target.put(entryKey, readValue(entryValue, property, targetEntity.getTypeInformation().getActualType())); } else { - target.put(entry.getKey(), readEntity(targetEntity, (Map) entry.getValue())); + target.put(entryKey, readEntity(targetEntity, (Map) entryValue)); } } } @@ -615,7 +623,14 @@ private Object writeMapValue(Map value, ElasticsearchPersistentP if (!typeHint.getActualType().getType().equals(Object.class) && isSimpleType(typeHint.getMapValueType().getType())) { - mapSource.forEach(it -> target.put(it.getKey(), getWriteSimpleValue(it.getValue()))); + mapSource.forEach(it -> { + + if (it.getValue() == null) { + target.put(it.getKey(), null); + } else { + target.put(it.getKey(), getWriteSimpleValue(it.getValue())); + } + }); } else { mapSource.forEach(it -> { From f354f986caaa36495fa9de222426231131aa2df2 Mon Sep 17 00:00:00 2001 From: xhaggi Date: Fri, 20 Mar 2020 14:09:08 +0100 Subject: [PATCH 0093/1191] DATAES-766 - Replace CloseableIterator with SearchHitsIterator in stream operations. Original pull request: #407 --- .../core/AbstractElasticsearchTemplate.java | 17 ++- .../core/ElasticsearchRestTemplate.java | 21 +-- .../core/ElasticsearchTemplate.java | 33 +++-- .../data/elasticsearch/core/ScrolledPage.java | 3 +- .../elasticsearch/core/SearchHitSupport.java | 12 +- .../data/elasticsearch/core/SearchHits.java | 125 ++++-------------- .../elasticsearch/core/SearchHitsImpl.java | 117 ++++++++++++++++ .../core/SearchHitsIterator.java | 60 +++++++++ .../elasticsearch/core/SearchOperations.java | 25 ++-- .../elasticsearch/core/SearchScrollHits.java | 34 +++++ .../elasticsearch/core/StreamQueries.java | 53 ++++++-- .../elasticsearch/core/TotalHitsRelation.java | 30 +++++ .../core/convert/ElasticsearchConverter.java | 18 ++- .../MappingElasticsearchConverter.java | 52 ++++---- .../core/ElasticsearchTemplateTests.java | 93 ++++++------- .../elasticsearch/core/StreamQueriesTest.java | 53 +++++--- 16 files changed, 494 insertions(+), 252 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHitsIterator.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchScrollHits.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/TotalHitsRelation.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 553a68781..f17774a1c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -208,20 +208,25 @@ public long count(Query query, Class clazz) { @Override public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { + long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); return (CloseableIterator) SearchHitSupport.unwrapSearchHits(searchForStream(query, clazz, index)); } @Override - public CloseableIterator> searchForStream(Query query, Class clazz) { + public SearchHitsIterator searchForStream(Query query, Class clazz) { return searchForStream(query, clazz, getIndexCoordinatesFor(clazz)); } @Override - public CloseableIterator> searchForStream(Query query, Class clazz, IndexCoordinates index) { + public SearchHitsIterator searchForStream(Query query, Class clazz, IndexCoordinates index) { + long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); - return StreamQueries.streamResults(searchScrollStart(scrollTimeInMillis, query, clazz, index), - scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz), this::searchScrollClear); + + return StreamQueries.streamResults( // + searchScrollStart(scrollTimeInMillis, query, clazz, index), // + scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz), // + this::searchScrollClear); } @Override @@ -283,13 +288,13 @@ public SearchHits search(Query query, Class clazz) { /* * internal use only, not for public API */ - abstract protected ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, + abstract protected SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index); /* * internal use only, not for public API */ - abstract protected ScrolledPage> searchScrollContinue(@Nullable String scrollId, + abstract protected SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, Class clazz); /* diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 147d66b7e..76ecd7c1d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -39,7 +39,6 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.suggest.SuggestBuilder; -import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -257,24 +256,28 @@ public SearchHits search(Query query, Class clazz, IndexCoordinates in } @Override - public ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, + public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { - Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); + Assert.notNull(query.getPageable(), "pageable of query must not be null."); SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); searchRequest.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - SearchResponse result = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(result), clazz, null); + + SearchResponse response = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); + + return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); } @Override - public ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz) { + public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + SearchScrollRequest request = new SearchScrollRequest(scrollId); request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - SearchResponse response = execute(client -> client.searchScroll(request, RequestOptions.DEFAULT)); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, Pageable.unpaged()); + + SearchResponse response = execute(client -> client.scroll(request, RequestOptions.DEFAULT)); + + return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index d8ef07650..22394d3ec 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -27,6 +27,7 @@ import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchScrollRequestBuilder; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.TimeValue; @@ -260,22 +261,32 @@ public SearchHits search(Query query, Class clazz, IndexCoordinates in } @Override - public ScrolledPage> searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, + public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query query, Class clazz, IndexCoordinates index) { - Assert.notNull(query.getPageable(), "Query.pageable is required for scan & scroll"); - SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); - searchRequestBuilder.setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)); - SearchResponse response = getSearchResponse(searchRequestBuilder); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, null); + Assert.notNull(query.getPageable(), "pageable of query must not be null."); + + ActionFuture action = requestFactory // + .searchRequestBuilder(client, query, clazz, index) // + .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)) // + .execute(); + + SearchResponse response = getSearchResponseWithTimeout(action); + + return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); } @Override - public ScrolledPage> searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz) { - SearchResponse response = getSearchResponseWithTimeout( - client.prepareSearchScroll(scrollId).setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)).execute()); - return elasticsearchConverter.mapResults(SearchDocumentResponse.from(response), clazz, Pageable.unpaged()); + public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + + ActionFuture action = client // + .prepareSearchScroll(scrollId) // + .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)) // + .execute(); + + SearchResponse response = getSearchResponseWithTimeout(action); + + return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java index 0e0d23158..e62fbf88b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ScrolledPage.java @@ -2,13 +2,14 @@ package org.springframework.data.elasticsearch.core; import org.springframework.data.domain.Page; -import org.springframework.lang.Nullable; /** * @author Artur Konczak * @author Peter-Josef Meisch * @author Sascha Woo + * @deprecated since 4.0, will be removed in a future version. */ +@Deprecated public interface ScrolledPage extends Page { String getScrollId(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 4947e62d1..3a7255aa1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -32,6 +32,7 @@ * Utility class with helper methods for working with {@link SearchHit}. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ public final class SearchHitSupport { @@ -95,10 +96,17 @@ public static Object unwrapSearchHits(Object result) { * @param searchHits, must not be {@literal null}. * @param pageable, must not be {@literal null}. * @return the created Page + * @deprecated since 4.0, will be removed in a future version. */ + @Deprecated public static AggregatedPage> page(SearchHits searchHits, Pageable pageable) { - return new AggregatedPageImpl<>(searchHits.getSearchHits(), pageable, searchHits.getTotalHits(), - searchHits.getAggregations(), searchHits.getScrollId(), searchHits.getMaxScore()); + return new AggregatedPageImpl<>( // + searchHits.getSearchHits(), // + pageable, // + searchHits.getTotalHits(), // + searchHits.getAggregations(), // + null, // + searchHits.getMaxScore()); } public static SearchPage searchPageFor(SearchHits searchHits, @Nullable Pageable pageable) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java index 57c18c9ae..b0a9cb4b1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHits.java @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 the original author or authors. + * Copyright 2020 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. @@ -15,143 +15,74 @@ */ package org.springframework.data.elasticsearch.core; -import java.util.Collections; import java.util.Iterator; import java.util.List; import org.elasticsearch.search.aggregations.Aggregations; import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Encapsulates a list of {@link SearchHit}s with additional information from the search. - * + * * @param the result data class. - * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ -public class SearchHits implements Streamable> { - - private final long totalHits; - private final TotalHitsRelation totalHitsRelation; - private final float maxScore; - private final String scrollId; - private final List> searchHits; - private final Aggregations aggregations; - - /** - * @param totalHits the number of total hits for the search - * @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null} - * @param maxScore the maximum score - * @param scrollId the scroll id if available - * @param searchHits must not be {@literal null} - * @param aggregations the aggregations if available - */ - public SearchHits(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId, - List> searchHits, @Nullable Aggregations aggregations) { - - Assert.notNull(searchHits, "searchHits must not be null"); - - this.totalHits = totalHits; - this.totalHitsRelation = totalHitsRelation; - this.maxScore = maxScore; - this.scrollId = scrollId; - this.searchHits = searchHits; - this.aggregations = aggregations; - } - - @SuppressWarnings("unchecked") - @Override - public Iterator> iterator() { - return (Iterator>) searchHits.iterator(); - } +public interface SearchHits extends Streamable> { - // region getter /** - * @return the number of total hits. - */ - public long getTotalHits() { - return totalHits; - } - - /** - * @return the relation for the total hits + * @return the aggregations. */ - public TotalHitsRelation getTotalHitsRelation() { - return totalHitsRelation; - } + @Nullable + Aggregations getAggregations(); /** * @return the maximum score */ - public float getMaxScore() { - return maxScore; - } + float getMaxScore(); /** - * @return the scroll id + * @param index position in List. + * @return the {@link SearchHit} at position {index} + * @throws IndexOutOfBoundsException on invalid index */ - @Nullable - public String getScrollId() { - return scrollId; - } + SearchHit getSearchHit(int index); /** * @return the contained {@link SearchHit}s. */ - public List> getSearchHits() { - return Collections.unmodifiableList(searchHits); - } - // endregion + List> getSearchHits(); - // region SearchHit access /** - * @param index position in List. - * @return the {@link SearchHit} at position {index} - * @throws IndexOutOfBoundsException on invalid index + * @return the number of total hits. */ - public SearchHit getSearchHit(int index) { - return searchHits.get(index); - } - // endregion + long getTotalHits(); - @Override - public String toString() { - return "SearchHits{" + // - "totalHits=" + totalHits + // - ", totalHitsRelation=" + totalHitsRelation + // - ", maxScore=" + maxScore + // - ", scrollId='" + scrollId + '\'' + // - ", searchHits={" + searchHits.size() + " elements}" + // - ", aggregations=" + aggregations + // - '}'; - } + /** + * @return the relation for the total hits + */ + TotalHitsRelation getTotalHitsRelation(); - // region aggregations /** * @return true if aggregations are available */ - public boolean hasAggregations() { - return aggregations != null; + default boolean hasAggregations() { + return getAggregations() != null; } /** - * @return the aggregations. + * @return whether the {@link SearchHits} has search hits. */ - @Nullable - public Aggregations getAggregations() { - return aggregations; + default boolean hasSearchHits() { + return !getSearchHits().isEmpty(); } - // endregion /** - * Enum to represent the relation that Elasticsearch returns for the totalHits value {@see Ekasticsearch - * docs} + * @return an iterator for {@link SearchHit} */ - public enum TotalHitsRelation { - EQUAL_TO, GREATER_THAN_OR_EQUAL_TO + default Iterator> iterator() { + return getSearchHits().iterator(); } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java new file mode 100644 index 000000000..e8bf45452 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsImpl.java @@ -0,0 +1,117 @@ +/* + * Copyright 2019-2020 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; + +import java.util.Collections; +import java.util.List; + +import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Basic implementation of {@link SearchScrollHits} + * + * @param the result data class. + * @author Peter-Josef Meisch + * @author Sascha Woo + * @since 4.0 + */ +public class SearchHitsImpl implements SearchScrollHits { + + private final long totalHits; + private final TotalHitsRelation totalHitsRelation; + private final float maxScore; + private final String scrollId; + private final List> searchHits; + private final Aggregations aggregations; + + /** + * @param totalHits the number of total hits for the search + * @param totalHitsRelation the relation {@see TotalHitsRelation}, must not be {@literal null} + * @param maxScore the maximum score + * @param scrollId the scroll id if available + * @param searchHits must not be {@literal null} + * @param aggregations the aggregations if available + */ + public SearchHitsImpl(long totalHits, TotalHitsRelation totalHitsRelation, float maxScore, @Nullable String scrollId, + List> searchHits, @Nullable Aggregations aggregations) { + + Assert.notNull(searchHits, "searchHits must not be null"); + + this.totalHits = totalHits; + this.totalHitsRelation = totalHitsRelation; + this.maxScore = maxScore; + this.scrollId = scrollId; + this.searchHits = searchHits; + this.aggregations = aggregations; + } + + // region getter + @Override + public long getTotalHits() { + return totalHits; + } + + @Override + public TotalHitsRelation getTotalHitsRelation() { + return totalHitsRelation; + } + + @Override + public float getMaxScore() { + return maxScore; + } + + @Override + @Nullable + public String getScrollId() { + return scrollId; + } + + @Override + public List> getSearchHits() { + return Collections.unmodifiableList(searchHits); + } + // endregion + + // region SearchHit access + @Override + public SearchHit getSearchHit(int index) { + return searchHits.get(index); + } + // endregion + + @Override + public String toString() { + return "SearchHits{" + // + "totalHits=" + totalHits + // + ", totalHitsRelation=" + totalHitsRelation + // + ", maxScore=" + maxScore + // + ", scrollId='" + scrollId + '\'' + // + ", searchHits={" + searchHits.size() + " elements}" + // + ", aggregations=" + aggregations + // + '}'; + } + + // region aggregations + @Override + @Nullable + public Aggregations getAggregations() { + return aggregations; + } + // endregion +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsIterator.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsIterator.java new file mode 100644 index 000000000..a5045f4be --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitsIterator.java @@ -0,0 +1,60 @@ +/* + * Copyright 2020 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; + +import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; + +/** + * A {@link SearchHitsIterator} encapsulates {@link SearchHit} results that can be wrapped in a Java 8 + * {@link java.util.stream.Stream}. + * + * @author Sascha Woo + * @param + * @since 4.0 + */ +public interface SearchHitsIterator extends CloseableIterator> { + + /** + * @return the aggregations. + */ + @Nullable + Aggregations getAggregations(); + + /** + * @return the maximum score + */ + float getMaxScore(); + + /** + * @return the number of total hits. + */ + long getTotalHits(); + + /** + * @return the relation for the total hits + */ + TotalHitsRelation getTotalHitsRelation(); + + /** + * @return true if aggregations are available + */ + default boolean hasAggregations() { + return getAggregations() != null; + } + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 9346d7e59..4f229be16 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -36,6 +36,7 @@ * APIs. * * @author Peter-Josef Meisch + * @author Sascha Woo * @since 4.0 */ public interface SearchOperations { @@ -155,8 +156,9 @@ default List> queryForPage(List queries, List * @param query the query to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against - * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * - * error. + * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed. The + * try-with-resources construct should be used to ensure that the close method is invoked after the operations + * are completed. * @deprecated since 4.0, use {@link #searchForStream(Query, Class, IndexCoordinates)}. */ @Deprecated @@ -237,7 +239,6 @@ default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class cla return (AggregatedPage) SearchHitSupport.unwrapSearchHits(aggregatedPage); } - // endregion /** @@ -340,27 +341,29 @@ default SearchHit searchOne(Query query, Class clazz, IndexCoordinates SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCoordinates index); /** - * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. + * Executes the given {@link Query} against elasticsearch and return result as {@link SearchHitsIterator}. *

* * @param element return type * @param query the query to execute * @param clazz the entity clazz used for property mapping and index name extraction - * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * - * error. + * @return a {@link SearchHitsIterator} that wraps an Elasticsearch scroll context that needs to be closed. The + * try-with-resources construct should be used to ensure that the close method is invoked after the operations + * are completed. */ - CloseableIterator> searchForStream(Query query, Class clazz); + SearchHitsIterator searchForStream(Query query, Class clazz); /** - * Executes the given {@link Query} against elasticsearch and return result as {@link CloseableIterator}. + * Executes the given {@link Query} against elasticsearch and return result as {@link SearchHitsIterator}. *

* * @param element return type * @param query the query to execute * @param clazz the entity clazz used for property mapping * @param index the index to run the query against - * @return a {@link CloseableIterator} that wraps an Elasticsearch scroll context that needs to be closed in case of * - * error. + * @return a {@link SearchHitsIterator} that wraps an Elasticsearch scroll context that needs to be closed. The + * try-with-resources construct should be used to ensure that the close method is invoked after the operations + * are completed. */ - CloseableIterator> searchForStream(Query query, Class clazz, IndexCoordinates index); + SearchHitsIterator searchForStream(Query query, Class clazz, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchScrollHits.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchScrollHits.java new file mode 100644 index 000000000..cb7d07694 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchScrollHits.java @@ -0,0 +1,34 @@ +/* + * Copyright 2020 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; + +/** + * This interface is used to expose the current {@code scrollId} from the underlying scroll context. + *

+ * Internal use only. + * + * @author Sascha Woo + * @param + * @since 4.0 + */ +public interface SearchScrollHits extends SearchHits { + + /** + * @return the scroll id + */ + String getScrollId(); + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index 62104b839..77573c8f1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -20,7 +20,8 @@ import java.util.function.Consumer; import java.util.function.Function; -import org.springframework.data.util.CloseableIterator; +import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -33,27 +34,32 @@ abstract class StreamQueries { /** - * Stream query results using {@link ScrolledPage}. + * Stream query results using {@link SearchScrollHits}. * - * @param page the initial scrolled page. + * @param searchHits the initial hits * @param continueScrollFunction function to continue scrolling applies to the current scrollId. * @param clearScrollConsumer consumer to clear the scroll context by accepting the current scrollId. * @param - * @return the {@link CloseableIterator}. + * @return the {@link SearchHitsIterator}. */ - static CloseableIterator streamResults(ScrolledPage page, - Function> continueScrollFunction, Consumer clearScrollConsumer) { + static SearchHitsIterator streamResults(SearchScrollHits searchHits, + Function> continueScrollFunction, Consumer clearScrollConsumer) { - Assert.notNull(page, "page must not be null."); - Assert.notNull(page.getScrollId(), "scrollId must not be null."); + Assert.notNull(searchHits, "searchHits must not be null."); + Assert.notNull(searchHits.getScrollId(), "scrollId of searchHits must not be null."); Assert.notNull(continueScrollFunction, "continueScrollFunction must not be null."); Assert.notNull(clearScrollConsumer, "clearScrollConsumer must not be null."); - return new CloseableIterator() { + Aggregations aggregations = searchHits.getAggregations(); + float maxScore = searchHits.getMaxScore(); + long totalHits = searchHits.getTotalHits(); + TotalHitsRelation totalHitsRelation = searchHits.getTotalHitsRelation(); + + return new SearchHitsIterator() { // As we couldn't retrieve single result with scroll, store current hits. - private volatile Iterator scrollHits = page.iterator(); - private volatile String scrollId = page.getScrollId(); + private volatile Iterator> scrollHits = searchHits.iterator(); + private volatile String scrollId = searchHits.getScrollId(); private volatile boolean continueScroll = scrollHits.hasNext(); @Override @@ -67,6 +73,27 @@ public void close() { } } + @Override + @Nullable + public Aggregations getAggregations() { + return aggregations; + } + + @Override + public float getMaxScore() { + return maxScore; + } + + @Override + public long getTotalHits() { + return totalHits; + } + + @Override + public TotalHitsRelation getTotalHitsRelation() { + return totalHitsRelation; + } + @Override public boolean hasNext() { @@ -75,7 +102,7 @@ public boolean hasNext() { } if (!scrollHits.hasNext()) { - ScrolledPage nextPage = continueScrollFunction.apply(scrollId); + SearchScrollHits nextPage = continueScrollFunction.apply(scrollId); scrollHits = nextPage.iterator(); scrollId = nextPage.getScrollId(); continueScroll = scrollHits.hasNext(); @@ -85,7 +112,7 @@ public boolean hasNext() { } @Override - public T next() { + public SearchHit next() { if (hasNext()) { return scrollHits.next(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/TotalHitsRelation.java b/src/main/java/org/springframework/data/elasticsearch/core/TotalHitsRelation.java new file mode 100644 index 000000000..14f069de0 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/TotalHitsRelation.java @@ -0,0 +1,30 @@ +/* + * Copyright 2020 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; + +/** + * Enum to represent the relation that Elasticsearch returns for the totalHits value {@see Ekasticsearch + * docs} + * + * @author Peter-Josef Meisch + * @author Sascha Woo + * @since 4.0 + */ +public enum TotalHitsRelation { + EQUAL_TO, // + GREATER_THAN_OR_EQUAL_TO +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index d1666ee70..eeac39123 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -19,10 +19,9 @@ import java.util.stream.Collectors; import org.springframework.data.convert.EntityConverter; -import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; +import org.springframework.data.elasticsearch.core.SearchScrollHits; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -39,6 +38,7 @@ * @author Mohsin Husen * @author Christoph Strobl * @author Peter-Josef Meisch + * @author Sasch Woo */ public interface ElasticsearchConverter extends EntityConverter, ElasticsearchPersistentProperty, Object, Document> { @@ -89,6 +89,17 @@ default List mapDocuments(List documents, Class type) { * @since 4.0 */ SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse); + + /** + * builds a {@link SearchScrollHits} from a {@link SearchDocumentResponse}. + * + * @param the clazz of the type, must not be {@literal null}. + * @param type the type of the returned data, must not be {@literal null}. + * @param searchDocumentResponse the response to read from, must not be {@literal null}. + * @return a {@link SearchScrollHits} object + * @since 4.0 + */ + SearchScrollHits readScroll(Class type, SearchDocumentResponse searchDocumentResponse); /** * builds a {@link SearchHit} from a {@link SearchDocument}. @@ -101,9 +112,6 @@ default List mapDocuments(List documents, Class type) { */ SearchHit read(Class type, SearchDocument searchDocument); - AggregatedPage> mapResults(SearchDocumentResponse response, Class clazz, - @Nullable Pageable pageable); - // endregion // region write diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index cf791fce1..566bf765b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -38,13 +38,13 @@ import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; import org.springframework.data.convert.CustomConversions; -import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.ScriptedField; +import org.springframework.data.elasticsearch.core.SearchScrollHits; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; -import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; +import org.springframework.data.elasticsearch.core.SearchHitsImpl; +import org.springframework.data.elasticsearch.core.TotalHitsRelation; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -147,18 +147,31 @@ public void afterPropertiesSet() { // region read @Override - public AggregatedPage> mapResults(SearchDocumentResponse response, Class type, - @Nullable Pageable pageable) { + public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { + return readResponse(type, searchDocumentResponse); + } - List> results = response.getSearchDocuments().stream() // - .map(searchDocument -> read(type, searchDocument)) // - .collect(Collectors.toList()); + @Override + public SearchHit read(Class type, SearchDocument searchDocument) { + + Assert.notNull(type, "type must not be null"); + Assert.notNull(searchDocument, "searchDocument must not be null"); - return new AggregatedPageImpl<>(results, pageable, response); + String id = searchDocument.hasId() ? searchDocument.getId() : null; + float score = searchDocument.getScore(); + Object[] sortValues = searchDocument.getSortValues(); + Map> highlightFields = getHighlightsAndRemapFieldNames(type, searchDocument); + T content = mapDocument(searchDocument, type); + + return new SearchHit(id, score, sortValues, highlightFields, content); } @Override - public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { + public SearchScrollHits readScroll(Class type, SearchDocumentResponse searchDocumentResponse) { + return readResponse(type, searchDocumentResponse); + } + + private SearchHitsImpl readResponse(Class type, SearchDocumentResponse searchDocumentResponse) { Assert.notNull(type, "type must not be null"); Assert.notNull(searchDocumentResponse, "searchDocumentResponse must not be null"); @@ -170,25 +183,10 @@ public SearchHits read(Class type, SearchDocumentResponse searchDocume .map(searchDocument -> read(type, searchDocument)) // .collect(Collectors.toList()); Aggregations aggregations = searchDocumentResponse.getAggregations(); - SearchHits.TotalHitsRelation totalHitsRelation = SearchHits.TotalHitsRelation + TotalHitsRelation totalHitsRelation = TotalHitsRelation .valueOf(searchDocumentResponse.getTotalHitsRelation()); - return new SearchHits<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); - } - - @Override - public SearchHit read(Class type, SearchDocument searchDocument) { - - Assert.notNull(type, "type must not be null"); - Assert.notNull(searchDocument, "searchDocument must not be null"); - - String id = searchDocument.hasId() ? searchDocument.getId() : null; - float score = searchDocument.getScore(); - Object[] sortValues = searchDocument.getSortValues(); - Map> highlightFields = getHighlightsAndRemapFieldNames(type, searchDocument); - T content = mapDocument(searchDocument, type); - - return new SearchHit(id, score, sortValues, highlightFields, content); + return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); } @Nullable diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 4c2d7a541..4b8a631d4 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -28,17 +28,12 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.lang.Double; -import java.lang.Integer; -import java.lang.Long; -import java.lang.Object; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -290,7 +285,7 @@ public void shouldReturnSearchHitsForGivenSearchQuery() { // then assertThat(searchHits).isNotNull(); assertThat(searchHits.getTotalHits()).isEqualTo(1); - assertThat(searchHits.getTotalHitsRelation()).isEqualByComparingTo(SearchHits.TotalHitsRelation.EQUAL_TO); + assertThat(searchHits.getTotalHitsRelation()).isEqualByComparingTo(TotalHitsRelation.EQUAL_TO); } @Test // DATAES-595 @@ -1055,11 +1050,11 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, criteriaQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -1082,11 +1077,11 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -1109,12 +1104,12 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue criteriaQuery.addFields("message"); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1136,12 +1131,12 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withFields("message") .withQuery(matchAllQuery()).withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1163,12 +1158,12 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1190,12 +1185,12 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1217,12 +1212,12 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, criteriaQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1244,12 +1239,12 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); String scrollId = scroll.getScrollId(); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); } @@ -1529,16 +1524,16 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withIndicesOptions(IndicesOptions.lenientExpandOpen()).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations) + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations) .searchScrollStart(scrollTimeInMillis, searchQuery, SampleEntity.class, index); - List> entities = new ArrayList<>(scroll.getContent()); + List> entities = new ArrayList<>(scroll.getSearchHits()); - while (scroll.hasContent()) { + while (scroll.hasSearchHits()) { scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class); - entities.addAll(scroll.getContent()); + entities.addAll(scroll.getSearchHits()); } // then @@ -2431,11 +2426,11 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("message").contains("message")); criteriaQuery.setPageable(PageRequest.of(0, 10)); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, criteriaQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -2469,11 +2464,11 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("message", "message")) .withPageable(PageRequest.of(0, 10)).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -2502,11 +2497,11 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withPageable(PageRequest.of(0, 10)).withSourceFilter(sourceFilter).build(); - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -2549,11 +2544,11 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { .withSort(new FieldSortBuilder("message").order(SortOrder.DESC)).withPageable(PageRequest.of(0, 10)).build(); // when - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } @@ -2598,11 +2593,11 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { .build(); // when - ScrolledPage> scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, + SearchScrollHits scroll = ((AbstractElasticsearchTemplate) operations).searchScrollStart(1000, searchQuery, SampleEntity.class, index); List> sampleEntities = new ArrayList<>(); - while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); + while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, SampleEntity.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java index 0508ee488..5a481c510 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java @@ -19,12 +19,14 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import org.elasticsearch.search.aggregations.Aggregations; import org.junit.jupiter.api.Test; import org.springframework.data.domain.PageImpl; -import org.springframework.data.util.CloseableIterator; +import org.springframework.data.domain.Pageable; import org.springframework.lang.Nullable; /** @@ -36,42 +38,51 @@ public class StreamQueriesTest { public void shouldCallClearScrollOnIteratorClose() { // given - List results = new ArrayList<>(); - results.add("one"); + List> hits = new ArrayList<>(); + hits.add(new SearchHit(null, 0, null, null, "one")); - ScrolledPage page = new ScrolledPageImpl("1234", results); + SearchScrollHits searchHits = newSearchScrollHits(hits); AtomicBoolean clearScrollCalled = new AtomicBoolean(false); // when - CloseableIterator closeableIterator = StreamQueries.streamResults( // - page, // - scrollId -> new ScrolledPageImpl(scrollId, Collections.emptyList()), // + SearchHitsIterator iterator = StreamQueries.streamResults( // + searchHits, // + scrollId -> newSearchScrollHits(Collections.emptyList()), // scrollId -> clearScrollCalled.set(true)); - while (closeableIterator.hasNext()) { - closeableIterator.next(); + while (iterator.hasNext()) { + iterator.next(); } - closeableIterator.close(); + iterator.close(); // then assertThat(clearScrollCalled).isTrue(); } - private static class ScrolledPageImpl extends PageImpl implements ScrolledPage { + @Test // DATAES-766 + public void shouldReturnTotalHits() { - private String scrollId; + // given + List> hits = new ArrayList<>(); + hits.add(new SearchHit(null, 0, null, null, "one")); - public ScrolledPageImpl(String scrollId, List content) { - super(content); - this.scrollId = scrollId; - } + SearchScrollHits searchHits = newSearchScrollHits(hits); - @Override - @Nullable - public String getScrollId() { - return scrollId; - } + // when + SearchHitsIterator iterator = StreamQueries.streamResults( // + searchHits, // + scrollId -> newSearchScrollHits(Collections.emptyList()), // + scrollId -> { + }); + + // then + assertThat(iterator.getTotalHits()).isEqualTo(1); + + } + + private SearchScrollHits newSearchScrollHits(List> hits) { + return new SearchHitsImpl(hits.size(), TotalHitsRelation.EQUAL_TO, 0, "1234", hits, null); } } From f8630a09df74e2eb28e49f799cbbd90731519d91 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 23 Mar 2020 20:59:30 +0100 Subject: [PATCH 0094/1191] Dataes 768 add missing query parameters for an update query. Original PR: #410 --- .../elasticsearch/core/RequestFactory.java | 66 ++++++++++ .../elasticsearch/core/query/UpdateQuery.java | 121 +++++++++++++++++- .../core/ElasticsearchRestTemplateTests.java | 50 ++++++++ .../core/ElasticsearchTemplateTests.java | 4 + .../ElasticsearchTransportTemplateTests.java | 48 +++++++ 5 files changed, 287 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 32192d32f..73220fce2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -19,6 +19,7 @@ import static org.springframework.util.CollectionUtils.*; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,6 +37,7 @@ import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.Client; @@ -499,6 +501,38 @@ public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { updateRequest.fetchSource(query.getFetchSource()); } + if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { + List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() + : Collections.emptyList(); + List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() + : Collections.emptyList(); + updateRequest.fetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); + } + + if (query.getIfSeqNo() != null) { + updateRequest.setIfSeqNo(query.getIfSeqNo()); + } + + if (query.getIfPrimaryTerm() != null) { + updateRequest.setIfPrimaryTerm(query.getIfPrimaryTerm()); + } + + if (query.getRefresh() != null) { + updateRequest.setRefreshPolicy(query.getRefresh().name().toLowerCase()); + } + + if (query.getRetryOnConflict() != null) { + updateRequest.retryOnConflict(query.getRetryOnConflict()); + } + + if (query.getTimeout() != null) { + updateRequest.timeout(query.getTimeout()); + } + + if (query.getWaitForActiveShards() != null) { + updateRequest.waitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); + } + return updateRequest; } @@ -541,6 +575,38 @@ public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery q updateRequestBuilder.setFetchSource(query.getFetchSource()); } + if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { + List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() + : Collections.emptyList(); + List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() + : Collections.emptyList(); + updateRequestBuilder.setFetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); + } + + if (query.getIfSeqNo() != null) { + updateRequestBuilder.setIfSeqNo(query.getIfSeqNo()); + } + + if (query.getIfPrimaryTerm() != null) { + updateRequestBuilder.setIfPrimaryTerm(query.getIfPrimaryTerm()); + } + + if (query.getRefresh() != null) { + updateRequestBuilder.setRefreshPolicy(query.getRefresh().name().toLowerCase()); + } + + if (query.getRetryOnConflict() != null) { + updateRequestBuilder.setRetryOnConflict(query.getRetryOnConflict()); + } + + if (query.getTimeout() != null) { + updateRequestBuilder.setTimeout(query.getTimeout()); + } + + if (query.getWaitForActiveShards() != null) { + updateRequestBuilder.setWaitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); + } + return updateRequestBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java index a346bf344..ef68ea7da 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/UpdateQuery.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.query; +import java.util.List; import java.util.Map; import org.springframework.data.elasticsearch.core.document.Document; @@ -40,6 +41,14 @@ public class UpdateQuery { @Nullable private Boolean scriptedUpsert; @Nullable private Boolean docAsUpsert; @Nullable private Boolean fetchSource; + @Nullable private List fetchSourceIncludes; + @Nullable private List fetchSourceExcludes; + @Nullable private Integer ifSeqNo; + @Nullable private Integer ifPrimaryTerm; + @Nullable private Refresh refresh; + @Nullable private Integer retryOnConflict; + @Nullable String timeout; + @Nullable String waitForActiveShards; public static Builder builder(String id) { return new Builder(id); @@ -47,7 +56,11 @@ public static Builder builder(String id) { private UpdateQuery(String id, @Nullable String script, @Nullable Map params, @Nullable Document document, @Nullable Document upsert, @Nullable String lang, @Nullable String routing, - @Nullable Boolean scriptedUpsert, @Nullable Boolean docAsUpsert, @Nullable Boolean fetchSource) { + @Nullable Boolean scriptedUpsert, @Nullable Boolean docAsUpsert, @Nullable Boolean fetchSource, + @Nullable List fetchSourceIncludes, @Nullable List fetchSourceExcludes, @Nullable Integer ifSeqNo, + @Nullable Integer ifPrimaryTerm, @Nullable Refresh refresh, @Nullable Integer retryOnConflict, + @Nullable String timeout, @Nullable String waitForActiveShards) { + this.id = id; this.script = script; this.params = params; @@ -58,6 +71,14 @@ private UpdateQuery(String id, @Nullable String script, @Nullable Map getFetchSourceIncludes() { + return fetchSourceIncludes; + } + + @Nullable + public List getFetchSourceExcludes() { + return fetchSourceExcludes; + } + + @Nullable + public Integer getIfSeqNo() { + return ifSeqNo; + } + + @Nullable + public Integer getIfPrimaryTerm() { + return ifPrimaryTerm; + } + + @Nullable + public Refresh getRefresh() { + return refresh; + } + + @Nullable + public Integer getRetryOnConflict() { + return retryOnConflict; + } + + @Nullable + public String getTimeout() { + return timeout; + } + + @Nullable + public String getWaitForActiveShards() { + return waitForActiveShards; + } + public static final class Builder { private String id; @Nullable private String script = null; @@ -120,6 +181,14 @@ public static final class Builder { @Nullable private Boolean scriptedUpsert; @Nullable private Boolean docAsUpsert; @Nullable private Boolean fetchSource; + @Nullable private Integer ifSeqNo; + @Nullable private Integer ifPrimaryTerm; + @Nullable private Refresh refresh; + @Nullable private Integer retryOnConflict; + @Nullable private String timeout; + @Nullable String waitForActiveShards; + @Nullable private List fetchSourceIncludes; + @Nullable private List fetchSourceExcludes; private Builder(String id) { this.id = id; @@ -170,13 +239,61 @@ public Builder withFetchSource(Boolean fetchSource) { return this; } + public Builder withIfSeqNo(Integer ifSeqNo) { + this.ifSeqNo = ifSeqNo; + return this; + } + + public Builder withIfPrimaryTerm(Integer ifPrimaryTerm) { + this.ifPrimaryTerm = ifPrimaryTerm; + return this; + } + + public Builder withRefresh(Refresh refresh) { + this.refresh = refresh; + return this; + } + + public Builder withRetryOnConflict(Integer retryOnConflict) { + this.retryOnConflict = retryOnConflict; + return this; + } + + public Builder withTimeout(String timeout) { + this.timeout = timeout; + return this; + } + + public Builder withWaitForActiveShards(String waitForActiveShards) { + this.waitForActiveShards = waitForActiveShards; + return this; + } + + public Builder withFetchSourceIncludes(List fetchSourceIncludes) { + this.fetchSourceIncludes = fetchSourceIncludes; + return this; + } + + public Builder withFetchSourceExcludes(List fetchSourceExcludes) { + this.fetchSourceExcludes = fetchSourceExcludes; + return this; + } + public UpdateQuery build() { if (script == null && document == null) { throw new IllegalArgumentException("either script or document must be set"); } return new UpdateQuery(id, script, params, document, upsert, lang, routing, scriptedUpsert, docAsUpsert, - fetchSource); + fetchSource, fetchSourceIncludes, fetchSourceExcludes, ifSeqNo, ifPrimaryTerm, refresh, retryOnConflict, + timeout, waitForActiveShards); } } + + /* + * names will be lowercased on building the query. + */ + public enum Refresh { + True, False, Wait_For + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index d3654b964..367cf8c42 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -21,12 +21,23 @@ import lombok.Builder; import lombok.Data; +import lombok.val; +import java.lang.Object; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.elasticsearch.action.support.ActiveShardCount; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.common.unit.TimeValue; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -69,4 +80,43 @@ static class SampleEntity { @Id private String id; @Field(type = Text, store = true, fielddata = true) private String type; } + + @Test // DATAES-768 + void shouldUseAllOptionsFromUpdateQuery() { + Map doc = new HashMap<>(); + doc.put("id", "1"); + doc.put("message", "test"); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .from(doc); + UpdateQuery updateQuery = UpdateQuery.builder("1") // + .withDocument(document) // + .withIfSeqNo(42) // + .withIfPrimaryTerm(13) // + .withScript("script")// + .withLang("lang") // + .withRefresh(UpdateQuery.Refresh.Wait_For) // + .withRetryOnConflict(7) // + .withTimeout("4711s") // + .withWaitForActiveShards("all") // + .withFetchSourceIncludes(Collections.singletonList("incl")) // + .withFetchSourceExcludes(Collections.singletonList("excl")) // + .build(); + + UpdateRequest request = getRequestFactory().updateRequest(updateQuery, IndexCoordinates.of("index")); + + assertThat(request).isNotNull(); + assertThat(request.ifSeqNo()).isEqualTo(42); + assertThat(request.ifPrimaryTerm()).isEqualTo(13); + assertThat(request.script().getIdOrCode()).isEqualTo("script"); + assertThat(request.script().getLang()).isEqualTo("lang"); + assertThat(request.getRefreshPolicy()).isEqualByComparingTo(WriteRequest.RefreshPolicy.WAIT_UNTIL); + assertThat(request.retryOnConflict()).isEqualTo(7); + assertThat(request.timeout()).isEqualByComparingTo(TimeValue.parseTimeValue("4711s", "test")); + assertThat(request.waitForActiveShards()).isEqualTo(ActiveShardCount.ALL); + val fetchSourceContext = request.fetchSource(); + assertThat(fetchSourceContext).isNotNull(); + assertThat(fetchSourceContext.includes()).containsExactlyInAnyOrder("incl"); + assertThat(fetchSourceContext.excludes()).containsExactlyInAnyOrder("excl"); + } + } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 4b8a631d4..fa83206ba 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -28,6 +28,10 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import java.lang.Double; +import java.lang.Integer; +import java.lang.Long; +import java.lang.Object; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 5c2e2469f..6f3126627 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -20,9 +20,19 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*; import lombok.Data; +import lombok.val; + +import java.lang.Object; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.support.ActiveShardCount; +import org.elasticsearch.action.support.WriteRequest; +import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.Client; +import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.engine.DocumentMissingException; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -83,6 +93,44 @@ public long getOffset() { assertThat(searchRequestBuilder.request().source().from()).isEqualTo(30); } + @Test // DATAES-768 + void shouldUseAllOptionsFromUpdateQuery() { + Map doc = new HashMap<>(); + doc.put("id", "1"); + doc.put("message", "test"); + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .from(doc); + UpdateQuery updateQuery = UpdateQuery.builder("1") // + .withDocument(document) // + .withIfSeqNo(42) // + .withIfPrimaryTerm(13) // + .withScript("script")// + .withLang("lang") // + .withRefresh(UpdateQuery.Refresh.Wait_For) // + .withRetryOnConflict(7) // + .withTimeout("4711s") // + .withWaitForActiveShards("all").withFetchSourceIncludes(Collections.singletonList("incl")) // + .withFetchSourceExcludes(Collections.singletonList("excl")) // + .build(); + + UpdateRequestBuilder request = getRequestFactory().updateRequestBuilderFor(client, updateQuery, + IndexCoordinates.of("index")); + + assertThat(request).isNotNull(); + assertThat(request.request().ifSeqNo()).isEqualTo(42); + assertThat(request.request().ifPrimaryTerm()).isEqualTo(13); + assertThat(request.request().script().getIdOrCode()).isEqualTo("script"); + assertThat(request.request().script().getLang()).isEqualTo("lang"); + assertThat(request.request().getRefreshPolicy()).isEqualByComparingTo(WriteRequest.RefreshPolicy.WAIT_UNTIL); + assertThat(request.request().retryOnConflict()).isEqualTo(7); + assertThat(request.request().timeout()).isEqualByComparingTo(TimeValue.parseTimeValue("4711s", "test")); + assertThat(request.request().waitForActiveShards()).isEqualTo(ActiveShardCount.ALL); + val fetchSourceContext = request.request().fetchSource(); + assertThat(fetchSourceContext).isNotNull(); + assertThat(fetchSourceContext.includes()).containsExactlyInAnyOrder("incl"); + assertThat(fetchSourceContext.excludes()).containsExactlyInAnyOrder("excl"); + } + @Data @Document(indexName = "test-index-sample-core-transport-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { From fd711093b177af3d365bb057cd374f20d7da5d9e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 25 Mar 2020 10:45:34 +0100 Subject: [PATCH 0095/1191] DATAES-756 - Updated changelog. --- src/main/resources/changelog.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index fbed7803f..2ee223c66 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,16 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.6.RELEASE (2020-03-25) +--------------------------------------------- +* DATAES-769 - Upgrade to Elasticsearch 6.8.7. +* DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents. +* DATAES-764 - StreamQueries#streamResults does not clear scroll context when finished. +* DATAES-763 - Allow map properties in entity with null values. +* DATAES-758 - fix documentation for @Query annotation. +* DATAES-756 - Release 3.2.6 (Moore SR6). + + Changes in version 4.0.0.M4 (2020-03-11) ---------------------------------------- * DATAES-759 - Update to Elasticsearch 7.6.1. @@ -1046,3 +1056,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 21406a5e7dbc96a334e0a9259f85ec21df982fb8 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 27 Mar 2020 17:19:56 +0100 Subject: [PATCH 0096/1191] DATAES-766 - Replace CloseableIterator with SearchHitsIterator in stream operations. Original PR: #412 fix documentation --- .../reference/elasticsearch-misc.adoc | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index 1cba145e2..41527cbed 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -27,10 +27,8 @@ Page sampleEntities = operations.searchForPage(searchQuery, Sample [[elasticsearch.scroll]] == Using Scroll For Big Result Set -Elasticsearch has a scroll API for getting big result set in chunks. `ElasticsearchOperations` has startScroll and continueScroll methods that can be used as below. +Elasticsearch has a scroll API for getting big result set in chunks. This is internally used by Spring Data Elasticsearch to provide the implementations of the ` SearchHitsIterator SearchOperations.searchForStream(Query query, Class clazz, IndexCoordinates index)` method. -.Using startScroll and continueScroll -==== [source,java] ---- IndexCoordinates index = IndexCoordinates.of("sample-index"); @@ -43,25 +41,23 @@ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withPageable(PageRequest.of(0, 10)) .build(); -ScrolledPage scroll = operations.startScroll(1000, searchQuery, SampleEntity.class, index); +SearchHitsIterator stream = elasticsearchTemplate.searchForStream(searchQuery, SampleEntity.class, index); -String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); -while (scroll.hasContent()) { - sampleEntities.addAll(scroll.getContent()); - scrollId = scroll.getScrollId(); - scroll = operations.continueScroll(scrollId, 1000, SampleEntity.class); +while (stream.hasNext()) { + sampleEntities.add(stream.next()); } -operations.clearScroll(scrollId); + +stream.close(); ---- -==== -`ElasticsearchOperations` additionally has the stream method which wraps the scan and scroll operations into a CloseableIterator. +There are no methods in the `SearchOperations` API to access the scroll id, if it should be necessary to access this, the following methods of the `ElasticsearchRestTemplate` can be used: -.Using stream -==== [source,java] ---- + +@Autowired ElasticsearchRestTemplate template; + IndexCoordinates index = IndexCoordinates.of("sample-index"); SearchQuery searchQuery = new NativeSearchQueryBuilder() @@ -72,14 +68,17 @@ SearchQuery searchQuery = new NativeSearchQueryBuilder() .withPageable(PageRequest.of(0, 10)) .build(); -CloseableIterator stream = elasticsearchTemplate.stream(searchQuery, SampleEntity.class, index); +SearchScrollHits scroll = template.searchScrollStart(1000, searchQuery, SampleEntity.class, index); +String scrollId = scroll.getScrollId(); List sampleEntities = new ArrayList<>(); -while (stream.hasNext()) { - sampleEntities.add(stream.next()); +while (scroll.hasSearchHits()) { + sampleEntities.addAll(scroll.getSearchHits()); + scrollId = scroll.getScrollId(); + scroll = template.searchScrollContinue(scrollId, 1000, SampleEntity.class); } +template.searchScrollClear(scrollId); ---- -==== [[elasticsearch.misc.sorts]] == Sort options From 2ec61ab4fff94383fe707759de9f04ad3e188545 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 28 Mar 2020 11:09:06 +0100 Subject: [PATCH 0097/1191] DATAES-435 - Report version mismatch if used with older ElasticSearch-version. Original PR: #413 --- pom.xml | 17 ++++ .../core/AbstractElasticsearchTemplate.java | 20 +++- .../core/ElasticsearchRestTemplate.java | 13 ++- .../core/ElasticsearchTemplate.java | 22 +++++ .../core/ReactiveElasticsearchTemplate.java | 20 ++++ .../elasticsearch/support/VersionInfo.java | 91 +++++++++++++++++++ src/main/resources/versions.properties | 2 + src/test/resources/logback.xml | 1 + 8 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java create mode 100644 src/main/resources/versions.properties diff --git a/pom.xml b/pom.xml index 3119d320a..44d519592 100644 --- a/pom.xml +++ b/pom.xml @@ -292,6 +292,23 @@ + + + src/main/resources + true + + **/versions.properties + + + + src/main/resources + false + + **/versions.properties + + + + INDICES - - static Function indexExists() { - return RequestConverters::indexExists; - } - - static Function indexDelete() { - return RequestConverters::indexDelete; - } - - static Function indexCreate() { - return RequestConverters::indexCreate; - } - - static Function indexOpen() { - return RequestConverters::indexOpen; - } - - static Function indexClose() { - return RequestConverters::indexClose; - } - - static Function indexRefresh() { - return RequestConverters::indexRefresh; - } - - static Function putMapping() { - return RequestConverters::putMapping; - } - - static Function flushIndex() { - return RequestConverters::flushIndex; - } - - static Function count() { - return RequestConverters::count; - } - - } - /** * Reactive client {@link ReactiveElasticsearchClient.Status} implementation. * diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java new file mode 100644 index 000000000..032e93be9 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java @@ -0,0 +1,8 @@ +package org.springframework.data.elasticsearch.client.reactive; + +/** + * @author Roman Puchkovskiy + * @since 4.0 + */ +class DefaultRequestCreator implements RequestCreator { +} diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java index 4bd0c921b..b62fa1eb8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java @@ -24,6 +24,7 @@ * * @author Christoph Strobl * @author Mark Paluch + * @author Roman Puchkovskiy * @since 3.2 */ public final class ReactiveRestClients { @@ -33,6 +34,8 @@ private ReactiveRestClients() {} /** * Start here to create a new client tailored to your needs. * + * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; + * must not be {@literal null}. * @return new instance of {@link ReactiveElasticsearchClient}. */ public static ReactiveElasticsearchClient create(ClientConfiguration clientConfiguration) { @@ -41,4 +44,21 @@ public static ReactiveElasticsearchClient create(ClientConfiguration clientConfi return DefaultReactiveElasticsearchClient.create(clientConfiguration); } + + /** + * Start here to create a new client tailored to your needs. + * + * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; + * must not be {@literal null}. + * @param requestCreator request creator to use in the client; must not be {@literal null}. + * @return new instance of {@link ReactiveElasticsearchClient}. + */ + public static ReactiveElasticsearchClient create(ClientConfiguration clientConfiguration, + RequestCreator requestCreator) { + + Assert.notNull(clientConfiguration, "ClientConfiguration must not be null!"); + Assert.notNull(requestCreator, "RequestCreator must not be null!"); + + return DefaultReactiveElasticsearchClient.create(clientConfiguration, requestCreator); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java new file mode 100644 index 000000000..a37343dc3 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java @@ -0,0 +1,134 @@ +package org.springframework.data.elasticsearch.client.reactive; + +import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.flush.FlushRequest; +import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; +import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; +import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.MultiGetRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.main.MainRequest; +import org.elasticsearch.action.search.ClearScrollRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchScrollRequest; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.client.Request; +import org.elasticsearch.client.core.CountRequest; +import org.elasticsearch.index.reindex.DeleteByQueryRequest; +import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.client.util.RequestConverters; + +import java.io.IOException; +import java.util.function.Function; + +/** + * @author Roman Puchkovskiy + * @since 4.0 + */ +public interface RequestCreator { + + default Function search() { + return RequestConverters::search; + } + + default Function scroll() { + return RequestConverters::searchScroll; + } + + default Function clearScroll() { + return RequestConverters::clearScroll; + } + + default Function index() { + return RequestConverters::index; + } + + default Function get() { + return RequestConverters::get; + } + + default Function ping() { + return (request) -> RequestConverters.ping(); + } + + default Function info() { + return (request) -> RequestConverters.info(); + } + + default Function multiGet() { + return RequestConverters::multiGet; + } + + default Function exists() { + return RequestConverters::exists; + } + + default Function update() { + return RequestConverters::update; + } + + default Function delete() { + return RequestConverters::delete; + } + + default Function deleteByQuery() { + return RequestConverters::deleteByQuery; + } + + default Function bulk() { + + return request -> { + + try { + return RequestConverters.bulk(request); + } catch (IOException e) { + throw new ElasticsearchException("Could not parse request", e); + } + }; + } + + // --> INDICES + + default Function indexExists() { + return RequestConverters::indexExists; + } + + default Function indexDelete() { + return RequestConverters::indexDelete; + } + + default Function indexCreate() { + return RequestConverters::indexCreate; + } + + default Function indexOpen() { + return RequestConverters::indexOpen; + } + + default Function indexClose() { + return RequestConverters::indexClose; + } + + default Function indexRefresh() { + return RequestConverters::indexRefresh; + } + + default Function putMapping() { + return RequestConverters::putMapping; + } + + default Function flushIndex() { + return RequestConverters::flushIndex; + } + + default Function count() { + return RequestConverters::count; + } + +} From a7cdfb84b0a44e4ef5e45b79ebf46f333a6f4c75 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 29 Mar 2020 19:09:53 +0200 Subject: [PATCH 0099/1191] DATAES-653 - Polishing. --- .../reactive/DefaultReactiveElasticsearchClient.java | 2 +- .../client/reactive/DefaultRequestCreator.java | 3 +-- .../client/reactive/ReactiveRestClients.java | 8 ++++---- .../elasticsearch/client/reactive/RequestCreator.java | 6 +++--- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 941659b7f..6ac72da1b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -133,7 +133,7 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearchClient, Indices { private final HostProvider hostProvider; - + private final RequestCreator requestCreator; /** diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java index 032e93be9..b5d5c7097 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultRequestCreator.java @@ -4,5 +4,4 @@ * @author Roman Puchkovskiy * @since 4.0 */ -class DefaultRequestCreator implements RequestCreator { -} +class DefaultRequestCreator implements RequestCreator {} diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java index b62fa1eb8..756cc0096 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveRestClients.java @@ -34,8 +34,8 @@ private ReactiveRestClients() {} /** * Start here to create a new client tailored to your needs. * - * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; - * must not be {@literal null}. + * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; must not + * be {@literal null}. * @return new instance of {@link ReactiveElasticsearchClient}. */ public static ReactiveElasticsearchClient create(ClientConfiguration clientConfiguration) { @@ -48,8 +48,8 @@ public static ReactiveElasticsearchClient create(ClientConfiguration clientConfi /** * Start here to create a new client tailored to your needs. * - * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; - * must not be {@literal null}. + * @param clientConfiguration client configuration to use for building {@link ReactiveElasticsearchClient}; must not + * be {@literal null}. * @param requestCreator request creator to use in the client; must not be {@literal null}. * @return new instance of {@link ReactiveElasticsearchClient}. */ diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java index a37343dc3..0c5e13e28 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java @@ -1,5 +1,8 @@ package org.springframework.data.elasticsearch.client.reactive; +import java.io.IOException; +import java.util.function.Function; + import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -24,9 +27,6 @@ import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.client.util.RequestConverters; -import java.io.IOException; -import java.util.function.Function; - /** * @author Roman Puchkovskiy * @since 4.0 From c73d1973bc7690d2d0ca0c10648e6bf6c1165eaf Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Sun, 29 Mar 2020 21:50:56 +0400 Subject: [PATCH 0100/1191] DATAES-771 - Add after-save entity callbacks support. Original PR: #414 --- .../core/AbstractElasticsearchTemplate.java | 46 ++- .../core/ElasticsearchRestTemplate.java | 8 +- .../core/ElasticsearchTemplate.java | 11 +- .../core/ReactiveElasticsearchTemplate.java | 18 +- .../core/event/AfterSaveCallback.java | 39 +++ .../core/event/ReactiveAfterSaveCallback.java | 40 +++ ...lasticsearchRestTemplateCallbackTests.java | 276 +++++++++++++++++ ...csearchTransportTemplateCallbackTests.java | 288 ++++++++++++++++++ ...iveElasticsearchTemplateCallbackTests.java | 229 ++++++++++++++ 9 files changed, 944 insertions(+), 11 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index b88caee93..844190f08 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -22,6 +22,7 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; +import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; @@ -45,6 +46,7 @@ * * @author Sascha Woo * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { @@ -117,8 +119,13 @@ public T save(T entity, IndexCoordinates index) { Assert.notNull(entity, "entity must not be null"); Assert.notNull(index, "index must not be null"); - index(getIndexQuery(entity), index); - return entity; + IndexQuery query = getIndexQuery(entity); + index(query, index); + + // suppressing because it's either entity itself or something of a correct type returned by an entity callback + @SuppressWarnings("unchecked") + T castResult = (T) query.getObject(); + return castResult; } @Override @@ -151,7 +158,10 @@ public Iterable save(Iterable entities, IndexCoordinates index) { }); } - return entities; + return indexQueries.stream() + .map(IndexQuery::getObject) + .map(entity -> (T) entity) + .collect(Collectors.toList()); } @Override @@ -455,11 +465,39 @@ protected void maybeCallbackBeforeConvertWithQuery(Object query) { } // this can be called with either a List or a List; these query classes - // don't have a common bas class, therefore the List argument + // don't have a common base class, therefore the List argument protected void maybeCallbackBeforeConvertWithQueries(List queries) { queries.forEach(this::maybeCallbackBeforeConvertWithQuery); } + protected T maybeCallbackAfterSave(T entity) { + + if (entityCallbacks != null) { + return entityCallbacks.callback(AfterSaveCallback.class, entity); + } + + return entity; + } + + protected void maybeCallbackAfterSaveWithQuery(Object query) { + + if (query instanceof IndexQuery) { + IndexQuery indexQuery = (IndexQuery) query; + Object queryObject = indexQuery.getObject(); + + if (queryObject != null) { + queryObject = maybeCallbackAfterSave(queryObject); + indexQuery.setObject(queryObject); + } + } + } + + // this can be called with either a List or a List; these query classes + // don't have a common base class, therefore the List argument + protected void maybeCallbackAfterSaveWithQueries(List queries) { + queries.forEach(this::maybeCallbackAfterSaveWithQuery); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index aa9bfd710..114f1f99a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -145,6 +145,9 @@ public String index(IndexQuery query, IndexCoordinates index) { if (queryObject != null) { setPersistentEntityId(queryObject, documentId); } + + maybeCallbackAfterSaveWithQuery(query); + return documentId; } @@ -226,7 +229,10 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { maybeCallbackBeforeConvertWithQueries(queries); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); - return checkForBulkOperationFailure(execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); + List ids = checkForBulkOperationFailure(execute( + client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); + maybeCallbackAfterSaveWithQueries(queries); + return ids; } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 4a13fa7bf..17a117d46 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -31,14 +31,12 @@ import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.action.search.SearchResponse; -import org.elasticsearch.action.search.SearchScrollRequestBuilder; import org.elasticsearch.action.update.UpdateRequestBuilder; import org.elasticsearch.client.Client; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -79,6 +77,7 @@ * @author Martin Choraine * @author Farid Azaza * @author Gyula Attila Csorogi + * @author Roman Puchkovskiy * @deprecated as of 4.0 */ @Deprecated @@ -153,6 +152,8 @@ public String index(IndexQuery query, IndexCoordinates index) { setPersistentEntityId(queryObject, documentId); } + maybeCallbackAfterSaveWithQuery(query); + return documentId; } @@ -188,7 +189,11 @@ public List bulkIndex(List queries, BulkOptions bulkOptions, Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - return doBulkOperation(queries, bulkOptions, index); + List ids = doBulkOperation(queries, bulkOptions, index); + + maybeCallbackAfterSaveWithQueries(queries); + + return ids; } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 7588f29df..ad9d9335f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -70,6 +70,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocument; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; @@ -97,6 +98,7 @@ * @author Peter-Josef Meisch * @author Mathias Teier * @author Aleksei Arsenev + * @author Roman Puchkovskiy * @since 3.2 */ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations, ApplicationContextAware { @@ -185,7 +187,8 @@ public Mono save(T entity, IndexCoordinates index) { return doIndex(entity, adaptableEntity, index) // .map(it -> { return adaptableEntity.populateIdIfNecessary(it.getId()); - }); + }) + .flatMap(this::maybeCallAfterSave); } @Override @@ -213,11 +216,11 @@ public Flux saveAll(Mono> entities, Ind .map(e -> getIndexQuery(e.getBean(), e)) // .collect(Collectors.toList()); return doBulkOperation(indexRequests, BulkOptions.defaultOptions(), index) // - .map(bulkItemResponse -> { + .flatMap(bulkItemResponse -> { AdaptibleEntity mappedEntity = iterator.next(); mappedEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); - return mappedEntity.getBean(); + return maybeCallAfterSave(mappedEntity.getBean()); }); }); } @@ -882,5 +885,14 @@ protected Mono maybeCallBeforeConvert(T entity) { return Mono.just(entity); } + + protected Mono maybeCallAfterSave(T entity) { + + if (null != entityCallbacks) { + return entityCallbacks.callback(ReactiveAfterSaveCallback.class, entity); + } + + return Mono.just(entity); + } // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java new file mode 100644 index 000000000..0ad8e1c3b --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java @@ -0,0 +1,39 @@ +/* + * Copyright 2020 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.event; + +import org.springframework.data.mapping.callback.EntityCallback; +import org.springframework.data.mapping.callback.EntityCallbacks; + +/** + * Entity callback triggered after save of an entity. + * + * @author Roman Puchkovskiy + * @since 4.0 + * @see EntityCallbacks + */ +@FunctionalInterface +public interface AfterSaveCallback extends EntityCallback { + + /** + * Entity callback method invoked after a domain object is saved. Can return either the same or a modified + * instance of the domain object. + * + * @param entity the domain object that was saved. + * @return the domain object that was persisted. + */ + T onAfterSave(T entity); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java new file mode 100644 index 000000000..561de46fd --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java @@ -0,0 +1,40 @@ +/* + * Copyright 2020 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.event; + +import org.reactivestreams.Publisher; +import org.springframework.data.mapping.callback.EntityCallback; +import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; + +/** + * Entity callback triggered after save of an entity. + * + * @author Roman Puchkovskiy + * @since 4.0 + * @see ReactiveEntityCallbacks + */ +@FunctionalInterface +public interface ReactiveAfterSaveCallback extends EntityCallback { + + /** + * Entity callback method invoked after a domain object is saved. Can return either the same or a modified + * instance of the domain object. + * + * @param entity the domain object that was saved. + * @return a {@link Publisher} emitting the domain object to be returned to the caller. + */ + Publisher onAfterSave(T entity); +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java new file mode 100644 index 000000000..0edb8ad51 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java @@ -0,0 +1,276 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.mapping.callback.EntityCallbacks; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * @author Roman Puchkovskiy + */ +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ElasticsearchRestTemplateCallbackTests { + + private ElasticsearchRestTemplate template; + + @Mock + private RestHighLevelClient client; + + @Mock + private IndexResponse indexResponse; + @Mock + private BulkResponse bulkResponse; + @Mock + private BulkItemResponse bulkItemResponse; + + @BeforeEach + public void setUp() throws Exception { + template = new ElasticsearchRestTemplate(client); + + doReturn(indexResponse).when(client).index(any(IndexRequest.class), any(RequestOptions.class)); + doReturn("response-id").when(indexResponse).getId(); + + doReturn(bulkResponse).when(client).bulk(any(BulkRequest.class), any(RequestOptions.class)); + doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn("response-id").when(bulkItemResponse).getId(); + } + + @Test // DATAES-771 + void saveOneShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity, IndexCoordinates.of("index")); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveArrayShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(entity1, entity2); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2)); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void indexShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + IndexQuery indexQuery = indexQueryForEntity(entity); + template.index(indexQuery, IndexCoordinates.of("index")); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + Person newPerson = (Person) indexQuery.getObject(); + assertThat(newPerson.id).isEqualTo("after-save"); + } + + private IndexQuery indexQueryForEntity(Person entity) { + IndexQuery indexQuery = new IndexQuery(); + indexQuery.setObject(entity); + return indexQuery; + } + + @Test // DATAES-771 + void bulkIndexShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + static class Person { + + @Id String id; + String firstname; + } + + static class ValueCapturingEntityCallback { + + private final List values = new ArrayList<>(1); + + protected void capture(T value) { + values.add(value); + } + + public List getValues() { + return values; + } + + @Nullable + public T getValue() { + return CollectionUtils.lastElement(values); + } + + } + + static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback + implements AfterSaveCallback { + + @Override + public Person onAfterSave(Person entity) { + + capture(entity); + return new Person() { + { + id = "after-save"; + firstname = entity.firstname; + } + }; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java new file mode 100644 index 000000000..b04c1e7cf --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java @@ -0,0 +1,288 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.elasticsearch.action.ActionFuture; +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequestBuilder; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.client.Client; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.mapping.callback.EntityCallbacks; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * @author Roman Puchkovskiy + */ +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ElasticsearchTransportTemplateCallbackTests { + + private ElasticsearchTemplate template; + + @Mock + private Client client; + + @Mock + private IndexRequestBuilder indexRequestBuilder; + @Mock + private ActionFuture indexResponseActionFuture; + @Mock + private IndexResponse indexResponse; + @Mock + private BulkRequestBuilder bulkRequestBuilder; + @Mock + private ActionFuture bulkResponseActionFuture; + @Mock + private BulkResponse bulkResponse; + @Mock + private BulkItemResponse bulkItemResponse; + + @BeforeEach + public void setUp() { + template = new ElasticsearchTemplate(client); + + when(client.prepareIndex(anyString(), anyString(), anyString())).thenReturn(indexRequestBuilder); + doReturn(indexResponseActionFuture).when(indexRequestBuilder).execute(); + when(indexResponseActionFuture.actionGet()).thenReturn(indexResponse); + doReturn("response-id").when(indexResponse).getId(); + + when(client.prepareBulk()).thenReturn(bulkRequestBuilder); + doReturn(bulkResponseActionFuture).when(bulkRequestBuilder).execute(); + when(bulkResponseActionFuture.actionGet()).thenReturn(bulkResponse); + doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn("response-id").when(bulkItemResponse).getId(); + } + + @Test // DATAES-771 + void saveOneShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity, IndexCoordinates.of("index")); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveArrayShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(entity1, entity2); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2)); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void indexShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + IndexQuery indexQuery = indexQueryForEntity(entity); + template.index(indexQuery, IndexCoordinates.of("index")); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + Person savedPerson = (Person) indexQuery.getObject(); + assertThat(savedPerson.id).isEqualTo("after-save"); + } + + private IndexQuery indexQueryForEntity(Person entity) { + IndexQuery indexQuery = new IndexQuery(); + indexQuery.setObject(entity); + return indexQuery; + } + + @Test // DATAES-771 + void bulkIndexShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), IndexCoordinates.of("index")); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + static class Person { + + @Id String id; + String firstname; + } + + static class ValueCapturingEntityCallback { + + private final List values = new ArrayList<>(1); + + protected void capture(T value) { + values.add(value); + } + + public List getValues() { + return values; + } + + @Nullable + public T getValue() { + return CollectionUtils.lastElement(values); + } + + } + + static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback + implements AfterSaveCallback { + + @Override + public Person onAfterSave(Person entity) { + + capture(entity); + return new Person() { + { + id = "after-save"; + firstname = entity.firstname; + } + }; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java new file mode 100644 index 000000000..8271ee709 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -0,0 +1,229 @@ +/* + * Copyright 2018-2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import reactor.core.publisher.Mono; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.elasticsearch.action.DocWriteResponse; +import org.elasticsearch.action.bulk.BulkItemResponse; +import org.elasticsearch.action.bulk.BulkRequest; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * @author Roman Puchkovskiy + */ +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +public class ReactiveElasticsearchTemplateCallbackTests { + + private ReactiveElasticsearchTemplate template; + + @Mock + private ReactiveElasticsearchClient client; + + @Mock + private IndexResponse indexResponse; + @Mock + private BulkResponse bulkResponse; + @Mock + private BulkItemResponse bulkItemResponse; + @Mock + private DocWriteResponse docWriteResponse; + + @BeforeEach + public void setUp() { + template = new ReactiveElasticsearchTemplate(client); + + when(client.index(any(IndexRequest.class))).thenReturn(Mono.just(indexResponse)); + doReturn("response-id").when(indexResponse).getId(); + + when(client.bulk(any(BulkRequest.class))).thenReturn(Mono.just(bulkResponse)); + doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn(docWriteResponse).when(bulkItemResponse).getResponse(); + doReturn("response-id").when(docWriteResponse).getId(); + } + + @Test // DATAES-771 + void saveOneShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity).block(Duration.ofSeconds(1)); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveOneFromPublisherShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(Mono.just(entity)).block(Duration.ofSeconds(1)); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity, IndexCoordinates.of("index")).block(Duration.ofSeconds(1)); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveFromPublisherWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity = new Person("init", "luke"); + + Person saved = template.save(Mono.just(entity), IndexCoordinates.of("index")).block(Duration.ofSeconds(1)); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveAllShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + List saved = template.saveAll(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")) + .toStream().collect(Collectors.toList()); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + assertThat(saved.get(0).getId()).isEqualTo("after-save"); + assertThat(saved.get(1).getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveFromMonoAllShouldInvokeAfterSaveCallbacks() { + + ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + List saved = template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), IndexCoordinates.of("index")) + .toStream().collect(Collectors.toList()); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + assertThat(saved.get(0).getId()).isEqualTo("after-save"); + assertThat(saved.get(1).getId()).isEqualTo("after-save"); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + static class Person { + + @Id String id; + String firstname; + } + + static class ValueCapturingEntityCallback { + + private final List values = new ArrayList<>(1); + + protected void capture(T value) { + values.add(value); + } + + public List getValues() { + return values; + } + + @Nullable + public T getValue() { + return CollectionUtils.lastElement(values); + } + + } + + static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback + implements ReactiveAfterSaveCallback { + + @Override + public Mono onAfterSave(Person entity) { + + return Mono.defer(() -> { + capture(entity); + Person newPerson = new Person() { + { + id = "after-save"; + firstname = entity.firstname; + } + }; + return Mono.just(newPerson); + }); + } + } +} From abf886e8777dce84d58cf3b265d9fb7f834de515 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 29 Mar 2020 19:54:00 +0200 Subject: [PATCH 0101/1191] DATAES-771 - Polishing. --- .../core/AbstractElasticsearchTemplate.java | 7 ++--- .../core/ElasticsearchRestTemplate.java | 4 +-- .../core/ElasticsearchTemplate.java | 21 ++++++-------- .../core/ReactiveElasticsearchTemplate.java | 3 +- .../core/event/AfterSaveCallback.java | 4 +-- .../core/event/ReactiveAfterSaveCallback.java | 4 +-- ...lasticsearchRestTemplateCallbackTests.java | 14 ++++------ ...csearchTransportTemplateCallbackTests.java | 28 +++++++------------ ...iveElasticsearchTemplateCallbackTests.java | 23 ++++++--------- 9 files changed, 42 insertions(+), 66 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 844190f08..acc20ed63 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -158,10 +158,7 @@ public Iterable save(Iterable entities, IndexCoordinates index) { }); } - return indexQueries.stream() - .map(IndexQuery::getObject) - .map(entity -> (T) entity) - .collect(Collectors.toList()); + return indexQueries.stream().map(IndexQuery::getObject).map(entity -> (T) entity).collect(Collectors.toList()); } @Override @@ -433,7 +430,7 @@ private IndexQuery getIndexQuery(T entity) { /** * tries to extract the version of the Elasticsearch cluster - * + * * @return the version as string if it can be retrieved */ @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 114f1f99a..cb8596c10 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -229,8 +229,8 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { maybeCallbackBeforeConvertWithQueries(queries); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); - List ids = checkForBulkOperationFailure(execute( - client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); + List ids = checkForBulkOperationFailure( + execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); maybeCallbackAfterSaveWithQueries(queries); return ids; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 17a117d46..740a6c5c5 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -17,7 +17,6 @@ import java.util.List; -import org.elasticsearch.Version; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder; @@ -286,13 +285,14 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query } @Override - public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, Class clazz) { + public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, + Class clazz) { - ActionFuture action = client // + ActionFuture action = client // .prepareSearchScroll(scrollId) // .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)) // .execute(); - + SearchResponse response = getSearchResponseWithTimeout(action); return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); @@ -330,21 +330,18 @@ private SearchResponse getSearchResponseWithTimeout(ActionFuture } // endregion - - //region helper methods + // region helper methods @Override protected String getClusterVersion() { try { - NodesInfoResponse nodesInfoResponse = client.admin().cluster().nodesInfo( - new NodesInfoRequestBuilder(client, NodesInfoAction.INSTANCE).request() - ).actionGet(); + NodesInfoResponse nodesInfoResponse = client.admin().cluster() + .nodesInfo(new NodesInfoRequestBuilder(client, NodesInfoAction.INSTANCE).request()).actionGet(); if (!nodesInfoResponse.getNodes().isEmpty()) { return nodesInfoResponse.getNodes().get(0).getVersion().toString(); } - } catch (Exception ignored) { - } + } catch (Exception ignored) {} return null; } - //endregion + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index ad9d9335f..2e1de1507 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -187,8 +187,7 @@ public Mono save(T entity, IndexCoordinates index) { return doIndex(entity, adaptableEntity, index) // .map(it -> { return adaptableEntity.populateIdIfNecessary(it.getId()); - }) - .flatMap(this::maybeCallAfterSave); + }).flatMap(this::maybeCallAfterSave); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java index 0ad8e1c3b..ca9639b8d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java @@ -29,8 +29,8 @@ public interface AfterSaveCallback extends EntityCallback { /** - * Entity callback method invoked after a domain object is saved. Can return either the same or a modified - * instance of the domain object. + * Entity callback method invoked after a domain object is saved. Can return either the same or a modified instance of + * the domain object. * * @param entity the domain object that was saved. * @return the domain object that was persisted. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java index 561de46fd..032e41962 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java @@ -30,8 +30,8 @@ public interface ReactiveAfterSaveCallback extends EntityCallback { /** - * Entity callback method invoked after a domain object is saved. Can return either the same or a modified - * instance of the domain object. + * Entity callback method invoked after a domain object is saved. Can return either the same or a modified instance of + * the domain object. * * @param entity the domain object that was saved. * @return a {@link Publisher} emitting the domain object to be returned to the caller. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java index 0edb8ad51..609144bc0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java @@ -59,15 +59,11 @@ public class ElasticsearchRestTemplateCallbackTests { private ElasticsearchRestTemplate template; - @Mock - private RestHighLevelClient client; + @Mock private RestHighLevelClient client; - @Mock - private IndexResponse indexResponse; - @Mock - private BulkResponse bulkResponse; - @Mock - private BulkItemResponse bulkItemResponse; + @Mock private IndexResponse indexResponse; + @Mock private BulkResponse bulkResponse; + @Mock private BulkItemResponse bulkItemResponse; @BeforeEach public void setUp() throws Exception { @@ -77,7 +73,7 @@ public void setUp() throws Exception { doReturn("response-id").when(indexResponse).getId(); doReturn(bulkResponse).when(client).bulk(any(BulkRequest.class), any(RequestOptions.class)); - doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn("response-id").when(bulkItemResponse).getId(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java index b04c1e7cf..eca544fc4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java @@ -59,23 +59,15 @@ public class ElasticsearchTransportTemplateCallbackTests { private ElasticsearchTemplate template; - @Mock - private Client client; - - @Mock - private IndexRequestBuilder indexRequestBuilder; - @Mock - private ActionFuture indexResponseActionFuture; - @Mock - private IndexResponse indexResponse; - @Mock - private BulkRequestBuilder bulkRequestBuilder; - @Mock - private ActionFuture bulkResponseActionFuture; - @Mock - private BulkResponse bulkResponse; - @Mock - private BulkItemResponse bulkItemResponse; + @Mock private Client client; + + @Mock private IndexRequestBuilder indexRequestBuilder; + @Mock private ActionFuture indexResponseActionFuture; + @Mock private IndexResponse indexResponse; + @Mock private BulkRequestBuilder bulkRequestBuilder; + @Mock private ActionFuture bulkResponseActionFuture; + @Mock private BulkResponse bulkResponse; + @Mock private BulkItemResponse bulkItemResponse; @BeforeEach public void setUp() { @@ -89,7 +81,7 @@ public void setUp() { when(client.prepareBulk()).thenReturn(bulkRequestBuilder); doReturn(bulkResponseActionFuture).when(bulkRequestBuilder).execute(); when(bulkResponseActionFuture.actionGet()).thenReturn(bulkResponse); - doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn("response-id").when(bulkItemResponse).getId(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java index 8271ee709..d49faa62e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -59,17 +59,12 @@ public class ReactiveElasticsearchTemplateCallbackTests { private ReactiveElasticsearchTemplate template; - @Mock - private ReactiveElasticsearchClient client; - - @Mock - private IndexResponse indexResponse; - @Mock - private BulkResponse bulkResponse; - @Mock - private BulkItemResponse bulkItemResponse; - @Mock - private DocWriteResponse docWriteResponse; + @Mock private ReactiveElasticsearchClient client; + + @Mock private IndexResponse indexResponse; + @Mock private BulkResponse bulkResponse; + @Mock private BulkItemResponse bulkItemResponse; + @Mock private DocWriteResponse docWriteResponse; @BeforeEach public void setUp() { @@ -79,7 +74,7 @@ public void setUp() { doReturn("response-id").when(indexResponse).getId(); when(client.bulk(any(BulkRequest.class))).thenReturn(Mono.just(bulkResponse)); - doReturn(new BulkItemResponse[] {bulkItemResponse, bulkItemResponse}).when(bulkResponse).getItems(); + doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn(docWriteResponse).when(bulkItemResponse).getResponse(); doReturn("response-id").when(docWriteResponse).getId(); } @@ -154,8 +149,8 @@ void saveAllShouldInvokeAfterSaveCallbacks() { Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); - List saved = template.saveAll(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")) - .toStream().collect(Collectors.toList()); + List saved = template.saveAll(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")).toStream() + .collect(Collectors.toList()); verify(afterSaveCallback, times(2)).onAfterSave(any()); assertThat(saved.get(0).getId()).isEqualTo("after-save"); From 863c54f24f74ac8d09dc7ea39334f84156cd1c93 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 31 Mar 2020 14:59:19 +0200 Subject: [PATCH 0102/1191] DATAES-762 - Updated changelog. --- src/main/resources/changelog.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 2ee223c66..d677cfbbf 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,21 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.RC1 (2020-03-31) +----------------------------------------- +* DATAES-771 - Add after-save entity callbacks support. +* DATAES-768 - Add missing query parameters for an UpdateQuery. +* DATAES-766 - Replace CloseableIterator with SearchHitsIterator in stream operations. +* DATAES-765 - Pageable.unpaged() is not used to build a query returning all documents. +* DATAES-763 - Allow map properties in entity with null values. +* DATAES-762 - Release 4.0 RC1 (Neumann). +* DATAES-751 - Introduce ClientCallbackfor the rest client. +* DATAES-653 - Make it easier to use a custom request converter when extending DefaultReactiveElasticsearchClient. +* DATAES-435 - Report version mismatch if used with older ElasticSearch version. +* DATAES-382 - Add Exception translation for Elasticsearch errors. +* DATAES-68 - Add support for auditing annotations. + + Changes in version 3.2.6.RELEASE (2020-03-25) --------------------------------------------- * DATAES-769 - Upgrade to Elasticsearch 6.8.7. @@ -1057,3 +1072,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 27871899b0119940c1ab07626259777ec8229298 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 31 Mar 2020 14:59:20 +0200 Subject: [PATCH 0103/1191] DATAES-762 - Prepare 4.0 RC1 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 44d519592..399d3b3e3 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RC1 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.1 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RC1 4.1.39.Final spring.data.elasticsearch @@ -372,8 +372,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 1b0c300e4..acc9f97c5 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 M4 +Spring Data Elasticsearch 4.0 RC1 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -12,3 +12,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From ed5fe948d15085b4859993b77085cbcdb90cd2a7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 31 Mar 2020 14:59:41 +0200 Subject: [PATCH 0104/1191] DATAES-762 - Release version 4.0 RC1 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 399d3b3e3..89490fbef 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.RC1 org.springframework.data.build From d0cfd498ee3beca5bee12789148db5031120ff3b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 31 Mar 2020 15:08:04 +0200 Subject: [PATCH 0105/1191] DATAES-762 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 89490fbef..399d3b3e3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.RC1 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From 40838e187c28f94b359e107bcdbb8f66d28d0994 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 31 Mar 2020 15:08:05 +0200 Subject: [PATCH 0106/1191] DATAES-762 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 399d3b3e3..44d519592 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.RC1 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.1 2.9.1 - 2.3.0.RC1 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -372,8 +372,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 40752c2235913bab1b4e4bcdc8d7befa196eb978 Mon Sep 17 00:00:00 2001 From: alesharik Date: Tue, 31 Mar 2020 21:24:44 +0300 Subject: [PATCH 0107/1191] DATAES-773 - Add search-as-you-type field support. Original PR: #415 --- .../data/elasticsearch/annotations/Field.java | 6 + .../elasticsearch/annotations/FieldType.java | 4 +- .../elasticsearch/annotations/InnerField.java | 6 + .../core/index/MappingParameters.java | 19 ++ .../core/SearchAsYouTypeTests.java | 191 ++++++++++++++++++ 5 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java index 7adaa7244..2c328c1be 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Field.java @@ -33,6 +33,7 @@ * @author Kevin Leturc * @author Peter-Josef Meisch * @author Xiao Yu + * @author Aleksei Arsenev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @@ -148,4 +149,9 @@ * @since 4.0 */ double scalingFactor() default 1; + + /** + * @since 4.0 + */ + int maxShingleSize() default -1; } diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java index 09cc014e4..a2d7088b8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java @@ -21,6 +21,7 @@ * @author Artur Konczak * @author Zeng Zetang * @author Peter-Josef Meisch + * @author Aleksei Arsenev */ public enum FieldType { Auto, @@ -49,5 +50,6 @@ public enum FieldType { Ip, TokenCount, Percolator, - Flattened + Flattened, + Search_As_You_Type } diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java index c6fa617d7..05edbea2f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java @@ -26,6 +26,7 @@ * @author Sascha Woo * @author Xiao Yu * @author Peter-Josef Meisch + * @author Aleksei Arsenev */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @@ -117,4 +118,9 @@ * @since 4.0 */ double scalingFactor() default 1; + + /** + * @since 4.0 + */ + int maxShingleSize() default -1; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java index 39bc8d760..9798e2dfd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; +import org.elasticsearch.common.Nullable; import org.elasticsearch.common.xcontent.XContentBuilder; import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; @@ -36,6 +37,7 @@ * {@link org.springframework.data.elasticsearch.annotations.InnerField} annotation. * * @author Peter-Josef Meisch + * @author Aleksei Arsenev * @since 4.0 */ public final class MappingParameters { @@ -64,6 +66,7 @@ public final class MappingParameters { static final String FIELD_PARAM_SIMILARITY = "similarity"; static final String FIELD_PARAM_TERM_VECTOR = "term_vector"; static final String FIELD_PARAM_TYPE = "type"; + static final String FIELD_PARAM_MAX_SHINGLE_SIZE = "max_shingle_size"; private boolean index = true; private boolean store = false; @@ -88,6 +91,8 @@ public final class MappingParameters { private Similarity similarity = Similarity.Default; private TermVector termVector = TermVector.none; private double scalingFactor = 1.0; + @Nullable + private Integer maxShingleSize; /** * extracts the mapping parameters from the relevant annotations. @@ -136,6 +141,11 @@ private MappingParameters(Field field) { similarity = field.similarity(); termVector = field.termVector(); scalingFactor = field.scalingFactor(); + maxShingleSize = field.maxShingleSize() >= 0 ? field.maxShingleSize() : null; + Assert.isTrue(type != FieldType.Search_As_You_Type + || maxShingleSize == null + || (maxShingleSize >= 2 && maxShingleSize <= 4), + "maxShingleSize must be in inclusive range from 2 to 4 for field type search_as_you_type"); } private MappingParameters(InnerField field) { @@ -165,6 +175,11 @@ private MappingParameters(InnerField field) { similarity = field.similarity(); termVector = field.termVector(); scalingFactor = field.scalingFactor(); + maxShingleSize = field.maxShingleSize() >= 0 ? field.maxShingleSize() : null; + Assert.isTrue(type != FieldType.Search_As_You_Type + || maxShingleSize == null + || (maxShingleSize >= 2 && maxShingleSize <= 4), + "maxShingleSize must be in inclusive range from 2 to 4 for field type search_as_you_type"); } public boolean isStore() { @@ -269,5 +284,9 @@ public void writeTypeAndParametersTo(XContentBuilder builder) throws IOException if (type == FieldType.Scaled_Float) { builder.field(FIELD_PARAM_SCALING_FACTOR, scalingFactor); } + + if (maxShingleSize != null) { + builder.field(FIELD_PARAM_MAX_SHINGLE_SIZE, maxShingleSize); + } } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java new file mode 100644 index 000000000..5157d441b --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java @@ -0,0 +1,191 @@ +/* + * Copyright 2014-2020 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; + +import lombok.*; +import org.elasticsearch.index.query.MultiMatchQueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.annotation.Id; +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.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.lang.Nullable; +import org.springframework.test.context.ContextConfiguration; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author Aleksei Arsenev + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { SearchAsYouTypeTests.Config.class }) +public class SearchAsYouTypeTests { + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + @Autowired + private ElasticsearchOperations operations; + + @BeforeEach + private void setup() { + IndexInitializer.init(operations.indexOps(SearchAsYouTypeEntity.class)); + } + + @AfterEach + void after() { + operations.indexOps(SearchAsYouTypeEntity.class).delete(); + } + + private void loadEntities() { + List indexQueries = new ArrayList<>(); + indexQueries.add(SearchAsYouTypeEntity.builder().id("1").name("test 1").suggest("test 1234").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("2").name("test 2").suggest("test 5678").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("3").name("test 3").suggest("asd 5678").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("4").name("test 4").suggest("not match").build().toIndex()); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + operations.bulkIndex(indexQueries, index); + operations.indexOps(SearchAsYouTypeEntity.class).refresh(); + } + + @Test // DATAES-773 + void shouldRetrieveEntityById() { + loadEntities(); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + operations.get("1", SearchAsYouTypeEntity.class, index); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForTextString() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("test ", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") + .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(2, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("1"))); + assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForNumQuery() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("5678 ", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") + .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(2, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); + assertTrue(result.contains(new SearchAsYouTypeEntity("3"))); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForNotMatchQuery() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("n mat", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") + .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(1, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("4"))); + } + + /** + * @author Aleksei Arsenev + */ + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(onlyExplicitlyIncluded = true) + @Document(indexName = "test-index-core-search-as-you-type", replicas = 0, refreshInterval = "-1") + static class SearchAsYouTypeEntity { + + public SearchAsYouTypeEntity(@Nonnull String id) { + this.id = id; + } + + @Nonnull + @Id + @EqualsAndHashCode.Include + private String id; + + @Nullable + private String name; + + @Nullable + @Field(type = FieldType.Search_As_You_Type, maxShingleSize = 4) + private String suggest; + + public IndexQuery toIndex() { + IndexQuery indexQuery = new IndexQuery(); + indexQuery.setId(getId()); + indexQuery.setObject(this); + return indexQuery; + } + } +} From 1cd572125ebb921d83b38b3d7192e6c723a669bd Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 31 Mar 2020 20:36:36 +0200 Subject: [PATCH 0108/1191] DATAES-773 - Polishing. --- .../core/index/MappingParameters.java | 15 +- .../core/SearchAsYouTypeTests.java | 289 +++++++++--------- 2 files changed, 150 insertions(+), 154 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java index 9798e2dfd..d22142f1d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingParameters.java @@ -91,8 +91,7 @@ public final class MappingParameters { private Similarity similarity = Similarity.Default; private TermVector termVector = TermVector.none; private double scalingFactor = 1.0; - @Nullable - private Integer maxShingleSize; + @Nullable private Integer maxShingleSize; /** * extracts the mapping parameters from the relevant annotations. @@ -142,9 +141,9 @@ private MappingParameters(Field field) { termVector = field.termVector(); scalingFactor = field.scalingFactor(); maxShingleSize = field.maxShingleSize() >= 0 ? field.maxShingleSize() : null; - Assert.isTrue(type != FieldType.Search_As_You_Type - || maxShingleSize == null - || (maxShingleSize >= 2 && maxShingleSize <= 4), + Assert.isTrue(type != FieldType.Search_As_You_Type // + || maxShingleSize == null // + || (maxShingleSize >= 2 && maxShingleSize <= 4), // "maxShingleSize must be in inclusive range from 2 to 4 for field type search_as_you_type"); } @@ -176,9 +175,9 @@ private MappingParameters(InnerField field) { termVector = field.termVector(); scalingFactor = field.scalingFactor(); maxShingleSize = field.maxShingleSize() >= 0 ? field.maxShingleSize() : null; - Assert.isTrue(type != FieldType.Search_As_You_Type - || maxShingleSize == null - || (maxShingleSize >= 2 && maxShingleSize <= 4), + Assert.isTrue(type != FieldType.Search_As_You_Type // + || maxShingleSize == null // + || (maxShingleSize >= 2 && maxShingleSize <= 4), // "maxShingleSize must be in inclusive range from 2 to 4 for field type search_as_you_type"); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java index 5157d441b..594a1a1e6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchAsYouTypeTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014-2020 the original author or authors. + * Copyright 2020 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. @@ -15,7 +15,20 @@ */ package org.springframework.data.elasticsearch.core; -import lombok.*; +import static org.junit.jupiter.api.Assertions.*; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; + import org.elasticsearch.index.query.MultiMatchQueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.junit.jupiter.api.AfterEach; @@ -35,157 +48,141 @@ import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * @author Aleksei Arsenev */ @SpringIntegrationTest @ContextConfiguration(classes = { SearchAsYouTypeTests.Config.class }) public class SearchAsYouTypeTests { - @Configuration - @Import({ ElasticsearchRestTemplateConfiguration.class }) - static class Config {} - @Autowired - private ElasticsearchOperations operations; - - @BeforeEach - private void setup() { - IndexInitializer.init(operations.indexOps(SearchAsYouTypeEntity.class)); - } - - @AfterEach - void after() { - operations.indexOps(SearchAsYouTypeEntity.class).delete(); - } - - private void loadEntities() { - List indexQueries = new ArrayList<>(); - indexQueries.add(SearchAsYouTypeEntity.builder().id("1").name("test 1").suggest("test 1234").build().toIndex()); - indexQueries.add(SearchAsYouTypeEntity.builder().id("2").name("test 2").suggest("test 5678").build().toIndex()); - indexQueries.add(SearchAsYouTypeEntity.builder().id("3").name("test 3").suggest("asd 5678").build().toIndex()); - indexQueries.add(SearchAsYouTypeEntity.builder().id("4").name("test 4").suggest("not match").build().toIndex()); - IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); - operations.bulkIndex(indexQueries, index); - operations.indexOps(SearchAsYouTypeEntity.class).refresh(); - } - - @Test // DATAES-773 - void shouldRetrieveEntityById() { - loadEntities(); - IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); - operations.get("1", SearchAsYouTypeEntity.class, index); - } - - @Test // DATAES-773 - void shouldReturnCorrectResultsForTextString() { - - // given - loadEntities(); - - // when - Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("test ", // - "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") - .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); - IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); - List result = operations.search(query, SearchAsYouTypeEntity.class, index) // - .getSearchHits() // - .stream() // - .map(SearchHit::getContent) // - .collect(Collectors.toList()); - - // then - assertEquals(2, result.size()); - assertTrue(result.contains(new SearchAsYouTypeEntity("1"))); - assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); - } - - @Test // DATAES-773 - void shouldReturnCorrectResultsForNumQuery() { - - // given - loadEntities(); - - // when - Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("5678 ", // - "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") - .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); - IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); - List result = operations.search(query, SearchAsYouTypeEntity.class, index) // - .getSearchHits() // - .stream() // - .map(SearchHit::getContent) // - .collect(Collectors.toList()); - - // then - assertEquals(2, result.size()); - assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); - assertTrue(result.contains(new SearchAsYouTypeEntity("3"))); - } - - @Test // DATAES-773 - void shouldReturnCorrectResultsForNotMatchQuery() { - - // given - loadEntities(); - - // when - Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("n mat", // - "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram") - .type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); - IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); - List result = operations.search(query, SearchAsYouTypeEntity.class, index) // - .getSearchHits() // - .stream() // - .map(SearchHit::getContent) // - .collect(Collectors.toList()); - - // then - assertEquals(1, result.size()); - assertTrue(result.contains(new SearchAsYouTypeEntity("4"))); - } - - /** - * @author Aleksei Arsenev - */ - @Data - @Builder - @NoArgsConstructor - @AllArgsConstructor - @EqualsAndHashCode(onlyExplicitlyIncluded = true) - @Document(indexName = "test-index-core-search-as-you-type", replicas = 0, refreshInterval = "-1") - static class SearchAsYouTypeEntity { - - public SearchAsYouTypeEntity(@Nonnull String id) { - this.id = id; - } - - @Nonnull - @Id - @EqualsAndHashCode.Include - private String id; - - @Nullable - private String name; - - @Nullable - @Field(type = FieldType.Search_As_You_Type, maxShingleSize = 4) - private String suggest; - - public IndexQuery toIndex() { - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(getId()); - indexQuery.setObject(this); - return indexQuery; - } - } + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + @Autowired private ElasticsearchOperations operations; + + @BeforeEach + private void setup() { + IndexInitializer.init(operations.indexOps(SearchAsYouTypeEntity.class)); + } + + @AfterEach + void after() { + operations.indexOps(SearchAsYouTypeEntity.class).delete(); + } + + private void loadEntities() { + List indexQueries = new ArrayList<>(); + indexQueries.add(SearchAsYouTypeEntity.builder().id("1").name("test 1").suggest("test 1234").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("2").name("test 2").suggest("test 5678").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("3").name("test 3").suggest("asd 5678").build().toIndex()); + indexQueries.add(SearchAsYouTypeEntity.builder().id("4").name("test 4").suggest("not match").build().toIndex()); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + operations.bulkIndex(indexQueries, index); + operations.indexOps(SearchAsYouTypeEntity.class).refresh(); + } + + @Test // DATAES-773 + void shouldRetrieveEntityById() { + loadEntities(); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + operations.get("1", SearchAsYouTypeEntity.class, index); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForTextString() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("test ", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram").type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(2, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("1"))); + assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForNumQuery() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("5678 ", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram").type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(2, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("2"))); + assertTrue(result.contains(new SearchAsYouTypeEntity("3"))); + } + + @Test // DATAES-773 + void shouldReturnCorrectResultsForNotMatchQuery() { + + // given + loadEntities(); + + // when + Query query = new NativeSearchQuery(QueryBuilders.multiMatchQuery("n mat", // + "suggest", "suggest._2gram", "suggest._3gram", "suggest._4gram").type(MultiMatchQueryBuilder.Type.BOOL_PREFIX)); + IndexCoordinates index = IndexCoordinates.of("test-index-core-search-as-you-type"); + List result = operations.search(query, SearchAsYouTypeEntity.class, index) // + .getSearchHits() // + .stream() // + .map(SearchHit::getContent) // + .collect(Collectors.toList()); + + // then + assertEquals(1, result.size()); + assertTrue(result.contains(new SearchAsYouTypeEntity("4"))); + } + + /** + * @author Aleksei Arsenev + */ + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + @EqualsAndHashCode(onlyExplicitlyIncluded = true) + @Document(indexName = "test-index-core-search-as-you-type", replicas = 0, refreshInterval = "-1") + static class SearchAsYouTypeEntity { + + public SearchAsYouTypeEntity(@Nonnull String id) { + this.id = id; + } + + @NonNull @Id @EqualsAndHashCode.Include private String id; + + @Nullable private String name; + + @Nullable @Field(type = FieldType.Search_As_You_Type, maxShingleSize = 4) private String suggest; + + public IndexQuery toIndex() { + IndexQuery indexQuery = new IndexQuery(); + indexQuery.setId(getId()); + indexQuery.setObject(this); + return indexQuery; + } + } } From 403d9d08e2075a6ba8645a69259a3db48d89e54c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 31 Mar 2020 22:15:30 +0200 Subject: [PATCH 0109/1191] DATAES-775 Fix test runner setup. Original PR: #416 --- pom.xml | 1 + ...ryTestsTransport.java => CriteriaQueryTransportTests.java} | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) rename src/test/java/org/springframework/data/elasticsearch/core/query/{CriteriaQueryTestsTransport.java => CriteriaQueryTransportTests.java} (90%) diff --git a/pom.xml b/pom.xml index 44d519592..799e6a873 100644 --- a/pom.xml +++ b/pom.xml @@ -321,6 +321,7 @@ false **/*Tests.java + **/*Test.java false diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTransportTests.java similarity index 90% rename from src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java rename to src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTransportTests.java index 58d1a5d90..bc3d729e1 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTestsTransport.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTransportTests.java @@ -24,8 +24,8 @@ /** * @author Peter-Josef Meisch */ -@ContextConfiguration(classes = { CriteriaQueryTestsTransport.Config.class }) -public class CriteriaQueryTestsTransport extends CriteriaQueryTests { +@ContextConfiguration(classes = { CriteriaQueryTransportTests.Config.class }) +public class CriteriaQueryTransportTests extends CriteriaQueryTests { @Configuration @Import({ ElasticsearchTemplateConfiguration.class }) @EnableElasticsearchRepositories(considerNestedRepositories = true) From bce9da43437364c9491fb1f3ef6b5537bdd938a3 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 1 Apr 2020 07:55:04 +0200 Subject: [PATCH 0110/1191] DATAES-766 - Adapt RestClients class to change in InetSocketAddress class in JDK14. Original PR: #417 --- .../data/elasticsearch/client/ClientConfiguration.java | 2 ++ .../client/DefaultClientConfiguration.java | 10 ++++++---- .../data/elasticsearch/client/RestClients.java | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index 755f37071..916cbdcdc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -26,6 +26,7 @@ import javax.net.ssl.SSLContext; import org.springframework.http.HttpHeaders; +import org.springframework.lang.Nullable; import org.springframework.web.reactive.function.client.WebClient; /** @@ -153,6 +154,7 @@ static ClientConfiguration create(InetSocketAddress socketAddress) { * @return the path prefix. * @since 4.0 */ + @Nullable String getPathPrefix(); /** diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index 6bdc9bea9..af7d745e2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -47,14 +47,15 @@ class DefaultClientConfiguration implements ClientConfiguration { private final @Nullable SSLContext sslContext; private final Duration soTimeout; private final Duration connectTimeout; - private final String pathPrefix; + private final @Nullable String pathPrefix; private final @Nullable HostnameVerifier hostnameVerifier; - private final String proxy; - private final Function webClientConfigurer; + private final @Nullable String proxy; + private final @Nullable Function webClientConfigurer; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, - @Nullable HostnameVerifier hostnameVerifier, String proxy, Function webClientConfigurer) { + @Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy, + @Nullable Function webClientConfigurer) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -103,6 +104,7 @@ public Duration getSocketTimeout() { return this.soTimeout; } + @Nullable @Override public String getPathPrefix() { return this.pathPrefix; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java index 7500943a6..38abe6bce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java @@ -55,6 +55,7 @@ * @author Mark Paluch * @author Huw Ayling-Miller * @author Henrique Amaral + * @author Peter-Josef Meisch * @since 3.2 */ public final class RestClients { @@ -134,7 +135,7 @@ public static ElasticsearchRestClient create(ClientConfiguration clientConfigura } private static List formattedHosts(List hosts, boolean useSsl) { - return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it).collect(Collectors.toList()); + return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ":" + it.getPort()).collect(Collectors.toList()); } /** From b434b05215fb10f3d6d6d79b8e004bcfcda63667 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 1 Apr 2020 21:18:52 +0200 Subject: [PATCH 0111/1191] DATAES-777 - SearchHitsSupport must preserve pageable when unwrapping to AggregatedPage. Original PR: #418 --- .../elasticsearch/core/SearchHitSupport.java | 4 +-- .../aggregation/impl/AggregatedPageImpl.java | 13 ++++---- .../CustomMethodRepositoryBaseTests.java | 31 +++++++++++++++++++ 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 3a7255aa1..9d99ff014 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -65,8 +65,8 @@ public static Object unwrapSearchHits(Object result) { if (result instanceof AggregatedPage) { AggregatedPage page = (AggregatedPage) result; List list = page.getContent().stream().map(SearchHitSupport::unwrapSearchHits).collect(Collectors.toList()); - return new AggregatedPageImpl<>(list, null, page.getTotalElements(), page.getAggregations(), page.getScrollId(), - page.getMaxScore()); + return new AggregatedPageImpl<>(list, page.getPageable(), page.getTotalElements(), page.getAggregations(), + page.getScrollId(), page.getMaxScore()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java index 88fd756d4..a7be288be 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/aggregation/impl/AggregatedPageImpl.java @@ -40,7 +40,7 @@ public class AggregatedPageImpl extends PageImpl implements AggregatedPage @Nullable private String scrollId; private float maxScore; - private static Pageable pageableOrUnpaged(Pageable pageable) { + private static Pageable pageableOrUnpaged(@Nullable Pageable pageable) { return ofNullable(pageable).orElse(Pageable.unpaged()); } @@ -82,24 +82,25 @@ public AggregatedPageImpl(List content, Pageable pageable, long total, String this.maxScore = maxScore; } - public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations) { + public AggregatedPageImpl(List content, Pageable pageable, long total, @Nullable Aggregations aggregations) { super(content, pageableOrUnpaged(pageable), total); this.aggregations = aggregations; } - public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, float maxScore) { + public AggregatedPageImpl(List content, Pageable pageable, long total, @Nullable Aggregations aggregations, + float maxScore) { this(content, pageableOrUnpaged(pageable), total, aggregations); this.maxScore = maxScore; } - public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, + public AggregatedPageImpl(List content, Pageable pageable, long total, @Nullable Aggregations aggregations, String scrollId) { this(content, pageableOrUnpaged(pageable), total, aggregations); this.scrollId = scrollId; } - public AggregatedPageImpl(List content, Pageable pageable, long total, Aggregations aggregations, String scrollId, - float maxScore) { + public AggregatedPageImpl(List content, Pageable pageable, long total, @Nullable Aggregations aggregations, + String scrollId, float maxScore) { this(content, pageableOrUnpaged(pageable), total, aggregations, scrollId); this.maxScore = maxScore; } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 9bb1d2050..f815d0bf0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -545,6 +545,37 @@ public void shouldExecuteCustomMethodWithBooleanParameter() { assertThat(page.getTotalElements()).isEqualTo(1L); } + @Test // DATAES-777 + public void shouldReturnPageableInUnwrappedPageResult() { + + // given + String documentId = randomNumeric(5); + SampleEntity sampleEntity = new SampleEntity(); + sampleEntity.setId(documentId); + sampleEntity.setType("test"); + sampleEntity.setMessage("foo"); + sampleEntity.setAvailable(true); + repository.save(sampleEntity); + + // given + String documentId2 = randomNumeric(5); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setType("test"); + sampleEntity2.setMessage("bar"); + sampleEntity2.setAvailable(false); + repository.save(sampleEntity2); + + // when + PageRequest pageable = PageRequest.of(0, 10); + Page page = repository.findByAvailable(false, pageable); + + // then + assertThat(page).isNotNull(); + assertThat(page.getTotalElements()).isEqualTo(1L); + assertThat(page.getPageable()).isSameAs(pageable); + } + @Test public void shouldReturnPageableResultsWithQueryAnnotationExpectedPageSize() { From e449944e3b5fe5da359b8281f108784e833565a5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 4 Apr 2020 11:10:36 +0200 Subject: [PATCH 0112/1191] DATAES-781 - Upgrade to Elasticsearch 7.6.2. Original PR: #419 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 2 +- .../asciidoc/reference/elasticsearch-new.adoc | 2 +- ...on-7.6.1.jar => analysis-common-7.6.2.jar} | Bin 198566 -> 198567 bytes .../plugin-descriptor.properties | 4 ++-- ....1.jar => elasticsearch-dissect-7.6.2.jar} | Bin 24704 -> 24704 bytes ...7.6.1.jar => elasticsearch-grok-7.6.2.jar} | Bin 33792 -> 33793 bytes ...mmon-7.6.1.jar => ingest-common-7.6.2.jar} | Bin 115431 -> 115433 bytes .../plugin-descriptor.properties | 4 ++-- ...on-7.6.1.jar => lang-expression-7.6.2.jar} | Bin 66047 -> 66049 bytes .../plugin-descriptor.properties | 4 ++-- .../modules/lang-painless/asm-7.2.jar | Bin 0 -> 114873 bytes .../lang-painless/asm-analysis-7.2.jar | Bin 0 -> 33444 bytes .../modules/lang-painless/asm-commons-7.2.jar | Bin 0 -> 70051 bytes .../lang-painless/asm-debug-all-5.1.jar | Bin 387750 -> 0 bytes .../modules/lang-painless/asm-tree-7.2.jar | Bin 0 -> 50283 bytes .../modules/lang-painless/asm-util-7.2.jar | Bin 0 -> 80707 bytes ...icsearch-scripting-painless-spi-7.6.2.jar} | Bin 27878 -> 27879 bytes ...less-7.6.1.jar => lang-painless-7.6.2.jar} | Bin 558852 -> 558853 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- ...url-7.6.1.jar => repository-url-7.6.2.jar} | Bin 14743 -> 14744 bytes 24 files changed, 17 insertions(+), 17 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.6.1.jar => analysis-common-7.6.2.jar} (88%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.6.1.jar => elasticsearch-dissect-7.6.2.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.6.1.jar => elasticsearch-grok-7.6.2.jar} (86%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.6.1.jar => ingest-common-7.6.2.jar} (89%) rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.6.1.jar => lang-expression-7.6.2.jar} (89%) create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-analysis-7.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-commons-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-debug-all-5.1.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.6.1.jar => elasticsearch-scripting-painless-spi-7.6.2.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.6.1.jar => lang-painless-7.6.2.jar} (93%) rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.6.1.jar => repository-url-7.6.2.jar} (81%) diff --git a/pom.xml b/pom.xml index 799e6a873..abf197b27 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.6.1 + 7.6.2 2.9.1 2.3.0.BUILD-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index ce2185f0e..2b518b027 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,7 +35,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.6.1 |2.3.xfootnote:cdv[] +| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.6.2 |2.3.xfootnote:cdv[] | Moore | 3.2.x |6.8.6 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 7684c084d..cf1915b92 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -5,7 +5,7 @@ == New in Spring Data Elasticsearch 4.0 * Uses Spring 5.2. -* Upgrade to Elasticsearch 7.6.1. +* Upgrade to Elasticsearch 7.6.2. * Deprecation of `TransportClient` usage. * Implements most of the mapping-types available for the index mappings. * Removal of the Jackson `ObjectMapper`, now using the <> diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.1.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.2.jar similarity index 88% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.1.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.2.jar index f1e7ef32e1b05a2ce2cb36292bd1ad40a1b2efc1..1c948e374783b48477c8797fc37a4dc2b7d6613e 100644 GIT binary patch delta 8214 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 Z^(~)RfHx~Jei<0VfG`(m@81Xz4*-$okLUmZ delta 1179 zcmZoT$k=d@kvG7bnT3mifrEoViz#*@uNp6q3OLSSWs%Ovz_4hdgLZvxyUE&}3S3T8 z!fdxVb=)?)sWvTW_olgA|Kz^2>h?3U%iC<;Z9MO*#FnT9pPxvs4R$--5-jH4e>$|; z`-)r*!%3f?Y^g~(t{WMjhdva@37kLoj>pP5hY!U+-{SqVUvWNH^{;KAz3P__Z1Yp| zs$TPE+b4&+`%b6uGG6(|;JeI7vR?D3>dLtcz`O<3{bx#l?jaqz*~-C3!v0$T?-^ zGjG;4v4gJ51Bb4Vk`O&y}!8n?Ehcc7eWr7x_az%3S;kKi>}4|h@fA^7`ypA z;~akG<&3eD^8|M>KLgU*LW*G8Uq~NJHwu}9=*=6w+nB(Ne#hU8V8(y7Du_sprmrAG zO4^1Q%((1v8zMEs{tHC$8LI;jkzQwKRS z9dSHhDf<{{CR1^+RDFyjSZFp-Xp znY6*0_B-=TJ}b>V`Fu3Qihn@c9rd76Y?HY?MJGqb^C*DK^8Wew$^u|c`3f}85@8g> zmPUC)um+HG`QxO(ir<|ztjGZ>T*8K~Sj-r#_@9-;WWQL5$u}Agh`wiGVA#!ruK1=Y z)F~2^-$MgIDq5OJ-WqBl=j7yQA#gz40}3Cp0Sc>6R*I1V3&qAtGktY|s#FCF$s|ZK z{c{5g{j*}991y{d5oAqQQj4AgT^+;Ez@UZV&5!OtjcSuW2m!+-8sc*MB{DlFb22a- plmJE}ied$Sur2$YS!MK+a}tY-1H4&*rUIh^2y=na@izj*0{{6x}=$`AAF%j(i@3Pt*>|uL2gN5ztl#5eTLrzX_!BR}4)=kO1KY6;KiB zs#OLm(g4K~wZ%$B5ur{MDTofxBGxiur=^yvIGAazrTaDr32tWR-o1P7*|YcVn-rB2 zR4Kt0g%~l-05CBDS>Ab-?B#4^L}gLe8dDemR8;V%_eVHJYZ& zwU$BCj_4kFWiC(l_f_r~laSa7=h$H$jF-`n|WTwAg#}?}uX_ z$BYrjSWgZlxo4I;_cv&w*KbQ6ay)Ui&G$;>z2CJX{PJ{dNmo#zF()=AZj~Z!q%?5F z!TMoOZU3lB%v_oEVY0SaUvuO9Z-Do@Jt_ExX5m1v85ny9niCw|$xMb;iaK?*y~!gz9?Wld{XPD32@ zkk*9Yabm2K+8_M&*R>kwCZA&e`hKU2s_Rnx2P!Md5ol88C33d+o3kmF) zlBWrycM;hS!sXbiMcvqzh?{8JG9?@`#ZH9$1`9h!VnP>Sh$b`z2f`v&V~&;**-ahU zxyT{B)3@;$6FXiXWzcfE#vR3^!>w(4jMAL9`e0s6 z65T1#rI^HQWfZygWU5|@T$;XPev&A>BK}*5gkM9`-rxcQ>F{o}1B_AWp3o5_t}X*M zs~s_WKU%)bh7)Q#yyT-d5Ss)2i)=U0WqH0~X(bQ+{~SfruvK^V=qXZslAWF;3Sljv P4|YbshbE{YN_zD_SY#v_ delta 1905 zcmZWp3s6&65WV?8K@!l2@(BVOje=-!fPzH~woDvBZJ3q|yar_`< z#B2N%w4(eHS`}-H#71@w zoEeVJ5$og@M>l1j{?b%0uCYm++g9~Ydwybxv*eKf@eujS;h56x!sEE^daoF=aaIO!$&GBziVK8aX;up1V@sds(rNEr0Pit zjSXw`u4I@0^s{;0^T+GXX?3Lql8~1DFFL(Feu+=h-BV3FmL+oBEA&ZL?BMVYO!{PQ zz~jynKyfS6tCulUO#1?^!rAO{`AFQCxdA87R-zksm1bOhsq71)F6c1TkbN- z-B|UE6s($Zp49_;Aa5qwSMx+<*YiT@z2!i#)QKnok=0CclISr+3}<;q*hGo-T;WNS zKO&;6E?1+3#Gn>;ITPi?TBFtXZhi>E<;`%=c~cY8iH9OjV~u?pb%hu%C%kPnTwH1* zhRF5X7_@>r)^rg=og%{OaX;e+VsL$bl_OEk$b862%SmOt3$d_rW!B)X^sBVtbkb$3 z$MO~5I}nds8=f+`45mBFHn@1On2*D?UgM`1r)b0cCJ>57rG{$5&02vUuq$qh%MwZqj|Wx$Q^47 zIdt{76igc0F}xI0PMfmWkN2vxW%ne z2yKyNXUjF}EPDo}9jc+@way5sA^UV2B!YYCi^8qC*@V+o6rb6?94jeb^7^fTKQnpd z7|^V(IT;)6+gz{bGY_u9MS5$CPYP}(#sQy7xCqX;L})dxHh7Ea7ID4u&@ni?2g?=K z8>yjkU^;9~Xyh9+vh4F!LB3`2_?(_kij?X2%z_W_^`+A$kg^Bb5q^jpC|^RpW~ZXB z2{N&PTke~Tu-8!430Oo~;iwXT`v@N`@geBn!0T5@cqqdUKQFOP*<4k2ufP$ZZkSd0 zyV#_LG9=?@{R|R!1ybKk!#$LMqz>bFdChi#&gLQnVK%9uhGlq;!Cyy6`SRAo2&hdA z-^6%QB&so_D09@A_M}K}Yc#2~0DA$}_}F`6-b=U$&h^U3=Q77_YMpnJ@{jWbME<_-&yWCm(C2);|!60 zc&Mh9F2{+*+X!>Z>w*(X2p5)aJ0l{MRVucl~1gPX6fO^>EU%>9nyxtq4vhEyHcmsi?rM|WSmxi))i*MqRCv4@I!U$$*L(%$I#u)88W1b1BeF>-#e-Fxm~KTdjk zdc?-BRz80(|Labdy5#WM7asmUPnVb*lqzmt{ltE(pZ`I{!z0^^f@>=)l)lc6FJ~#A zX^1T47q(BG+ZOZFcV>^4wyo_s|L7m)1vN*mn|_gSs;_fXj%!-yh42Zh7BrQ-sa4(1 zO`e?j_P(Xl2F>=HhDXiIzWC|ai!O7&FS=a$<_W(&%Yzq8K3?=^=*72cDq~Jwx;Jjg zZvXnmhFeL2$>OK6FXFnMTE1-=WsH;W!`a=2$opGc9ikU4fB8qA0fl8=O8Dfdn zu~S!H@75L*Vs$H0zT~eZJK^|5B;^gZj8*KY$YvS%c`K5!q?);)0Vdn5hi>Z7jG2_0 zG75Exp3Gs?*+=wHai2dE3`%3iu6UKvn7y-9nR zAI}8T$I^X!30llfbq0UV@*eJlT3C=*iD|FFWYS;cSY`Fwf z<%mW#uv1_0>=%1P={J8=sHsC5$!z=YH+X(U#)v6N7ZZJDya*Yxq>0nf53~Tvo?L`A^hPWKY?q7ZaKTZzXpcV9 zFx4Dh5}40N?!q;Jzt2Y=nlP}iqySl=OZc?{WJ_iiUO@g%#H$O?B$64t7yce=FXgy( z8&^7qhYEq4L8&oM%F8#H8jjYXL!jGAbXM5=5R%A9dZ9WTL`Q#Qs!xtH;{KXdLrzX| z8if+>pYX@QU0~5RhU0vP4LGhQ{XbG%cmz4)oMUJlW!ifJ9JZSg80=DpUZ)P1Ye?TU zh0*z?3CFn!>=jmU(w2`sBf;zIkd#97)B}WtJ>KAp=HO>Qno3KLf;4L~PS-_lIBpHn z#sf!@355?1bJR-(dYalC=OKW1p2{1yI`AjoFvi|TRnc!syzBotoc;rX2^5?jaHh1+ zmBRG$3o@X-se|u(dNlsO$*PklmkFPFfZR`iwEUMqIUROEoh40 z#7oUkfSTdC3XtLjgoZO8TQvr+FIT1cRTDY?4y0|G8l?FQ2yZPRp=LEei;|XGMAweCqjy+y{4i+Vs%DkU zJ%%hP$GRh3yT!oI*l={^qH0-(%`{<`i8fB20zi}v6#iO0(#1b3kR8*I%aM6j-6*)X z2$@jTAem!|mZ1zeQlZN^5N`j9BCR`z>?j+->K7EI{}Pz{sSA6W6gKiINuw=(G9Har z_wiuH{A?NYurKt8mjLABHsX%g&ycD!A4jgo^BY46lTmU_WgwhzleLYwT-7$o2|$T(ekU*&VejFHrUV$q|a8?TRt%MoGaaOfCp*p=XB zj=)7m7wrSQdkPe_t4`GjDJ6ik_X#2DfE!Cx*V~m;DY=K@dsoBxG=+*%ED22S1r3Z} zD;MFDWh$fsGCLApsYb3g?rcI*S`+nSXY^ROp^YP&kQd%sr7HAY64zQCBAtP!pHhv@ zhDwlz8{%2DXwuM2i1m!T3N%YCsD?bs9jL>s?-xxgHQ=}j(?-`%Y{NiWBP{Tm64gpD z-~V2p7nJ)RR7JSoL{k}ZN)giMo!5?NbO+$?cDzYQYzd9VSVK@ zm}7WMV0cXEU_St$HZpsytFz&b-vc}0cI@_JHs$^L_}URwGOtU@mTiXGlK(}7Q|_Mu zjE(1M)n0i;E=W)ilMcv{HEu6eg?w-8vboLR@G-oQg@Yw?E-q|9c6i%i7)0S&XvCb7 zlg*qnpW(sX9Z&fmwh#NJ0-)AF_JmO03kg&Zy$|VRU-(2aTUfE|wys@QY1$02e+Q#f zxG-E6lO71A9@LM`(WmA|v;N6DuDW1?=cl0iSH%$DA(YILY9NyoOUdx?2IZgqVn|0L zb(iZt4n;zScf#!#X1FbmnZRS5Z`?29|N2OTy^gEe{|Z_A$;()TFps3<;W~~Yw)xEK zT>)WsK$yZ3uUs)qLOu0!N~>qN0D*oWAnZq*RYS+E)PpR5jOCJ~;j%eWpEq^#;?kfj zmCz?Hf=mo-9F797YCsk=C9TB(^34{e8E(=Ehmkc^uOaH_RHC-U_nMFxD~gdRRi%*~ zQ}NFsOcV8E;!kop+dicl`ovbx%=%NH>fIx7$4Wpko5)6-wQmTM{_7*f3)5i`4ZjFe zTHuUjE<=~)A&bAge&J1jmPleMZYjEvtEGE>_YMxjAN%9O%#U-<{hsf6+;cDYKi0YX zv5rwxxJXl<<8*a7SB_J(a_ zl6h#5uJcg0zHQUB|9I9P>dU)r^E5sF9sPL<#jTF5U0d(UtQAK*x7cnA?YCU#$;W=x zv*Ai_U$M~y-3W81s}%)L9M4TYn~*K;m}Iu`L7T_OH+^ZP(aon)NBr)FOwU}OF*&1~ zd|4Ut`n0Bp9o3mGV$R1TRz{M=Q1hw_<`?-FN8$f7kc-fjXT1B`Q6l3 zMNoL+l)24I7oXpB?fHjG43GTMW|fh2dsFhyMoY`yPVCgGsalzKB(vLkhq&$cFp+7! z#*)j1HeC+c!xF7`?Us3;Pn&sRURZ8y_~GL@y}@PSVPR{`zRO(X=Q#0N9)`mWIB|MHD^RrBremsePqI+LOVFZ9CBIA2z`2W$@EGw$5~G&S#e0nO%4|F_`iTmOo<;I8l=7&HhZy{ z1FO9l9aDEWz-SC5zrk3~kAWx5d;dx(q4x5(SHNVpQs?|KW}h(O*Ih9>6wVY<$ZNtfJJ8zNaeDHd>& zE$RORrm(kd@vs``;?<4D@1<+yxvrk#)t#$-byh-Ezw zLv<;@%@cb*+lT<(TD;WJN%mW7A!EF9P|9L}i32Qo+x6fUbuT;k;}4A6ivvoQm?`VL1DE@&qT;>w3SnF1fM{Efx%g1sG|4a-kA+xWBN@5`K}?L6$IU7t6!kWnjrr zH~x{TjCHvu3&r`64MSR#58vt1Jmh};KC{lgyovdX3V}dPn*9Fs)$==WUfeez(Tl;E zbhm+#{K|ajp@!s}V?aj+d3FpA7>qd-kyQRP^egAcv2Ghx$=LdXIyr2*(x? z7l9R=Bd$eYFU&0xCH%dXBo~35K$7I)-yZf7Hn^g~)qvH88=5Ge3EZDS^CkSi9#gmf zx4?4Lo)Z>q6Bbwz-(oPNe#45vN~1wSQftAUWETV7Zsb7?N*_!3l6x~q*csf;0>v41 zD16fr*V~blI&h}K`=uzfpNc|ze#I_hazgcozs{@G&E%GET^l?NN z_PoEZgeXeD&_?J%)x6}mxv#i$Tw~TDXEIO=;neTkDqP<28W}E!*U5ft5h}gdj?%iB zg4CW*an~c}3YbVyE0-V4cf~?y8F1WuHB^xYa_}W*+Ld7*Y(tEEZ%X-68@N#5Od%on z{RQAzq^kz|PsoUo5d6P`scA$hxKUwYGYYTIqr&UWU`>TpCs4Ry!6-3P^5TRt+{<$o z4zI=Se@lzwW~mYL3#S;diC{#|mM9|(5P+UU3P9fE&HcVHkK^2dhCJ6l zzv=*n9BasNzG}$(6426#JlY9*s)7VmAV%66im|f-rZL{9QCPj63h$o=7Yb~C_}vk2 z1n$SyR|g(UR@T#y6v<&SwSNAn*W@W$7hvYq1KgZC>dc6=mn#E&a27qbZ4orQpHxEp zT0lZ^3Oy!649=xJI8I+z3#V}#TDy~=FO}J7Z9$0TJ6Mj2SAY(&XjQiROQDB1e?a~E zp8+Qt z(XPaV`;gtI!Ilb3gl#dkmJiCCqq2-Vg~EyTXgPy65>4m+M@9>JFt#MU@v&LAPzp6A z*mwIXlvQkhC*CCo+w^<9C;6#me_^{|&R5kn@_}22=%vb z>2@H$o&p0^8(ImiJiChq9N(mDWz`8iekLsFV`V=2xpJfH7WTch828dSY|c4qMEh?b zs68pR083SFa)kWu9uPtxcsQGl(X^tb>}RUE&J0~u z5g#y7tm@&Le{QSD#(W$$8o%VtKLy6Ki9!#wiD8p+hdjg96nTk&Prc+#q8gM#@sW@w zGad3bIUW%)+Xv5B+&&0u?)cM*#+PN=fHO>@SgzCG#;M0StKYUL7*M3JfWl zt42-NB}A*neXEXEJw-tCS5-L$_pIou4UoKYup_l4@E4kBwTqBiWInDe3HVQf1vx5% zNwi{r;LsO^xG_RFSPbbwNL7hK(7MvmC`?tpYw-va>CJkTDRaKoUx(`l{Q*#}AW+V2Dhgv9C0;oN1 zT`?bUO4m2~=s=HUD?C&oJh=d204uv9EIMK=wB)^U*3t*Dk9V=N(5U5QAoAJEY?| zEV5hAoCxf0(ThY>3pkWf;Ta_kofqR3;K+(9up7=mdQBBE%jEAIHR zh(2YG@s=~DEJ7u)UFb9RviVEUq(ZW|6Kv=Pv2zcJ@j)BmEC^=C^z&ra!a{Pe6W$ni iH@+Zb;-^C9(4Z40n`&V{a$Fq#L^^QXuH!gExc>o)3QaZu diff --git a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties index 98d70ce6c..775c286a5 100644 --- a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=ingest-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.1.jar b/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.2.jar similarity index 89% rename from src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.1.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.2.jar index 68951ebd8fdf29f2291eb54478e28d1f1cd83081..6e8acfc35cf50910fa47cd001ebbaaca634b3540 100644 GIT binary patch delta 2830 zcmZWqd0bOR9-sGeA(xP#AP)rPhFVb(6{G^KAr_TbbkSu+vHFoxMG9K++& ztrS6|)?*dY1Qm-1+jc*;N|mCkiz`Jr#3qqTP$Yz%H&+pC1mZfJ+Y+AEq z_P-n3hWs5Ju1hB=Wfy}SkNhzBS>}pqzXxUX?zklI7kc?bKiGGh2I2)>~1P(5h57%Tg+JFZOx|ypS&59{4nMc}-d0 zhMN{XDL#|8C~p$7W_d4rB2w{nI?nA}?poZn)F-G7nV;28gHOb+vdVUOyEF;`MuR7`v)|DrIiC6k@u$kGsIQ9&NhFCBU{cinZ9HqX8`@e{Fm*HlGlcMZoG;XM*sJoq z8;MTosT+KZmMolWfj3j4a>&UhzfXzKDu?wv+*ZdzT<1b0bOKhThAa9+s{ZH_ql4!j zl8xu)2q8A=_MtE_4Pm1NP?;L0T9p1?X&eqP<43#rRemGwa*Syr`%SZw*cgQyH$ z9Hy`{KNTgA7z9D@B>#rwY(%UaOh(2#|MHBWoju%0=u+3aL`YLBb;kTJKE6#(o|fAa zaCO{5qm3FJ*;J@k5_&+BG4lEI9`JDx8y+8N`&9ryf;A2zG`>}U&qX$0w>?AW)z)ym zgD=d8;KQzNdsXg*^@LH^o&sBu<5&{rD3Isr%sV6`~ z=~UPt#V?#Za2j5zN4CPJ$U^WLY3&)0*M_EJPe&W>)yWng|FrD547cj;<8)0GMwEz#FIBlASz}*K>o6bi*OF6dmn-I_+ zx)eB!2Dm-^M%5|w{Jx3u9K->)Ctz^shyymHea+DAi71m{@ZBMj$+1B<{yxZ)ut&*# z63mr%F?8NXSnheY4LsLH`176|=-GwrW}%)4<=C#?j+0_2oeZ}Oh_S}a5r)p)g)|lx zxEm`O32trNiTFDZKZL`-SIF|wRg%D#kA-iHZ^UVVj|(oKpxHLyX6Tz@Y}o0Px?>9}(Sf!T(d1e1(+V{F`y&;8j->_%w3$RzHuw_tqh zKdMG?hnaM<1uD8*E%x;Ka|?L?HL1nAA%=FphL2qe#PI46nIxkRhe-f6-{Z96w**TR zIkMC3=na&>5HRjQoDrHC3*ir?Hq%}R&PC0u}=g*|3m=ha6m5}Aj`h+jb3{U s%=I?EI1?%LqnQ-O0sgDSm?sw;%z}P~mbYVWM*ox|4MkZCb2KdD|5o$73;+NC delta 2744 zcmaJ?dsvfI7(d^)IZ;5zxY`Gb5MV$sNN#RmOcE6@C`wumBP#(dAQ7cfB)kh=IKaGz z=97kjC}c*Mp=ktKqECQepcEAj8RM1$lir=PR$n|%-yfWp_x#@9dq2zAA{@>Xnny+m zgkuphF+pCea=*E&IUJE1-yu;FgHZAQ7ah_o=l>$LstB*1zO?m9!khJ}v+f)+JyBro zd3t-aN%Gn|_21^K48M@saJi*EU$H(zFnW@_NB+XZ!5CR-#(_TsTjDCB!lcJm1t=4b z3sfnJeO~j<7wi~sE;zH&cb(ATVSZm~T$b!yqn}mG07~|FH|Cs=<)p>Uo-yq;l?`FG zRpZhZTKpoJ8XJ&S;59s@`!kD_c68Hr*S!e=6&)FVmu`>2v%P}aa;n>N*1F7biHNR_ zU$XO*e9*eL@yb`a1K$_vJkc?wW_eg;pyl*azotw~c{}6A2Y={7Ztl(esc2JOc(8R^ zs-|Ax?mZ+-T9ZE%dIPS zAJx@9_M%ssOYEZP50-1$$>%K22OeH?(KGshwYsoLb7aHG7h3v6J>i{ZMXs$R6E;yq4cPw>@*ORyMccZvWYhE@esOdy5wAT2q$2Z&g~q?LQqUWR#I* zrT3Ua;{~S}B~G&_7eIHgzhp8wUy*o|GfU!6&TEoT{aKpi8Zn9ptLMHZAi|ILcMC~l z16sFg(}W0ph;Lo>zy%s1E_rNMYPl{`NN`7zovDG;dlD6zXYQh04?mwFBAA~G8z|Tz zz|WLun7cKjiLgYmjb8n*po=9M5qWn}^8sU(;Ax zct=CAt@%Gv>uGkaRP(h*A|cj6)xP;QbAhrlnP_s z`i%_oLuz1N z@Q7j#rpNJU~r&p({CekuLari-K&ahSj<4)o{^;G^+;ySgT0A>S^>)@Cg z?B3x_#v>B`OTcS7ob*2M{tj-cn*^c6cUO5wM(`LT5qzxv4}1VId}5>vjga66PF9}( zXE5P!JklF%)EjVE_Q;HQo%4ueFX&aSINP9-b#d$fRVCV4VYOD`sDEN`&!NR40YZT$ z2u(LqB2<7 zyS(yka40j5i0gpTD+hu-IwGTkYxN%Tqzv^Cfo{C99_q9XmL{0zVRtIl=1(`y2U`>W z&30fcg>YWv0hRBQTodi=@qEKDb+$SnOUShZ+=ueOicO?fVx0vZ?y@3D-cs%C-UG~A zN5oo|L8=isObct)$+0K47=}@d<2!AL{fXkTwk)tuA7TIbHezqSVl@7;kG8sae*~^J-DT24IeYoE1ECA>7F&;H1kEtm>x^Lq<*3 zV-qNQCNRIm16Qc9&!17GTuoQmYH!H?9Bjrc9?0!5VeHbml6gD=4^qWPuq<+%q@`P0 z@`Pg=@#H}_T&?BsxB=Ri8yb%7JqdZvFb+U|lwjKH;3UKpp$MLnoYOegcb;*quDpS- zZ-V>^M^sK(1glS1Pn~P88iKs)AY=uPO;$qs;M7n1&^d3x_JAF36`1FFghaK)fC z$?da#j_v#c(v^>Rux+n@b95hYj2x%VFA0ZcfI90c*s(}$kI>Mv|87Kc1pwt(`h>P6 zX!B&`0>$Wn@cBJ-Ya|tKN*4d~Hh004mo&rf1z~$<6Jteh#@Yz407)Y}1^kuT^#Gob eVATeOAx|P!LOag8l diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties index c52e59353..615f4d45c 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Lucene expressions integration for Elasticsearch # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=lang-expression @@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..5058db4fa55694ac6029e146b00101c788b4effa GIT binary patch literal 114873 zcmb5Ub981=urCZdFR4uK8=0|NsB0wVH{{@)801Oh}sLS2MGMp2UKYYYSg97I_T`ak$U z!2Xj<`M(uL|HtwF2rGyv%1BD6sWU1_hQ!M`_A#RbUnkrVX=c^Yl$Fbh;KLn&fT<_U zb?nnG48|?Edw#t00xVQi%8oM}-7U4`qX>AF3}<;wfJkEAX_QHt%V?t$HREXW^QrO%hTdapuCTnV8C1Rd2pc z&61>kyKPfX#nk=bXY)6H?;e@G&BT5Nn?2t?S%~OT{9*jJ>192O(sfb#0=K~d)C<)x z6i?}}92p_#8BCFdCh!#3eZot-mh9KrUP30WNXRos)rTxH|AoD_2kVnllCJ=r!rZ}+ z|4^{jlCKdFCQk9=U)M`7i{LE_y4dDp<6z6q42B$TGB0GR-|B-B*pK)rZZ z;lQ4{2^43ztzWCHU#=}G6p|#A4T8z%-o!)aK;m4!Iw};SBowDnZ4)8_f;<9q&qxnA zc?z~RHafO;Apa9oJoOK7D(zIf>R8bKwOwv-b93VUt+nSL{r6u3@$appixt!V$reNU zPZ>v3TMILwhlT0?ku=)>N7}>{@P9M|&3`$Ah=YS8&;)4X=%8uiY6En1`M>{6OtPNR z4;7T*?-B;|C5;nIWg1#fzU6}KXBrIrF{!Vj3!b1G(hiZ87#I}WcVcLxIGfP{Y5HJl97@yPn7TYE2u)=FXbrcc$XlfKmCMJPSage}* zs(P1Hi)1&t^VD;U{-;z!%otj>{1v9!Zj9#WbioH2d~&~6=UjE zuMktE9rEEnXxLi}1gllaLEzFA3#HaVO|G&ML~pCVQNvF!v$0NetmJkU7$aYw@)Dxi zxW|PSc;52tyG&uMv$=G%TFwAO;HZKAum<(#7=d)((BJd@W%|7uiXrGJi7IsMmKsa! z#D{ujluk8t(&ZH<8qNgw(On|iIS1`;M^`C8y0!p`)J_>Ql!xNNJwBeUUCz=8a+R-o#6{$o8hn4$2(xlDmQWbChWa9n?QCYo|X0 zk1UX@cz7r0li=#OvQgGoo@ET%>o4afVbwyzv zC5_FuW>P)}4Q_P;M&c4hecwTm4T2|~h{|oZC!)DfWE`N!4a@<>$yG|{mXdi3VhB8U z2NsbT`2^oK-|UGNG+Rhz zBEN5t0E`!DV-eETCjMD>o5syf`n6{Mx#f;dT0*6CRJPP`E-Euib{kTk`SeWSvQNp># zKCJCzsVCPJW9oe14em@8Ve$j4` zUMF?HHaIj~ms9V^uTUMs)&wf4hOV0(bRJqvYQk$va93(cCH5@~cOMpHwL504`>va@ zgwPPfgMKQh5^t7CTm}-b20lrH_O+zhaG5A0mV_6)!W{bRh=Gn&uHU2Dopvs0N>lXS zWksg#`tasMl;{&aMrsUX%tMK=z>`6DDw*BIpv6lmH)}?$woS z>ACKsd9Z!Fg{XNIlG`kj1chg1N4t|fg4w@M=JtFvClLiq=&f#~3ZbqST$dY)&zv3K zj*I+U&x2SJd;Cc1+NE}GBXjQ7OWv-0=uGQgP#UvePPC|!bEM{3Fuafttl`ikH7O8;NbB66= zq66!5W?RE3l1n{!vK#;Q+!Wf&F=w{_kLI~{#V-!$gL z(W8ENn$$lLA<6Vs*AM<94Ho^Vxh*goOzmW>Nk@gR0C;LG=i?0N?o$h|1!rBg2vwc9 zjS22^&@$UYbD2YHgx7j|px#J=dY!0QO0*1@)7LFa_mO#^VztBeP)JYc zCJ+%$ld%vpen9D~$okr8u4=av#jb*xv?kt7dq`2#wC~ae*&@pbZVy_o2v1Kpx%;ut z@`mP+7JZd#llI5}zr47-#NO_V1+b88?|i90lztxhEjF%|p@~trc|E8lU_IbR|F+mX ztVNNOkd3olUy{#q2w4__yB>GZ#)qlI6OO-D;U&-*(M5lD+17P@n%u4kSSrH2*i_?9 zMpIjFI>qqWw%|~Z_cfynH62=|8s#^uqrtAyGF6p1(dXm`vl~(pH>;+%KpNHZt)E|i zP1@u12d%@C-h0sgV7PS!&88=7VQ_+eoJVCLGsGXzsCVTVFm_OSU=6XfIQ=`c!dUJg zJ8-}N*sxWmot&uhGcp&S{PE&jZOT^8{`GT?-ogs6wN%Jq$h$z5XfB&IsQuQA=}#g- zROm58q0uN2Z;4s)l{(E?D_nQSzw@{PN*;nG>*)oqzhRTSNDrD33$J6{zD+eCu?Z@92 z_w1b#arNL2qL>d`)Jk!Y3k@!Xp-ZDZFyl8UEIQ+o_9~Mlijg5b^5^u6S(4gGCutf0 zN|R$z1}8%sPZtm>RrGb$b%L&!9+z3<(`Akbq%(@2V)TT7lWRZ}YFWp_Lpt zPLiw7?0ou(QnS>#senqVdW@s^&8{|aP6R&2h*bXDT}0_$-}Bpw(JA%G*FCj+n=?L* zDuv^Y`)Pau2m(d_X(Y@EPYAYO7Gf|EQDMsH2#9&)*lS^sExj{P2~=TIu_W|xQ21in z_)hrZhCQhGqNn|l@85UZgK#oL2^j-()9>y*apR~1ilp0vTniZ7@LGFJg}Q*vs3N!& zd>OA`T$u=Vjzrc|Tk;|&C#rB(JfB3WLPkvf$TmHq-uh7GT6^q@Fz4c_?jxx@03xsG zVO;K=o=vbCM$2^kv;y_OF?wR|;NVgTe)iydFz%=xhw5~5!pQsb+Vl444@Q5jwP!8f zD6pyP{9^qtJS6U4c`DXmQvv(r{2{XN+l8IT_tlPSdhfL`VsOj6Q9iiKvJ3P1qA^p$ zP(^tua23^(siAkJv+&`IGGkEojkUbbu8Qj?agZ%n{glJaB=&GuVzVH{_iBCJ0afis zcT_Xn!tbuD%T!!rL{bH7b`FFK&rUw)AV(FKwmv@R%wHzh34SMy;fy3I&md#1ivrPq zK(S**xF6ikl%x376BP(az4!+khK_KEBv~^@6iC@57Oa0{^tbXyNxx%6xFZ_JlG?WX z8~2S=Uz(_-ogYCsT|RBUaM3O7P69R%HF&{d!7&uO`VKu_v!A7@o;x%(uyIU2C6C&> z7+E~`4n-IgQB>vfv7>DAtFdf#3}0K7WaO*2=Aj%e0OEjnDWftvjP zcy;J&_8rmawbtqFhD=xGQn|G09e4gcNL!`vH>=B1NX==~_D}4Vsnz!n9jrI3rzam* z%9%h58@X%19G|}9f=w;SwyCR3qPI#s#FDIKAHB1TI-LAa2s(`9z#P{db-~ox;tV?U zJ#6f6Rb!!R&D43O>&He|H9u9SgHs;A{UI->#9H?aebhihYq9Q>TkM9Zmf{MEHTy zam%i@$>tmX3A5cFcgy`}@Z1y0anH*#F$V^mDcqMcRKioH((+ns`a0yL&AN9yAF(E! zJ2w3Mw)};*d)s)JBbaNz|3j32Q1hHRHWK;u6Q+A5cV6 zr{=JQ@aJsijn*fcZ=uJ2@RU}oKYX_bj6%2G$=hdN9uW#-3cHax+~#CAwpx*51l(*; zO>b_rMk|q)^QHI1t^?un8p_aeU6`Ge%yOKg6F}&cu!kyFEmD;HhPWap?%xV@t2cX^ z91|NvGRkil^rxH1^nKFH)^qtaUXUDu6%Rt>55$PlAdA6Y3$wV zJEN#j^K>zu9tF#!$<%ip0kE_KBSB22DKAL-{)mmZVr+OV71^}zvTxKPYB5`W%|m%1 zipYX4DIl3wFp9B+$P>Y@nv&{?niq*T2f-PX#bfAl6(v+PB*4Cw*4^5d)Kh5i=rGM) z^_hAN3gT}mQ)0cej2>_KsU`j9X&!x5P(Y4r{X}RT%(#i*NGGFJp`23Oz7k9DHKYS1 zmpI>~*ld5PEtSYac`(nvKd#X#iDFz93Pg$ zTcRn>1t>n6&n9hHu+PtYGrcKP(GEKSj~Y)1=Mss`ig5bM!X*xN{l*yZ4aUSs5Ta zGcQ7K2fby^70M~HHD;-Uz~32~!Gj7jvZGdfBL-uSP;ynPR&ygtS2N^(z^_#pA>Y6k zv1{*Kmh4z(uCNMk*zt0RBi77bf#YlW*LNb$@Ajx&4_Pt?AZ-+%%xvto>%rcd-ODe) zJC`&A-X5+lZ@2uaUz7R_kEYSX(+Z2^_MUlV-!FR-uyQ=9^T?NH?A){$Mrs>wZ7^*oTBP0R z&S{|%z9|V#aN0CNd*k$GUZ>g3Km`TPbTiuf`oq~i`Wb=uLr3Gj&ji%4&G7SlF1$_% z{iIJV#4zAnzsMBL_5o>2BdD^^hn5%7GPWe;bK`}m)A9W_ZQ&l=bB2UPi~9ktWLst? zYW!m=C55q@Y)3ZF9Tv|m#H=Q%)(CbobqX(0(6^CCoj+QLqa@a`AvQ`@ti}mi9~u>= z6&uTEGw81aggz^_{x7Q7kPin85Gb->b$BtCaX1hyO^{Y|koYe*x7$q|qZ9D}F(&v| z^q0mm>V>-ue?J)Kzp`{axB%X%S<76-d$R(~@X0lK{mMzv3d|nPDi{?`p-o*_??#@L zyvhEQHQ$R_%pG0;iNmtupdbHpfM)r^-)u~#0r?_#ti`|TWt$O`E9Nx@6U&(hVBl50 zm!l}o4W3QwK=pb!+ESG@?}x zbK?3vjoHa0{Rk8CkkRnldduzehyqS`RjEYT>Y|XiB5%-d_UR zo=FrZu&`GiF&_+iP(vs#(77&qZwFgJfh2Ec4gn6f@t!${M6qK+H80X68d=O;%yJKCdwK;MP@N64SLkglUosCCM>^`DQe2a zB`ShEm{dU<>^UebtTID6RML-5^IfyaDTnmbPI}_8Kpu4wBa&8YZdVuLq4|>5xlTG~ z{Ts4S6WcVBOpC=mg;i}5znE|R(L}T=ab8K5A+-)q{V+e;9oE2+3JaN{pq4DsAgx#0 z>Q`sTWt&R$@<7U(&8Ctv#v;373L8yD)p6euRqq6OKgrpHj5`-YPRpWB+wnR0#NSB> zA=h+@ELAr3391zH2MxQ^XBGv-+iL1KWa^yAlQnpNn_lEl@=JYgF(Qpc!+GJvs=T<+ zWKxGY+n|qVd*b$}A?shye8B|lKb!X*XN7VQYrQa4*f^Od>Yl9iFw43bjZ*wsLOc(a#s8YTJ0bOfwPR% zMxg+SFNN}EP^($N@(1L9m?GF>;|ce_TGBe?|740J|FbFnrx|L=xuP#)d|h>VTUrN` zvj>UbW@?ezkSil-W6MyBf=$HF_7lb<^uY=gq_UeXR6R5zkirfjd0o~&(rS$Md9|v_ z$YPeQ#AjpaSSBcJrF8F%Rj5*KcWs_!80W##E<8J5@f^QTc__8`-;dT1f_s8)qn^}e z5Bhhs+NW-;Th?utRzKvp8kFekyDA`x=6bDq_Mg;XFPVNPv(BSnTEj)hj{5~3d)&A- z8sDkQ6Hf#R4;UD6KNk&F zg$tLz&u{ryri*w?N5=|S%a8_X62OxGfXP#^Y*Md=BOhC=SYjCe3!vFQ2lE+QboSY* z94D=_Zucs%*0kPU-DGP~P_@m3z4RGM4OI*U%9|PPJYE6tqqU-KA2qHrr<57Fxc>OK zC;uUkNwCgL8t_yeW;{W=G(l@K6GxPa=pe^pOr<+oS?dcrJ$b3*|H1)&#!o9SQATZqiqpBIvzNGk*MPwPde}%Pr<=#$&oZ zWNp96Va45I@s`bZX@_mubJfP8R8J<8HF(@Yeb;v(oR9;pL769~_%iYiF{l;I2f0kW zNy>|K?>-vO-l)6+DzpFeyECj4f`_1EmOMo)v4Fx+K%-tu(*|=z3;wVp+SQZK67HN% zqQhm7T5}?gkoVNq{9tyt$4g%JRuR>sskvL=${TuJwsT5YOk|iRn!*WEi^ko|-+!aI zyxOEqYcnM6&#XxL485V;-2?~0FYLs!$y4r#AF!CmZixmOxfk;@ECV9 zn|l&Yu32ndY%`|%HxicJ9avW{3V(WoK7mIkg?q(F=PoYqUsAjc9bXOMk{Et}MR#@` zCD=lfXdh2C-p*+#n}zCxZ&5tE%7~$0si8%Stt2MBqk}csS>VU}O!?JK^ltLuhS7p+ zss(R3!AKAl{L^nWRtvddk~xB1DPe4eJBkq%>A!@;-?#M@+o-Q+xl@Er?g{Vc1c|F* zE18#mL}fV@Y}-56l-{6{Ha}zk4&5kBtqIr(W+qP;M)nED_^n*OU#PiyM|5JnM3$w{ z9Ev@=`w@YiD&-&u`Q0@E6eXQN2);)Bzs=b{U@~$9+*-9gxN-6Qk*43ne)cSK=NJ$X z0~tC37sT*!7v^-2`d{9;=Q;wfrW%_A$#y50ocXI3H(F?`uao9m;``RQBWo&@YrL<( zQrpwFkJVoo{r_YuE{DoXL>m~Gq0E;`abXFoohRtw@Lg^JJ4EgjJ_0(Hl=c_$7 zs5u~rv$GHE7Ch+io;sX4Un)?tPXI3QV>Lg3iB2eU8&yHn5H8Zxk{Oe5rvBG0@Pq8( zxp*Iain4mTxbaAv_fPDjg=&I2@CO&?&0r=MG`o$H7xULu(sps9?on8Zy8kr(xA62& zbHSga$Ulo~zeNK-QUJ$}aD#|U4gsbMQY2D(A^3=JJhbtYcNci*CriZgWvw2^j&p(-L54J~kgzU9)a`BXA=tQ|mNV&=KKX~WR_bSsu`d~TQ zi-4q37;X`w*qYLP|N71JLf_YD8I&9(l>M?yd4bx^&)5|6EfGx1YngLpD^c;*V(Nt` zSeGjlPb3si6)$Q0OrZOh|86H`joWqfXOp}2{MNYmQOZHTWNiGWY_35jetnp_4 zD)dH*oO|?WOc+b%gjh)LwSh}u5ZcPAwn6Ao&;@SQ2z#+{QLIF&|`Ct4zr*xHOawb*7{1K>b+N8x3YjIw@`)H$W>!Zh& zC0sV0`d0e;JKSwy>7-vajp15O%IGgG(-^?0iW4k0ZW>ExUH$&>)>v5Q0!7E9z%5Gf zE`>MmB(ex4{}MlVWhTLxeQqP;ZOyuZ@BbCXfqF4Sp8wiG!N~tp7$^NN!?>sy&_eTH zBl&-KY_qihPU>1X{)$gqT^-}1jCour_3(kAXq<>9NwvbnL?}Vz;<*$M;Kh@ct}@LH ztAmrFn2lqN8Ed+LQDlOO7nKWkwpe#-hMg58-U7{{GwyvNw-4)2!k@fnrTgL2JkM8~ zAyD~!=Ffjzr@gk0{kD!fpRXQ&{=CEu;2we`ZTk>+b+{nm)9_p&v{O`6;<)Bfs}19x zIz)s4z0W&1HFu@V$hH z+8rQ-B@|W`)dd?W%Lv+_tBuXX1n0c4r_9Ky?JpJ42#2YF3^H?(U}Y1FE-K6L-I~IL z+UNx45ATDWsrc4+@!1N8Lze|1 zNfS)~&|C>S^dZ9s*_O+KXjVm)A;PaB3mx=$KE1~&7;=&p41?3@YtyHvM`7dv@K_*^=jqbP1qVembN%VE|eBnEb$|clPuaY+8N!QvuD7?U#^xG z%U;N1G{6K>vx8VONP8XIzoW0*eW^qH&K6Qe_5sJ?DIKJgl1*=zg%HH6fN98*RG(IU( zzt+pkVYW4QeHL)Mqf6u1=IC*RL_!4R1(i(U|MVgGLS%ck%O5(#xwV{wcxhahch0MM z{i>)R#l|!E657*lzoqc$oe?ZTDAGG z*H}H(U)}LKi9FBq9~Of@(0rJoofa$BY41#G$m;w%5N<@doTgnO2OJq!f5lijrCa#a zc-Uce?NB|c^=GQ_w|5~}I_I&EI<8IE%4^w#i$SMDr?xf>7P`*C)n!mc@8-;)@jM)uV2lr(UFM)jQOf zD@0e!Vc2Z~kF&rnyjP*jiqoo_mnwZ8MuV^LN#(Q-@1ZPTiIq9i@$}!n?b{!NuT1iL zl%zjOBZ3;V$o=38H}S=WP2PWJ^Sus*q?{11AcuKiN@lu13pL=8E9vyd|QpI zxfy}-FhX#o0c@nNd?euY@IN@3T^w2)VydgJg&A|HK}beFegimbDF`C*H9Hxn4r;3oskH?EbSk$+U zv!>#4EtHxPe(7v-otHo@GYGuJ@`?{VI>Wx&h!?&Mxa%JwG^!l3RX1o?JGbb|nbHro zs@0qYqsl;31{6M+7GT6D2WiG9YwC%}*o26(S|XZ2T6k?aLjH4MT;2HFJF4G0u9wi$ z|9Zuzu31-!uJ43+{C8bw7+k1S0-}yCp~jkf}|wiV`d_i!mC<|(L7b` z`{hje41e(5P$Kuo4Jv-fT%d^pBQ^5n*rOc2Or>vH+~c^(pJ>6e5Alo{;*!|od(R2R zg#9^h;wsvRiDZn_T|sTa^UFLB(`5|_fZn(@NIU`x_{x&=>8t*NS%oA-139n1DHE7( zNQft?w&AabQCq5hM%x{Li!7D!>e`;FEOp!>(mSdPs&I8j?yl78Hub#caR*tL#=9Vy z6mf?lnqp7xd9MDTy2_5?R*KDAbIGb&w;6YqSROvdy{35QQB9&M*U+k@!&v&$nF@^+SOBL0kVo*8Pqzgx-)7$x15w>X(%D+y) z+(fYCk7(4(BDVr+e|z&Xh0|b&d?WuyjU(D}`D5}Qe6!*obnw4N;*tHAha<87Ko_c7 zn3(@>sLVnav@gcs6Ssfy#TKB&DoI~e`h*-5f?Zg-P%NG>GC*3?CD2%!8I~B6e&Fj* zq#%50xOR1ysIWwx>2T!ds?YVC{cCo{W>*_5=%-+J_s`jB%aUw1tEns=3(Kdw0V0oW zXpqm<5(t;GGpy$dy;gR^)mGZSwMG*C_5KC6w79s%!*u0)kAlPyqH=VanhzCar3M?0 zk@hFxp+z*4Z;_Y~5B2@BC5+e{77y59g~=vZFo2Q1Su@Egd@5OLP_@+PY(dkxbXJuC z*q32^LAQZ}S(*^srya~#>deMmpv$VcN^Ceu2k>qogAFrzGF{Mepb)Y^Y682?c;O`@ z30Y5Blh*^G88$)_9(Kly47O0ozQ`Zw>*d#3pU+~*kt|%RIwREFPATXzm@jebO`h-K zWpkO|P7{U6F@T2$;Y$-JZD9ZqGm`-9PYg-?veH z(5tI#pR?NpYz-i#Z!|Lml`vIS*x6fG)@TdTY_%3v)5=IW=?t^00Zd>N4Qo~( zT7@aF)Pr^$e@#`6e@>eTx;PFL|4la@$%a>y$XH}S2C>KgtZulT!tF6U@R|0~z_K^c zDgLA|T{um1Ds^dL0848jy40xCRHw7qd4eV7_AqAAtw|7Dp19x>AzEL>fJ~x!ARuoh zP53#Z36U<9Y1m;;!z*#7Q$pHit3I;G?a_;F{}C~qPU)9ed>qDj+OS;(%)@EZ^Tg9u z#mJ>?DP&lm)9gA-vMm0HKVB>vqSTKW-1971Fq^I?sNQBXlPqgKLWy!R7xJG}*vt?} zWGI-O1A&@M)iEV^jSE3C%sMx~NJyM`8f~GfNnQ7uSCBTMUyAwu#XS+Osqlgc0vkb7 zinfe_A3_)=MEE8mnC9>SWGZzqeUi->r=h4ZE2n)JG0r4)MP0`vDTm4=rTW$)v0@Zc zLA(Djvu9>?Cao?qop;nUWer(8{f7ct$sM0cRTULD8ZG(FDwRtZkB`)}1?0Xq0F4i9 z{VD*Qz^sCY995H%{wxIs;^nF2g!Y<44+QJxX<7BTmTrfy1Q}_h7Cjy{4fqPc&yawHQjP3lpTtRo!sb6gj*~IcZ9ILb7!5so0ysJ>Vv1)X5`!0OE^?q z?AE&>$E9_{4!X8o&*;oSS>`Clc>I*K6dcEzE~lA{-)4Da2!}IKR-mmETAG&La(W94 z)nD0P4G7%2^kMil^9dDr`($V5bec*!v*{OG(BJGk_<4Bw1SrS9?wu~fPi4+jlBe%? z!N8Y#yOm9~7PYvB7+R&Rmt1#D>2=f_@=YQj&qLbzpgDIw*q11LFyU1c4=kM8O1Hv6 zQaIcY!%dUGor-#VDVi(Ft$Kau3A9kX&!Q&Mh2p~`}1fjZi( z9B9 zWu?y(wAoy;E1FhK6o^u8Xek}Qm^1VPTZtlVHfuhg%W>Pua)(lf$_gS~T1~yBt(e5} zA!v^u*smp?ysUFF_+mven@D^Rj#m;}>cs(QBkybn5MbkU${vf1e@Hn%kyw`UL;=x6 zzpfU4LGhCpHTIDi+xi)p8SI}O2Jy7LQ!NHb8K=d<5H{_A=5-SV4KuXe<~T610RTD;>uF-wjuFu#S(;4!h|}t zotoMdh<{zYf~)gu5sTh+&9-}5g8a7gHrgMOm#QxUc8HudTO4b#MukY`sTMV=P=4GH z9pokbQCBhG8&f&&&cERaQKO@cE7zt^|K#%qy98uGF|;Z|e$r^RH!pvM0Iqi_s78eqG^E@TZ(eB8W?kdEfyaP5z0K4k&b9}l}I+&#PO+=qB9H{ zrpzeDhg*HZAv*`L4>0d6T-S5Q92K_uaXKo#o5*49x#1>fJYs~aF)ZLtssrZO9M+;y z37ZTI@NfvLPlC7`a!Amh(;=R6?b>JIa7GpM+|^c*+E~X^IMvthD#AP!ZHM~{?8jh; zZ!-AFMtg<@@4D31k8{h-IP*X(0QuXn^~gYN1(h-iT{=bq4)xf7O`!_qkF7g&cH~k% z=ITt?14ijv9zntfAS%4)!m#LF?1qanR|tog(wNwm(8^Lz%h@n&Ly6Ih1PeOB6jWd& zDM~ZNF@YqOKGoB$inGuxA<|WZ-jVM#KgU@6Mn&OrwKRc7Tru(&yVgj2R zFy@jTyORnac8Hv*kp94~hIEU&y~3cWcyZJwg2zw{)NW3DhO}Fx(C(wj@OnGCVcXVD z8zPw8T$qS19xwA{EB5*Gp_V81{rNLstc%m&{Q215v#PyixG~OsiPZ+D(|)a3Ad~-6)PLFEo7b~smMGO{giz~LXC1!-hp4Uw(S*T3d-$hTILQU_4!l{Nx zMV`Q0g38rc1a)Yzy1dKnHvh{JsE}-Z1T!);9t*bb04vyaSAOh{Y_$|tC zcbB5ttV#CQt_{*NE>6` zK7>+s(YHL!Tleo%lgYR7-XlZJ`MRa5)1I5l3+D?G^g3^h&^=JTIzWF*IFPl#n{!~tcmJM<7NJOc^oO#maPTtJKJ-8DVwd2p)ZqV0{ z-+mEdbYzyr1b6BjICC2;2+rF2Wv^-WJ0z53aViynGnZGxm3-mgTe?8ki;!WDgh>^? zKt$1MF0k7kK!O>pK@F?Xoz-apAJzI5>cfOvo>**#8H|Ro=ku6!;)-e_Z?tF^mXn%= zIZ10Tx-sfw(KV!^6rSd3Ex#!p;aGes#8_N$r!o2bsV%QzQneOh%k}=QWjCSUuejzY z=KIvMdN|nF*j%?^dc}1*#(RuHLzq(kykzl8$e)w@vlAaTGMxWNb>$wt^3pJ3<#Hb4 zyH%GWN01lid#clR01=M3>&M+=l;ntThw+M;*%&pXkAn*SSpnMfd;lGIA%!0Jgo+&~ z_GJpP)GIz7eqnV-)Ei_plk*1e>3hKS>qBt}-urGKC(wa>Ibi_}dluChKwr4W`Tsp?%q!czpJcBQLz4R!<>A%Y}|Y~H6YL5MKd|Z56v7FiE6$j z&9X!$_N}{vGdB)H@40~v48l7n37?|^w)eCn+{1w=6V*mn3YX#W;5`|F)JjJNG^DN; zu`tmb;FZDTcEy(xM`l=KZr6QR_Ye-oC6>$`&_;)E@>t^~t!V08urr8LEpGF|jBQft zUQek7pI9gM;-vAKfIG^)Xmdt#=BhM+P6du79vuTB(&rPI>xw^Epp2WexNFv$mk;r= zLP~>OlMzQpP0I^C@GkaXJ@Au>me)nrhJ*p_ygZJ1-7N)!qk;CUV$gXO;Z~~PQ#l|j zZ>(pE!12m|I7<6{9@JDHe2^oEQ=5g@m4zsn&fL@u;9HO2z1b&1YFkro%iu9(j=GPc zYdXWIj_+{UmAOzG=NkDP@s^=wJ1cg=Eb^2mEulm9wwpwo+7TQh+_jHk15`f`Jk=&C zx#9sKAnQWm)nsNU(nYbGy;ZcZsUVC`Nfc5Q(SBeq868;as&-e99Ja%yqvu_<;VL3i zXUl4c<>X@EXG&2ln1?jh;S=UzO$*IHy3!%wNN8p7ZvABu3!{6M${_Vazun$T!Ofy+ zUVUWP-;=@8l~6#G+1r0k&wVFyVCj1c=%G$oOP_lv>P|OP$Q0YMUi3p!NCUCF>uA(W zMpvdne0fFhSqKZqE6$A1fL`1&qJ!=%B2doNzhgq6#Lhs zcX{vHp5OUcaP5qD1M>6&CH)VvLv+H7dFPNLQ0!w!Ni#=Uaq0L*6mbXHI9>AIa}O@~ z4s@}oh={k|b@{^!%LQt(HOwcJUIUr>GF4Gq`I&=IZ(0wuN_DMJbUxd6RN)<=hIF}T ze{dYk8ekSa(%$#KUGW$cHXk3LL?&Y(ygP7P5e2IHvt#{W2lcnZWnV3ax!NELV!A;% ziksm~99)eZq^>WSdUBPt4QL*|v-keaiUHy8+#KDD2$Mftzo9AK4PV~NPKEz|o!!C# ziq|2mT70}cRR>wPvpNVQT;dwQnK1U#bqDAtN>{Et&{s?0+9-&$SGH;w7;2Jx!{>-C z!N?Z;<`e@)J6!%!xVSAwW%Bo}XObY}`=a^Nw(r`;_z2Fn73d^Dcz0PXU1%HyBmt&cT6#PSUYw!?ubv$S*Y|=jL zrK&SY`pOnG59Ay&0?VL}?bM^prGr z7PvcIjs&XeV)hgHN#nUJIy;1acaG_j1c4DGsS@LENHckTPyJ9RLrbhH(u$N59F4~1 zT9c8J3<4Ajti_-0lZ!Qks^@S+8c2HvK02!}XrSfhiM2iGS}g;yQOPU#_&a2_PA99b zUYw{_g)ct#fZo9e9rN?MqX~QxkneW${(n2#W1gKy4)W>OepWn5PoC+T9O|dBwwJfl zGG_gyQEieg+1?CGRSn&uerP(mR=imut(hOq2C7=J^pz@hFoza##7eubwZJ{GXtWQJ zWoJ&yv!%zK{)u_YpG5~Bm$xy_pm4Y-ibODCR9Zs3y&J3FWC--b?|;=_$~EV3Ul65l zk6j84cfftNYx%^37us_9^>*|hHz9OeVElQVfAS2eZKp>{o52Xu><#KE$ z0C_F(i>9=tpi8ot&^jDb+SyUlxYn@pMyY1I(K}?o+z;W7?|l8}>$H@DJ5ja{YXS+y zqhl@W4>_Gh95}*K4x%_+)?7|&+NBwE1m3mKN@JM&1rbHY|2-4?}#9hHh4;4EMmz z({EAb9#N38$5N3oTc5W8I505RW+us$&hodhvg!uz*t$-ig>FSQn}hYCTAd{kl~GPg z$DV_4DFEk!J9%_&lx-*)k8RVGio0q#oPx!9EF1@uZ0P7KfASKxs1zx z0e86#RWTn3)ZJWOFyph&dI$=kpNd@8Vk)l&GWv`L096PA!F}913)pRiI*^Jm`Em@1 z&0meU|0UO$gpq;!5A9GH_!Rb)V!3lW+*Y91NO8w`5}jbDT`8PHX*>>@$IKC#-E$@) zN?t?BWtbg(yDyYkDWhyuij6ClB_LvJigbL~rgJd#E?Lk^+JS81sm-ha^I<~gsjqT8 zdR7Vi@U4DkgzRstW8ly0Guo_a2hQ3Oy_>ifbdvh#LqMHgoSb=$5Bpwu*G`#-T<>IL z*Lbp{zBqf!n%e~FO5tW29b7xYOwji(ZS`qfXC^Tkba+MeR9j{Z7Si-%{1wKXUyjqX zUO%XFQLeMfT_}370J3!4a`8r%ZRPXW=T!^6w3u5zT9g2(lKU#7hlfwiwS_m&Gt$?G z9XEM`p>>b%Q}D}BrNHm%pQk?UH-=+F!|vk}+Z|#83z-6TwN@*xebR9X0Mf@!`VJwiQvvcx;PBGO6?YmOvg|wxaJ<9o{egF)!iLUNHgyZRN)oxZ5yMYDX*gQ z{r%=K_Ven6;QhM5a@(|pgCB*Uo1stDigb_q$9NQnVI`GuW0GReOuV5zF#+sJ4JM4K z6Y=3-C}8Dp1<5jJq#x|a4eU)V?bq)hqIKgZMZKoM9yA7M^p(F=%+P@?eVt%>M##n3 zUmp-o^%$7wD{J1hwUeBsz{tI-q*VmJn`@-3J|7i?D={8_kfL)DZWKb%2yb+xU&FZw zgkfaHT=W4}#7NV9Xr4&1LC1NRhQS!M&`W*eH-eq8M7?^{o7X*9H;lfB*S#LvZ)CD> zKWmS;Ua)m{*!p%{^ZT&G!)n42jgstN{s2RAWRPEwPh$cNQDsepL`RALFTTDhxECh) zGRci?+s-exZQHiZ8{4*R+qRP%+qSXae`{a%VfSICtE;A_=Aj>Yy8E0nH~}b(M-m}B z3>PCuN}?qMZVU#MD%sSU6eBa>pdA}y$@$>X zaoDSQm}g+58y6(K5fU&*JIQZdR+P%Tdvab)WRG+4^V z*Qj?0We?@O`gxDWBDBir!j_C@lw#~{7P*Gke}|&f8;H@?JR%{O$?ZTzHuM~TGAp9W zjb1kGStsxyF9OUD_c&#cG7Vusq!WB=>JZ_>ZG#hKg*7hN-Wy3I04_|96?laM4G|x- zZ@>f_nj~yUiv4lnsa?ul@Dj&%H8huj>KfKtNmOT6fG{ zV(IvjS%Z3&X3IDr5$9amRLqcG{?L^WGe?bhy$J|&7~rKv7h6#CpdEE?9YkTgskfxz zK|9pmt3VcYXwpb0G?esxQ=2q4@{(ea`P^!bwY2mrBW{z9CP$O4w9H~W?43c3!fK6p zZZy?QlFE`fdV*N^IwQVooz<+di_#A^aMeI#2i1mWIQ&R$xUjOoS|_Uq}z7n%SM0L{RBZ_~C}%ZZ!; z#lrTaDe0Gr4;<&d2C}D`kchW9>PdFXfD$4hxLOI|2hJ1ald{B+>bFjiSAr&n^5A*M z(B5nFO_-BMCik&El5V3l_*A%`7?e$@+a6@O8klWxcB9z5+!Rff`SQoA1b{Or`URrAoFT=_X}Q#fh>d z)1qx7C7+y%;$}5%A^qWKRjA%L@3tQgLund&8EH=EFCB|ELmpRLwE^Nr_dspdaKK0p zX%L`YlOcA?%r6FvUbAe*me`Y=H$>~^V~jFoN=~<~3Tp<~a+;VKN+r4)8O>Uj>+xDP+RCvFXDsL@iSZpt`a&3j>L8HC|3Kv5ls)5DzaLT#v?SGN#T;T`j2q0DI8s%S zrJK9$&1=I3LAaOB8JJ7>yXLP?Qq7o9KLw91vn~yN0&KZrW|Bw$B*xrdQzOc7UL1PL za84Fw;BF+>kZI*Qt;nKV!C(k$NJV$XL?icJW7q}RED&~4akmU;tmoHfB$KO>_dv>$ z#aqvtccKSU(y?{GKa9uBCvAcHj?XwCjvAAU*8n26z#qr29Y{O=R8Hj7C)xz8r1K?g z!Ij11IZ$^X%o4s1tse<;gz>;$j?=$kc*4??%lCsnpz6rE6?OQb*AmYSwH%4I=XS%g zC#dhkKVb6+?D$hm^cf;}qUaIb_IDlWKDq4*BfR=P+3^#CzsCnph?7S7$ap2lj{`kW zVF~e(6pf#nP`?LGlj$cyKcI0&`o#3!upfCm&~e82h|iMjCP_~q9AQ6@bcB3~WKPT- z`8^OkP`-!oi2IS%#qW-H9k~y`LA2TxSRj-OLcu9ZHBpuIlnZ?-@bkulpBZ2mh9&+x z!?aqeV9A*sbLWg%IA)2$7v^3M^MSAv@{{CVc6txe8H zZjWMK_RGbKj6crq1jArm^oiOJt0z`pw(brY?G&iHK!`=j_7-4~-5&EM3W(cNP0 zw=S0|z-}`JY#?;>e#oxDBA-Db6ei4ZVKqzQ(0tsiScIk&xsfgW6`}d0o92_13tdQB zj;OsLf(de}>5}ezjLc{w?gtwegfbvyDvqk0%tbD#zE2o9gPw3rq%IZjY^5>L zKF+!qHdNb3ZXwmjoj+p;7r79d;`n@GJ|UB z01!TnY&uAGuY)PmK@VGsAD}z9Kd}7AsY&3pE@A!1;VIth0dH|kDIcNJLEALi6|pa5 zI)QN&vNvN|^n)dRn1T2aP%^~h7y8r+%Mqd;PXhWMFo831dMp{t{Lb@8!saxr>3!b> zxD>PJn(? zCQw+#C;X<}aU4$c3V9({bWmE^IoSFns$#~Z!(rMdc15IZI*dyVt+n6cp(2EFCUvx< zVK_P?4y2E_^a_N;tPq>L%C;9j6558IkS?p}<7HDVDWsE?Hxxcw-+;e2BYW*g-1L{R zFcmJ#XW7=(AQ9wmVxRytm|!tb*Td!_f<~5w=itab2FI7I->~BT0Y@)s{4i27hX{2r zri7%%nlsDk;0h{!5nhAv;0)|0Qd}U@@EWQh`=js`zyQK{-^|IY@Ytzs$o~v5k7}`G z2v|3yTsPEk!$jf(>I5nj-p|`m>4l0^DJVl~%RX!*2Pc_`X8LT!LJ|juMeit!AR@Iab+;ylv!sPP&~C`Al4;q+ zWy~CX6;qLtVG4ryVyk@6o;`7fFP$qh2osEJHULS-xTf+z<-eN zL`R+~elYV0{|!+;x4*-$%wsqsxMQ^qxCJ=8XCPS^CZ9zoxQt4|F6Cszp#ox_49Pje zHBA7IN&B=Cvd~v1;(wc1R<6KGB zn)n^L$4Q%-7)}J2Qut=P6Ux;Xo}tg=3{650@HE7E4SYw^t7%{T9|`DgKrI@7u}!|q zXTTSASQOrE5U&ToVO(WXh1k>K-j6^km`;Sz-!V$R9EhlQVM-p_K~}azHPHQW7#+Gb zC=rAdJ$H%FMydcYI>f3|-hkNZu|`6lfD4Bp6}sI5u5J|@KO*x+`Z zW?@!W$aP8;MCu$tQ14*K_w^77;nM@eMku1eBW6sATGa1Ef_(P%=<7luOOHr&<=Vm$ z-V&t}CNy_9Q^pnvJF|#n1$|6|B_AiWN*y#)3iV2z;`q{ps*=K)0&pa6WUiNIh)%7t zqC&iAdTEetIuyCV*XKlQgd{1apgn9($X-!)SkI6ec`21r)jc7>#a zn%268abRd^6XN7(LXYIF$V}m3iFbO$T3?EteoZLt7lfIY zz?V7duuyd z%D`fY|29%w(2aV$21xK@x?8A6Ck7`#g^7HC6A&A=3LCr&8~$K5>US~Jd=?(Ks15a# z@sc4>7BEDECLkRTUU*#xbM#~gvK2^5lT*e74G^R{m{1L!TF-$ylG-n&24}sdq%js7 z7*h>yXEJ3#Qx%d^4Uca=wJ-X#xMT8s2W;(Mr$O>Hu7+qp6A@QKZ0H6%VKSDOd&QwN zyqXwL9RX`pmSA}0!W5VzO5WHs!SaH@6!o1nZFs3LkSmYg03!kSiD7Aik-&Oo4(Nr~VdS&Ir+7-IhUrXj*e>o2C#=AaYM;ce3HL-L>{=n0fb7iPK zVLiU+zRvc*xGC3b=AQIhkC)uwT`}pl$npX-WA<8<=$q|kEWfm4!+t%NTM#tw&7aI0 zmoO0J!nG-E-k7$q^cSt?OMQOmZx~xW!WrY)O5QkMX<4KE8UI?@6VD4)kH4=ZgQ32p zsV=;(AzbDBXE8CIlkX)ZE|k6WE*Gry9@)9J_&Byi+K&x3b(jw}wX#p=A~XrfS!w5tj-{+_AbnX4Gt?CM&3z^n&_; zrJ!dib5V;eQB^X>nxe(Mb9rZO)TV;CNMatvX9k=J*|j8-P`K#Gv+crw_MY=6?XH?- z-v%v8SDc%|c}w;Hb|aa}jREBj<-!L-w4V%$^{1=+KIgwFv~0Q~MwJha z7f_x6=p8xLJNJS>dpbz+y-rF`#uCzO|EPH-4lp)`RWdF^2GU;R1>CiYlYHzML2E%u z;4twCX(}=cp;563n*S^le01VJB`IP_5~HF9iPvZeF`QN6LN&xtOw^M)r7ZHB}v&7l8aIY8!M zoQsF(r&%*c!YsuNPq^9>6;|YV&`YSA41+K(m3@?QZ6vs5<8t;=;=Z{!P2209_`8u! zQBS(c;PTDgbXzYxxPMZ}bu zM|Mu7Q?j$aP+YATTrA^$3&Ssuw#hI-7bbsTn;Oai;fjWcOaGA$A=*Z>mm^Cv2nN09 z)*L_!%qq(cmT#7mIsKsGNSYT+!CtX9C(vOo{Sn~|@R2JZFbDWsV@?!3jw@2!1Hm2= zMW2!YGRp=ya^X=t$i<#>45;TqnQ~#8Jn*OYb@w56@G3nJG^V|U@NVI%Jb|l^LmaSg zqwc-=qZbkUY2JaN+aU&RzXaOD2tX0;j65O{{sVR!c>GzqeL#MTL3 zVB=4A8NuvDAP|H(w?3t+h)8t?ES?g*DB zR)3f{;^GV0nkY-`dUtu?U?Ayw=V=Th5Y#&sPi%V!dBE3~_}Po1I!sYHTv?t=TSVl~ zG<)#c$Y7rr^g+W5yz^x8zk57e@xklK)fchf$5=A+gW4YWw-okX;=vr3u^@2Dit(X5hzw zGwa@{^aDh5h|s9{WvDjd-hllB$(?y?7W3uVn%UPccf!!P^p5XF|2IQ-P~SA`-TDgq z2fQn(Z{lYE*X;EXVO{u3`33Vgns=_xjN#FKjr)uLO8AH7Gw^q`_pq-?|Bc`ZVP`Nx zsG|~KN1a_pg&jxL+5G7)jKp(wQ(-#zCtm(f`XphOE&|~nwWN{7KlO%m84SGsE*n@i z#_^#5SJI8ydfKYMS{7o1bFlOw1&H4pH{Sr6jjIokbC8w^!o}%s*ub3^uk7_0*g#nyD8auv}T&G3EZ2121Tv3omGh zg1KaR-jIPS-%KLm_JT8cQzM7+0*nvxn2AqFlC{g`r0#D(X3u}857+SjDX07AYNkG+ zk{8sa((#5=Tv46#f)+&c()WZRP8)Su#BR}K4dEAdFoE&~ZZq&kQmPd2Q}RTzR4%Y= zWSs2#DBK6Z#fm53pcar;hPpdNjtrRmB9E-!IJsBMJ2;!$iwq^pYx(s=SX%(#vNpXu z8#GNWyT9}{OmEaSiiQV;oSPOg^u<&g_)FJ(3^27;Q6aAU+fR!$_P$=htxA=Dc82=K zPScXx((GQpw*7u+I)C&__kZK!())g0yUo9P#AkPPeC#&(w?DmxTQu&ACoR3(No&m; zYBCpp-Coz9`krj;4@d=P>FU4RQ%8K;1dkc5ap=;whc$&b-u2#>mmk1tj=d9)r2?Z- zqO#Jaj(v-Cma2}fk>cHH;u70Zv)w~KXI*v~Uv;l~Av$gcZoI=k=^b}v-*98*o{4vd z7qWaCBdVZ0NIgm7K5hCsODlDBM4qHqjuRrWJjEU3%6cp3Tj1Cnr?zSNI(Ys2cOM3R z7`eOvq)+)xJ*>-?N7h3maNEt~awzd6Z;)7l)`+Q36t~Faex9={&3-l)b_;V<4wIyX zi2?y-K{-D4{nryS+^5e**$=^Ob`T27sn*#Nab+T2#iTLe@p8!V z^pNpCw488JxGY$9yWWw^3CD_F0<^+n%*>+QWd_~saCCy0c^UzDC>mU>Bjwu_6)5mU zb=t|Q2If#ojNRcK?r`fX>wUuI zhddm6IN21XOWO+)oO!@>aL9N3k>VQTx($rhI2E#=#RF$qvKk0T5!F89;C_V$hz8mP zw)^M<4~cq|LLD?hQ>DrdnuGH--DgA%lhxxUq1>v2sJ4ePfz1;FnM!oq2&(#50bv{zQ-h9_P z|EA^f7gdp9BmYj#?H+CaVi4>e{K9y+|MZAY%t&JM-VH9uyaJMEv}ZIyN-zzDbIl;LXIomN<9S_aXoXFcFk!J@S> znClZ)&kIW4S_m-flG(6(BUxW%S0+#L+La_4Y+iK(x?8bixEYrFr~{-Z8Isjhvm>pn z-u)AO7HAzqEYL$Q*#t2iLm#G$-@_?@A*MEF5bGa3IQc_J@CnG}sb*>FomI!mD9?!@ zuL7@OhAc!u3B`peAaN=p!A)_8xM6fz)AFy@WYkK|NA}GZIP`a30i^27R_(6nvkC}TS8i?uWF*h$@8?9) zGOwKEiQN9Fx_C$h`p~6sPEv3>WD?f3qO&h4n=a6Y@o(*~S1d~R7S$7iX>4h_rG#a|ULgeb_dZ+B^0p&8TP7Ix+8d4?JP`6X6L zq**RwNN%sA?)*LZ#SkZGr>#s3=j+RO6KAHck%pw^mGQIm&KQ@x7(Ij! zF}KnuA7r|Jql=&qat$mIJX3<0Lzj~M&J$=#i8QT`Wt{(vR><0goQ_vC@TYp}+MBjLNpMl8Y%jKq+*1{YP}vV_ zb}OjBi2n`4c^a$i%wN;mpE-3gx2{26ZtoFQFhu4YpT|x`NF@#)7Bbv~VoFNBYTVFs zU>+~s1i09S{xs-xiR*LQqZ~z{GTd6bZ-Tl7j8h)l=`8UEByI-%SFNUxb`^9)lIFJe ze=|N!L#TJ8+D*2Ih+4Oe79FXv!Udpk&E0fkQ6sAA=}&k#&Mu7HAY=Q1h2rQ6k+2Qa z2NHAZPs7NI@t2P(oq+X>Xy14I$*XCor37*>DCTrtP7XWhQk3yFroH|(tE&#uvvurS zL#F`iVBGA`w}}c0+(PDFcB=O{zycYV8mSY<#J@HRxB8*@Ovk9eVeBF_7 z!6MiP^|qn^;-64TUc>A~7;>5(!%`)nV<{qU{q+exr5p1+YKHpVWDL!y#xUh$zIkrkFw(laZb)Ql$uT9TBi&1i;}aZM{TtEQDcshpSpB$F)fPlC7xH!9%O z46iUwBD-cgC3ERjs8UeUtVB#&xmG$ga>-gMmC^hvOeMozz#fCUmO8a@Nqeg0)O6?L z*LIi8D(U6g9Ihm-3@s}!Gr87q$=fQ?tSGOTURXl9g17Q1 z>lWpP(9Np-2K?&h=T_ON%qgQ>ykEqmcPW3TZB*-(@095k-zYJt<*70#>MQ)Ks;k0T zMp%|!iCdXko?D(;AwaxPe}*Pdu6ur831+C&JDpOpzk61&e|lE7f50o=x#CvYzRAkp zIi^v*eVI|by-%s)_K8{!^PyP@^Bt>@f0t9td&w!~JNzvBsJ`WS7Try`z~61TsOrU8 z`RCJCQTN$eY5#Vk_IvFu;k)#j{*iji`E0u@eZk%PZ$;jhpepaZSC#+uyVS41RjF^G zvog=BXN91J=;C&RGOsY^`Mnv6Pd4j-x#gU%k8KKL{^WgdBca#j+CpDOd;hW+?{;c& z^~0&9$tS19+1GPJwbyP#w|8gbPcO)|q<+CmuD$1fFudwSTyU^T2 z%+jOJ;WLPSg&e_=JHPtl`=>?cU!Y!uMc7}1nJ0vm&d)OI zo^O~IkiR`@NBokPxB7K(clt$ePrKE4XZEY$@3)JgZ|)XkKRFwKU*(O0pVPbVLbl1@ zMz)RLOt#Tqd)w?^W!vsw?V9D^CN`q}=0*QXJoNfz$pE>HBY{{p*7&j+NK~sP5aH(a z0L6{{fQgOleimChgI+dRWDtMcv zRPdXXSZJQ=6;L53O6G_We%#$KRNi(=28QM>tzG` z>t=%lH?jY2XZ8qpQ*&s4iQAL8&KnqNaSnWJb{#O?cpo_402=_me%Pbh7~SK#j@&ER zDBWY-NEz5{nHlJ6t_qB^{0FN44|zbo`7&tNf*thlq8;>4;WqM@ZWoD(rF&>&GhM;W z#;U^K8cr6OO?2!ETLjsK8|az&8+g2eZ4|BiYe>448@Ltg*O1sHx6oCCUP*64m)sYH zGmz{3dC?7&0_zqE;eXchA$E&yVff3raJ+@Q7+x~oL{HT(MrX16Z2(aMw8w8s6;LwZ4e6OMI~ID}3+-`M${b(YHY@_CrN2w}U7xc|*q=b^9Y5 zxBFVxaSlOpgA`{hK8dqKzso6iA#Zwh5QFL$19#6}q&`XbaP|vJgRd7E`xMV|``cb> zZ(zLKU#Yn$KLT@be=FVL|CXGF{axx3`SSWFk-9^dSoa$JwCXMTao$4`^b|N=;AL2> z!Vo#V{3(Kd;Y%|0b%Dk^&NT)6*0S_t|0I#c={ zKV$R~eKP4`@@myX;}zFOl|73pYCHIpvvE%ArS{6}<@yNsvw4#IZa;JWxL@G?fLc(0 zN-DI!q=+Knd*K~^$B37|MT3x=6gZQ*O@fePPVwnf#+ON?LEb_OQEg!;I%+RZ_?qO@t8D16e9f5h8|kNz`8>Z{Q$Cg5)Wuxas3gu z_W@T0VSN~3)Qw6v&BF#E8G2PehXd7-pkJtCM{Cj(*4aM8ig&Y=b5 zLhEw=VKR}nc|h?6oS^=Hd}BqwrS?K`^GFIpyM;>y<{Wrl00mkUEXrm%69p_=@8PA}2h+J2%kk;-560 zWj#Qq1>yUK_<>sH3jjX4dG=I^NIpQnHSkYP#Ba;;_OycrEttPmcE<1!ds6(!5uC$B z>WcEX!#Wn=o?x)F%G_*F8%(OhI2am7DvZXEU3itpGjmRH# z5KPRv@+ZpDOk&?rzC|_O6zBrHK8j!;Yx3^FMR2}x6`q}mip%^Mvr@l|*kr9>-(e6E zNl*>F$v-2Et?#kwbmLW*rwyF)IJGemz8g*gYocE*cNfI&&ea7}c9S1SFx?tSxYrY| z-GZylpd;ypX}`~b+NR!(I!D%%akZAuHC(3Tk$ZM_YL~JcT-b#>{j4X?m=bf$NV#Vu zVs8++rq3g7Mb__0Iwu}XbSLh6pGWGa{}n5#Rj+GJyYHH9P=wZY*2pESct^TwBbeed zv?Wh)xl6wTD8Acro0M~7FMjBMemCa|Zk*j9<|?iUZqs-pW5`q1#gYO9FFjs2#gzT5 zuYHV*4vND`Lhxsi@+`HF_2?HKM3N>)7IG$)VsAi^VNYQ>r3(_W3^Ls%8C(z^XOPmU zY+P}erDRA28)C?gkDX3(5X2kAVIORGw?M3o$VcnCGu|5t9=FRg{pDIK$qOW`Ws}5^ z`}i>)Tj-;r6yOE_!je5X&OcK)TJnS>cH%rdo9Czf@Zje631B~~k7IwUIyL@ab1MJM zsb1P8OuMj8jQP+$^7^)Il>HmFRr6QoW`&>V^>Q~M?CExb{@cBAlkkWvD6tJr&W{as z5|-c@2OACxe1?^FV+debfK=)Wmj%zrbnZYRHg?u^ZYUP3LzSfnQ5S^2NS=PAG@i;f zKx_@T!@vlIePD()5nRNOxp1#L(Qp82DPj9JA+0bbq*OKPaK1z2N?%)iM7A@L%T|_@ zl;%Ov1mMtDmoYB7+WC%_Ei>MlTPt*-j4GsmCc>bxOsPV*(rKA5allwx4|%l> zH4rp()6YJeFQ3Vu&k~V?R=J$x6bXiAiX=363UMhSFv0#-ZWc)^PCXl3tmh|IK6pU1 zg1Sd=?$kO!EuIxfW^N2aGl@E$v%R7Ji!G!1J(Mk;{LPN=PJf({{s8Md`J>(aE6;0E z`w6Kfxf$j&|I^@^TvA7MA{$L^&^B&5j!VDz*`p&ETSS;lJ_>Dn{9h4_re{TZD1GA}QdWj;OUS;(G2s&$Z(A|+mfIwtCZ#OdR#fLB znLLG5%TB6aFfdt060 zVs9K(TT^L=y6Ru#l-_88Knzko4#|XwF>QunG)Ys;y-6)&0xb)9LOWvyEn{iI@u*AV z1|`WD4)b`$sEkuAW0a1`GGD#3L!=qz*u31RRi-hncoz;uK0apxJU~up zyFsls@3@>1`OF(;d!MAO;Fa1XOzbA`XVHCm!YiH5HBd@zs6i=@(g=*KWeBzcCD>&; zp0A*OYU%jHyc`NXi7T{7@0{2*ICI09PLn7ad~jky;Iy4zAMs@l0Ns&rGf;lAB6?NGNnQ?%uF9z?g(XqbxA}JBVFJ~18R&1NRtRmA};v zPu-x~;uth0h>4J)RD}(g{|3?wvjdDSmDICTvlW9}J)8Umd_P zU7M`Pa=gj?X?ePD$bpgPrKmY3csW*d&UhU}KMMew6+bZi9@2%$O_2SMG3z1Y(dOZJ zTUorl{1B!wy9`rqkmcwjV97)A!HR2f11_+->Z|@wh1|ojgC~{h-Lbhmgp>bkqBx_GQsI0k?v7sC>}OxEWSGysRJu0rnhxy!ROp z2e0A5_R%kcYRwN>^Dqj_PN(1<(|1lMCL-^$wjnBOaC*lF*8S`4V>5jbbN1=CM@Kzv zX>v2Smqg#M%Isiy>OY`A*ss2$d9N!(U;mLG-jq-fsroKx)o#wt2i%4oq!_??ujKaS z{5N4Ui`vpC=BIOphOh~97ImjVkwA0KjZ6L< z5q=DGk>Jj&t4-|_fsx%NqrTTvz}i;_(Yq$UE!)~DEUg%>D=KivILoPn>daasX{dDE zqZm$v5X&v-MogNvOTOOePm8#_a0_;>8=45|;_1IhQ7Q>)jToRu+-uVaS7yD<_9Emk zKnrZyu6v2>#3DrffTH&FL00_6TJjQqI)@rx3S%iDaRq72agUc`3pGy92#fO)m`w~s z2l~Yhk_m#CD=g3?;^S-ji6=1i()P!ssT5kE55_{WUm8(?4r$kB9T<2`*XOcNJ#KRy zX$jN@$WUKcqc4~j#L$=Q06HJf#o)iHW1U=EQ^*pS&3p))#9H@@QD|fOLr^%?uBjjN zSRwTfqUyc)9y4F)pBQ<=@O#c^)?N|jXI5N0A8|1p{`iT}I1~8ZIDj89OmyDD{aeT~ zW?!P}8{g_%Ot!(7oE#Gs=Zwh_u1_5^=X+X3e3UFf$Kvw1>|5{3@&sO~U~8sd;}UG* z>3z>wbiDdBrRR3@#F!b^`}8!SekS8XP==`1w2jmZrs_0qWk$y`%cDhVhP?9(JbdSi6O`4rD$pT&l!&o0|24WK0WBH>%`!rgEN@1DY)Xq zz$^ozsoWD%njOJ({lsB)2zNj%i)5WcMxIH$3F`!tZ4-CwBsrnbx zHrjFd;YKYr2w<*Mwua+H!lHLszmg1{=kZAaTydj2&C)SwnCkmy;CcqD-2Q8ow<(90 ze?kyr)!(XhZ<$6|n1|x*=g7jqbA21VTITJ2Pp8;Pkk9DF(CM>71^ZcFRIU)&U>)B*uXr(8AC(ZP&$bd+CP6&m_4`>jE{WURF- zK{2_%0__-B9duYUqeP{v9Jb#G$3N3SS7sD5#E69VZRAb6jzhct+nGo!8{;mrKz{aO zUOyx?2BUUA# z8UQv=>Ula5UsDw;f;a`7@>c8K&H0AMaS-DASMG z*yADV^aTMs+L+XnL8V)u(RXSDAOqhNX^y=#Xa$*RsZk@`XX#EeGAA=V96nW(SZfDa z@WX8_0c%pGt0!s>eFp|S3hN*f2(EpB+B`C!nfd|yPBR$hzr(>Y_J#Zhy8~=|;ghHH z3uL^LOf&xt3^|!oF#mzTp3&decx2bG{((2o`r8j?2BTvFY|{+6Wue$Ub1-j1RllUP zk2MA1O$)cv>hd6rKI^u_+*$iL6QqI4uU~IKXWuH9LjTm zgoA)}p3Pkvbm&ePTV2D3_5gh5O*bDt< z-oF3*Qf;)dZeypkeSF*G`>+N?@5l}>+7#XSa7_lI z>?hL2>Z4EE3)v_Ypov0gg$I6EBMDf~gk7qx0BmN0JJ&E#wwVc(u)$`Gg{cP-viqYuEC>nA8RviUym*oNZJHzw%}bK;510x^H<#mnL1!rC)pL3?6p~ToGAD9NcKG`+C@4y zOq#Re+)5TaVD>dfwH^z8Xt1nf=G!g{1}tjC?EQvDhZFj30t;)L$Umc!u%pmV#kvd~ z9hpRNL$K5R?-RVt=m0ukGysQ7}u7>jP}Ki_7xmyaRJx< zad#j0DqDGyqe9QBbilYUZl*Cy7uA{l*++VJQwT)FuZC@{1kgvol!;iB2@nM`ZuvX# z1K$q-nY5hpHhPIEJBxVnJmVaad)-lfFp zQ&6yilmq8Ow5`>cUS(q3V%r*7+vBH59Oaj;HhFx-O__?N(=~!JO^cUCNYm zh=pHq^Mu)}b1}PgazomAAl%0v0Z3EIN20a%cv2W)LXPwM#t{AB_Vps;K}X&z(IpbS z>NA$ufzlK)ysBAyaH%3;xhng*+tOSI#xNbcxp7KB`8V~Y6cF~>J9qio5KU*R2Z%~@ zgC?IEfrvdhlvAF%?>qumMA{+o^WZn(Lu%1ZB;d9Et)RI>Egb~0o#4=&F9wxiu@#zgs}o`vdQseSp{rm%)D(=vefE5zqkd%VKNrl{$fY}o!Cd5HLO~XX5lU}%2G>W&SK)4~%(@gKL zqM{=G>DRh#`wU0;fJ|T_Rum(vR0>BTODu9YVGz2*&mggYN4`U`tthv?6DOlBl(s zqnr0!?*`D%eC&(`olnw`$!5(>0Jr`vP>O)d=sOjPt#tM>eQZ8KQNy{qRDoPCd^|&} zN+V9x3N(enRP8t4VtX=atkXhkEhZNp$6)m{#^g`)8v-B7!(B7n3`rtApI%m>H zK76vC-*XOd?&&_iXhu)R2BfpUF#VM@1|~uT(@hd#gx6FaIo=szTL4K(1ePu8BNK7K z-ieOW5$LmMGrL%|DS9If&c7%=qzirdf1HHxUIFuyzy`oS=zk!V4O%=;)cVu~i_pJ> zmlk{J?}bNEFFHjCQY?$U(`*b4(>PKV9yjS7N0YBY9af8HmknGd2!}r($XS<;|Y|C;1yC;)uGqSPt zKwuA(+0DVHlh8YR;|D>sn+CPp^z)L&Wt{AE!KI+X&eg2HPxjXt?#k9;GgMSrNZ;X@bhRkF<-GxtiJ zuQ(nH;&_V#g1wR7(P5bTndZm>UXQa`Z+kxi-`knjM}}P>p5Z^Cjj&y@HUv=WJt($e z;=E-ykCa@=jT1w)Yn*PP`kqYb;Kr1A_ibDEp7XBQg5tQh2+Kd0ww#b$3;g{YLk}hi za5LuVaUy4qePn~-kqkI~fXu~wc`L!%qm?WL) z-|ieS5K$OQoeV+PDsF<-GU2@qPcSypLrHC?B}bzEc90h zP`PE(u-J}LjPM@8I=VsOotGJq66vm!X2(hKk*5IM;98HH_rM*)=nbF)jX~72oB}CL zSSk}&b5wIzeei+uOU{p-vgtA&xzoyTvLu!%&M2m+ zzrL0m%|tz9mX=u{A%(I+(t;hRlOrHCa4&()&FI~>iME~bc7tZh{WyU-EOZv9WbrKfqjEKYwCRKVPQEORcZ>rf$+^I8R@>`u|cin?B94Eo%lC6v@BDE(*1ZNgCcDkA> zn%>p9nU+skQt2{2hEC4CS6j(I8rPL(RWjBofQI`2p&kNHm{uXTCmk;s6D0T#u<97> z%qs=!yx752G5T0xG=49`lvi3-1W$x#627q+2kBWqV-sV7f{g z1(42j)u>3vW-i~;ri5`WwzgwwAP@qoQ-~ir+do<@uohf9EVIs9b10doA4%Y2g^kWw zI#H^n6iaWPooJwYQRL(n{JW8T2eCQS+hFkxi~^Lc>SbCd$Mk?As#3?aN9oZf3dl>k zqsT);62&KMX4%8hz0~pE`1TG78dB6vT*{Ku+Co;E3a<{?j2f8R1?AqniA8icBW!xv zqj!Pww0ldpai*x!zr~r^KDGGowVmBWWh$?#(f!?+^@6-lXUC>A5VvqGg}mwl{&Jo! zD6OwCw0jj0HwT7x^dAEBy7q2=IPr&XxL7q!j%GsvDG5>{4EeDy_(01G-s(I}q3D#-UbiF(`?@r#gv z`f?0FL-)kWW>bGMK@US7K$eHq*8>zxou?fPDRlH|(Cud`uyl&;I5Mvn8038sgT4dK zF09>KG+I{BYfFPSi1sK(c_L!cFf|KPYGRf`yHG0;-cAlsOFyuXyKRfM{i%d;ExCIA z2QY?^Z7QBJ()+|$&Rf>gZluhLfjKon} z5cPlt1*rO)>UXZdGtAkw$**aF_P|vzxE7&Zw?~YdNqo1FP&hDT9-vi!wfZ-f9qf@dDwNdw_!igp zDAo6<)cYyEy}vMCCMI8soXZEEDIe#B%u;QHMOmpAiGCgMPKJOur%GWr7D8RNkcD^J zN?oj27%wK3q!<8_6ske>wU!iYSb_FJv>P-xahlzxD%QDtO_2zj zW~uewR$bDgOTVOOt@&iPb*B!9n6b$y!oDaIt=ZVQ(X?X{#{QHcRSEM3r|!VEDrrR; zkuU{9a?n6O(_u>a18t4;J~;m?!Qo$sSjItufRz15^BL0rcY@P!vUK@h`szd4Fy5+5 zO9IE;oatjX&})!b{oRsj$jE<^%Yq(S`|Zr+dOmHrUvqysUuj+6JR>1p zLHeWght1OBRN@opwNa>MYhr41^J3Ky@;80U`!Ys`pyj9GBImpRlmUe914WaTv7ldK zGlpV?9#H;p>VthY0ktr2-&HkV0qgou6xnp98=(mP4TDs+u<|=HZ4HUJYGc zsR(kFFsoun4=B{b_LZ5y?K|s;(H9s!fzV@ZG@AGsIJVKq{55<+21E1G8Cn>zLujo1 z`Ry4O(T9}9OvYIT* znbq+#Q2xqH9V`W_b1cgX@S#MO6`qde9Vb5aKM*&Q@%WF$OR}NJj?REJfXMo_h+SXi zDPwDGq{#0y+W@NUEt-n_IB?Rxo!TwrO!Op~?T%IPXrZ-@$j}ugqleMtAzoEVSt$o4 zhE3jNVM%O{{}s`%G6;QU$T61B3@+*6SKI%gb*2a=1rCaWH#9np3J3ov)@qg(zZ2=h z36!m*%iKD-2Eu*GVHI@B8?hY+jPLQ?ADXaXccB# zgG)4o?LQEq7YO!`TxToc*a`%tnk1KsYcWLE8X?p(Wsm8c_n|a5=c)X{*4$0RA6y(E0YpW z!7MMNyVFmBnn)Hy!0nO&GN~|We^VwVLRwpuh?CxmG9_?P*IB^_*08-@k=G`<=Nk73 zHoZ}z-{N<;YT~8XdUY_ncS6t-jk;)%xY*k#<5HEh^5J&4Oi2HnULPle z0%_{(V}A9wY7uyTtltXG&|*lH)R5F8dO|mpQCR5sQ(fLGtlXp>rw^?T(>*@(SXoq# z{Hrd^^=eJ)UW4v0rGjht1c!w0B=vFaRAlEr@zwG5wz0q;krz`gNpr3!hgI;;ZG)>Lb;2(-!uLw*}INc32< zU~44H-7kXRud;P*P1`3O#gbiqNh=xT^Ot`XO39GjsRKf%N$N${NsDbJz*sXhj(WW0}oU0fZ0wzf`GZ zDhZP0A}3R+nqhr;r*U26-;KG>mc^pgIx#8@OK@LDle%M+mCRBMr)+^y>g z;Ljs`s(6?-drZLD_iq56^P#Mt@!_NwPx#LE)vKrUPg+nX0{wcS+C&d?brB)YaagSo zrsSJlo2%UZF3IV9#OH`K|Et>yt=kX2IHBIU!8Uol#uEdK^0@i|LuP<7aKD8a`2%a{ zPpZYg3I@tb2Tt52=jfghyJyH*z6R75PM7i_5luJ0mVX`;LK7_s@bzE1k&JKia|7W1 z9-CQ?DqFEfy5f?@wI^)W(RhnXs+%VRGEPVu`tWGT@9R}LtCqD+fEc+Z48`5;ibWiC z>;3W<1Lg%{idorhPiJf;h#r2>=K`$4Ln^3Y&~8!BL^jSlVH6oF%rYL%O99T^Y2Kk z(6ynFK3XkrWUkJ%YPOZK3}R6%wRs_sAza)X!lWtxlp5EalzkD9DAN)&R4lU2lNple z2&Wx!%)xRTCil*AWGyLt-zIC| z{TNk$-M%9&gz{e)rz5}C+nJ%acyw^MOsS4B5R^AU&x%+~0N28t@68+VJzQA{O2cL&MW~>M*-f2XgfWL@M8d zIp44;5?<#~k|(C|zhB4f*p$t%)@$D?*0jd9rXB?$){7B26^*%%%y8!~6XcR=_eG?N zGLX@~Z4764V&FLeR%LMNVJzQvjVe6dF}l+4I_t-+-T~}VHOM@E3U{-dSjG+uq(+>aZDm9f2OEXXeB&&b{sEe=N_- z_24vELk9w9Q?gMD)aWmneh!}70FO$TCvg{N0LGKnfq@UmIhfA z@b%TAX#CdXJZ+!@dCJXbhm)_gV$Z@DlKdZz#N0b3&91W8T~*oZ*2qqUjhi>gMGf#A z&)`%1F=cEv#$K6eB?M+=S*6sBzGr8+$Lp5fJ1jC5p25yLj;bp1OeWi;VQaoQs0zW@ z_#WxKH|ly{fcmglpuR#1>8>n+*xt!vk2F|tq(Z-z2cTEFj;9rlce6M03}Z!NVw82UY(=&9P zHvUw^u05mOa07K_XK_Vj@biwv>L`-6MIKs~?2gJp1m%a+^#|+m#_H5F`fWTk0|Tx2 z$?@o-eK@tw+48h!o0g=)_&++Mc(Q`TlgZh!R-V!<$NY9BmQr!+=ikoiT&NkOe!|ON zCHW5OjXatyOjvMt9XS{4zY`qBkY}K`&KW0VvW$qg&?-ORWU)LmRu4OEq*9>})W@iFkxg`bS z=FcHT%DoZiX8e6qPLCC-QfG{Q?>Kz$YF`unAU$+W%DRRc6;MkYgt&LZ8?{DtfT}Hm z7{1sI2^@MHKQ$+Y%0UxjJF7_P)5L-zlGxX>P0$RXXvWa({X#a?&T|lklZ8*>gY@h$ zoZl0Klifm0!AoiCjW$bLTWB(ZbAfHm1O{KuHkDHE$i5uGVBO1-o+1&vzM&Amqzyw! zo+wB*Dny){Gof_*m)|6du4>#iqsRvl4$$?FkPg$F2$~Pzg~b`VU~->J3qQzfZoyl>bH5oz z3Yb5sry=J_urA(qw}*93Av4o#@^kiVf%=@F#51yfaPvP&Hu+tdaoPzy^GxL!+694% z{}DJdn-8i?CZI@g1kKnL#`Iu@`kjaSngz_s*=$lD zjM}BRm%^W-Ot&8GEhs|bl(DzA&SdjSDugVjC&-3mE?=@mE{&&_fWc`yD8pr&FGugy z)-0vZQ_|_(t@kM+O=*y|viq3z*@e3ZWW{Xh4b2w^4wGfAz#o@}oR5>uAyGW~dtbl| zt-{6j^T!6^+lb)9Vxf)^TSjaJ=i(9JfW%qcX{ zUk2^boQKz7TN8x!WJL_-#e@HFgtm0g14mI5wM9Nu=A@FK_DN1e)G~l@AlEGhPA(#* z)!24x z@x+_VgH~)V1F%@(CV2e_^;(F5I!z8iMQOsZb_?He$G6(ZCeO#4qnNK{_Ewte{`m0? zNT7UnDfcLwm|-bh*~XbkD4%!7pQ6f#;(dP+nV82YAKJ$?=6F@iQK1|Ga%cgyNjdY; zQmbOp7AhM*RljL&7hpG@8kVx~-8084IGHFH+ooq_r$Ip!39AVM;Q{JWT1sd>K$IoI z!K4GqBhKuw+AFedJ`OZmt+w6exMV#_c{6&}SSO zdaNlsUGS?6Wowv9G(6a6q}kqCRJkp3*ml_zKa);7$~|+(NPD7&YuE;4EYm}kDxh@5 zSe6oGl@iJWWIx%kLYcAR95usX!VO8YVy%I?ydvW~N>WA>?PHI3ayJ!jA#yjEKEs(s z*O^IY8hr*p_IaZporr!5rB0Y3B(e2{?tPh2O}8&{J(Uoj{0w2+J3jDq(wI{>45kvl z{c=YL=i$?j-sG?)oC$^o@AAPJiBK4VojNu9v&*qo9VBD~zwtAJZ<~2w@iRKEB>0ti zj=tpgF31us-mpM^QHB2wTwB7`s@_c-8dqr<;8{BGivr>k7vfWg;481!FB9fd`d?`! zwT>QGaVv!Q?gQeDiS7S+1M?=?w(<$-uZDI}fOH7m@PhNbjl>5x;M;WRG>~QKBs(wV zF$9Fw=kVx1{&h4IxmIe(GQ}R6WQY(qy_p4&A4<8@q$zfz@o$3JPp|pjfED)tQmZw+ z4oaA!NKsVs-^M^&E%93g%Z+ok6?p!u)CcS3OL)JX6-53*;JX%)tx=WM+fLul@N3d$ zjMFB-Si26p%c@&&W`=PTissMjyaNFy6sg_Zxzl1hNtd0cRgc8f+x`1%^o!l^&v$f^ z66bETc!8ldXfK=9`3xO}kIP3N#la3w&ET%YRfQ`%X$4LUp#P!^3tu)}zfk$9-s!2H z7#9~iA8SNF^`Dxao6M|kW5Q=2`29$-l$x?pYNdg~!x3wiBD`|PEB7;>9+h#E`^c`h zyi~Fd&WJ+xwXVqPGz>Jhz*}lVw6+}Ds&<4(cVN+wm0iZnR^W(0KXXkHgn8`UGoP4d z`kV8+n2gC?0-;S2uymnS3 zT+o=4@?SH3)~?Aw9C-OEDBz+s-TLjPeTk!r!p2}+=EedqMA9P zr=RG4(bdl%h(iKK3Q|MY3bekAsiEu5=_ZpamT*g_zDV>Bo;nV;iFoUCI-8oS#O~gxGXy|>Y>Jhi5MzZP4Pb4`X+5B%MS7KCdZJg{Jk^4KflN3M zR`reKp*#&}J#*O%QW~Ot!Y~Y#?s9nJH1D%IQ1Zh~J)3(#=Y~n#K&(bF_9s5G@W$2j z$~@C_M*0P~->^R;8-#&9b3PO72y%9ZggkS+-dwNZ@AUn6CV;&0p&RkrwRi^^0ZMRT z3k+L&fS3a*JxF|GDfcm3(R&81-eEQNdzd13jNy9*SZ};G!=Y|Temt`Vcr-EHh#T$U z_lNXg*m)~@+!)12c?DzUA_Mp-dG_H*kake@Zb+5<4Z?+KE+R#9PAJ+J{62yWk|GI= zt4>HuBD)JB&E!!&hAfT!TV>(VS0aV>I2@B!g=PTSZ94EMagqKWvPlt?LyEWcSQOjH z14A2o7Po(~i22b;hf0l;p5^gOS_dr#P%%OcqS;>~9L3AA?4yyd$LmdOsEH|lWV(|AyhChr`ZhtawJQt>!@X{aQ_yH(! zY9e2THwwm|1?iahF(|POBE^QE_I@pp12R30Bi7XD*rCEzCj0g%k0k3hvxozaoa)wf z>HE!8tC$rqU5~_-?DeTgj%LIbJGI%;RwB|o8^SZ)BZFW3E!dvIn~t1~vtJ4{?Yk+a znFNq=C&7#hU$VJ0C{8Ab6m%6ZFrLcv7sT|i3|2L>(p={sGYs~5(nsm?2ZNG-YLiY+-`Ge zpVjwqKJUPLu8sw~z!o{%oVlPBOMBpEbac(I=skq;vX1y(2tF149pq6N5y@`NPYce# zyVFrqgJj+V^FC4A!)fz0bzyuRG425x10X^nDXoCk4)1~MPRTk{ocMVw=L?|Y<9hF*(?Ax=qAV>5`t9! z%F(1s4w01`tQE2NkLgn-u5Vm|sx10$5wLfX!Zm@dl>@Ug*7YupJLuq=uGjP3T1p-> z-Rjtzip^R#@|#6eI^yP&h|8Chb^2o38HqMh65cnz7aMEo39AWG&8dYAPiwz?l6F)J zcM~;;g=3XljQH0Q73*eX>QW2Duu;jrUBy*{&Dv7w8gZ!zi~ohyhjXmYc>>n4U~S<; zI6{SSMe_TJR`_HY&I%CSI86HiCx1r7nE`nhh`a8Fsh94KWElSO!}=+- zZT>0rNt%+|dm2G};foL1ss92K7!&{|X6y+2d?lB@kl(J+ZJyyf_Idgxv~P|#bWHMY znUe5Js7bn|m$?n6);n-_;HTR)nMym3wRo+0dz#TLOw=wps*LV*MjD_tn>w|xI?^9C zaeLZcdNw`EdWTq1B-i~VVc0Y^kj6fU;Wm94xCn+DE^d~m;~*MKBE9|9bb*_FHuD{f~g2z-3-N0))t;}&AijNDHG`;&_) zLAi6m{_jRF0};N7lT<^q2w$*ZM(C=u3zFs>CbX^5nfa@&2<_M{{yVK0kT@GgNsg4N zSSvDQw|iA( zTsQnp`m5)j(+9aK4}Eb-0)>j>uw-KT$}X1UT#pj?PXK}#MZ+9khoXV0VsrP4@rK=3 zga0c0v=i+wmSKZ{?D765W&`E_z3^ji=j>u+=OXH9XJl(>@;^v4K5FMGxN7KMwghxV z8wsK28Oy>-nRIcDO;*&J2>D5iH?ttp=hlh3{mZpcnK6;Mi?@}&b8|mjUA(8cyvtaH zfATEM)qE<&9&hWRY62({H=Q4IcDQ@)Rulcc-tJKRC(0yGIIE@C>9$SC-}uyJt(%%$ zmf5VD%~lg}Lz_!de@UViJTnUbX|b2olq5LXyE_{oPBMS6Yx1tZVdGMP*^ma;Pz%_=~Bnrh<8%vNMEFX4OR6>yyc>rd_MS zZk1#O@8Q_uCyd^h?syG?(H2$16S?F;-j@YblUQL%HPaR4;fB0^MBwL-pG>jx*uTma zujVVvOv5F^!+&AG8*v2+MgJMW*s565YR}PGGoYcCp?Z|pt6cWb%w^b7a)3~9f?mYu1-Dr<2(z8^cQeBmGKtz^O{IsR_QqEI*m02(?or&b}@KB_Sq! zUZJitm0?;!6a<%b7aY7GXE9x?6{5vLamv>ytJ9#BQ~l@5fhASu5M36i4$jFu_pP3us z2G^#!Tm9E^pn6qglSNA7S%TTAt~;SPtl1V#9d*~Z1tXM2wtqKsw~}P!tq+O(I>la* zp71e@x9G+(I$4tB+aCubo|!Tv2W|XKp)j7tAO=?tC_XFR#-QhG7hJ*gjX&l@GRzcX z$8!IeLl8HG@fHkSoR@AzbHR7l7YGCXaHabH;mXYW!_pDwiQ|N2vZKIPxLB z3%GUA2Uo%a;|vcT@$S>pzo}<@=6&_<<;CHtMg=~*LKcxsTO|6b+n(EM$cT(`xR%{tYBgd2A~$j%?X9_YgeU(rK^w@&a5 z6+j;xv=QV-$~1t>FS?`0+Z8d91!k!yjJr!uTy2iI!ePlq%{{+|bh}A$fQ$mi5m9cu zC{PODlZWafMf%-qLxkRJ(clxKPUtyS`1~FvQ_(1GLSQ!Ysv{+ON-<54lrIq`=wTJK$K=CDUzejlnoWUaQTFY=L zWN(P+^VOLJ5&!Cc{|DB2AZifZB`km#GGwvCaK#0$zmpiztK-rXW$X-)kMQ;@WO{Op znKs*<6W_%!!v7@vuLviGP{bYs4gzuu^PeId@qdhP&i^yEEkEThief?Dz+5gDMoOZf zi1O_HaO+E$IJyF*KBw^Vr$0(@pxZQ^*`f>VdfN87?!vr?L{O~DH@tqZzu9L^>^j)u zyHD--kl!{pV@V&o8unZ68OO>T`Ak`THZE@{U#%OT38Q?)m(y?SkfMe>oQ3Om0!t+0 zFivh6wm$n8I87mw#9sS}io3#T_HYn2;S&rgZKJt4!p}R6OSjcDwoTAj#LMJTUt>t2PCNoZv8r+WEB_iDm!=MQBCd6T<23AgV1~aEx}KkEVC%sb zyD}G2fP!kRno46eJjX;evfjCa2AFk^ybSz3#kN#cc~Wm%*~%{p2ijBQ;(1sf7dh8z zzNG3hu{^21qL|G=8)LLYw4+96k`qe!mySW9&JlHEOy7*hwxW>w{jQxz_cScTJMwb6 zyeXqTaiZegIiK~WUm7Mcld7(-IeCJnVx!=8jdOiSn)VBrO51k2sr^h@ zg57pAY*1V*#ImPwzWgu3M_%+#>AG^%4XqW~C3a_VR=dh}s(}aL-OS`G#2!_>6zmh> z7Idu<(ow6?+m$vMDWn>?ORYBK&~RJ6UirF$?oP<)A~mlkkBO_n z+qGs_O#IzAD}n4kPj&?(aHSMR&gUgHQ# z7Zq$rdH!S?(~-N^gbS;Gym}w z^V4A#$eEN|TpGzw=8{qQNa}j8Kzb=RC)xNd+VA%W>Uxh$wxYy~#_s`qC8N{f)b*@F z++)+<0~<^tFSeP*+z?aL8tSI4(Dnal7GY8VZbi_d-i>PI|AkQkUPw`+I#bUGt2e^!3_$ArGAHefb-qM8`;BpOM6(}nhSrS#`r$e8*owKp z;)UB&kwQLmY0Wzn5|W2(Z2gqW+~5QKmi)0C&N+MS@vV;~jBSAV`t?4p(|c6!OC`ZM zX=0)kc^NztbJ9kL3y(xh0EtAojZGlM3%i}{0neM_!D+#J3+{omCv}rE=+&nZUfQ=1 zVcy>m{uFwQ%-QE0aXj#bdW}RV=#A{nbPMW1d~0+A9Aw#)%?ef9Q*Vv&K8Ykn2O`ih8qn!`_zPSPqsBm?P)H$)cgB05b*4XqJ&Wwc?a~ht z4&);H!TO26b9W{`!#&IF+1|MA)$GuW`o6z`e}xqk zOTEXM+U!;xuMsLlCSX7Rlw{-YGuyxZQ|A9M_G$cXe*H^n>4x#YavB!nDQCzxUCRae zKjk#S|5r|PG4*iyUzB$pdsHEGei2Kh!IZ#9aoa9c9VW+zwqfvcGP&h>=ud}qJg@YWpR0@ zkmo40_tS6H*-9MT4Rf&BYQp%r9SNC6JQ1z}A||0+lCYL}n_U&R>h1<|-QCH5d>A3A z)QKp~r(KuOpkR-09p`u*8&PFL&vV@(ilUa;)(NOXlXzq$?>q>j0Izqj{MNy_(yGs+DArC9w(rKW+A#otRF~zz=R}-@r6O<|6$i>8z$DeUwd%vZnOl<7-6aU zS>@3U`-Hds^oS6bS$pWPaqh;u%zO3Q8^jCo>Ek261MS@rFFecx7P;EA?G_)g8%PW# z@z=$g*T0>11!k9;*ZB&eRQnU`zp#ZW2TP6g&2^XjUNb4mfPtffKtn@+BT4A{`Twr} z2iM)z$;s5tMcm2A*7Sb>EJWGXdO;D3Pa(6>T0L8@iB;#RK;4#Bdx*2PkSItv|Jjsf z&R(i>F}lcolWh6}?km!OL-7XcLINRoQ(QwcD1hvkpYb^Bc-zbO_Kwrv+(U9T!D>G7 zD*tBB1o)Umb#X~99bw6 zZVi|P)R>Src?5-stCCcIa15QlG@zyw$|MF~e#yq8Qsz(=NFH50?w~P0HWnt= z31D0&%wo_aYU0bxz#!rsmY&mDTuz938lOOcDtJ zMCuT>H+#aqDVO)@^*XEGfVy@LQs^^pSXc9;-F~Rp8sXz=H-%6X28w5{3M&=bUfd+P zE;>NDr>EWso~QYJBLWI~KJ1fX_6G<^_QEu+{k z^Z$tqSH%hWenE6T5hd^nBC3MtO{qe4%)e}Q&=gprs7?HC3p~bBmt;O=KYPX?m>q#o z&q{mQ z2HU{nB1^+oY61%pa&$^q@RRdbnvJADbSt6OW)!tyJF)!#yQ4yLvc#_fBC-D{Yd3 z6IBsKDQc0K_26HM9FzZk=CgOm7wY!?|0KR=`TyS;E^cXR^XvcUX318aab6I|^1;pI zLXqAZmC93s4lIc=MU{nXOe*pRgGs{?mO7Jf9eW%`Q6nRs2zXqUx9@t)N&kdkQn|op z0pmpcDCGHYBezl5gJJEu_*?YU_0&yR>G$b#2k6E0m}EMKc<9vd9IpgA>yPQgY`tep zWoxh5t>$AE^215R*WLq6`sE7Bmc_~ z;>Hz8%h#pbIkt;2V%Fi2t@}mbiP6ANo;IW6^BXHy?~ip8Pfr4NVRUWpS+&2 z&?f}*Jj9T(@>0xpjY#u{styUuVfQYHSLYy?f=QS|C2yrKD7=26> zQiD>nEK()Izx)y;10R!haWnp!J~~RRP&~#jG>!R8o~|$Qn;|*;J_lLQu{~K&2TY&R zPd5Fr-S6+n`oxK93t1U;_mPbvgi{ZH;V^Ru!>d*@xi0YcnomWccJr>fNt9egl0 z{xk{G2?jjNUfCb)n26e7nrXNGOX#|gjFldRoU<{;J0wV#m7oZ!e3l;nH9F5uEm8=W zco!1*HcRR!`xLYN#~6)g=qb}NH$3GY@1$+>+Q0X!K18_YISGD~7(27fuizbjav+)F zuV@iI8pR>jp_Q`h)hJ^6yrytYa2=UXX+(5PGBl~;>FAJDx*yz=KECuP_iZ;(w!!b; zxmPD8N`pRYUN}o>ZA7^Nb>UhlI&escXkXHUJ##PaQdQ!_%*+E%s6KlF{}sBs2~Awe zzr!{g)PI`#|977Mf1mpQJI{Yg-P#6E1LO0r`=y@!NSw`iQ3U>qyl}^MjES=J`mo*l zAlWIP1;(+H;b<;;#l$P&L3TA=ZXdA8At&RRB(cE39>?z~S*BWE7Bhr|EUc*r({#vL zut$sx4GtPmCWx`q#hRnFfomUyyf<>i=X|{B-0ghjKAn}i^FHnV<6>|HoMU4sg23y( zHQxQ2P29`HyyDp35`8!{s>B-I1R3-aQ)w(c_8SEe&}^yr>yEkt#c;ZHudDhi^cjWZ zE2|t9t;~xsjeqmeMRbXTAKJQa7LSg(mWv?K(6J(mJQW;Kd<5w4l`6j z;d8nlwNoz7{#xpQZqW3??s&BkH$Sq_YMn1y{lu@_!pr7wlQoqg$E8ii8JQ~Bhde#d z(*SL~&lo*>m7Q>Tg3gju8*^|I+;&tDYN7ZIY1x}`;*KbUtqH}U+8FoBxR{4Gcg}-Y1IpP1ZGnq>2-k!1r$<%+6O1Jo1MHwpC1mNLdh@p( zj@6+>P{7|5BiU@(hj$I1b@4I+t z4wQMT#POaBA;}FV$9*hg35b;c&FVGv^g1ImC@+}M-ha&VOwHH-2e&Y5pwH)sXMTSB z0HzS@Zm6^LHa3o^)~gy=CYkXd6B-!&nlh~x{o8c?E0qWJS;|{fpJihr#VY={V>`<< z>PAXo!914rACrJ-Y4Jz74)NHTqVCR&5}1K5H32(JXYn~=90d2iq?ji=Wy|UXX76ZD zxv-!_x4Go$`s6a*Bl!WoR?YzIO-$m<=Syvgoj#1Gjdwb0F50e@{U49C>(k@aabBea zBxnkF3vCMXSf)cCSc*I?3%4 zzs{y_>n{=}E*zzG-q5W(4zPk2Qhr*tnsrwpiIut>2WN={zNtkcuO_v?LF6F1AYt0B zq#(?+NlIvPFwmxOIsjlI3V|}Mqbih zLgL)~ySKVz_UwMJ){GEudV+p0$;{(2&ju*at`o2%vLH<9_5k1#l_ioLnJ)E~D0M|q zSCUn7Bhtq`rG;}3;U>Imk#B`9fd2Ge=4A5bdKc6VKYgGNu5X&y{&+S7#IK|O4tgfH z@JS+l-dXl||D@MbcSz0n>c$2tO$9btao(siE(JW+aCXEgXO(RFD&>TZgKDLEqoWO; ze%FnMuwAj4bMG>y3jCf-j(5n*FT?!>9qkp*>rSIKyAs?b=9ma%F$M{_Q*j>ZmN-;bI`VojE#z6s(xgw5ZSt?GJKXhOF+<$sKDt`2LEp+XYbT-ND>0l|yy+dO3vgsL zCN;fY!vUmbkIGjY;4&?N2c+LQEq!Gx;k(##y&e_|I=(5K`k5<6_v$K2%K0bm;XH%* zkdI~Q`^RUcr;lJqV%r_+afD=o=zGRU|@y zn3p7Crj(Y?+3*7Kx2drfKUp$j(`S;p$niidB_dkz@d!b z7DRyC0x~2+lSy$>pe0Y40o)y&m)RP{oANUXRG&{k_DSW)`f{Hi2KN!|D>YfK(Wz6E z1A=H)y=%d(7WDh_KE02>Q~oWmsSGHmtY;mzr5Z-~sjZd$k9Iy_l9oowcZ#=0{ZDBg z|Npu}``-l1i!l z^UK6-Kt>jYl!PB8J`9OKZGL@`5?oZwR;{W!&Nnx1*{W%ISzX6kr@Be|B{$v6{fPqn zqx(z4w`Yy}cru;Ud^(HU+04!Zc#cN-W0%Am#YnQX$;ifI=*&>hMbBYqRj|m?#?d;D z+5&{6s0y(PA=(z6jWfDhkq(jxJk@wK#Wq;=Fco77U1OdRG=(Vv4*HnN%5rG(eZC?i z%BrH`&V0I@x}1TAm79D89$dmyNloc6us}G%UL5OXs>>>pp^|}yk!?+&G~ax>A}tg7 zSs^$8#`HInU&QWo?$6X4@HY)7k~Vil zbj7a*fJ!lA528jhBq#cIsIgnUomNkT^TgTmDwGSrl- z28&Rl);PtnWg8mEBoo+WwS1TG9+RE$oaw|26{G^$Lkk4|S+arF&N8Gd@8PW<{ou=dVu+@^R zrpd^lTiIDgrG%b?#-M=PO2J?Y##a;sw6iy|_uDGriU^=J;i%YPeKd+w)2Ytktd1@L z0qd3dM~ZCd7Vx(4q9VYfbYQcYvD}pu`RS{w)VRn^3{T~FA?BYpi5UIeP=JN&kFapu zGvX6)g!NITIkkMr9ai=DXtRqlxE32KI|R;bQ>;V<#9CCGqE*_>+VSAOE(16gNwe;o z$Sjr`ZAMKndY7RT4G%b+Y(d2N)?3INIyHq4n$%(owFrF{pOKP{?24Gx+q0-i;|DFl zkptCoKk6q2yBjOkXB)q3@A#T?Sd;XZ_!Z6)3-t(+iZU66eW8YxKRD-HM5g8-0*0IO zSac$A?E>%_TCwdeQT|mHROcT-g4u~+c^~a6OM%&y(o1Ayib$ghFPF`4vp7jS<#!!S zyABYno(FE#&Y-JeMK3mmY8Mze%?TBX=TeU$xcBST4{SkW`>akf?CyPq%+cMF&*MPt z=0&L=BVYPJZ7v*Rm%mT@4;-x0a)<`G0$&Y>#*^a>7ZG+6D>q?wC_lO#UBG+=o#7W( zX6$2s`qXYW0(bds%2eNoH?IR3JpA2$b=j8Wu&!Aeh@%D(!@mJ^Mtur~AG1!S7dwzt zWa6xB5!q5`p+0v!EGB73MG#p0xy|hjd_`1z(d9>}1;iaG7fnRF?9}qub2*?0)mVO) z;L7(WGOR)SGjpT~S*je>3W**G9^ zL1SL35p3o9jx6S0+YO_lVK2+HIQ_Y zTwdwp9o0fox3@FzY$54SCnNw&uzoJDt(JXe9FQa^mb9GjEt_n5H#D{mZ3)Y|ML?-9 zW*;rzv9*?q^PAAkfSx=hP>$R`WpYgYvkehMxZr1Jfhd+8CB3h!LJ3)1?$R0OLFcDQ zd;`MGXzNNg`0QRbKH(4vyp(dK2pd|g=6(oZ02OydUW6G;GI4w zJ54)bzakSx(fH=JYALyJ5}!gXqze(S#5o=zvB9dhA<45&S^2Eq6h}xl&0*#l?MMQ$ zP>W>`Cymj>jyW?039@av1ByK720!8SdO?@u9|p7ef>Fkfvykto-A;WyyE}YHVF>XS zwPSyz8dzu7aaM^G6v4mB_+_`DB0}9r3&bsvm9G*u@pLujNXu_louieTvMr_QZR6FB zCIR=d)Z?J%TmOx(b8ONi3bSo>*|zbPZM)01tuEWPZQHhO+g6ut-=3NK;ogXuiO7un z0h#eco^$qE`!tE%nml3Z+ul7z24c<4Xd&S$J)&XfM-G-m1UzA$I&i*a#q?}@h0~9c z$>wV0mkrCDU{5dz<<_LQz3Cr)T8Cgf)zh#nQuGCJ^Ok9xaoZYpvE&J{tuzbxw7(<$ zfBpCrtxd{U4Piu?DUB1x%@X`6Z&M!mTzQOJ6LzrDTGeFH8*|0p^yr~Zye~>{bp~WB zSvK>&O-o@l=NermoezUK5(+S43gR5t=s>=X>MczWU5wCqE{CLXjb_P>pc~#1P29a? z%Gz_3A!`s;nnl91#AbY4(0WW{seYosv9~zl;eD~+46!-u{ixu%Z;?Z#ix*HH`D_j8duPz?qyD<74hO+&9ksQ&RG@d3MXv&2kRVxjALv zRumCnvyQz!Msl1R$l>0be_DD|;)tRb6c|Y^*u=iQjJa-C8p_JASIMh85aS_1Oq+1qp-&~ZoPwHAzUK;mGzy1GbK^v05D&MEZ#bDM+94;E|K z>a<|gL?pZbZR54XV=WsOC;_1-V!s(3n;FO_xZlQySbQ7Wxcv&?BjwB`BYBY)Jn9@< zC(e)Jq=Jo`^nOq_7gWA1kU_MHNi!E#wCY)z4x3e;r*3Ci!lkjb)I_pswkg3!W5NK{ z6h>|htD$O6j1Z0%#FPzh_qv!2&d&?%_faKo| z(Gz$LX7d6>vrUA=l5N=zGDFQa>>EMOw(J{05v&?@v9y(i`j|8HjCw8T2f*cuzYeqU zgx*S7y#fZvUk-8&2miU1Ee1=Ga?A!xQTPT!PEd5`Du1MLbj97`;poXe6><0?Z;^5M zGH*HAx{_|0aCBweMCjiftzUTtsIA@5_Lteb`1WC}UWEqe8}}n2^{fU{5qp+G=t;cV z;cAJxRze^k^$Z3tPFwK0Bvi}#6;MT922;vaBW+J3krd47=!q2@^(=nlBzg>rWo_@?tm;)UM0xSPK5z96?hKyIzVA=q3; zSh5EggXqk`N`oMj2vfc9c}@9AqV?BJ2=;F;{;Vbw|J z)0JxU2w8Ohwj$(USOW>w@6E7H4N zVbY#Hp@aSjg46A~{tRc0G~0zc50&cvchVxKR8qB(7siBju~A%AiC4-omOK|Y3p$elVWS?gX29^YPs5IO zCge&T+OrN8enIAvVJ0}#4j*^W0yh-Kj+kyp$`0wTqD@w)RK4Fdi-^-9WxpoPFd7HO zMIChDP;&x@>b?W)JemcZ0ydQ8h%@F$WgQrIU9!U=#q~(@#5nx?^^Q?HdZ8slU~W7C z%v7{6n0*-lemYth=5X$w12szc;uM#iR1dAN-{6(HOB`_&=X8nP{HTwSo&1#a_%E_Y zy5_O_5A^4jlUo(Zwa?JA-|i%V>-g)S@$!sA5dH9c4?=@?&QAf=w%q9^mM zJF+L67Sx%C_#!}i9n7@_5$y(1HOg&3y#v;Y?2Ul$_vMCoT^giIr%xK3A_`q-n^3Op zG!+%9*RMrY#)pWIgg|jv5U`_4mK+DGDlOQXGAZb>4R%v@Ebi~R&z{o1OSmPXO;CrM zeT=C)=nCnueEA5E$2{s5eK)$_iq_zR`E5rJNS_N0r9BjRQH7em~%91Ld^AZ;DMUFrPM4d zHDLXQWIK%Aw+N^mJlSL80qZ<-;uk055n9mAEB45~ZM`LZ{YSa=j;bvkSQlxll{#LM zFm(#L_XR^c^zlIlAty|}3VLDjhtVHG+>%>j@%!-)j#~VC^p=?<&5{2``R%PoTPAB` zPkY71Ibt&r^j$I{o}cI&>P#F>Qm$B|o%5X79b5RL+R-5cFNGu1Bd5{Lu4QJ!_Ox@4 z+jhLO>2OcT!PB_N?kWM`^~|u%W%^8UlF(LUoKD3gmBBOU&42ju=KAqP;QRDz84QgJ z_KnD`;d7W}ujVuxrA>hQiE~F);1BiH+~5&nE)4^Ib7)eUo6S8)=xGq4Ois~>B-~$Af$7-nB4TRbYPDt=ZRAnn!De6hJ5k(s@4 zr6XH3b9I*_?O7jU7qfoLksM_0@G?&%RGDnHX7RNu9Ipjl5vO%9u4p_GKZ7vv!zSz2 zrL!Z4RS6uMZf(|0V5=-ksTD^Q|pI?392pgJ}{^minoc4*~v zHL=FQfPN-vl6jgOW9)F2C+5tMq?SJfD|_#ucxnehR!?&OmjiA7A9#LRRZ$^0_e5}O zzS9k0J4+aI1G>QY4Pwkn+WcS*^xZoadF|}TWktf_@On4+;~gi6c-y5E!&pt6lBklN zFH{}Zpe_1M(vs&%Hp^bCi*~)1&F4tNl;=&+kKh=8r_Jk^$p<+tVap}RuVz!sqTv40 z=032EW8+@cv3cUS%Ibeo4JIz*pEht&9S%)rtZ|B6*y84s1@`f_O%{D#bW>=hDIk8;itTz$s z=Fg~-WZqkAA{C_I1JxF^RNh{*o||OOP9pSCU`H-sYQ-#(8W2ETj?9ZOXvK43;w4IMGGG7%=cL7nhWFL^cGL1lL6{u_h*=WwL zQ|W}W$@hSG+OEEeCTAoej51pOiw#$4mnHdoL=cExk$jD`4zqCy>Tmw!gqQ_)Lis_- zHqLH~r_l*$%qUced7>_Rqo~=Blk>8j1H;d}ieGdwQ;y^{dy-J4^7@2g<&fJ-nuAIB zOa1F>)$dK;ic_brgJorjuY;G5F>*qkR{O$b3XX@%9w7L11QF!}a?30mbp zO5u8mKB!@j63QzY@AwQS`9G&WF_lkEXv^R48s{M1O9YBk zxN;=>2JQ_;cMaW2-8OHa=K41%b)P)ZDfdc!W|@GeKw6b}u3u;r`bd1_qN9Cg|5@6N zb}rAJ!7X~>^Aw@)n_={OCSaEmLAQ+W9#!y5gf4(*hemQ29Y4$K@5mo3Z|eJ(u#bFJ+k#^jn9`=&TETxYu223O<*OWICb^+!4UvEQi*jnA7ObDQV}I5~r6_ zrMVxl5}MiHPlfBS>QxQ*3H{VpRtVDAQkqgV&7@ZfG(VV0P<7S?hDh%&Pr4J}^`G%s25~<90zO zx$o-Mw^!V>suVO049H!EZXbWydGTkNWrW2ULFhBEPAjGQl`}P`f>$<7W}u~-kSu)X zniTN8MO3ojm4H8tGdPi=xnEDN7BVW+;63_1jZ{oX9CS77{>(5BR*#chDRojg>fC#{Y!GXgdS7c#Qs@jdATtf+i`P@6PSO-*K7Uw_FgBb2Q z;TAF3($@*f*EeELz6N?_&!*uSAhVof2DTxm9{)_7S=c@F*POo5;!34O-7}hY(P#X; ziCshd1I==2$28XRrjEe;ropWFWlgSmw;|W^rcteVw~@UWVQq7RVBNMEVV$5kb}hGw zzmdKtMM^_C zabHQe2b*w^de0wYl>-M=+JY)oEB#;f;mhH)Rk~J2g7zp{lrD8DhU_rmoog0%IxV7J zxvUWo>WOY?!Nc||#Ig;O!^~AGU46s{Xy|CQjcj-5TGTrR7sEGe;CD!y6yFmyh`Eh2 z2fLS&+4U|uW|_|HosutgwD0mR%|7rKbF*fvr#>wz1fw;}j%#e*Oq(@wW~&z>m*C#; zoeH_5HVYUHnNKE{=-n|_bHbOZyi+dc)|YJFyq!9>W}Q#)En>Sf&*!am-tV$5y*;74 zdArm2O9%~OPlK01JHz;k1g5bUV(X3XP|sQ4sNBUrY29V~v$_j zm#kmB&mG?o&mrGPAI0D7&n4ejo?1T`AFQP3H<(*_i=mRLJln4KlaJ> zp=;u6{XQ9{n9U8~x-zOo82T-;g?Xn|+?RxX5}i)3iu}h{1>Y(8 z4hf6WSw_**Vhkp(vSO6tf@wk9kG^PJavh&XC#Of50yL*Ta0QW~CU_EFkF4eR2AlfT zR-QC^-p`g;vt(TlyPVvaQ(lZakj=&~9!i`#78knJiaaMaUnXGc)6XH(&oOg^I%Fd0 z4oZi}wC-C!j6>gTFXD6BP)`Jqvl*P5?4IUgA^Hb}8KP=K!n=^j?o7vy4Jh`I(nbsG z5^95&y?9yfqR)YOB1<@6z1mcDJWqy+GGsp^a7LV0J`B`(pDdPoG^IZ62F15yEvNUc=d^tV@w+ zL{Bx%!@2XC<&jsrP4+N1{Bde4VPw5I!{l<{Wf)QcTdeo^*X4UW|V&R*RTNB zvNXy*$aN!2BLMm%1SONLs8qVNlwPb^eRqrznp>WuxI&ahr1vt_Q{Uc+tf;LRAth-~ zNg1-LV2SbwN{Q{7iV`Pt?Eu2i1ET$@irMEnAn$_%d(yeb(}Oc|+Z{Lh(qH@uPjT!z zXz~eEwHHb_b`xysL(p_bFxTV*$&PYE=Y#ruZ}UpW4<4)d1@J}9DSW*n_J!5mm+RyH z1ayt&`p3RC-eUQ}v-&`T{a}$jVAxamLWSO?+N1t(%93q3ePhq;*BY_Bs#b zXTH_iq4>hI%5SoLTOK#a^$Sd-ra34>XiLr;WxpHN6U$nbq!|cdBur-Pa$E;JNJEBd zR?9lc)0Omi>a!YWD%x>o)oSXf0}ZdJAvqkanG%k9-1J}EQ5Bd&ZxpbB3|hOfy3Co{ zDQxC0iDLWVESJph8@0jIDs;3R>5*#^EZ7p^zm4g|ne@~a69DyhESNta3{_v<*Q5yb z6XliV_<4D3Lex~j)|Tz*oU_^xY)2hAW|h7IWii>h4xOXjqs>kp-~6J8aD*j^(GFmn zjNE&4c?wvKUbUW?=iWDPCn#FcY-a~d3T)N%Fe+_cRfxop(nu^v5No^)5JpNWL>OZ# z`gu?QZjz(7R!+-ED~Pr~M|6dy^TtF~QaHCAXEEisHG;{Uwa9oeW6b7YsV&gL*h{n8%}9D#Tn8FohXpuDbVOBFuwHD z#RI_OfpLZf+B9MPafapFl!^v?;=vK-CET=OLzND+-6XOgYQrD)z3qQ_0YnG%hA22_ zMGMK8<|#+?BQQhP4T)ngI5{-51KbUfXAqT=FmC*f*QD_s6YryOmdQ01<&2sR?I?E& z{?z&txKhaR;8}|B!kdhE#$gQinqur#o6eE_A!niBr|sKJ%7xAf>8#4*#kW<{n;J#2 zl9cG*ZX3Oyxm!prFNGD#oKVM4oR5mhrGcJpM;&T3M+;J8pC#AHmTMBvTHF`;lmB#r z9+yP)Mf#6&0Z5^mLs3yZ9Vnsa!!9Jdf;&SHd8MU_gc2n^Vq5(C>|Bo9;H&jQQrE6N3_GOyEez(27q za04z#x=&>~mxrfQ_$6UT2aEhbD5E^!rT~^G!YYjclc!D-gj^r?X$hqqQOux66F52K zP=>~OWY&C(hvY|V2&PSPZjcH&fM1{BRsHK4t#S_vDd1$-;Oui)GM^ zIEqj+E_`wxv3jDEivmeJu->g!a}+!xDl~a@3+99}17(NowC>G2wLp)iWFEElSol}+Tr@u+U-rQ*2~`JH9SreWv8dx7!ky2gZ%v8M zeJxE*T)V=*oMKm$cb)EEc1~?F$@|(rd8*y>)AHpbkZ*d`%Mkgc$~r>xc{s5&mqBM5 zluf5%pFR@u1dz9{NM2Pqa*BsxRj8p>O&dN<(}0&q-VEmfwG|y#Xm;KbUn;fLo#21F zg&8(rX^!Elk}SR+2h^b8N)Bi^TO{T8e7#Z`utz6M5AXzFZ>y~5av92*-O@^w=mKcT z#{i#t$_pl780osGzH~Bm0sUksT_OE&C{rYLs{qCRbux~$J|UE-*@XsqDl7w)0WPRi z@3blC11dZDgKKoPKryF2Kz*|Iqb3F7ssiMeES(204H~;ZbQ=`$fvGyRi$LcZlv=n> zoz50KH^p+V(k1EY7Q`-wt2{>+3VvzP&!{24gFWK*0U}wXr(M`T-t0Gd4C3w}%#b&S z=s(*_IKctHp8szIgnfw{WaKc3I$g{j&wO;`5TiB~{;k8)K{g%NS%U@7iuEqkh}?tg>pQ&|WR1&^Z|aWH%XFV(Obr zbfh{3RtDHq3Q!iZj@a(RuV(DmU~0SWgMvZ?l=G_Tk$}z3i)9Gij$?(gJgqrNnNbe< z`A)VxdmMWn2EQL_&3b>e`DwwH(sn8|RlK-QyN^|hbayLt&NWZ z{-nx;Zf<%+*Q}unTkSBwnZ@s0)O;Ey{Wv7-8e?)gbPc##>n`Hyk|P)Y;5bwFmLFis zQa}=k40Fg7PBW;!wO%XK*v$+_QH1F$i@@Fy37IJa7ywQ7Xc3j&6^3ieGiCC35p%kQ zrYvoaVl1gb3Z5v&Hf?x($&(OI9J2Tq4bwte`La?~r_{c4|LjAY*_E&}O#s}4!2N?X z)%^TCeeg!qzUuqj!KYiN%_J3+(UKh-IxXj#1L7H|OHwW;8g{b5Q~it!yh4=|7hGHF zwg3g_;+t!S#uLz(aJM#8eC&SYpP9zbg9J-9sJv-~=4j(bPXm}DTRT(=QOV+|`JNXN{k|9&o zF=v?EUW8jr9M9(+BKZglLa@Kb=z!cW0S!LY>8EU1k?1@M7?TB2 zL>W(C`u!fa1nOV61R4y66@l5dL$=L*wH;-utcpOM2m6}eX= zd$k|%2caAVf`V^ALxEl+aX~T?cx*y)QfHBmG`a-ROX_z|A(XG&W}O)KGf4b<{5N-O zeGqw*|Hm4!r;e<;;sg63-A>VL_;-laVVHGscGsBp> zR3gJsMg}>{a_2&cn@q`>F(5b0^hJCX+GmySN{`gS1>u^L*d&0zh4UZjc5}!r#*2UHc8Gtx z+W!o;{P$Soe~k@?|Dx8aRc_?8R4{#HH#bupj!W?ZfddK#tTkFWPhyEEa3D2XM94;V zJ84r})IG+pOaeqpWuwCt_)o={AIbUk52E@hxl@)l- zeB_*X=e&5!y*=dK)c)e|qx5┱P>`HdjYi%%ZY>3NYm~14S3>Sc8na(tuavG;O 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

GlX^?)Cm3Qv@C|&z3S>ezME6R5 zQV(p4XoE_NG{ksvKbV9tB%OhMgU$uh=l)o@zr>DnTOYW+uJ^Xi0k@m@anRZ=*iZEQ2G(_V4DNDg;~UW3orU`wz(ftR_9~e3iS}*)YxyqI z<0t3mEAsvvJM-zuyZGZQ=cBmiGxXa8Ak5amgv95}n9Xf^AmTL-mi!Mtw#3#?{+RYx zFeliFGMRa$bR?_$iMA|0p z1QygEQ2$xezA_Bc5npHD2w#rx|6RqG=6~db{MVXRGd8g^rx15=bMgK!_cu3b)?q^k zb)*lf?imAi4IE!|LFk)ua7v*}59Kta4JFx`1~9(F?19TB^_4w}*nt znc9kIHI+mYWB;za^&2j>kK6lAPcSCu0jDdNJiN*>S4?*KGkJX1zE6kMr;0{P5aVfRhAa&R|G6 zTFM+=SK6i9k-tQute6-&&uw``%o+Y96wx?r7vBuwJ%ttR=|ya)x=P{fhE$JMMl_Yx zuNkUTfHd%N3(Z!`X0uFl_e|J==j^|TV%hHvoNJ`a0)kG?&*U~$R=~c2+)K&B<@R5JhQQ|E| zT{(&WO3^R=iLPq`z6sgDDWRfN8(wgF9{5FUX8gmOopoFdPr~ zga2o0F0U^?i+v$%xS;;GsY(9-nwtMjo!0#V*oe0Zmc9Hu!{ zWtRRuS_n*g$t{U0l7fipynebJIfDC)`%k-(7W?m+2xK=UOehjwUWcN>!`}GG7)2tY z-Jfi6-L4lJyIXF&8K*bz^XHxJRSLPhm!6fpvu_{}8W=96#rGpl&gB@Z>TYH=ENz@h zLNq%E+y*OAQFBv2@A^i;BWN*@KCT`Cp)v{LYD@+bOeavdr`34S8**SzbpfB1oX~n> z4;m*(l@l$g>LPf0S~mNFtbi)y!?klJe}%<}Uqr{%^oueg<-v#uRi(%?Nhs9x5VjW@ zD=#Y|KkXiC3`s94m4q;hz!`$NaO!sDs9apZs3+>$O?u*_V=BuXw09ETsl+y5O^05+ zVje$bt!~=RgN`UUV{KQhY3BBmM5GV0xYQvcByG->{61HEeGS(-jvZ=s3Q63Cpb87m zP>-u26?46ws@Pz%)eIWQQNXB&lNrJcxREr=?t=s-ruT`36OKIwLBG36K{%qr;{Fz8 zJ=?-B7UeZ_vW-B_Oc}emQg9n5~C2L%p8XJn+lUAIs`xBvAgk&l}KjK zjj0D;lB_n>%?)7g9RtzI#i2tJG9<%BH9(Q)Tq-Rx;SG;qK^tqhh;AGxZ*2pgq>4DM z%hFO!|GBhM@TG1Bx+@d--RwBECL?WknaC{z=HB~_2bNg6#`lDq2s>^6ttjl;h}3Umcx;g=DBAml5_5oeCw+M}+$QKzHOoc^AHY7VWr(GN zQLy$WY_i*l=b>m$d%4|WaEZ~`MXK#q3<{CeU&jr@?nJy!hf4TAmb)3D3 z)Z+NBfn)A9a2n+pn5C5#eN5-5ul3BwlH#BU*N~aZEAL-wt=AK1xG2V74s;b8%ZjpeDZO&K)UcPW+qot0x}EykH6MtvwndUXfjig zU|<;$i7U`8j>yIS-Njv0(Zi?GHTr37oq_)&GGv)g&~nsm`&e9Vx2IAkYmARR zOd<(DV!Nzch zx%n^z9?hCGiw&oCftQzVWYuOvLG=Nq*mROt(7vz@;Nq86YKnUo3P1Huo&_Q_)9sjP zx>*dlk7DjuYT`YbmnNXpCBTjcmbnkOe8b4hVbEtoy`7`a{N?==fBNso;APJ4?(ZWN zq8LbbujqX#!R~3!HFQ!FiqFasXq%9OcTeT*5v81Por6=~Tfyi*-{46JBRfM-aULi5 zUmL~;496O5)|T$jn{r`4c`5u|ea<2U@JmFqtjqlmwS*YB-l*ZI33U|dkgiE1>-KE( zo;+EDovgOm7t4-hv6zxG@@N$wXg7a`MV=fs?`0XO>xW$8lo|_opIb{*t2l+JMVdA} za!zsqq*?nfwiATg#s*Db=fp+I%ims{r09a1|cxJ_om;aoP?vc{sTr@56G_Az( zlbdO!Z0vbaV!j%2L-#0oo)dQLh|9F{V)^#dvyl2Wm*6#FNYlB=bVQEm)g%t5X?~Yy z0w9%<&2^tLa2Ecqjr)xkE_gqi0A}9fvSPVm&5kI1Pl*Y6WRZ7}0|Wi!WLof8$2()z z7K)cr2ZN%sApx;Wr&dmVS_y&W6#nHJeM z+B^m4E;^)<9}fJ3)gjooinWg@amC3bynA- zI;nukdibhLnR3@^Wj!)>3Mp$59BXxkFS%V3{I@w0ZzSr)CfT0$N&xM)iKh4tbo0^FG9oPkW?<9O=YS=`0?q^pXsvRCO+`P=U?TAjv(G&&nyMSrEA)2 z>+U(}zDTUta&6-93hnwyzqAWqE~u#%XF;wfCv~u@KU<$w`GC-GLF3Ay7DGhNQz{)5 zisoE^kSh-G`;r+ml?Xb z9E0u35vVo;T!YlBf;pBlyGQIYMRQpDZw2I01~yT=lIW!ZkUxWNBDqLmD+dHaKDNb2 zktq?V6`jybE+k%H*KZ|NRuWY;^+%8k4qh*p_oZD-i#eCfVk>P8#5S)@Ms9=b^N3?0 z-vf&b?VxH3bxjTp-P4~v5vd&o zrCGQrI{IGfMT}u%ZggQD{y=ks#ExO+J8JLN<+(XrgQZ5QrQ(^bkw4w_t&(3 z2!i3MyA=;{eTz%3yk=uJa*uXGj?cLzd9UTCc8^<{arr{|grILx<4ZQ+Fg@U7D9xgu zLO@|$-2Px@?u0N9pdDpkF2Dmd3<_EFqtOGFFk}EGBPBz`|5aH9dQHgAks{4sA^I&S ztsB;5-()OUc1X=kxhz$Q1t5eMZlBx&#eyKWzsdbq1< z8de!kXsBgH!9!QboSrU^j7vNyE3jS*pa-xgJ$L2w=3+H2BcHYcM;nBdwdRp=nt^mn z1t%%8Ha2$Z1pG@Zt))a7Z9oH_l|k}>>$xRpF1BwvG2pp*4+>Xf9SlpG46>J-MgQ$5g7fzf z%nS8?4-9)ym{9iG8Fly;gqj8%}y!>EIkhsq;JcTa^4^^)u?5F6< z2SRsjKCtVFqnn8zR3H`B2TS5h*0{%ZuHU94^_1iBi&B~_Q)5Q6X4#2Xng+^E$Gmtg<)nU6h^AE);02Yc+q>EV2UC`!k7@{Zi`xFgb8?U@2SQ4vUIBMH3kL~rhU zUW4|iP+D`}+$BLYt()Pt=*9J|nU>f)kZbGH$p@G|~tN z{5fy}k^jU>ug%7&;=se#9qSw*8+E zzx(N}dAk7Vh+$xFdA<56Us0Oi6)QM2RfNSFOfISSq_jvU4q6b`3r55NP5TM#Wur9l zSLPVxgArpL#IOSjUQ#O70R;QTHXUPgE5NVMI+)3b1Oq2a3IivZuo4`H< zQ>gNnX$KnL641+z9m=j8nQ&yj2QFMiK0PDY-wUj~Y3_4y^yR1xUp*msJp#I|7raLc z&KhRjaRqmoA!>`WUib+_K)P=4AjZdnsUj9+oH^V`ytVjzNb-bU0eBL|N0!kp>(HoI zLL#}crsF-@%2nI%P`0E5OwIP+M|IA~ZNFtNL62k}N#bNYOy@HDA=BnNHP?3@op^Yz z=Y)u@iP+YaFn1%r9Qfc$1$whPge>0Tv?9efJ>iyd(mzefIkSrwG#WHdDD6DXk=sTc z+TYL;bQoZF7%VVkZhh@pk_j~ypp(zG<;Bhsq^H#{Yj?j1ujie4uGnBDyTCE0+WZ>P z3cKgzPTs|vIZ)ATy_5!wc@PCKxvr+PcihU;kVe~0JK>OoI6m=hwg5I&FKqapD-kD0 zA=dFlN6njaG@Ma;e~*2ZbVNtmQHZ|tD|5nY&|j>r@jZp&7vZl6GKu+)zCA$aG^3m3d{Jk292Uugu%V9ECxB{L)?XkhhUcy{qNLG(sbyWl;D}7+2@Cf;@L`oL3@7UxpB4ON*og2 z8t(8(5TG{pAk5=!*fcGTI7B4rYVqiJRtWkdvHMMXVZl`?WOfkm2||vFnG5Cr@|BG5m1+{;@P)@7+?i1umYJ@Gdxw z)KRG>kA-5+&nDqaH)&j%)~t={G$`7M+b~d}RH}<9ph@m=CCI9Fum>~rNaG>t=^_Fv5~Ev%$jkStnS^IF-%{Q zgOF^DK^$-$>ZqTE?Vc4w#e~se45voya(4+sle?R7eb=Z$k=28e0h%!(ZY=PPVk|M3 zrba=y27t&CglCrv^QjMWZ*8x*e-8Fo~>--Z)Bu*(0f2`CsOPHL;7ZG=2a6~ zO$iwbTFpjkvrGJ8wOTX9WCn|PQ)g+i=zkQAPpLmlZiDJ;rLDUQkC5A4Hk|$W3-Ad@ z+r-D@LntoaOfki+lE{vb+F?irzQI{>tXr+?TVhb+jlj~~dPZUA56p!X@Q(V!qR7J^ zHQL*(ZzKy1aN0L9alk@0i{Sqw{Oj1eufZy0|HIQ?wX!AGR~+96GyVyV$-Ra5^F)s^ z>a0Ug3*8GjmE-;SnfN>NUyYz&k|Gm;KZMC6?Qf>a zhG6cYuiVzRj++?>yfq|;8}=f9^tMm8e9BK#dT$b8Dq0op4gUd#paSnrE!0-WiIR?olX2UZ2pavd|a%*iW za2s4xDv&$CKijdAA~~SG0v-5CRDju_K{If(C{3Y)C)iUT@q>cWVyzbST=Rf#ZfG@u z{KEkO`fn0TDP~`4`a3O?ZAyBbW*J;8sP|wWkCpIG#S%R7eq<#0k8^Vav{WAPV$20G z1+pwihn=YOS8KhX$Qzoa_w1vO zZ%;$gxEDeIC)h7hGNYV9C^kZe>~(b=zG^k?A#rf~I(EKX6^h9;3?cGrAPzq2_seftBR~%uUZ&7PdI2B-Lv1R z$@^!cfTDcolbatk(RXEdhpI>w#6xRl%x z7l*M=>V-;ni*5ivxpT^*1&(NzDcliHn#>7K7Nq?u2aD`j`es5p54OQX8%U*hK-O2t zjx}FG?neFe*CK{7zz_oQ7}g`WKrnU1pXRe(QCX)<$uAAg^;6>l@o51bo<~9j@tGBQ ziH|Jd$f_ZN876%3>(Q?Q`EpNr7oSEC@i-%zO9#g z43qe?tS=te{d7`G87lW2w+Xy#|F%HH_kGftTF&VzNIP!(NaLqb;Gu&{O^?#enk5~1 zt9H`5Mai4JhTX2kvfd`h-^}jx^G{SN8bJ-K$+s4Has4VYc7Wsv40e*N128|h(Xwej z>K|IBH(|VJ;~@aijj+j?YwW-wVR-xdC89;b@m4VXDKW*f8#<15lH!8k2V0`18O2?c zW!G(#f5pVXt5^yvhO$o$fy`%G3gqXJ%2%$c$AmU#${^m50WxCzmxyeG%lF)$m>TD5 zDBX5g#Uv6?Q~*)eX?{FS6mCKA^h4FN3^dKbuMT}1;8ZpjFn3cqCb4#grh z#M)72OK16C=zlAE2YPo7)1d6==}5UnJyGRk5kkb3Z!!+{ME7iiFw?29pc<1SYO_dh zN_Q+Td>%490E+i)CkBI~yrn}DRrhYZHOqC==R`hD`{R07sYDkY=5 z^>|<6W|Csy`JFJ5l7G{oqPPojE|N zg(w}?UC%|R_;|=L*lL?FJ;KdZ_=7Zw>>)tp9bsW_VWzz=!uiMJ2lw3%WBBI)=8TA; zXR@wuN0SKOYvA~G*ov*tq*ist4ps+n?FFPgiWtJ^>$UWM_xHd|V74m;TElMzpV7Hs zzEVr65I)*0>@`AslFrW(r&5oX%Q@aqr8J3BG9~KI=8J=Ug!mcPGk?XzjnxpDq#LDA?gHOT z$^TN4pa15bmbyq#WC{1M$1$_@97L^&r5)^Hmf4ha>3~VI`X?Ovmrtu^8^yNeyC@hD@kHTKC@wvma(12Ci{i*p9GBCwSu?5$>veM3yLu^U^}2c0g$w zOsh~WE`#GW)TfAcf`3HTp~4F5d%N<}$7w}#q?!1XE5ziYJn+A+an%PEmAXGsa1|wZC4WxPa)%3- z0zwhbTca7!=rz)H3_gZ`zByaJ^!T~bGRAe~tr*n5_Q?$_d@eiFU_|MUD5|SSk&3+6 zRiE7uIL)W(pZC}mrJKylDoeT=e4Kl~-O|k$74!7cG4So&=`?pwFm=C?D~a2-cCs#+ zHoxgt^jKG|xJPF(QURD2hsCTpx=&BBwmUAKnAPVgyNC@pQy;oG7b>vN)uP>K6aUgI z?9wdIEe*?u<+{~sBnG@mw)UqRC(hQ7Spx31vM3I}F}W4#SW!+V*H88;DIdi8T7+A# z$YlOkX--nCd1%$Ch&ypcoV;jEDxlPw`bC&(&XD$Br3CwMB@s^6LzqnuD*y!wj*Y-a3{Wm!+&l>qb+_yU|aN2ds zx4YikgvjLk_>>Hm7UdC`c`J5$;C1P}-?|jKzcO54_U~XM+Gl_f7W}Y#Zf5Sl3b4}A zuAtKX8^P=8C%8Yl6Z^7yDnbNp?vrr8x{ju%zOu?BfW;}LhM~ezi@d$Lqan!HWZzCp zS95nPLR6@(GWB=z3SHHu3`LSKLFJ{*ti>8-g0ewdMYE2BCx*7PpPw`vIq{2{W@l}o zoWle~b!nlqy*`g=GUV1!XJKz^ah7vkfWN4py1crny6SMpF&2{fqdEcpoCZa~km8r7|3Au_a(co9W0 zev`Y8Ng(t+gYR!d_wBTK43$Sg3`Ja+X>J80jYcXCR{4||&kS}(6Rupi?f%ucto+vnC}x**;QAkyZhEs_mXOIxJ~CQj7^#R38(NXEnH_e8gz? z9Y-RG06p=K6m26L{p0q9xBxzD16nM^Vpv=KMDBhF!VyC_9@OGU#N{wH`_Fp3AxaX2 zb?Hs%dE>@Xuj1`cSAOnvY3vM&0yLP^k;8c>z==pU%(a|*rSvjOkn*`WjSRXzu~-Jh zECr9DQKx)ytrFQ%nn`AtKm?0^t@J9}04|a~<`g5vmr$sDfAKjH8sYKn&I*9Ys{p1e zqr9JDLm)`moSm3V0_Ud_+#;lW)}+LkKG7-eYZ{Cu^Eg>@ar~bVW@%|wJcVMiTP<-i zH0u4jnIR4UW`-Ql5+xn#e860e*{1<#)p^KoGa5aG^}#b`V56{Lo8mpjjfJ9qVTKp& zPlO6P17q}PQiYf!0g<3`2A1FSPF>`}dT~kYMlHzNkVzf?(Ggfv{on~$*$lIWQuy#; zfjaS3Hf8HMKHgqOhglPyP5n%A%RETRh9`%hs*gHs?+_Tyxdar<3euaJW`c zcm)L2K*f&OREoa~V1Av?%!+kB$GIb^w)p3`)Lr#fHyr2G7}06vkC{S3EUlDUiN_mj{=u2o^$0Ny3>o(hkZUF0c7eXZTafh!+H4}@ zxRYlwJ@NH*+_JkH#ULi6>xK^ooXT|V!5mjGnRUuVGS)Nd_!awRm6lW>7KVNX+!fc) zZhgkLtV*;F({ETPQTlUTh zyILM*cPXsk(n^j{$vC4^Q}3;r++lr)nPd4g+ee+Ax5PKE0@nm+ETRV_gD~_TeM-E| zsV`RSTX<2(nO!EDy6xeYi3p!rk@4-Ac-Jd6gcl#B8);M6PIsWFt8YCy>(6@ky?h=j zOnW2LW>p$ZM_sp?Iww>6BbJaYDzTo22#qpHvdsja3iA@ugR!5*Ey%U44sTp&5*6j0 zw|yxd8|JwlhmH_U5(LG~TJp#bKE~=<8zUMjJ>yO9rHKdwwShZMF_F zSb>efK0btKmo&H8O(pSqwP>0}Nl!&dfP2z9{CbF@p#W!4C<)_R-^@y>V#mEbmUSH+ zX5TN`1e7LkqwnWgl`~8YnVVZjzMD{C%#t}$TsO|;5^BmdP1oQj=D3bpb1qIXY(?Kw z)r}c1I$%;Kco4F$cUYS>Z=O(a4vu5$mwI1k`p>T!Sn6pUv9TD^8`Uvl0^TI9rSJt@ zsJ2efy)(%IG-&{LSzBaMGnaT1xN5NU+~Yp}vE{N_OC@f?S6HTM4u=-4q`tzA+$-1y zxs0q=VR|!RdZhIfHLFw!VNL#x6p66s9jNdF1Rd=oY>xePXJX|t>#_UZL-F?}#p^fROk=-N%WzyvI@@Dv|j#1ib zX^eb!H^j_{t^QmoMcr-zJ5CaHh%#ilZkn{K>vK}lfopexeKD!lb&X#b9GQh_q8#M4 z+-3>mqVq@PM@AmJRrjq)d8aHbLy|MMQDNxn{L8~E`*s|Qg^X;HrFum8X_R08lPd`y>}$>(=3H)nR8LpSRCiaMD~$1)i-r`>MXNM5G`7T-C<$XqX5DX?1ljis7%b916Cs{T)%jBqPti*)VTEt255?;bEOPA3KhCSuq;A{1w<(cd1adGE>k zYwNwp5Fys;WNi(yJ4fa`qe=_ZCiYe~M_&lXo|04x6fQf?jaR}{beLvkOK!++R~5x# z6T4qUib-j3U+!NFKizCVN^{wHK;KIx-CK@dPgrDM&u3q5yP1LoI$2smOHKLICEohlwC~lX)NI$e+QZZc0A%` zgn$|RzHig|f+LV+&kRE0CJXTiJst*+K}gsHoyqe0{+fqLtUI1Z8PR8Q^asU|wyxuF zF_SMtr?X{nmkjg-cgLhW2$Vc#qG(F}D1*E{BK=s=OJ%y@+|CM`j0oU>7+=qjc-UJJ z{Et_V8CYW!@BFwVmtCAcGv3CArZXz8RJ`Pv2d!Dub9s<67BJwF$t1gv^h6pgV53vS z@4WJ=PT}EIPfOo2=J3(3I6!%G5n4u`HOD!>?++g;W$2h~Ma5oT+=Ew(WGq z@uu^1v_QvrpO>e}SS8nP@FD9)1cjgd4RAqFUlL8i252?xogPR1C>6l7bp*00DrFy5 z8QMF&Hg=fQH&6{h@^vAM_Hyp0Xz#YCYsX&0ZqXo1)_(qQcLImWH&FJ#L7BCNi7Sh1 z^5QVbL1bLP#og8mx%WX|zNOVVC$I`;1Bsi}C^lX(d2zvjDF|VRKG%OSmTa-fd_g697WMoh-5SYOZ0`SP~2pTu2AoAMvrTi=mlF{s4A_Xju>a(1bQYZv)Sa^ zuG-1BKkS5iYM4S$;&;Bdikr40bJ&g^v{uh^LMeTZA+|<_&rt1#v9k5?`aL?R%HXa&**F9msJehUg^1f)NgLtnEhl6Ge z4-0J}%MK5t%%WV!vgo9%_GG__i5kmxYhoYHJA#ke-zl5D#mM%`2qQGyho52D^cA(f zqI@azImk{$;wz`NFtu~+6lX2|TxYn{KC5cQ)(G5BQguQ4#we!*glm0x=Xe!)w_4{s zmWcSDw9caqn_!BipQN!U_-!~vM&kqA_%t>6eP_3nY?$aO7{q6%oIZyl^+}Ne;SDMr zRV$sJ#~AKn0^)hhqYy74oX3X;I!Wqp)w8h@rOw}|$$La1ry3~E3I(3)Vr>` z)7h2)rKaG1Tf9|TJRbVi5Jx2-Dp)oZtdSKvww|NG=adOfAeeZ@K52}(U9RB#%#*q3 zZD#JO#;`pt(40w& z>X_2q7>6J&I7}LS>Zp1_PVBd5+=?5J-x-%y39DO}G9I6<8Sa(`K4$0O?HX;@;*E`CPpF`F)%vJy$bVu}nff6biH%>5rKt*IQFPkzd zQy)vez@%gY$!1qJA!e6eQzkfVbP8DNh$Pm&Ymz9bJU!Ayjcun8!$%FL(1cs1SktSv z4wSNcAj_G^YUx~IO|B5N6R1?&lrrh; z?ikDMAcAo`i-DIj;gF9lC8kpeQMfJ<&1($IcIbQ7@7AL9%a##jBIG=Pv{H~C{N^Lk z){VXF4IXgk=}l{nd7t>aQk-MmW`LV&(pumbrL8$0Hmy-PjTcXw-m3(vU2xZZ9I~?N z&TjLUJh5ojJ0(zeORQLMQy^U%&^vhn@X`9F_y%d-%#$zohJn@0v!L|)rM-!#kmLg@ z)QO!&e)6h3gQ`(m3Mp(cx;3vw zji6)dTrc|}#zT0WNE+#!26hwW>KdiC51ZwMh0z%_^r@@p*Yp+=2`xLa3DI4i8drO= z39(PpkFk9cb+!t#@}#A1!}o;dUsjGp`u2925wuO8kmBfURJh$A$5R3XA1IJ0Z)VOm z_Iu!-Jw^eisBU}MLfF$a64sXL6Fs*n*%Fb|028ZPRJH?t$rX+)*sAJ`_Ss5kDkQ+ow& z4uB21VDoYpK3Yn zm`}_kp)?oWv)LNVBbmCa*(&Doykn5nW8zW}vlCQ1{oB?q$mp z@JiuiB91guFzxu|Hn?+e=S)%57}b_3+BB-DRHAQ-kp@;Enp<8(d+VrIaW5b#W%(UT z0)c&&6%na&BfvR;hK2!FzVTmDQwLcse=(LG$f@Q(M+S7jfVj_NEeZrlTwBIyr>Z6| z_BNEEND+@904M%PZc|1eF_1AO1@hOun z6=3KpZ%>>!(GZRR!Vm4ofA8E<0CqVM8MHv*TvhaJI3WL*}$$p=#qMpF`0_SktAiH`I>T zi>Z{uJl!1ipYk+^^iH)zf_s)d!Koe{@zz(_{NFOqLi!TFW0&@&gdI=YgoNYbeZ$N9 zFiu46NbHsl(s0gObwyGCUMZ2i?Xya-zO1YC*pryuS4>n%-8(eqH%61rbK0_>>NfTy z-`2W6nXH)Y$<#8P8-0N`M>0v`KkDNsiKtoZ1g&Qm`-)p=oOf^20|gSTEM_$!#@x$aZ8u(CXO^M*#d=%s$i@TzTH7?@olR|%B4 zvpQso`NC0o2UcmF;jgjb^%Xf#Oc6&LaO#Qvzzvouh9F*FjEA!(#K~$D!obyH-l&4efflSV&?nwZHZFmKN@0d4QA6;sA#le?EBsdq>pY zmc`@^jSOuKE%pChA8Sh(u>&}w4s?5*?g^o$@DPF*ODohDe1jYl#m-0KVrWGqVMIE@ z>X#JXS{*;wV$>FLq9bX$mGJ^+15{B#4mAoSjZz*AY=zx=uQQ(4i^=~0Gkl)dCH^C@ zVmWh1#%C*6S68R&*_B!c+N1QKE-kNXXqI*1I( z<55{0k@u^@ZN$bE$kg2qr3CLhR0y~OPS-)t56 zFa!$Ev0FED&FJlZjrsYi*+;Qf!A`5zI8x}EL$$+Fr=AY|I_H|w(uj{IqbCIxXX0*y zl>Nvboqf-DX5)enB~1jvEW1fEi}x<+29Io`h7z1Qy`p?}R4?B;dw|gx`dw=iJ)Yx8 zjjkH#jrFXbX-Q~Gelp1Apw}a)?6Ef~7WI+c5+!;$9tP9!eHtHk$Sir!t_jJ2BO&Ws zt?5y$%3Yug;EbMmbYQ2c=JE80Ne^96?bM(45)p`89YdbVox(IGraA!M^r#Yq|Y^IS}ZAHsqCxUGflOD6UKJZ!a z(42m*jagiBPEgI*4v|@Ia;Hf47>b!$w>citlMk||FRy@Szxwb5-A831h=N3gm zxdL6=@FV2lAzxh@TenMkjHH0~Lo@~E77i8;=)S?P2J-1>Uq zmRqA~;&Hvlir3wsYr>hQV?*^38v6=O^E^PeN%YxsV;`*{1VYRIBl{(_FyiAiw_icB zb(YgL@SBe6Vhi)nPQsUpj|BaUmwY(F?1DZ@4f0jP`!JwNr|e!&h||!vh`3^}%R$3z z4bY>HwT0nqtvXKzzlPc%C=i)jvh7VzVML@@gDtLo5z_D;_uq%k9@(6X4+p>M@IMJ8 z7;5CTj2*X=hak@HhGTt>^g7TfmXmA-HX=GsgEJ}ZY8__~e<4|bM5f|9WILMYUchh+ z<0|R#0F?IX!T-hevj44M1X@NXs-)c-#Z|W12Z#<|81J=fx+75}LVUJU6%Z!JM@+nR z=`BGkb5M}RBcvXXoK@l0MIalrNH++*S)}uXaP|=-o`5D{q}xMG@v&8T!%?0w=?cz* zbH^9GEQRT#Ttu^l{7Df(t>NrrNO&QT-SfiSI)XsX=6qe?Z&V_I>g4&{&maV>sSq4{ zaE#-1E&!)jhcwN{0nwq?kzgn@so2|l>5eez6q{nY9fFrL;vYPfP5&D>Ee zrQP8R1C9CF_y^9bv(Ly{eSO_WF)FTx$l|7EpAeOd@H!7=mQS-#7RdNMMF^k##5gI`BqS?beB=^5=gXW|$w6 z)&qe90aYRVZAkh3P76Decb2;L4z`ALFaB|c3V7210{GteC;fSNVgUU8zjtkXXTANu zRCz;P14G;YyrIM^x|zRK#CT4>cGPScQPSBVM8^!V*Hm>uU)8BWD~Rv1P8HN@Zn>$T zvTxjK*vSTc>hcSUESfUFs5J>wWYm+TfQ0I8WZ;oQkrgEH2@V29VManZavDF;heuh( z-&?aAKXvo$I9-c;=5)pB#38{f(RW?IK3XaQM^T@ntwcV(?kCoj5+iY#TTWQ6FA*1= zqtSuA2_Hu9!&a=TY7{C`)zK@$AXMwg#~8k7;EXetH^lg;A!{YEk3^#}Alv#XM+o^E z7XIV4wIYP?km4L+E+{KDNgTjOPhSX8m~Ip@cQkuX*{)n3KVG>@R4Y|i)>5KQ($>AF z5+~8QC{aP^;4$%5eU^`;up&*`K9Vw<_>R>p)KG$n_wcW+=yp`))1)0@EXGWT6+ zkuJ5j$!O;9i&v(|I$+YOSR@5g2G|mAM^c_U>r)r|V;HrR2rDyS&YfA?)xIj`5sEBb z!S0#%JaE&A8_NoDVOSQfOX{K5>cyITRL-6F9bNtrK5KD3=Nu=h$N?}hP zVBbrPpV1qq1DC&h#gNjO>dN~}IokW8r;TNQ(|`_5JU}l?^L_KzT%%GS#E%7Kg)hHg z1_{qqA&=b+GIjY>!EwJLH7!+p^^s4EIAlt8z(v_)R49xR4nbX_5h>#}3oB3SUJNff zQT)YjP(g*{jUy7T%fXicCUk|I5AsHI78ccccnYaRa%l0r9>ML$B*Puib+N|UAXMCJ zGsVGYM6Sy#frKrk2-(L3=^E#&sjt*G#q@342I2x{+Kmy_$9RVHD;-2l6z)Sxx#7j2IYMTVq63!Ys2z}p844$k z>6cR>=o7S#z;$w!9|(q_%A|95A$Os>R*{JpS$JyO91*u*t-XQXCgY3dd(dA>LiZJ< zDYlp)j)+pYm0%50tR^Vl2Sdz?y>$50O~|3$>$9TiuCyPMJtK=aq^6pJ)}&FC9YArV z0m6h;q~w$hGQtoooR3UX)J^HUe#3?Vga`sviQw+fgGsTHoRDN98&#c(sq0+H0u#xsYP+VK?S)!a$&>ee>F9#k>iJIY-)A*Bqu037h@q8B8 z^w>tWb*uO|q0a@z_SpvhLwfIuqqyauMWvl>a|*X*VGngv^O9}?XJ8snPD0-{6((MN zTfmHB%}2PLF5ShzgI=>jRHAyd(%d}!ns+rU;q??MeMY{7ro`{kDP9{U#l0sj9t9Ra zhcnW8LU12?XT#NpDtdDdTta%@cdva8tVAz+~+%JrVf@oHR`ASNkOh%n5xqtuA8ccr_0%6<5R;&bSZ3xs{tV zOSpZ6I6X)>16=IhbZ4~fU2g25w>H4|8;m^Nitj^s&oLRlq@is}81;)O`BbW4wj05x z>CITDjCD4afv?xzvG<^VqE-*FqxQR`4udgA@i4%mts$YUw)m2K(n)9jvZAW(OFVZ( z>9N@3ct*kEhQTrMJsctu8*z^=SS#q=iHxLbM9u`N1{CbD!sr zEs^mzhvSJAd91fVgmjfj0dGs&BKiBtb1!emVi2&TZm-ufZ#>p>utJ-<39HF1TT464t5=f}GP7P?&CozPE;^p4$~-BHz_ zfka~6GO@(T6t)bbFfSBVzaHXN{5IakpHQ=6zTsnO-}HRJ#rtu@y$Z1@!+>*^8P>1M zu)!KG+0x`6{9VD{CP@9a3KmflU*sbhPauz9L3A|&RfL|!+^L`zd%@~54ngTUlH+(7jUk5#Unl|@r0{V8_|0Y zp#&9YkUtI-3{+`wj5lfOLzH$@0tZ01d6Ab8Fs`NSJRVj?0_GQHZj`ZBHuo?BPNN?2ge z&(YFa#?O&RS-~#J61tL5Dlv{h@(9C0Yj1j+D`7uGB{AkSpmWFrMnI$yM|}|3DzlWU z4py0B&n7kARk&w%BZe~$`bd5(4oX^XI5vR-|WUo)G=~r-o7en5xVF4cq6Y*jK zf4~lYv2`kplkoKt$F(jwGHbhVEf%w%ER@8*+MQGCu@LJxpioxbHJW1qr%z*6Sm8YHa zg>v-J>0wdz^FNcz=R{8uCxFwzi@yfk`JX43KStk)SCX*8R>a^&;fll}w@G`K%1lUs zFd%k97N@L53J(Xm0zKE2jjEW!K4TD~ufAm?K+0$M0$YVob&~d#4;XQA# zKQ9_}zGHwpT*SR`jde-nLMgU(r_ZBK<4*0TD|C0~9dzv=^nNo~;1~0HuX#PE1{X^E z-)qp(4utONNjFL)Aj!l#*(I1@E735+`9464rV7oBGj$hc8$w7P=d|aT711pvB&$ot zjUM~xny@FK?wyxqsD~A{RtmF#CR}~8UsIc}6@puuf!*ywY0js^2HjR|v!qE#2v19| zxgM>3G!hmZOG;)sfr4un^;`;63atUT$jZXgf)xD zhqe@~LzhhQI;GXWTaJGqq$sFV_eQ=;cF4>){8*lcGN!BtxXUF;{7Rr}kj8jFMDqGn zwSd6Yx@E92@j$V=Rd*W+$pzwiCn+)D?6WgmctlWfnHDwK1!?qTwdnH`G$9;+lo5mh znaIh@t1v=ujeUh;9TiOPiHx_^$1aGzIVg(kCE2=e>`Z`o#(@1yzK~7z*px3a8Is;e zw^Bi*y{FYjHD{tjI7;vF(_&tE$4ixNgbX9hpq~s@ApKU##MrhSWj)VfWOlDsm?K|o zWSZ_n7o56-?aT)_{^;?Ag!?qz;#(}ASxyRE$$D~)dIXn);Yt=*D3lewsUxMugD}hL zX@`pUa#x&Or#A_S%r(n+SAEQQNbSyXV9CRD^fUc=$xPCT345w0%I@sR6Z?y{EZe#S z@pP(~`b(o&`}wH6d*S%HHjz!G$ZL-CUK*+d6*R5ct#*&@VKN9k1GtD00oZJJ52R}2 zmN^!p)DsxNlH$W8OnI%drOuB09CBXd+MPDWH8cwuf8&2zj6_!gh28_A}w&prsJ6LU9{sE2wfYPURDkT=6tWm&^uh|>deH=_=4 zhis*7@2`F;y6p_r^c2e36T1Ql)_OxlTU$-%66A_Db&i zHg1j8kW%$U7lTNwv{Dt{#wM+D6<;}-aUPlRp%acw%^v6LY0iG9-AC5wN~S%hqG1VIr{ax&z|R^rV24% zK8ke1jTFBn&tj#owYzyd46cklSNzlgj_E00FhfiBtT>LV?Q$Wb(2USwGx{vu#9MSN zgJ9p{!;_tr8Mk_3Q+nblB8>yFQ2(~U$Nf3S{drfr)zf&!lN*&={3``{&b{Y18}g6= zIOG8+5KzTG(<5LIR3KC!NJv1Z3d9e%zQ4dj0Rg`BQ<4%=;HMFj7N&a|{x-AvIji#g zdu@DRAfQLU1z3~(A#nrl|6f)qerYjbfIDPbDdArUXINR8k$~@Z0xl%L^*v<(m=^!U zOrtTeG_v}SMc~)$-@g8TjSoLdZVvePo5A64IpDwlH^5!izd61iEcshrWzd6eNo(KS+{2h527hW&9o{FMqaSGUg&5NjE*^zdzQ;d=^1`z_Vp-qu9V!QPPMt)czz zYs+3e9N!sGc0YjGiSRoQaEFZfSLE+;VMZSx#{fE93Q!!PpKyx=zrzW**c&PV&J0=o zYhL=b#Es1g?_1vj0eKey0TKViy8+bJe?Lb-b6q>TAMI7Y0;4orEztp*(FAymv_An~ zc>EElU}Yt#Yx~Yn$XVae`di)qzVNumf+mrG>Ma61%WnY(zb6N;KeGR-M$H6UvqgY< z`1JbM;wuIIk@zf8%1QYhj}Q`*LH@ z9kBTW%Ka_&($6}?0I0U#RMNlDe$$Gw?m_Z2k@koa*IzR5=N5CLF3g|oGiNg3K3TN(V1-Af>3$O!^05YSh^)BCyiAG!N8{IB}*V?gDf zHIN1z_%|*0Kl1)fVSWt9`m>N*0>35xGoARWkUxfY`&r0a;Xfn)CghK?Fn(5_C+Xi2 ze+m%yYn}h-g#Tx~##j3t?8jglzp{Sxn*Q@_F1($dXqWkBRQ;Z!Oa4dvUz_2N j?<+rxZ(Q*|@_%lVV1OwD5D+Ec=MvDXRn-Egb57%&6|H z%*gz{Dmh7D5R@Mf5D-6p{NVrF{_h3(1LTLauo6G5xQqz>*VvCAz(3?9!T&Mt2he|y zlKWqUQT~qjA7N>J8F3L|MI}0EktBI(***r0F8Wm;*ZK@d>R*P;#5gZ2Kl>o`&juA& zxAY4wYA?Y)Jh&G4L0IrIc(-k&K*!~=zaf*16#{1nm#dg4gokGFM<47MVRr{prB|#K zwGmojLzT+GegP<u2C@;;LHO@k z@`IF{oQ3Fg8Cf*7;x#5IgakkjJtiFkbapgHQH*Ed=I7K(#gwGP<#QMarTj_mxDJ~9 z$lnbpIV8VL<_bE9`8$;w*2MrH9Ma20TBll8 zY%3&Z+X}vWV48=-KcxthF#A%lAC3)UIUW*PKv625@f`U%njtLG_+=XXAS)?op26TZ z`mzia?*dp4#-i(!%)O4>+xmC!pHZVbvuSgkd=9lwOo$gzr)#T_$1AwA)V>=WmMN&1 znJW6SFMbi`2G|D!y_mi=;_Pp>48Eq0iT0`$%IAVux{Z5`>&eQ<&~bt8_&kS)WML}zZl(~H$AR6jLJO&}1H1u%$J?d}c-E#svTW^6&K6d+ zEsV$tn(X`>^5;4S83(ThLX>PNiW9gie;I~)Yr9_Y5$ReserII+zBnO@B^>BmU4d0Q z^~y646Ew0%aBqptk5Q9*G8cBF7^RSX$i5NF_i{@Fu;;=ai~f`l2&F*`6;NW>s9d#7 zxt5i94N0O6HS6otH7{!k)?ZGwk4*kyZ_4x7`HvRnYGUF1$Kh%0cA3$^UKtPq27sn&w0>I^^JWHV@vEH%$ckVUA&B6R`?mBPRSYYi=qZ-p?P^Kg z@8L*26Ut&N*y0gZTXfj!CqoDEqU6Z^STO_ga*;)+d(dYH9+_I@g$bg}=itrsCBoD` z=x2zqrA3x85+P`M^1s@h2#H|SjqW4>*X?oS9UMatmGKc@Y{`1<3lUbMv6ZYNFT-P; z4jP9L;YN&P+)AiR({QqNE0IsjhaX3H(4$PQe-0#u&0XT4hA343^jWi4F{t4sq^iA0 zYn<_oHT7fT6o>=ES5c?v5A^#3l!_Jsx~vJMzAsEH^2@O%mtSW4{$d~P6@gz#W?Slp z8C0`8|FKu3DI*mSO0x-F|7+E)qs)>3y@8pWuoY4z#Xtj<5zAMCAOpS)UQ@T z*~WU%@02WVNfLS1KdSZeOH(jEv_Aw}h>C^7Uytq zRRE7QJU&__FAd%YOWz8wwS8_BZbE;Ga_rkpN#LI74TeR6$@vo7{RZ;VMnd4vxS2N0 zSur9stIS0VZMJ&;K=VW;Wyp2eeN6p#^}daLbiCxm_p0$r*Qtp4*(uK;4Z%lCDXr0G zp03Aw=R3kMxZG!MbgtpwQf!(S(dZ-)m%9WcO$1e1=#iy3jAZRUorAf0Z;75DKR*L+ zS9kJfS!gF4&-*gjITzhxVQch-4f{fDBy!jTQ`j#`W_qpN)Hd!Aq7lMlh6ACu$FdC0 z{l~EdHz|GA1D0>%KlDEgk0&drrzlXv)wyqN1xwi5^4Qfj)J@xO!FDgaPijMC)q%dV z&`jILCQiG<{b2SeD}fR{<6`^T2yg*i!!=ffBg^v)!qNIgN1UO&dVitRJ>U@^>^&I0 z>9853TVG!ZHDn=BX(@v*hV~BYJ^qBc3)zllo(ORwl_8ATxwqaZI-F8*sA*bE=Mgc-v2QhUbuL$a-5K&VSi zO0XE}aW-azu;E~@Pzu8lnPQdV1t#kqDa`3}TS8Zy%) zse2Mu+@_aR&k*QvZD*&>M8#QC&a{4lDE)Iup-Of9q#KfaEYXrrmp)4;dTaAR9V~hw z$<9=QL}iPU4@Y{_vF_!k+{KG??JL7!Q_=^aUIRs!5~^0jS|v5Jr`Q*jeGOdIpDFbH zUTwM%O_A?HX5VjuSBtE4lpB}1lT!SK%}U;pRk}9n*|o>yN`7&Ei6(6%r-lq0lAI~Y z8OoFO5>_0mp*)X7M$}hulW0V5L|JsO@wHx8E3Sim750nPS{fY)-!hjD8I-uZnEN$n z7glIGPk~(U*U_x3E6eD@Z6bF1Ld(KJ3R7gtBMxO(f`!wF6_gm!p#ZfzfXk`(`NSC= z54Va@>TswzlSis#dAk;3y}>yR&%5Egz^`s<&{Npu<^h9TvA*QFbf5F3&Fp*02I)Z4R_f&!-|WwRg}K!gP;~rtbBT z5T7&fweTjcqQV)CP;SPh&5id8iGFSQx^;bZyMN30XqZAZt)Wh%E6<0l$PbMt)lR!~ z=O@Mjl?_sP9)SVUB?;Sa(&Xz(*pSan3hSaZ3Ki6+VTJ`E7mE}upYpX@{i_n~52;%H zg7zMH+cd&A!W?1CGYsz=R>qRamZ}-hrWLpzmXw>!Ro;-ahgqnt8t9Jhb_YdulOtYr zPu*oG6%ZxnN6{p9FrotROuFM($5(CY&d%I&g(Rg0mGC$7pa5-)ZLcm>D@sL=D)JAC zH_h|70v|F@F|Oe)F;`6z-PJc0;gu?(&!9|3Bl<2usD=uJ!%G_c>~#2w{&8`zlu~w9;dLAS2#a4%2>Zz11!JZhhD-(tD0oLVRnvc@xs*O)xvRGbjDEGq-h+Fb398iAWNl~{-jt^zz?rti~ zjMhdlHA<-}Ev4COkV($d?)OL82Q0Cewc{7kf$5E{FpwvnGVrn znG)=BN6TU8Af{SiA>8DLrOr{2g-&GaP35Mt{3*pSApQ3hTI2 z(DR~=@k!IoaRLB6-RVx@8x}Y+L&QC5?nPsk8B*hmqOp!~RL4%x85eh8^*>G4!`U}( z+tS=I-rB`cU5i$PhP7Pr_xm{?ayNHa@5Z!pp_9)_| z?`LK=H2R87DbJGTBi%yDu8tS_kp}TK-2^ndbMBPgldXvRs5K4Ag^oU!HtvVZJ)ROh30Z0mTt&I~h>qO~2bh+?MV+ zOxsi$-Z@rp**(JG()TiN#NS7tXm@HhY6Aw@a=S=TRJoKi+&4FRRojOp`4ZI>Yu6Hc z=Se#A83X&M9Cxl|eaFwJEzP;H_^<0bhoW1~FwigBZ@ZS+fCO_`0NkdvVi<8<#dCO=;{?TZ=76o2R%(nJhoap(oYEjOTz2J-H&i2BeBr!9e~Sw>JsOAivC zn-s9aW7?)M0*zx6cT@Q>YEvu#Ne~pC+mzqjtgj4+o|BN_dVQXW4Z>x1B={3sfV`Sy zcEE=oJyL z(3fE;=K!tTHChgo54~|mQJjf{z7f`n#7HKZl7rMS8&p<{$*|)PU8TN(s2XtKu1CkV zMNr*W)(XJik$jo>y-Pm>T-S4DTY3;G#%< zl`Gv6W8L%V$hJ%nv(N7yJ=|WK0Jlf@hK5(fHX~xQFaP!wdt?M=u@^0@l4(LnQzR*VxVoyf&{7teU)RyzYPDpg&OPnE#_eJPF zd35-H`BhX%NJzQ?T} z?~m(K!CNjb6z}Sk9l=lL5B}_+-)GP_aa}n0=TR?0-H1NR*L$zvHhVz`BAc_kq$qioT3Ztre>LSBrx26 z7FL|cDMi0(1#He?o(!W`3mHtnyfoWwzMQ999szDaGiQ?#pVAwX~`~gJz$y|Xp~TC z9paVBgFX>Bz{t+Y6kQz2g@33wZ5oN;T_RV2HFTc;{ZK1Ghc`JBGK+&XQb>^EUYa+{ z5q-2rOa~5dM0}49?#4_gNp@j>@n(%aOHH3j$CtQ2MZ$2D(-nrstXE7*yH~T2@L@)@ ze&?=#;SQJ08gJxC8?;4JrW2*@aJ0j^_GjKwk97!1|C?e$w?F>(9P)G8i!YccY@$g@1% z_ganAjl-dR*v{`nzwbk-kLrhkZwcL-av>9`c+O`As>0MHp<&YIKPN+DBQlO=Br4Go z;yWjr64o)L<0Behjkh+xzxSRzI^eq-v-iUaULW&Fs zM16^#&JZ2xJQkRx3Quu7rUYr<4?UY+5IhW-JhZ6a*PN94)lKM3QX|+cCi)eXB1qoH zA}kkeW;{RQt=?oEAu%mCIT}L2<_)l9Bv;7k4o&Sa-pGac}veh$N_o_QmnxsX*UGX-pW+j;q@$^@Hfn>-U3+-TQmr& zPa!QiQi9EQT8_#DvdeA`6IY9|ZgRWwB!Rmc9r|hE6wq2e!!@;gH6%4w848@daYfhI~ zOPri=cOs7mP;X`Xf275r^~%XpY|aydec8)6!=;@|xfIZz&6J6fKCby;MX`}S3i?{=N=o-EUhVEd>o$K{-J`D`xJJ2cA5++KS=&1XI%NP$d(%I7 z|1%e=35i4@`s4nL?SD}2+O#}DH{9e5W8exvE zS7Xu~v0ASg9{{~f86pntqOH+#e&S2J;p8Yc=z)oAz<*{woWYP}YqF*WRigm85hPI+ zC$w{=wAD-*Sxbo{2h@BsrQl{%h}2mga`JpPUG{|QNuN^u{{8bGEK}m+Gbu_cF{wG;bskAPGERUic(j+%#Te|^bGl&f^#Y7Y;5Tgl&4Aw&t zlJ?~IgEt;~D#e7(pZx)v{rMx?3js;mlZosr(noK@gcGHpGXA7LbJZieb6MwnV)g#> zxS0M2S#1x485ij!oh9_B z5vR(7I@zL9-aID7&du$pkNWxlK~I#iqkRF#1eQ4uERk-{E=A|TYmnI$8aUOR?=5Yq^7 zJ5bw{`|!KDlZ=`iGf}E+$DHb(U(aCk30HfANy-l~J)PpyN`oO%Wo8<< z8Hhf**}h~XT26|eywc%-r=Sy}lWSpu*L~qOM$8)m%D%xFRC7Lb7Yub;FRMd|1-J7A z7^plO4^0giqd)@EhcnPeW;H%K&$#ZLeIDVrtPpysJ7te*`74WOVQ_We%N%EfLvHN7 zezA)ZdV=YhNkP`-zQPgq-YE4oqwUVMJ`IP=I3BY`y+=z{CYd3H1lnNwsE^PS@<#8x z@0Meuc$7|;2)%B8O7VU=WZ~uj4WeNSZqAVRe|bbWZYpEtUrrSU>|c2V>%ZX<0{RYS zhT_(a0DD_|z~ART9b!?<%~eYo^?Ne~kSsIrD8XiKrqSdWAK!!$Mgpr&mRmY6EZ|Cu2#7^PK5%&Ha6fEDNOO8v}Y2()S0D`{a~P-zINCuSk48o~JKO ztr%dQ!?qWbxLAhRUCoHG*r%-@)r|(>hc|6HA8)J_O;u4nTLjkD7+x06JSVN)B^QEL zia;@Hpbc#gT4W+rPoS%3U*ZvbPOZH4Cf-Bq*9dmqse4=xx&(U9%x0(0A<7&$x{e)K+5?pB5wM9PzO={BH8fvJ7L1d)S88(GkF5^tq9)+<3;&M{d zW352YBgwRh(;OOX=Z-2+*_|WL)OL#cF`aZO|OONJ@oR`ihq@a~+VH0m>jymL_NvPkO(xVNv7&$EZ=g#*_h1nWG4@eDOFv12JX5bgkK3=duc4N5G}g5mTGw)p6s z4XVq+8l?FbZTqS+rMTz;olCv9%azYIy1{8#3H>0YiJ5$?q)zW-v37Crl9a6Q)-qm* z83&CX)AJ6{g?1!CI)F+>%nIqs#YA#BQEpiarnZafiNm}p(1C0@w`|doI2L)ZPhU2~ zA!_xOfH10H>o*Xvc@fa=6bD?!(*UIlE05QKpgDps+SX~Ll_8Xi^-=4ZKnU8))b#tU z+XcdA+`|4md{9>LRBUom*&tolpzb1FN29(HXjuHB_8ll z-JLH68?v~SSCX{_e-C03=a$%*yP2JLkq>7w8LrcbW*Do_gG_nJ4N{|SzNOYw2Q*>IFtEPw+y?L zU^AAUC0TKMX@&g`pu^yp@EzGND*v2Y#A&$9>_Yz@>1oX4W*TIQ!xwQ2g@5^uh+z9loW`aM=La zIzgjjzo!!H8Qkv(`1K-+Rw)V#@>|p|{qqHzL`AJ4smu2@Mc%rG3!!Fj`rs^5;_?=p z#pe0VnRcV>?vvtrpD-KCRI%Ut)yjEoU)Ex&m{O3mB$5(faq9x6tm4g)Pr88nWCr`? z8@$>;3f~bKUo&f$#>r5%vEr*t*gf}7f8j}5oIIL!!( zf43Z_^`%0L&ywn^Ar*w}1BmHQjlq1uS=V}1O%2l?OoLkYT!s-KkG*iOPDy7ug;0c{ zMCP|=vIAiZ^!&(BlTH6y(`N+%sH0D*F@;V8+St>hM4GDWhKPUx2h>ed1{?_L?es zM}=aWY%S~}n&3nIeMA4d3|4}H5hT^)YfPp~dq-cPV@Thba^uxMhN zHJ?JSMicW?ijJBNXIT9_<(LDhrzPnWOE+zjnHw*7FP#InY_9W4y@YGx($=hXM8KO5 zAWzkyS?-o}?&tD70u;*TI@QA{tK+Y-{?Vpbop*c!8LgUIwIB6%V;XAD)Ln&B2CC0@ zWlB!E5@GDuVyU0;Mz>^ww$dz!okmGlXP5b2nz+U-(NwPk{sXh4aoolaA_-orkFdFJ z`$Pwnm0xYEV-R%D)_=N(bPT_jciG~|99sFJksYz5&EabyZTIT-`NKMtI=0TOYOnAo z#4XBtkKV)F?eXj?`dn|yOl!(tM9`1zb?pn6bbD}dCB)(ev1;(Q9qw1axiFnIg31O3 z*$x>aE?WfA22r?Oxmw`55GpGq8-BXZ2HnywT&*AcxPx7BODg<0_G^hJ#&f9m2D$UT zcP%>nS;l;j)>QRilvFiN)d!SypMC4%fJH5=ZRBkQwXJ_gRycSeA*+6x^phA<^cyb5-vM!5yZ~7owP270-mF!eQT>yv z@g{7+YqEM0xTT+_8a@3`G&%mYAVKVsyVbw)TlV)g zs=Us)`%Q8Sj7`KJS5fZ%jG=K?*^cPvL9Q3Ri+@A=u5Lg zfNatskVN^2;#weS9Q@ds8gDGqz2C--=MG?e0^Dt5_Ej8*}QRZV!B5AADin>9I&>8RKnG9ew0j$WG^_AU@A#B>;Dw;x9(7Suqx?>9H0 z;hO4jWAzc{6Y(dNj^FWP{j*J|cIM%VgWy@uw$pkR!Sry`X{$&*Si~2~a8P_Q+HIk* zrGjqRkA)<+S zdGFQVKoU}&Evp0T(aX{uphXI3DGl$FaSOEtKizSrBdHIlJ zelWAw-;g^*!1mrof)0nn@5%12zCmQmO?h>2a|aiGx-XIZ7=tt+F@gKaZC?5Y`bXId zT<7WU2mRxRHu1ko@)`c!Bwt0}(h2a-^gc>SQ&CeH<;$6lBoMe4BvxTvgECrl(tN{oJKV)`J`!6xzjnQ8?N&M8 zYLQCBaQMNOF>;&v3gb3-wqp2xFBx1Wc*due0*Ec(8*>-v*Z?BgAx*0&QQVkG)BQ|? zG>!Hg=6>~CSKVKqJ%QS(I=Z0#)d>Ez?sdZ*-L%xxjiuZrw>zi!(LYP`+|3`fQ;F^% zzEp{y9<5zR)#SNpl;P7qUE(454xUz1y8NE5|Mo_nKMpE@38&N)Laz@Tos1=Nzfhn3 z=9g@(RU;<1Q@tY6sBvFh{`_rCp3^i+BxZ0ax~RKtd;ua*A}gCCZ1tUIv2D7Lf`r(& z#oRaNYo&8(-eu{zr7k4{ZCnT&6jKgj+#)>~WI`d26 zKCV4Ur`i$&87?!D%FP~6u>2Vjpvj`iseQhVrNSVtSTo;oyfGL9A76S#w0Z8}0Go8N zm1c3&^hSIR-n8-{e$*Epz$eom3bQhkBVL}PucSdr|E=VTTIa@b^m=oDiOb;%i@%So z^FS8W7(ZR0^d$@UqHYk;lF+!QSY&qKYA!3%{#6D`=v{8iOciWpSCQFeU@=^kW>&7h z$DDKm1e@HzGxS*49ctL2Zx>ynsCZn$IlOR+ZsJSN{6}Yxko43oNiIDV*YPb+mJv0I zXXrst08T6a7$cLYFUZNDC2|^4deqe5Fmq$Cf?0H8r)4h^8m1*bhQVtl9~)^3mOp>= zhj9N5luXGuW%$vx@yns$#8;@iSKgj4tAGPnDX zdHY@0yVq;|zkBwH?2idv7kTgGVlun%g}*B2Y$(w-1J)by-+`mwLv6RZ5h6d~LTXSr zT&TB^X)c}tT#)cQ79^uiby9O*U}W;enP^kFv&EkZvhSn{Z?w6OX<42riBJ6Me#5W6 zBGhx8JS*v&%NjMyYaBFGWmbjjS`P@v&kQInu6!!~nkg-feU%4(MzXjt4fZKnx^wOq zbM71cAYFNnFX>xe^C?a;fJcF1h_pwpTF0Iw-Q5)<+1fAUDTjN6Yv|Y{0{R|NqzNdw zL;@1Nv;e+C6HCYzqHQlSzP;R&#AQy&RzCZU;$uAW(=fsK9D*8gaa}dGN#c95`+qCO}ijk^Tx^-LFo0$s6l)L#vC-^M2$-2 zB?&-pnPyvg`DSIire?FI0bYOF%Gw>iOy zqDUeYw8kV06xuu2ppLU^awcN2EL=E{9UmIFtG+!+s#&_{f@t;~w!PFCg>Pt$ zfkczS%10HeH;~+uA_m@)6nN;7qvO?LkBmX}o)~^{Ixxc&y&R=Ocgbk^9198w5TucH zkFX+|L^x4K{nba~PX;hkIY417`gv%|FlH9Uc8Ix6HGE^B{n&X{+R9cUGzB-H%g3-F zDhl|2cM!vd-HCB4U|KO7!`d&&Nro^|`%wG=o&Qq0Mp9nU8<=x8&eIzsP@W!I^~b@J zRMrG8KgvyhkBxBXWCuTn^bc5O#ZCxQ)@gNgvJxMx`^DcYmweVAlo}rZ9ZQbUl#^FB z5PVB$I$8|XfvTJYovqBik8e^C>rk2M3(krH4`DyP$It7xk$ zXlQ7wC?acZSY4W95jME@)L(b4} zB6OH1wK_6}n0x4r)tL>8!!>qo9;AN*rPuf4s@?_2r5KAEV-^u|aL&r+?gs{RpNOPk zcspufXjKFTV_R7l`K};onSBk0B*^|75Z$FYu@DQa?(DXu0?{06HNA>Yxk4w$r~=J> z9$4c>Q)q3~lE$q67ljcVM*Qb{4Gwk3Oieru{IH}!ty~I^;H)pnH?KD z8YZHG+UY>|SO~Rk^4<0$_k;-X){bC)qhBUnMn=KIbMC6fHCAt0sTEb&a8xR1dz~81 z*tlUOx+-7`mHnDzlnc%g zY_jSr7uKG?Elm~yTRN9UlvrPY^o6b=vk-BVSzmW?tRsa5qtfQl{#fp+u)gN z&BQ@8qbLXNhvjAsUiv&q)fdA7iZ}$7ErqUE>uwpIc{AlSQ4VRj=~|zSW9&7jHhn;N z`fJeNU7sJUrib!7^p*nml7`*_;bRPk7`TJ4@6p2LV%_psH9cK{WXrt4LD6Aqf(Jzm zq?u`T*b@Vam6>zqJxWJPJ9IbtU;O4C)pc6Y_^L1sU2isem>#2p>u!mI5rG|PV;n`Q zStZ(ua#bGpB+j1paXKIbDaA}U!=aK_K9o{SJb!4GW3$t|l6O>8oo3sj@9)BPG{@{| zHCANDUx=Hg-!t|OY`xDcKSWdabL{q8a~F7CPrKg3GgsTg!9t1@c`BB=ENWC0E^Z7c zfT7gdW{4xBTg6C1!IXHk`MjGX0?QFT;NYaf8NW_4%eSkjV6^xa-jB~lFZcblAp8b}=HhA%EKlKL?IN z=(BCp(6_gNZFu$a06FwSf8EhZJghK4C#Bt zCVE^a1}G&wms}(BK`s)4aIih#M9nAa{Y?-#gAP~jYBY3FPq-%b} zdN&V-KdTk~coQAa`FO(xsEUK%rT$*2k4C-LlAQYRM>Wj!i#q9++u9?+b?ppu<`fNw zQ(GzqFh1ye-ZXoKE}(ctM)+kImP$-#CB2FzfJ9qT?@&}%Na|ax?WJl%RPUh07aoBD z(;YjkJ^qADKbE6crG7ygT^zuh zMTW4`@B>N<@(V@YBu;=^(r?Hj6ZNie%D#n(1^q@?O6{aLBC}EsTBm}-hp&KMZtd;f zlccV$KW1KVOkVo2>}>0XOp0~c>dh-|QG-)~gHtLIf24a$!E0UVdE4<-pK_w(3;FM? zox)=Y6I^>sC$OBKhXL)QVCHKvHK0P%_AES-;|aa~eRvH3hE=@78Mh?y!V>1Y*KRQE zL-Vek{Fm?n+j7S}*3&**d)li+`aSDb(DegWPsyu3=hGv}Oa87@yk0MR2>20)71H4v zO&PtI%mJNOQoJ~LF@W$jnQK@j1b5ItBxj*av16rT+aM*bWHO32?pU@xh0j>ghqzRO zXn|rEE@Q-<`fCwW@E2eB-J8Uh*1!Wq^R7Wrdm5gRd-y48(W_KJNYm)q`*LhUv!1oz zlf{vV*Moca3o+P8q0Lv^veEh8$$X5=Y1?DU12@-aE2kFL1367UmGf+R#O9{GP7T4y zbweO?H5cPrDO!6QBhiWOwg<=-^c$PeUv%-ohfwgrbH+zI*i?7sdk|*U#s7=mB-9%A zjmHOsj8@N{TJ|#@c{Gl#n3v`l}`eDf_S8V>rHm#!xD9U!a zz1(;3_=|^JhM(Y?7I$UR9;OwccMk1vy#{jD{Ms#XB{IFKwyXSlXiCE*d!AMA_?pUx z(0Z_H!{tk96LPhAyRFoE!2a6L%o(^{mP-bm<>(#QONy<9=-uNr@yvy-A^HZFTkK1o z4;2r5d{cag26$mdY35B@-c9QM$GBet&k?%#^o9>%_QBrKQVZncBs{uPOV9^eUg?>| z(~0+w;|D-qRazzV$&~JY4o=HSO4!8xw#b6sob2Pe#KRxf0qI@ZMd!~WFozU}oLVC+ z?zY&QX%W(d>2k(H8~8 z9_w+P$0J)VM)+iaw&cW99Z}Y~xF{DRWZYFF(d6rqB96MWXiG+7OG%aEk)u5vPu%UC z^5T419WaiPx#6WH*Suj-{Pz!z)l9s z-b-;T&1f6HyWNg-lFC=kWIPVbRvC>d(>&;c4w~-zM|eut)p) zW9TFga?4?5lQu1#!I+n})Dd#%GD0zLm$&L}Y2bNBYQUrS@vYAztguZjlDe=FjPpu1 zH0tb-%WqL~KWX5pz?h7t-e640bmLOmZM3c{N@rN*-YUM4_RN(4NTY6HyX+5LPaCij zfYxu?A@e}ZuG3dyZ{Pwx++{{d3E1oNp-R*-ZzM7(SB7$8LDDaK1BxqM=0|2+K8t(m z9h#F&T8M9yC*3&K<-ls2n8e~Iiti4R;(4hKaVIu3UmGq!M6;I=+`BBAuD>a=b7t{z zmMeYv-7X89xCuXl`_c&O$icQS=_w^q>pQ-1#a0ZAI}dNlrU1r{nv-DYsHo*aE+YvIc8azkZFXaP0UUcff5TVfc^Cafhh+z&Z)NbyN=RzJeWDWwIbWUtN ztr5?;jejFbg^-wcc6JI|P+{sGfGg6khD{Os2P{M&1&jmBXr&hnQ$>%V7cMP!&;c1z zsGwgqJVG{H!h)#n>bl*W}c_Hc-gaAO^PjuOOOTEkYVuP5t!G z3tKR$L(ZuJH`9G(2vXv{up0Nk;3y;3iyXh8=^}^F?B&1bB)jNf!$;{M#uUj6U})K2`2_HvgjGUUq{cHIPLSThL-DhEok)UEhVmlwLia3D7HJ%85OP(n zyZvp|4ZK?N&Jtt=XkwMmXars(`SHqub+&`sObe>4SJSUfPJi^!Ne>A@=u= zD3R{K*U*JO|LEw71(33;jS;Um{#p=xj24^WFTuI;?Z>~dx(Ok^;v1M9<>y>#74&wo zD4y2$yN3vDZ(m2hiMJV=uA%#bV~!DYz;oOWs$~Kzz{~a~glpk8%t=Irw1AB$LoI

ZAVbAYWJ_Pik2>=};XQ>a4x91N9{gO2f?SEJjLn2QtnqSCp)J+6e0tvb zM@;4h#1QtVB(h?1{?s8P(tiQ>LL^luu`7c@xGhCW^8yaU9}yhV7Np&a(52@bqN&lY zp{wdjEQWZ3B@^JssO_EJWpVHE!TYOVyt8*3^>Xf=qc1R(^F0iF8!Vd~ zi||9be@Gl)!H#6_K}5np0CZ7sQx1%%Taw`{Y7aDZoBoZzdLKoKt3NaIcKF z2*BfV?9u9i*A|C9W(dIE$mM5Zi%*DeUf;#)a@B>+xTry(Y7MkN{PpUL0N#0wGF66{ zW~S+it2IsA(F=!nWADkfmJ6Bgc4d5Lju&yT@BBhuGU97@V2YQ4<4 zBEdx%YqKMR1Rq`0VlUKS@Z+Ft3%wT>Z zwJ+gz{c^XTFSyx^_<914eaV*QWwIZZ1;mcN-F$wgzUaBQuQurr7n|ZTKOk6{ZttiL z{z^VyawOt53>mx)25uDYTLN1SRe9?G2yXSBxP-gSY8R}w1r8UT_n8gb78InhG}E_r z6pt;TN@LsERwbC!aO^jPb7p$9tK?7PR;>#?zk@$u_ zpnQjKH?$lc)+AGOBA+o|;W!CgjtBK#Sqwy}l~6~=!c9hw6otTe%gF7a>%&R1Lv`lG z$Z}EGOwQ$cdt@2W33~Z{;DVbF@hufNnMJw^d~$t462yE9%`;^Zyx*kC2bF8ujTNiN zHxc%qw5a@1tb}11&}6# zy0Un|r@ewVG>>^)T1Kn0T<--@5!eg&fb>$80Q!<*eS~PGhf?7}@Wqu_+?J_^v_BT! zDJoq#;$>lOAF2WAYT)yxv#1*~yTV?PSNh`#x6MxUt59c)^TW#-PE0ijO2F+=hjsd~ z4mO5mJ!wwh0_x_z!X{!(OmoLLcmmypSSCL3(_9d0no3J!H zuz_)pNY*?e>g+zyg6Gvc@^Wy6?7_XnRRS(_b?{--K(KX!9BJ3`!;Dj`JCerSvtq z(US5%`H|a*U8E2pga`XbkHNp!%!$lV8ErtYeaxsueRF?ysK?s04$a z_DyEPlQMYw7z|B}ki&=%EXyCG&BT;%>@#l$e`xT-eUI>k0APK8PO4>YYHEOGX^7=9 zyz(rB3Wry3at2fjsq7LyM5(@`5%#@#sX(%ceH1;`0rWPm%y}n-6HH#31OZqcXG_07 zr*-ZfXs)qTI!9@VSm0yNK4fsc4C88fA;+~i9!RZ$EJ*@8Y9RUeYKH!djbH+->a_=l(fTPEYLa4Is-1{Slt z?5@_g0Mw&czWcz{j(E(tJ08~~pz8vzQ^DWTf`=P$BX%b&91n@XCK#J%71*7TL5;$S zD?=v3`JK3Owi$IwrnF;$WE{K=hj@kT@8Hwh^NaZ=Y_v&p+NDUeHO!3tXrp1_R(F=HuO_zi2_AaX zz;?GpbT5_23|7rfRtPnx+H;l)q&BIXbZ z6^D!lYcMb7jB`-xNY%Y_F&aRtI8V59EdV@XA|ao;j|$tLu=hO+DRNT~*9(Ga%hlmp z$5d7z1)tZ4gpw(Q4ykXjO4uqVZVzc-j0z$TrmHr*F?q-+x7CF6$9p8=w>pY(ZkCYI zeF@FzbVHjW%95rmb_tl_BW0s#*mUC8^qHj3jw$>lp);tGax;Sb!ASc)JsO^lT%zf? za^gfdomn%hUxXw{u6GS))W~F0GiJyo-Q!8Ih7$-8nlQ(!79=Um!`n#-) zSVatIq%w(7VfboEcEB~wj8~!6mI&HX9Pk0#b2aRlbL|1Q%}B)_Xgbn}={r`Mh`ZX= zY>c(u4>vjBIH6opU2m=!s!3F)mqB;wM0h*0RWSyQX1>B(J4Upd;aPJTFO0Tdf%pez zI0kMUy{Q+iAm)M8-X!AW297m{p3;VBl!bI~LK_Lw8Sjrk_$pE&oM(IJXYc$=#uPX5O4M`^o^INywo9h``>O4MV_WmWxe5Uat55l z;6LxeVh&&!ZpE=Ekdb%$EMd~QISCrE zchuPMy+p%~zcVfh_I#;Fd$UPo8T=0H=tvWb`}R}ZKI8VIdCtg7ksA0SGg<+Y?qhv~ z#^wF~Rd(~`2A<2;j>{NVZ)yDk94At_1e<2YdMpmru%jLwDqoaa$a3H)7A->&?R!2r zs+5{h$Y-iVN!Oj_8DMrH51`R}v}$e6aFiJYZTxmWr~mB(rTucie?hDf(tGYC+j3bYBv82CWig+XNuC zQB8<8imkiT;_Y_FM{wN29MLvPZ+2Ao5!!UzA%Dt0UCQp$`-pLTb)~S|Ss&4Ii@Ks} zQ+s6DDDsL}jpy5SQR#VBq2kRp-G+6B<}E(hrFF*S%}3qswZ!1fofr_CZ+YNpfW%Xp z>|Z~I^itFblq*TvnzaPaQefMuJC0~pYX^RwZ@ut#=JLtD+X+6leG&JD6wS=b+)v8q^;SQNgj;pJ*LFg3dj72rCz5BS{b;vtk)gxkDe{%wffzi3 z^A>7;r|qM~jeq|1mZld-eoyhD+4(#@Zy4KMoUkQhFzaFq(kc3?Tly}>`7sWN5HSWzz3 z%V=IqB0Il@H47)DB~Q5L6H-1Uvyqcr<`+g&wGDkniHmNp=>% zfa=0V4RBItqt+)-@9UB8C9M7`k`q(mPueK3CP4*$?nXYN6AR2{S5#&sYxoHOiQ}9W zF``A>mD9nMrYPn+bQy(FEWvKlj)EGV`xv%F02#s~MuFPaH-Y?d{28p(r@fuStup_* zcx)3eYvjt$@|P# z!pB?V>%%|iPc5r!t?+|wzRn(blD49D472tcy6{jNv2{_p5V zWLduMad4Bc-(p#+L&U-(z&t&IW73Uds_Ks4fKsHt#o{+6$B>R-P2Pb+VS1$cDU05J z?=dEtV0Wq*$SgGxGkzbgL*JU*slPX5Li@_(t9qU?p-$n1HBAKBBH6C(kP+@ZsFz;P z|$U0ob#23ANtG}v@uS71=ebbHm(3NnS4X%F>INz8|@2`1;eA| zG+v5`EVV@aTzZ%Wd+29W$c$P7q5B%txGL0Fh!yk{LSY3|uLxFMw@5{-BzX+6Fv_v!e4U?GAh z>SH&Ov;W$#!EbL8Q(zqgXV$gaZcV*5|b`>swcC*!pGU9$>cctq@ zpE({}U$e-Xw?!hn$?4?b04FaNyC&B|4P3&yJppk3ur9uTOwP5~-@;mD-oagx(l_Aq ztvNLrDzXFQ5mK9?_#&l&`eNY63_7!|x-Vr53AKq-}(AWaYV0`>s%3bF6! z5(K83vMt7dT@gqxI)E6k-M`X)f6jBC-d@*Xx6$DxA{?e{%4{|&vtDTv_Pv$JlG7FQ zJ5}IROaFMI5xd8*W1zL9-zI`#cxd49m81Jq2_>5rp&qr}b+9&DOGC+~!nC_+Tzeye zWY0=q-IfSF=8lX%0u{pyWROX-i0H61g;pS0Tt%Tp{9U1W@{9#$4o_Zuw!^1pt)O0W z3w=Kw`#?z+Jz;}u2Ur51C=wTBIZ>*V=(+?KrM)_Y0z>9iJ}^jQW{_sSmOU7_jX|Ap zZgOv)tLaG-K$q0J={Mw0yx%+-(_{CW*Gj{*de&>%?1kXaVbWYO(lX!J`+o3uehx1b z*sZkJnz@4JjbcDw#FS||`{~qtIJ9pC4vVbmsf;GGSWUw>TSu>=k{N1U<=E8Wj8gFK zy}AMa==bd;^U1(~0mRj%y;v3w&K$pqjUymZ7d-Cqjg0yRir;F4=|96AXJ%@0TUUXB8v-<)5@&SsFX?l>+kM!ua+*aDi ztDI4b5S{rBhl@~sC1LP|C&Z;ldb9LmP1=$0EU^qyNkUS>G)(#IgNv8a-gtR(s6It^ zVm4lNY7Sn_mHc}TTS!%6+Iy7G6C3}WGH7MAW5zcCi9Dgt>W?g`Af|#9ky8rkufCPe zQ{HpH)i^>ZICHg=Dx>3p*(*9P-xYX1EueMpI;YEeeeDv2&%6;xK2x|b3W%$Il`irM zIGd!rua9ypqS!T?m`RWNLMneQB%$t`uG_3e6Y4@ce;-~BHxuaTLP-uGbM!MwUmeh-iYCm{Pt7i~Z*TH?XE?v60NWj_ z`}~jEvO}1^n*x~s!4#lmVPkJ?qWY)evIaGXkK!_vH#^f<2~z(6eqZq^agF?I>Ek9e{xu4j5FCT;rteF?oQ7g2p=EzvlolSDw zlr#uU(M@s=v{9H zO6(%~!w>q(#mRBi&~?|9E^=jP29yH@7A8^`P>D=!@KSxgmvR{NsRkdz(C(>(J=87; zvn#6NM3T8}tlC&=>Xn+>JK3_6$O_C;8jIxSfD#qbkHsTFu&^asw9k9^1=kh^ruBwk zKt{&SkU%0yJisCT~*%qg_19(E_uS+rbS#MN&zcTA72dCVOJq&ofaou+lrkzzf3>wwm{z(W#G-T zx3sLGL}b7eib)kFH&C`MXVXO7Hm`#+`_>^~8$N&@sFJnv)rc!pLP60a^@npWL{?9i z?S&3Fd3t<(^~%UfPo|5e`-uR?KnnxvE)P2du+xubCZ3_MQle(=(KeB!?$N+a;S+aV z{(y{zg&cx32B_jFDg&)0+%5TV5r(2Jbu|VOBF-u{`==^Wl%;5Dln>8&bN-TJ!`;^DVvNV@kZ3=!(RLM(B1o9ol-(~h zlv^3luE)exM8ipIlTT5bZcQ8Sg2Aq9_$PF->2vL>j&6z_kmd>DDCw0D18MP^s~u(c zdq%d(C1;i4Xqjv1h@3G_G=&frgakaM#$r=6HBY)7%i;Z~3M$F1)Gd`{2vKcq)0Z(L znZalEPDRBj4FJwkaSAmYR3+B@J!W@6k0BfC(Z{io6UHRvMrgm9pI9=7ma`Pz_c6mQ zgud2Ya!7R`R7C}9Au5=zM#pB>lIKH==dz9@s?0dOE*&q1c!W;K3XhAxArjICs1{08 z?L0xRX(3lm(4=j0W-6HO9YE zlQlPg_n6N$fl3C`W0iVw6ljhOiItR)^0ImFyRWhy#Ith^gl5I6VV-%FM6+aTKj>*- zrrOX%Tday5RcSxyb8g;SJ9g#*HbuDdtG%*1&9Hvpx zMm|@+Fzohb8Myy?rSwH8aWHvscYEMKUZ*b^DU6jOefehxb^nWum(;Oa+1H=wYpYsX zZ7LJ%g&O6mD_uA%>%XqBVs6KwQ{eO{~Ou2qS)|{tv!{rWV1-$rH!t=_?oud~q zM_BkXTc_^~WvD`iV!%{Cz;i%r5@OFrhG#dJW`_j#=oP;oW-qPibM5TnO&@~y$l6a-8JGfG&(|yBm@E{%cWm{t>)LB@CO0Q25 zu`-;7=?PjWIJ9Bg=;J!AsW(=3{mk7`tJ0Y2>dYgD2NzF&X5i zw8pqmAPw+UEz^jEM1WN{;#+1vVgOvsQF_^lC@T*;qs`|EiF2#SReFzcT}3gNY0#s9sX@de{Tz?1RTRwOlOSEh9E zq*%R-G~n|NnW1JGwGnY{-$QR7p89+cW@&8)%MpniFkV>F_Oh8Uu6d(Q*Bh?~B7 zaKcYdX9lJ{p<~Zkh-TC8CQGw-`dTP5^^m?oWYGzn+&;D#(r=^triZ!azrqhjyAp~L zPrqpus*b|#3-6R|8#=3ysS!P_VMGRs!g-zOir;nxc}+-3*X}Uq2bG@UjQ2adr#-l9c7u$f5@{SGdm$3s4k3-L>v!f{Msy(@;a7A< zpO}h=yU^%^b)9#@9%4~yKr6-j#HM$KxZe%ZPZw=BA_3ocnsb5GY#XpUTD6$*3eQ<1 zik9N_PjCxvFGjjQcPbwy#?^GLNM4^bYuzQ0u_QiJbiv*^&Ix91@MkfS+OU3=)>{Q! z>wEAz%Z}(7dupGX=?*_N9zM@Ic)i$FXsjHZiB4D@8o6|aT6XgiB6=>HKo`;Da$st= zIoQC@j1$}xTzg09Iv05rpqE$-`Iy0 zeaYH>z8|y7Rc%BCdVuC>l4<99=5kRLyse~8-G%h&k{Ife!f~c9IrPwC35q>SEfvKr zrsM{3;bH}Ga1?p~A?O*UaL&pCyRqM81eHpg@q1bxbfsQ@Jrd=RNvSw^zsRX`q9?3Y z!DCI-TZ=gsFFYK`YhfDf?!2!_Ihp?QlXlKEedc*TMARp1vd7gK?gJ|+_h6&585<9z zQ6>uKMjBJdB4~Fe7k%q4;y~_u*znkvJt;rynIbgM+cwZNs>;qRpZf#8YB)F)V;4iY zv@z#Taqy8HJ21)DsX>bU?HWj9Sk$L%8isZ?bDIP9ZT=2!Nz8X(%DX&>T^|WVxa#yw zCb!ZUb@Zaf@2)B|MMA+qPHf=@E> zOl3)+M*R48{kmaTylQBtEaIajGebl-y-MmrOsGvpf1+%Wm!?K)Wlb~VR9WG$O=6+{ z^~QmM46B~g0mT`B&#TtF z8|@~ebKVWv(ZDBmCJ_5rd8wBiBqllB(!+-iF+nT& z^N|$646?Y-m%xGg`h2>IOQA8?FUs5S2eJ+x-V}+e&Nt4%7;w`$7!$A~+D~Amkjs{| zNQIapmbkKN0^zDq@bYNciu3w@nqN5^kjLAw>x(t5+}wAy3$6?r?lQ=U*581^9hgndhXOpvkC)+NF+-^I4p5QOWE5f0kbR{oVo^obVw~k zU&q<&W%@2I6^;{k)4~A(?+PEtiU5pA92yJi-& z>rqx%3^AIQx!#6>oGW3YqtH+>PG8SvrykTaMql)5wd6uv*A2f|jQE;gVV)8}49bws z4>u!0JdG#ziAW+J=mb(|Zk1I#$m>$@(8A_^qko1%Y5m|lb?MrxQ7$BEpUZ;gx{2l1 z9OH|El9{Vkom9lJi<3#2r;5To^s1r*ksn5Wi63~=(YMrgD)Th61UxO%=Z8Hn>m zEx6&YCJ<)*dzDl_077Ed?MruJ3?QYaEj;+=B*gaShbCrRk-Gt2m2iCGZ}4ejc;ptK zW+0E0@4%Dlu7lCXX|WAYc?2L)#bF;Iz=-vTBH5I;Xl#)fQSuG2)c`jkS0tra!|@jp zSP(>E0u*Ak`K`WHTQ$on#!^NnGQ2KFp}zvMJV7e#J*@(o8ZT%4;2IcK#wPLnI6tjLbnO8#`)o=xmC>I>BUHIL+ZF zOTniWtc|+JPWsB#5&8Nrh#3fH%!ZN=h#3QrzZ((%gqT6;zedD=_nz8esldO;xFwuIJA=vi&jsq~bLG zWwZPwXmQGWk=ePI;gn|b>SjO4V0E-GD*!%OPg|o{houthyA3!o zapq4FL?U}jbyl&mjw4K;*$URmWeH-CdfhPok^1qV zqX#D-q}Ol|L*l03R5Wy*dhAiX+#>qc(rthNCUN{S0{`F{^zMKlh5{LgzE_!1q$#W3 ztFwt*_Rj&>+BsQ|r<5hA$ug9~(H&hifK%Pw78uwAMdkLUK#x7vlTE%!iAF3qev$?cKAxk+ZzleekcHlSGS zQY(R_9_NanBJs<I;)9 zU1z4#VUX3guT5nyobd@uh`8^%Ah0R4z4 z%Y%I}E9dsq#egV1i;utyM93q^MUE9#aC>(NN-)bLq+P&DM*COyK4Z1OW?GAtivqtV zWV)L@A7sFkl|qV{dqRr!4tggQ^+^w(y2gC78AVjySq(WWmgH4Wca0|Ih4IHYNgwo( zn=k1oRZ^(>;02hEdI*0V;y6uIri*K`_qCK=Xbb7hVR408o|5FxU81G1{Rm{&64MZK zR5i<<>k}tO_BqR&yVh+&*9KFlux~Tzkgw-Zt{2?Fh95qzZT=(T&m#d-1Vyd*l`AzK@qNbE*q5>bm`znypQ^Wi|PNS!TBe+Y)W>{jz%W`Bk(`2 z{;a0Fi1HT6)H_5^2uGqwqL7B33>Y$rE>Y>=o(zQ-%{HV7obPHlEBFP^o_6 zJ>j>5(r@1hK7nf5Hqe@gywZ?qNpeQm&y-sgkJ7hS@S&fv?m7d#VI#M0Ba>&Ljz@6& z)l$IHZkk~;f4VvrijmJ1=u*&_Kk~(bw^s!%~fyECp~vH;`!6sUK)HpCmPBoMHkh`~4r){hfgVk@9G!#iOuJ$V}{%n3qvVwcESe zXN%Vn8GF}}LR*;9*Mz%=Q&*8{V~1;Edu>QegXiocHHaQrza3rvgkddT4-H z68uhq3s`@sVz`=qXR37Uah@7+G5a?AsSxG>nc0t{+x%T$asqpt*UV8eWerjKyPAlh z;fD(!rOVS<%~DsoIb@EqvtcC0X>;T`gl7T%nAo+f~4y+DoY z(!@px8p&<+<=^K>>^GTxSI30ym04twLpRlVGN?Ow_&nYw3zMIMSdg__HZM%Lm# zx$TceKdWT4c_arvaV(#jDx5PJ@zmelTG%|lxJFCi!b4B3A-k-~xX0h^^7Dq-N@rgs zMth60kEz&RXuFUQQ35$@xRorzGm6ynXp^sX)mp-ejR>p3!;$;*}^f>YAbJA_|*e=aR0`RfosQf2O_NMHqKf0 z8G(W1%l?76d5WQuEkJ=1;L@u4W}DA3OBq2##Z#o|BT8IOl_gu*aJ~eb=;b)vz*lv$LW}i$(1^?E*I);kS{CcV+z_tci(h;b&tz z&kYK!L1XG8X!96!cSO_`?=Ad`8Qd6y!ybs9`QNXB*gDB;Z9Rcb`)H45xqy20)Pam` ztidv)2i_$0FB-AZ+ELEjv^5>N!&u9lCG?-qUOwTdDf{muz5%P2PhPn5MXLI>lB}4Z z7K|_4=8_;YXvKN!n3nf$ndQBF3I~m_FG7GCc3szCZHbe-<@fO{CNsPU>S-L@Nal9t zSukiLL1wK9pwxlCib5MJ8Ve5YRC`<)K@e!^Qd6W465J#|NEq|L0$G%Aw1S4>?HH=j zXdc)^WPfZ$b$5ezs)2Pi;PDy7t!lvCe}F7dddtbH!D@Cy{fHqDYFI7EtCM~Y6Bu*X*5 zSaURg=dXglGM`JS6|38i5oKrE-{g`!w6sdB7&fxHTKXtciL*X4m9pIF|7xT-TcoKJ z7e1)sL{v06B)gngqU$F;T-F7B^DtcV<}Setpz{M#*=Cl+nqIT}`^ec9TU$Wq zwdal!*Ki^O|K`Dfqx}G5V@DB?bC2msfFxUvCKs|6UJqwbdBSFmnokl<)C=Ssgd2ZW z`hEu$JHeJ(r`eWc+o93(9Ce!+mwv|Q_brMWIpkeE3Njsz`&~d2aSorJ#Oir1qoT8# zS?s#n-Di;q=v^&Nu04Ys%a*9&_VUz8@}OC^^{aR-U)rZn%acI*kF~Ogf;p3P2$skr zt4EKCp^C*AFX|*kT^c()!?lLn6;q-uA#9;~W5$tOz*DlSXi(EHuFJA&gMg~a%smNIgwTZ^XmEl3|W|&RS zjUk5F((q;;&!mk>r>Q`)D>$RY^KirIyv6n4u!?RIV9Y3nK*>%y+{0p(y0vONwmYMA zn^k&ti^cXQN1_q(v2LC*jvYxD|?#P$304lQbUKF0e2}Hn4-NFM}}l zNyKoMBeX)DNo`8GNUNelYi_@oi-7f~T74nXgwJLRM zD7ljRGa^BAHMM1HjUl1};RNZDXe`kB>izIL&_pHLYVH-+3Md5O2qCQ|F+t0Dk}qmb zB|{otc}j{uD~Nn@fNB46LbL!8RHNMC$?BtHCbE9WT>JyAMhUt-5w0(qmw~KTvgzVI z?<_FyCgh87_aEvr);NWj4KQI-=?}_}Wb<%XEg@PV7TcBTM zTgQpL!??7{lw(Ed^hNjdOny+QCt$j^gMtXFn&=t2mzh?2&c`mh^+`2;s!D3n*@KaK zd7kJqINX@X0&ZYg^GviMl+cOt6`tXx78RYeQxEs|f-(-yp2o1~!>?Ezt`of^SOL2U zsY3Ty>k~%`iDJ9~ttjPgld`aCmQc+_33o^b$|n&|4&Xi$;w2lZ{x+Y+o+pQ`uZT9a zOge#wzdR7Bgk3Fr0&2kBg^nv3S)%IF6?4H6;0%aHp;a9*L%XCqL%U;S(^xKtbe_GO ze+$vgO|n19X>JH8L!BLBkjjbLLsQ$(l^0Vq-z&A(8jhh?Nw5#B@QOrw5A4h{qYin4m19gsg_lV^`>qo})qt^c5Z^d!k;D%+her zC>|byC{IIQeu~nYsSR`G_(=AP>n46j~lLI$p|_%!zBRF>*s;PnA9(1d<(SF`{o8VctyUlbxB_q01H*DqS- zX(02@slkoiTvXr@tFeh{8?BNu=nWtGZ7OTl=_^@|H zEaXg}oPdtJ3?}*ju}8Z3(?Yz5jAMEXke*}a7ZCjJXeN*Z@RL|Bp*fv?%wTZTA2-|j z`P21)ynHzKqu&93euA%dMR6kQ>d^+(pcS9Lr)^ls3K>|_d*mDrg=6dgRkbBBkjlkZ-k|D;M z0fKc3?2-AjP+68;$eWCQKLMVhr_4PS8*<&89r&7lm>PNmAj##}{*BIgjl|E72Rspw zWL59BU7SjdsFG-Qz<1$HIYZF+2b6KP4V7M3|I*wu3Shs<(Wy5@qin5u4ik2sM zcYA!eYx=N|iS2~#YiX*ZcA#8~1}L2uri}-SMZ-~l_@*}Z2UNUlxACXqBLR<&!dt3I z&Y$%Sp;6^bROU?{@2sj*2JQTdFO-p$*@GUTnK>-!;@b;)4l!k3ckrOrWBf7nNf1sT zgYds9F2IlP z#nZEOkZCuK?9RD?lZaH>MtMwo>IbnpQIDTVRoEWYzrGJSK{T3^py_NIcyQ~S z8m;1-$k7+qJWsrft}VGiGqHxJ4Ls!4KYTQ-rV{I%bsEK5q%L80z`K2gS~=J16^Fz^ z$6~0DULU}uExJe^XOYufG%ZPL|6uHe)_R1$nSHP9X3cAd3) zUG*}#2Qw7hR!$$W5;y3^*!}$*0K1{cQjj^vTm|b<4vW;6U1Svv&dbS-TQ3y8Vn77e zinYM@&xv%`-S}kXhusE_pNv>k&IA%(1O_SzBypg{`d1;`BwgZ77@!}xxk z8wyLbk^e`UBJSfUF9isM4De@C?T^{&U-FAo`_J;_WoP- zH-hcITKJta8R1VBwm%4>{|Ei^U)6tU{QqPB^N}}yy#0%2`R_D-(JKETr~jq#M-l4Z z>HZ>B{zE7~{x`q8{h|A-fc5Y6e^Dy`A=dw^{=W)f|IP^h9~M4d)&1W_{=16yuhxDi zQTP?L|3iR3zR&-8N`J1&{WH1pUv2*mNB=9__lJ;u0)%x$C1HTaV{tzd+e`@_tC6Rx1 z@OusRuj%U#@!4t_&2_^aXHD?5L!{{N6Mh5u~$f5dhFYX0}^>#y?AKV(wnKb!yG zibenG;rDFTuPp8#5^DGlJpA7|-M>2eJtqF=VU}+4&mH|cRrXigzu%qxd6;!t`~%zn zdyM_BPJUn0{`selar&oD{$>pPe(nA925>O#bV^|9YN+qP}nw*497jBVStZJwDk_RPNTZ}0AAalf0}=}!8Os!A$V zm2^M#l%fm>C@K&nBqR_JkkCKp|5{K$pg?kBszP*9^5P8NlR!WqK#DRD|H=UY|Cf~F zf2)l8kHr6}EGHx{B`&6-N-rlKmn`G3#fTVs3;alc-icO!JSwyx7>*!UBm&GsS@b(2 zPknjQY$jrm?CbTVBv}yNn&hvSg?S&IbC5WFl;3v@u8fUzJ7sU_gd1Z`(dTOP*_anp zK=7zd4O~wDnw|&FP&@O;XrVJc0IWNatsooXe(d6 zIGPY@ft69z^#MKy{0%$9Z=|K?{y;o8C37q0gk9$ax1!$uSi z$*SUjR(Nl!iBT4yjJUhPA`zK4Pl6rwqi^asx)e@=P_pg6r znPlD}6#WYb$Q1mTwLtpW#EGa5k;%i1cwO* zGTRqnI5AOw1`tr!;L0kmYdBA z&;PHdM8XF$RsZ;b@{hOwy{Dl6NH{oKF#Jz49sa*`9E`2aOk6$8jQ>a4$p0^GBNw~> zkp=AkPYWgvc6JW-F8?D-bpO$kkg2nrUoJ-w<{^{y@DuBw*xTb{Go8B#!Cf#U=%iLSGxICn~6JA~-pINrA$ zMOIV1A_Ioa*LDg`MN>~MJ-+l|`iae#4zlP(j6v^={oB8m@=kq0N41Hg@|Qhl`t zqZl2!HU)H7ha^s0J(WTaZ8a(HjA=*B2KrSQMu%v67L_QCjo|c72V}ufI*Vu!58}?! z;Kq17YA~9ZC~%q-PsQlTA=wB9q+27rCbnVES+F@AHep@Ewf68XvPn|&oPS~&4RsRG z)THOkAK*uaa-#*++or2bLQK%jh$EJq!p94v8I1%9TJAgzV<<;L!icH!oYB#}k|KOJ z7L5mAgC=NzqukY-A!HhrNSeqC70p+ezcp2dbkI-iyp$+XVV7B`!9=lu3)^i)NsuC^ zoZ};)UkLPc~@i8$+lX1)6~8TV`Ch-Lw9!T;##_SYl^uOh$W#wWL3<}ow8YK=DA2k zr7L(O5z?UK&)lsT@WcWqfu8WJK=35{R4mO1l{S{AKR|$Guc}^+T%S%_MWz)AIy~CK zN`rHe`pwXX-Q6(hRmQ@Ca?%VjDSYdoV{M}9Esn+LUiC+u$#T2rfW8a$0-A}e+O5QJ^U!j zv>o)8fC zexU7%dCF0|_AEq&AJ0Qa;$gO=CqpIrO%BqFA}oHexie7^0AC2V%eyttVFu#%J&!mc&*hd6zp@)VEeIk1_TzTbU(nn^_=+p>fA&nso}|!b>;6(Lunz zfS5;}v*iwA3>lXbD0j>ABlqBOlGVL`1g&&MF_W zj=Ku{^%MlPEW>Vks>8kqtR9aqZEHnUla&i6mhIXwM!YUd^@BxY>aX70!`-XNb!?%KxGTMGZeig^!>8w;>H7Vp;O|!uN1F|RPIj4B;q3AW8k$W z$w7{+PWF~D8MM;}$T7Of105dxUYJ%E8p>2&nYn)5!U>I(I+5|G{VTP!-2COvM~(y* z;H8tF_&(qo&Sq9+$(@)Q7D7~Gu5w~W9k8Xk@<%ZtNFTDy_LMdVCuSPcyXb$ zN^Jem*H;t6CX&D2B>A+cIi7H58geX=U*L}a^721A?j@5T2)LZo7xl_D=j&cPdvXqr5ubxOOyDm6R>fI^UT_G@KEae8Xx(c(Ztl=P!r0Ln!wc zt|}q}PG!7>a-7I8rIPo$6r=5_PZ!9tu&Egl6#3+(yIC&O4pm|Wyz$IG0`+Cp`++Juoe5E+n3Wa%Oh0Z~RXQ)1L>Au7(`mA+h*u4k<5WIFzrKq!4B&MSzk`jtYcceDFHtZ&DxX+Se1F4a)8jk zPRa<6T^~w#Ye&%tg>S6N^NS3jh(NkQ>(X8svgQk=1BX9wA@{yWCra4{klS&yl_YUZ z3$R5XaUCIup!xVotm^AhSo6f<;l9<)%v=n~tFOiRy%wD-9pVXZ z-<&;Dwmp$F&r?`lwHWn3qCFkuLnzN|;f@Sgyx?w|s~3z_58|1#-LPgDwrNH1okIH# z@nU?;i1XU(M^a43+%>diKvWERN1p0PR4l$@`AvGKp=;JH zS*=1Dp7YEkZ?k)2Yl?F1^GCeanz9^~3)G?00s<*;zvsdDk&%H36(Ugeum zuDBlU2~b-3HL(*hYu22X(n`9o;VU-s^%_0fKUWnSZV}U4;|w_WVr}EK7g9?C!rO+v zevx|aTIStqSEGXaW#N2v&^qrgFy;SGSZ~vS2~UnSIfkzq7B#j*szF}08MZ4LsQ)Zw z=AZ6U{uxP4S-%Lpt3E!2JC4X!Hzv-Fp{YPxo43}L!PpnK9;922)u{k`Srof2xpEZH z3x+sX=9SGjKm>CP4faeG_Vu>&fQCZPRpIY8hSBtHqq$4b{aG)Hcih-Na2RWU&DOAd zI)bPB1JTm_g05{&@T}T#uY06^BhD^x`OBgC?)7gG};JHoc2c<;zXGpKzs7xckWRSxMXGA)0j2p`aLi+zaKqAMmFL>B7rsTM*igQ>I;f{ zo%=}VUe-ff;+Hu(x8W*qy5NBZPvA0cQNe4RFLcTic}gRebcxq`;tnbiQB_?;kN~f; zaUdJKK+V%1h;Pp5TTt|^QhCi}CPcdC!G6Wx%5kTnwDjT<;K%_TJ&Mx$WLWLK&CB1y z*CSA4!1_Hbu~oU<%iHGpgb)FJ&J55ir<_DA3qI z=UVMkXtD!ica^@Iu)(71TR)-P<@7LZp?rAMZcf?x(Y$}N6x>yH==0h(>NQr$S>%{G z(R4HV=;c+bz~D^7hSB-)7g%STvc?sI=1aqUTdVdMxE9fM8(@+k*8(!`>cu{LWcVd_ zY-4WXmyWyqS}?AagVjfxZ_t5I!R?S|&aNB7UHgg2^@w{qub?O-FoN~SoBiVQ3ft4~ zbaDo{AY)mUu^`mfukH=Db&=7Yr$09HXcJH4P!O?u+3_$f~)}{lw7Muynq&=`K86&-R>JwU*@p>qu4kRKHRu5OCUF zUEbPuck;>FN)WeX$SHz~)A(~H&`A~BswO8tcW;vOX!`E?atjNoGYsjSzw-?eFA^|N z6&}U`i{Wo_ysu|M`)wIJ_|wPNK=A%vtfOfw+$kx>50+Tw$dAx zMij3>ZGAiTV|j6Ab#cXcL34%>fbHyNlG<+~E0o8CmJ(-`X)fylOoHN4U5I)+u@Z9m zh4oYQ&;2Lj1?w2TBd^)$y1B-I{EXSmFJMIww@yWHIm1ZulyHhtB!~%PBpiVyHk!37 z=YkLr^-nI%4NG)J9_JOXs3|aN-Aj;N_8EHTP)WwuHt+>cH)rQ~MU2}yBC#&@%4i=` zyEc#`EKu?rl|zNqiX5{oIXEweB{u{f&fQ zXsi#Np%g(}j9>DZV?yhJsz2O5(kQBF27k&d@nk05uFTZ^M>i=9mD@1A_W{}HCb-3* zCra|9dsP7iTr@Ks22NlUlP1Z8)v&aIx`r|HgfYLQuG`aKKPd(6yNgT&! z@%hs2`LZR3Q0BXPuvC*ikHPK-kur#t(ln+1xDNO_%!1Mq3;jm+NDkhiF=UD|>-?{N z!RcRl1eNbBe`-%i0~hb?P+BBkvyV>K;eYR#QDPXqnu@q^7oe zWUbb@g-c)c1~zh-2NgZv^LmqYXx}y9nZvjb`)ZaXevIDY`UF;Jf*7#;yXJ{43`vC+ zOKA=LfgMflTlm*Abik<`YSkyCtfAI2o!kDCRJ$}{FfS`jcCu-E>i0d*pQ~v@usXFZ zm27OkxZe7?rG1^-ni_qKzsOPeOr+-Cz|FR<60*Sh$S!A^Ct5mYOpzy$Qjgk323jw5 zR*&FOA(^>q2L*Kv@y}Q&nN?DdF%R4d86M(f{htsmu>|Z2!BBzqqzu0Xepa#Q&%t_f z2@4RYxb#KIAIXqbyoOY8c!`juw0G+>MNpl)VH%0XptR-_WNZ8yy9)<&&a4PG!h4oh zS3Nb+AU){9 zt;%&7V%XONXF<-8(9fgaYWtvY(0Yl`R#K#G#KS(QP5?#mQNFgu?#AxU?&c!jh2}=Hm9tch1wZ4+bdK;IH&SN| z*@&hTL+qT8`JQ5sY{ro0%ZeH|A+S{Pp$u&PtBAFzyH1Mk|buXNuRtXGp z$6})x6wA;x6c&LnF8NHj;cBVj%Fls%=4xk*=`b%|mVEO`nyRu~KD&4rbnR*e;<7w_ zrmE&mFd5ouFH=FZCh9r&0cIE{{-laLwk@!!nip(j_l@cf73$KCew#w|#GnO$858(g zRfxg*byoqt@AM=XYP}_h46|got`zuHFu099nsEMeZb@Mx$9Oz59p-WWwTG}^hh$`M zK1?uULJ5wukb=Q zk3=)((E$dL>hPOQZC`_t9=(q(A@1Z;Eu1H|O;1Y)O=gs$z5e*sj9PU`RhaEO4Sn!-+?zuEipj3w*W;d*4BG#ADcoKZmqK*q9p$h z?oO&cZk$||s&U~8+$sy*FNjrP9-_D(CRy_7&g$ylXh|RLvPKIj^A@@0F~c3i;{4+C zIM&vL`O?ZoG!C$Ai)#0iTEtyO2r}LbT$vs(8;q(gt$aI-J??kS5tj5~jt6rIqq z9|I@`G=}_|)njAcDU_0mc(=AoQ=HBFTXYSl(fUbC%(Q0)vU76WmFlKd=V% zpg)67b=@&&0cKmT(UK9FkMr;x??jshLwjClRLLF%RH}Pr--`le zFxace5XuJv1uQ`osyh*UaYkFpvbg8NLb{ArL~4s#+>|eD)JmO>kY5k3#9MHaR5J>cOodGxX;H8x zkV|3>PDwh#%C$+NE7;dmlNGa`yi~F6UY&a1O}f`QWiwDtbSp90p7IQ>)+-rHI~|eb zOK-pe4hNw)lio`C$*GR3Y#u|igY~acf~jA7bV<(nE6FRMWpoZ;!i^{IE1q z6WeClS6+cXV3wEg;f(c^G&ZW5oVsotDC)pcbBR8ct(tuT?dgd7cC;_2LL|(8T;)zQ zEmE7UDR(r=wT`OKdl=QoT~wP6Q@;P8C7qcCMkX@Iw z<-{&8wjNxy`6ZWKdHIZw)+_E{wp4ktYuJKDq0BQ3hXYtZlJaPx$Wb3*+*#WX`(?_A z4V0PM4);Bx_ekC^bSs6o3$}K#@M4p}CVfc8Q71_`UV4jz(#ZwTBT;je<`V{=~Kk|@MxAkdEZ zf^42F20j}|1O$C}q$ng3^{cRecTfrpjzm%=5$C?bc=^>QdnDCyDa#Zn=U{e{bZp$`njw1}2GG zm0&MFn7$-tukVOSiH93{>i)$h0{^8iW8D`IYtA$A>5U1=Q-Ek6s^o}rac5p0s$)pB zEpKxh2vM%$2m7p)unNpDz~_kjJk;gL;0yjTfU)fPozf|ff-gwH8wvP}Xg(w~UAF7Q zi92ZAjz^*Bpb4KqjRO!d-;zyTP5i^D)rVw56xj)p&L(8bA^gu#7V=7OK^%53riuJB zTEKU8AUtKyn7g|H-DV!8H~$Axx0}&T1V`6b$Ue z{`_DgjMp7edotBuXJDv>1X~vgr+vdl)C;q%?d2qPWL}u-q zOR>A<+>)&Lz28xIzVdzbikLsrkEFar_PrEFIu;*@jJ!~CPk@DtXWEnbgXVy>X+f9Z z?A010i+CU=lo#lU%I)X&@0fs!IL*de@<6rWJg+;^R8s<@wl{6=%X_2`vs+GFLcRR? zMZpKZU4k#+A;Q7Y$bVrW+r|D)9px|k=_hRAC!NJ9)%X<)dpQ^V02|}3dI)CvO6zo- zz{C!*GW=_=ghxvQXIr9gTKEHNXXV=9;&+|oOMr^2OAVe<=Z;+`>`onP)F<5-{{cF8 z&=aRv?q5N5=}~&gIq8cg7;n>(*bOi#Evh5;kcyT-atf-H>DdjaQu*7>w^pT5m$bs> zA2_EcI@s`^Ammq$jop`Mo;Ek_)GjKeo6`PYBRhtRA0epdWJUy~?Z$U+3Y%l9Yste2 z*WqZxQd=&Jhmg4B7~a2?-;l%ZBoKsg6wt&;wihgj00dz*e^KXf!_N?@t-i@f-Cjuc z)qXoVwTl*SKmoA9Zre!1I+t#{nxHrL?Ua3lBDSa)M1GM=pT}dH7Qlln1PVhd70>@d zVZ=f>@H8VN>BF45X?D_YtpQ3$g#^X*7h2i9{BmO=?k!s*aO3rF%2XT3q8X{YuBh zjs%_}N^38c-2@*lJ+|mpGXy6!ayXCjE23~Qj>}2L<|AW6hP}X&%B^s}6#X7FhUl%6 z%+L8PpOnKd{dJ^&p1Xn))M$hdljaKTM?er6)a30S@SbcOBC_t1IJ~>y-ak{FC(GeI zSg2ROwgaA@k@>mWisO!2DzD1*G%1_He7UnDs03U3N z3(K{Padx0cIcTI9Ymcb_umVOOM4gmpsgI1FWElt{8HlhDLX;Q+#|2qC)Lf4{+Rp$L zklnb#%7Jv)Cw-0FPvJ!C9cF&zkynY71PMiNa79G>ow?%RDMAIiQso-!x%%Du}KwM6W)CwOr7QbDl`KCW0DKUSPz&CZd?Q zBn4)Lx;P>DHkB}QV9lfXY%wM#;nQvZRtOmfGf==^i$fo--ww)r$9o`1hYs{m{RN!T2rE0SpIA zHDNMnhv>qOt>~*G^xdpKP?^&(OZ5rD)#St1xr{_VnA4@s?#AxXDa_*T(u?*j<#pPr zX}QU^Jr-3jrnP`g#xqM8HE;#PfS7$CwhWm_A)X1GhlGOybzIp~)Fz_Y##NOfpx=R! zRg$i8$4UN@BP+iL38NT6?O}%?ZHW_X$sKe-(Av=}9r3`lLox)- zvMPhNv#;-AkC;+<-W2Ax?sJY6#W&JAqC2i`OQv)P+4cMf_2V(dWu@?T zga_li+Q(ftk0FGJQ8hQoNdYF{IfsPyM`t1GS{*+`TnsOcO!N5xq4A-b*_CoSqL0S; zC}7ydQxP>4)0$8oD+(4@ksw^AWf2qu4G3t$%Cxv59LZJSrYwBOpO{rh9EmDJm-|_Z%)O+4rm}ICL<3#;QT}!_y^49apENV^1quigRT#8>M$#EVlK~efxcA zRhnnte6albfx?D7FUTv(b&7-;CsD))k3ozSA6?wg$car8LlvQk)QefRAtufwPa&Ch z>e(9om;9v0rQG9?JV1O|odKL?5?$*lMW+Q%OTEizC6N7!)y{)-rbZKK?o-M58}s)8 z$~-|nse~7|c#fFTY0NSQsH&m@nfyS2af4Px-0D6aE;&sp(Eh!lYr6CaouOjAH{oQ2 z3Y*uQO762T2HQ*ArR@O0=ru~)x;S%d70Qcf=eOjU@4Lx}P>>qWu*`uO_ZJ%T^ig6$ z-2kR9pE$HhaZYRtmysoeqbkN{8$@;)S#uWG+zIo@ERn!AjCS}ZIq8uO=@$x9+gw~8 zpi2I5D*y)Pk1sM|9-s-~VZ&GDp3?b@U@*URP?~w;6EIo+)&%ww(N4vR4$}6q+CDI9 zU@Sn;cBfw3KwssxtOcyhKjtB+f2-_u&rcSDu+RMoYCo!AMBy(kb>OldV$jd`it&o(5A{#8 zbUQpCWbDp{GrDZw>N6ZWCZIq26|Xz)Cm7-H9+USsBlQD9#jc^oOu_E9v)VvFRr3?C zmKz_?MfF;_eaq%hyQpB7)&m92Op7a> zMS`1jXKCczUUjZL*O!;B6Dg}BG+rkR2y+;e#XO4vso0Vb_M;M8`RYPNd8o09yYe3l zRrsA;=Ox#bbe4eD3MCuba&IurO4+z*2@*@IHww(c)+5-D{;UBgKG zedL`Bb-scO$)JNG3e+W+V95~W1sL-fS4~3iAunQrT?npgUDiyf{v9&NdXE#K_PMIZNyTZq1OxSftcsUfsW9%Wmo z46#~seVEn0Gayr8!R45S*tC}ZOJ2jY=%Wb{zqMGHP+UxPk!qik)Qpa zpV~((mgUbjJzj!8pRAn==OQMYaZ&8M=?zL|b8@jM0n=Wi_wIO%(;^c@3+vBAAs1q1 zczq0~6|;JBCU|jjtgU3L8BR2C(paamSM=R$u+2l4xoi69UJeWF?F6C(5neS^i_exc zNAGxcO1~Et%*Wg~H%;5Jp@(2lebrIp<vXJxbkS z$!%)dqj7NFtV_kO?<3%Ar>*9gtV6NUmaXkvEgobEKj1s&JBUsdeHi5O9pq5b%=DB1_%dcWTl+xN676zNxTWQ-M_PdhACV}rx#)~w!21KNP-RZn^Hlh6ygxNK{;Ibbmgi5n)rZ-(0Hulf69XMFEhT#$7)fjl>3>0n<}Qq3lA#(Mx5U&%abTXYkUnnPa=xs{fRG6Fa{|UqF`9{s+T*X!0AL- zt+|K`PNM7CMOm%FinMTuRxQblYuH7qmri5gHjx{Ybm-Zw_?;@yku$7phRyAY+jYCt zZ5Qk@)~tO-+&1|eM79|0=Wj6RHbV~a{}gy?`iSB#aR=<+q`caw!O>Vh3k{;E@MQuJ(?Yc-k>>L(TvUWnppx$2T3==$74MV)U-xc~dy-N0pd@A+Hd`j&x@UIde=AYLbs(jVI$_h~P zujL~JtOk(u&KsZwECkSmeYd8*6Z|d>Anm%ypS*d`XpH!dlU?Xb0ldF7))h|C4iQ0M z?i>piXW*KeP7H_(04!jWhhW=WaY#&inWWLNQH~u=8gY$MCz3`x?rBZpam}XFMn;Lb zM*ogCh}YmcydHy+5K>^<9Fv;#IPXPOnqXF||%OAAxfXwQH$kwoL&>?YXAb zDJ*ba#<@nn8Yev!)o~zBc#n{{_Bg3AFcl`nMx8p=J@xV|auQ|aB6#<%iTKPbtC?8L zY5;T^nIWdRT%zyO!d^jMrM8S?<7(znkJ%;6hUpUpUbV1*w8n`Xn(P@c=NhbZ48Ya# z$SJ&6lvm2OoFMMw{-^?9o>B)3j)FuzpPP9lV;!Zv7P-ax`x&@ogX% zh|fe8P`Zz4#xx$Sey25Jk-cR5^A@vk-ENtXn1BY1WzpRjp#FL+gP()~=wMEia0uv- zx@Yw|=IPwU3w-1ay#3r`*d;zIQ_08k(h64eaD))(cSOjfQx{l${ROOb?vNkFROabX z7h?wiGRHFu51S0fGsYIP0vXZ)lkBID@UPfKuma9G8Mini@?EgWTxCZrjluTNDroxs zqJQXK4{V+QMq_(FVZRi@Q*aYVDVu~?Z-CK(s}F^F=m8Lx)>7pNJi!>+O=>Wx>H$fG zA-dB6$qeEy39L-rxR^vq>*^pTySH-Yxz!)&S|S?DIu_5@!r*L7#O!^vEn!i)N(086_wWXAa&A9fA%WE`Us2pVNOC4JFXGHmSTz=>F55?p zPlJ#wlm$w}_y##T}$5GE6%sM=h* z3hCtGYGmuippu!?)Z|NIGPmGVjpo`l)gyBDeMXx`=|5ldj zG$7^upFtXHi2qbs|Cy67^6wr3Nu$(uXD0 z80AfoZ3_y6OL_p?p+R250H^}L@|qEiKV64att|-JHZ-l7m{w@b(IuNN+TXW7-?w$G zA3QIovsd!WF)L{!xh`{jd*9D5yl0Mg0(E`A3NQjR)>9|s#h8yGYCOL)+3=ZMDkOPR zq|FvP#^ZkjrsA}zT)a0Y!3$8?Rq0n_Mv*&2`G?r}!_tu(=ptr{O9vaPA8PBF)b);n zm*b%0oPw~JRM3e`f{~@NE-J?JeA$!o4uivkM7fjpY8`#XK^ihw<611Yc~3=v6eGjK zzXd$OgDs(p;Av1l-$bHv22aIEWwymXVm*_j!{SRM7n)>P+O%q*1{2gl;2>F(_spRA zUAPMi!ci|1CY8gI=I0elwrl`gid2%%qjh#E)OLF>c6-5yyS3llTc@Lj;!Noeo&z*md) zaCbyx;Y$$2-<(dd?8i_X)^d%{_web z>g!6gDi^P^d8ZzpojwOVK1ssAy&)P?D6LQ7wYW4W0~KUGpD4(WsJGSuzQkBjWX@ij zf3bX9kst+MNwP7?;7v<0cIr5OEE=}G3me|}I0&RmFn`hO;sl&M<`xcqU3dHu&ou84QK zNXhShA0E|X<$AdD|uO$=T3DAb%(&jd=wv};`9?# zz84>dYVkw}fIA`GKH%1qun%`XHa8>(?!F&M} zE?5L(jfY-gB=DYvtBFA$%fYIkNJx~3puJk$0&h>Pi46atM7Z0vpQ%;T7}m{edMMco zRN&6P8u|3Z)X4}P;b^Pm;zyAaSa`)av*wbCFx4x#+CtVjAmk5p=4sic?y>hdpcC;` zo~h~#fq^blH6{bXwGy||fotT2gD4ujWfv1c>4%K6{6N=;qOQ2w;Hc!-tZ7^;o{0_> z{|vR@u3RWF;2kX$Uvb`FEl6-xt`*ma+7`evD8v&(u%$$N~k|d%pm@D_Xk4VX_zkp! zLlQQVQ699o=9}yKs?MRx<4@hoe1JglGmy%$P)$Hr+~MWza9Pf}EAzp#4S}n*JU<_@ zyuWnaV$Nkp@|j`8QkO4A0=#?f*gzT6yc;}3MAw|5@32Qm-^v~fg1)GJ|7f0iU+MN` zzC>fZ9R1Ax49V3{Z^Y;2a)1D=#|#mJ*D1|p6UuZ^1Yj{C@uIjLIiWDWkK+hR{K&?h zcdY=2rMZ7DO$R_SW+}vCGF}zdYB=BGnuye%F#S^rBgRz~ZzJ%)d%lS}zkvf+hcWxv zR+!!EZ#Zz~zQQ;s3}erMK6zHim2>W(SxzJ#0`{m$gpI>`BX#K?UY&pP;Zhxb%XF4+ ze8Ov>%B7UyqPiBdNHVd)&8HnHzg&|;i9e=s5oed`8@!t|c>tJdxF8TkOBlr^>D}2= zwBAXvgA21)G{VU4SNRHR4YbiPM4wCBdSX%EnrlF3VDj!WCe=6J>5crAv+5qV`L5Sx zT&u^lR-0*~G2KEV{-dkV6Aw$fRPOF5JkznyN#ai>FqNG;p@VT%ZD6-1?3)nRabK0-BtQAVTeiNzkHEjL zEI*iG92h7dpb53wMFLhm0&S;eza-;B)WLDOpzMZ-hetqwOF*ECD|+`U))!Ht zhTCKXi-4u~J0?I-?`$DElf3_x>}5N}?^)lcrst)j@B3?pIFQbBQZOSs`^JePL9=2o zhi${;l!cFqBgHA#ch22o61yS4-hDdjqDafpMFg3!JGOS4)I0wxPNkb&4gk$xcJ%H4pmWu1Natp*qmEKLG}PT9}zxMF_LUm!S# z6EuwQCSdAeiV@@>PhnU*4u&deCTvm{9QDj9H%tAUQ{ixh`oj+Ztt~;zP3mi{$t{e% zOxWUIadDx`r9Y~yp-9SGOdxShgDQ&?Jfe6C(X8A~agIK88_r~F;DejeIPXVNR$hFo zFjH`*>oeM1O8{+VJT{j>*4TFD4N1W!ausc=pIw3cmei`1V|B^Z6!zSUyd>dS_fj&z z&N?Z)J-X@Qrr?w_4@lMTuH4qNJmv3JwFeI}9^%uPcCq2@N!T5(G2(6Sv1vy4NU)5_ z4Xq04l-LSaMWK%$hj}I>w-)5$JqQ8B(Ld|tg7xCrs9zwn%aJ*H}zDz zu}t@6X#lqb?T`min=;hWuREIH=I;KR;#jMyfbMC}eAYx%yRibnwjsf*-&g4OVL1Rb z)p8f`O`8wa`qsmFLHo|kh8*DRlS*o&jLVa6WAduS%ks?_k<;I4>96i4lKWdCP)o)s zB)?0)lpEmXtY)>3R+7!r(%d6-Ex03*K#~@B3v_a1b%c0_OT z60?+`o*SHO7Mc8|jLQt8I3qU3b7~IPct^i8xpU0h1CO(aTi4u$z0tO6eVQ}B7%De2 zlQYEAf=CoQM4gwjC;~g3WV;KZ zl<05sZ|WrP`uc*SEZl%Kt8;h71$vh>*`xu^XerH+awF3mb;h2st5@uOUQvJEQ1Xkv zg3nk9IohNmjLZt~up`y^ww1hIYbztX5H5yHvhtpXg~DqE9>cWVBGn{_I|JQHaCIcX zI7@{wO~HBQ!*k7sTYNfNkGKIM;MzS!|se62&1JHwJK+-%`l71|nU-Uymo?!bIfSiC1uiNO?=Bgqme8KV>a z4HagJA+!R?Sw-gy*uEw<%SbgsNe?)g4 zHML2fBSnZKNyZf03(jX))ltf|M-&Uc4V&LF9A8E(ANGE5`{?GeEl1a6O4j!a?I|-F zt(hldGG@)=Askm?DUe98@Hl5DxrOBNh^{R*80L%+^2#2L~MMkG0>q$rcZ+v}Yj4olfW!tuG+dOUC*4wsi z+qP}vG*8>MZJ*|uzV{}RnMvkLYF9m#)SoA*UD1)ESKp&fda~0heeqKC?#((smh=!(r?K~kzx3t53hVak|4xp$XZAv=^}#E+ zth;sGlZpAL_u#9{+ADpKguZj_;Rs;Oi6unYlDN8xhd#!09fQykYC~C$kNHMb`ihDDD^?^;6;DtVB5F9cd^jeh3LQBzs^|Bmia(8>E>RSX zGOZ5rFE;caulFM&$6!9YxO4u^G}XzI?On+e%IALrh6;1t+9*GehR6?f{{L^Z@SkA~ zaZ58B)Bgw7_}^F|%q5I6gSIdjm{*|L2(C1IB(PEmiU_Uv!DJg8Q^~e%8|-lYe*K-= z|A7_4(zoau`>b=bde69Xo1eVq-wFax5lthxZ`m%6-#!Gn_dk}YQD=get2$jpb&`2F zI>)BhIAwMtGldnNn5MQc&%5i`-hkp=cc=W6flGI;3gVM>?wZSSeGE^TOF8W^p{U*spBzq zRaJ~VWUjavJ`rJIbrh*(A}Ela)#Z9}iL&k5BaIR-+lV1Ck(DJnt=AU7ud%jy9;+^Y zA?7MqeA-SE1RMr665XS0m|-EDZX>YZ2r7aD;iw`3w^~|^99Fq_esOUz-0q?~!oD8t z7?w`IxoUH9uo!QRB@!gONoHP0RV^%@-J9UM{_K;u2*-idRhwJ_cZg}@5uasnIn~;XYjA&T_!%wk+Z6M zSmYOEenF;}G(TCa2Yd8!1xism)Fap^4II(oc+uf=Q{~7A6Br0JHl|%feq+t4wRj7oSote{rRiFR2m_!HK=SNH; z_}a&rIetWLO8h@+5?LtT33+v>Ffb`eO&TULRF^$XF5-Fym#*w z(iL)m0-!$`Ao3JXHyjJuHU4Ik;C@>Fc^kYw%=&eGU1;dB#pge_dmbIaBa`KekL+KL ziWPh?d{`|a*VhJNVBX(eHceOu>l)?G2C;rGIim4*uYjwW80B zIe5y-i>+=NQ z`pp{F;G+xT2Ih9c)og9QTl?C&A{Y+F1mYS~N>q12sm^ z9NgYJ0;gtg*yYj(8=a~`X}7Nv+Fii8L|`&d*EFfjcPf@#Rc{q6T8&@0h9}L)?@~NK zQ`R_&pwh7ypq!8w1HK?qgankV;i^HnN|?k_b-@;;E;o^SqkuIpxi*U7gqzFGtDm(9QQByTqXlRY=pk{s}NtQW*8OI^^Qk1x_oc9+z#ycjyar22OPZ;Qgb}tz5{&s^P8o z%o$)ToUwTyscM|bfKx#itw(s@u#mUNI2a6xuprDn-+|k-pxFg59bMt&I?z&tKQC!k zoNVcP=ob#!t(+bw``X&{+urGM`as%Ig6fJX??zVA;%VYO75-Madl?-Bw;Hr)f{Nd9 zWC(qMHddyh+!`$~$Vq}<6ZV@E?+h&jHUm~3g?$YQz0A?8okh1w< z%dzcot>~mV#CPe*m~E+aaD}q9(qkPc&RwuV>`%!LF4}Pc&kkp(a&k&htcRM@1Z4<7 z&Y~`2T0Fo?LR$6?Rf(7$vM0DFxP2${HXx-l8%zCT_W!IqCaAM@w zExta%#o)#&w7s!?bHSwunO!BfUm)=B;N9+hdamn?M^2=FiCz=6y5up2ACNfj3{CX$ zDn*&+-+YBJKheQUl9s{!MN*+3)gV4?rxyYi z8QHQDQvU(}Bct_4lc{N%vUqlV&vH2L+DjI2W86l&@7^=;jnP_-Vs#k!*R@BD`8fzK z=$IJycugU&i)mw*tfF9r&c<*$e25j(BtkvJgnkcBdYsMV1eOJ+`@5_!7fw89G#e}3 zEUFHMTKvAct(bZ##^Ng@ zd2Yc(28q*@1gJr_u}=#_4N&w~62auhummDVqnBz;99#svxY7+*Zw?to(T08vso$*u zs2m-d4SlTS!Z?^};dl5l0dCA9F;Gs)K$0ZT%maMd#6kp4)!sd|n4k5!d?CvcdJL8g zmelCFBwoRvsKLpA@1g~xVq~(jT_WCftiP-8^vWqH2`pCh%#LL6o@R3M(NT zI5t6e+{lmd@jJD}+_*MPS9w7dzhHko04wjvC_<=OxY|q#!PZ>Ro%e5}oWV`*Lu6Ca z{NkWJnLkMz96u?LjgYzQm|$RRKvB;cJZWNCidw5Lz}pvaI$BR-K9OD>8q7Z#5(ug! z@wc**NAga`y;4?}J9G#x2$iat_f7M#Dab8owL$Ln#C}J@mXY)2$riq-=429`A%zih zg1uIsTqlEtRXxNVYa(3|eq&q;ESsN?@NnLIzLCX@-dw$Xg|lI3 zmhu)vB?7#U(c%)e0jqn(W4t!MkH|r}29YygYB*n|v-TV@Wf$SS_y>8$=aIteF`H{V zND^w~FGgLpq$C3C8VB9@-F^G^6%7o!SR}2Zs(wjxbz}+>uZ!`nk)r=i>`N%uu=tA} zXLsy&oN@B|TwP*^GqEgn~l8F4A4q4!fn#Jb<|J15Pq^2?2D0taUNKFR5!c zz(wksnMg$W18yv33ADor$Etc_Brs`!pk#+*MK1Kf`zTM4ZEgFCpvW(z6C&6&RZ>Xq zY$tw<>9t~jA-&FL4jc=U#+HwC-W26l(_(arU{nrsNST!sNtdu|fia0tE1~LL%fLMI zkL{l^0i_iY7Q&IY`bg|yaLRenB(2;r2?%fHxFM9~dGwMBL@i}!1zaX12&Cs4;PoW0 zod8{_UJIeP5c-5d@Z0Q@;1K8X*6Cg5JT-@0OVOj)?O>|qf`CsLyN>^2*hvkm^@ z^bQ7@%TAFgLE<(?9zeFBwjRykAa~4lR9|8Fq(8H|O*j_qvn`5>He1obYHQdfP6_y=olIzQP7y3;I#!`2G8dqPcqazUedoX;jyoxtbv0B|DYQS zACz9rxQc;CEtU4-)=BJZ$gq5U({wU^xZ~Iu4~1RNHl;TK3Y@&Q9)8)RVvdK}zD)G2 zzZ)UCT+{geG* zP;`9-3VIRFtl{VCaR589FnWu-QIXamBh=!&pEIy}NS_008P1ZAa0M#*?ST}8cj^~r z)SzBttkNyD_S*P1nl)(2;NT#-IR*Bn90{jKRd)Fu+Y{uzIRg?(Qg1|zpTR1 zIUgv0qB+i$t2T4atKcOk0`C{s8&D#<=wkf-p#7cjRW6!9!l~gixrP~)iT30Ae!w5Lxia+Xq>_ZS z1ET0Th@4j0*`(YeOBr$}kl?7{&Qog#4i98P8GUAKSE>$@^f-oO*xbTsIhLfgTFLe) zBxOkFnWA84fUqOo(yUVrC9}Ei86d|PJb&Cg@ncGS5`6IBu4W{B1SEf^((jafjF|)Y zc}mvn6ogJ*zuK(3#ZE37Acq>}ZWRpZEh`ZymW2L~KL-y>K0%(aK$ zQmGFNp446Xdry1Au0%|mR|I$JIj9WE%XTSxvamhw0Bq`Xo6jt!7!? z>1YHOA^Ts>zsH*352+9aG*z;FI3|+af_N{H8HWbpuF7kBay2*_Ea|YK>J=^-7DQN; zWkEgg-n|8 z;rW+KKBo4K%mou3&Q#=L<*mA6s_K9K85NLi2y5d*Y+_3>pzLc>1{NdwjO)9+8toZA zbn>${Rx0_l=h2Z*epz7y^%w@pf7yNInXJ1uRuxHp&xq|pLDnRe2ZLWQ82b=+%{>2A zR;jLU4*1UK zD{yUIn{IjO*-vk7Qq<~910U-B7*BO);_9&(Z2A1BrE%qWqXo6~!-Bwbsp*4pL`(pa zH~i#XJ4lGJ-5Mq4&v0`*$g8@syx39LUR>rE*=Aklm)ZWP=DiUf_ATf_RDQ*CC9JvW zJjes}Ot7C|1=|#%zXq{EY;FlR@eV2FN7=;G+9+<|-&kN6e!-I247RN=)eE_9Omkyy z8`au4Y~&wU$cwm^N_#Q2QD|%_H~uh|`9QHzXl^Mt@eV8HN8N0uyIx<*GqIc%qfa-) zz0;T8oxRtmc*>F5Wgh88IobdD%Kd$7z@xpQ(G1|<9m%Vn-$3X&^=4swK8c;4_b&K@ z8u~8l2c#S)GSoz%>GpusJ7JG$ctplX8muvwBPg->nY0_opG*!FRF4$?_I3x~frpJO zcHk(S7?4$H;|bl#7k{Ct054aeM zvvA^6R)KVAiD=>!LSavJ$`oyb-0ZvOpA!r*BUpXTmwrxfa3|P~c!yFSx(x3lhh$H| zfe2_TS}$Hqw8%ne@m=MZn<47NHB$agF>Zup%&bc^E-lUur>9~E8MK?T!0v;k0bMQ- z4LX_N0XqB#Ef_SzU8po8rBO+hqQo*$Qn^U+!R-kL(tUy_YCXl>U~k8FyLX=I5}Q#< zHmi!$VU>nn?d;T3{zgQWUeCOqNToF`cU1FjgRf=pIWz|#PxzsLAt&P4;{lhkMh@)J^r8og9T~;|LNwXb2_;gCvccs8CJu@b_egv-Ox;SaY*ozZx1m?M ztA3Iaz=R4DdibHm+lpD)eP)bsV{*GS1SRFC;``%vSjpLq;IS-BoFG1U$7zVTSU!Xb`$X)YjUC5y`8o%P1`7XfiwAPTt^tO$4ic`x z7H`JL7}K6M3%DyoN>+?mRRV(q6mbqO5IKJ9L^{Jqi3E0dJSll}yI@Hrv%rxSRz|hV zw`-9NDEYS}mVlCLL2A{YhBZUQm|fB*p=Bqb6_fd+B*h3z=_4aw5_>2}HK}$U6Wvme z%V64!&lA3GRQ%(aTL+wt)=3C<%olwNQ~VYlo2^{>XFeYKmdG2+vzER ztec&#`=hyv3DEGYx!eV;hG?#)16C6>S2X}X)FB)u3XpE_Wmnp&OOA|5yKu29gbEXP zVbpG1?X_1!{%%Z;#_NXI>j0f~`L%Jk0lPL_0u%2&rcKD%rms5?UZDCW$bI$~(7*iN zYef%>WfKa;6DlPW)M$DMM*cBL1j16@a}A?c@RL}FQPFOJx_QD3vn1)KiIdUL9cM93 zoaGA5QIoM}Eh$qyDeMb+tJjLaE@>RRg6@Q-r%IYL`B-K*%guHROrE{@tJyk7+HdG3 z%?6~48q98AIDZ;;Gdu-QFE{n7V(zkxJ(&L~A4!iYnnXNLp2IexoU!1^9ezZ5mYGXv ziR-64$H$+PGwbx(YNezF1)0G{BclfsCP4XFf&BeV^!afLJ-a3p^9Q9*co@h>rqY?W zLGqvD{y4j%D#j!0J%P;vb=%rkIG&PBmJh+P|p+U&~X%K+2>sg41^V;AV; zw9ip+D|P44Rkn*uIOm}ieIA(97W7vKEX1QJ)}L)Ah|R+eqZREA9pfRTaDdLA0%01Xn9z;|0(8@vb5bW}dH252oD5l&}&t>>f zzzLr50HI1J%Yc)pJYU7L$R=Y22L6fIrhDmIB@U^$94}N6xt@*5t>CLb#Gm>C^c>IK zkqv4dGjC8u|0v6xSwcktWiit%Ka!-nl_aWFTwcLwio<^d z-$8&guqQ)5PqrK)$8M&e*2GHp8%4$^tkak3KFe9M=cxuoAv(PSp4?6%GWeAKzDbik zsI;R@+7Velnz_e#B?{AvzvKb_rL-feF2*mzBwoupz7w0dJqOgev-6A*S&g)h_LoyJ z{LXZTSG(4)@J-!hT9g91R^c~JlNK+^)mu|&i}1AP=D@B|HR zN^peJ7y^la^Ipig~IH}h|{!yROMdXH9P;+nh?qeqyYjf%VICZfdN zoapnEXhC2GKfK4OWTu4teqCpjut)QOq5NRuZ$8<5#z8he7{Glx-KA$+Cl8=Gp~@VP zec3q#ht&$`@At$!-eBxqWzziQ5N^LeeSFgi zXuz63Xre_JaG}Yo9TQk$59E``&d?Pk;=zHT!q5wqcLgp@uf+NgEPuuNsKqhY*_to| zMQee@GhUI|4t5-MGbg<)}6Af63WyFs?dMxd*p0L8k8CQAx#+zBP0g}Plw zq3tGsO0S5Tn#`rYWDY}l5ann~A#a2sZ-gLk#2{aYR;~z9svRmeC0v$a_HzIx_$;|C z64bWahORP0ck~&xY3<7}6HjFatXq$@V^&#u82CeOn(vsr>&kGW=86-1fX9u(*QtBp z1*ZI>+G~cc%sp5UnlLEI@(9@+X2dP&9!Mk^WDk4YAR?U~FXQk|xY{*7U9AtR4Q$Jta$(4S( zT0n5e&EEo2%w<)97hH3C!vc@m9mzY})|*0f0c<|Gy@flBN)k}x4^siX=$LS=*#o7v z&1iDtWf9|7?pLpap!%F6l}Zko(m5AcHOG89A=cLj!@Z~rt=)8MnJ}B7j?`hkS-td) zZ$h3nqcn7RuA;Ijrl|yMC>2+bP>bZwBik+%gTtQ>EQY6c4u`g@1d=lW-rdC1pf{-D z6#h-P4)Iub{LFi3FLt}63g9ezKwYcd;SJW|>(2#e7pP1BN`kszj(w`~D8cQ~qH*^8 z3Q$#e2q6pdUG?Bn6de~+fxF8uwq15bUb(Rw;%_j``}MoxCj%hQ1b9GS7JV%U+x*4b zGS&ndOcQMMBq=GVsTT2cjIgpyIMJ-Ujf&b3%PbK0Xt;pjwK+vw2>T(fB^+{Jm~0ja z0`0Bi2k|#d8dP|px?6@EWO+dptdu+?cwufWNB4ZMxjyy0Q3Mv``^`6`{{Hd~W4_iZ zvz~1>y#@zZlxv2)pspBrNB-m#V6jzW4elDVM)&ed=!MJ%;GfFtH`O+=t|@jU3towM zJc>{1-)+;jo9Xh zuxLQb{kid<&b7unKy;qvGg;h@$VdWWZgc(0@hwEURVBn3^;Wn7(vUXeH1$@ndG=B` zn;y}x?a(slW!F5v$Iwd|`SzWCHOUX;8qTFYTi=_54A3D2^L#hNDnHHYJ0I=}9k?9q zN?W9w>EtuVnRS&nzxJFnh$VgNQw5GWk}18_eH^MCIwckQ1QT}b>gC)X^C;6%kfQ91D^P4HvZjef;_wsa^Lz<0Y~HT*4r zO0Zx)AneP*7wS8EPJUOU4^w|;c8A-G=NJF#{w)1BTmZ3e?vyoLe}v`9)25&=;rNo> zCPaVo&slVcyC}1#r9&c5wN0q5aB06E7M;&-fcMh59*pW>s}Gm5yllE&&J3eo2GYh~ z$&#c-@w><9zf=YOB3wc}`$6%IN9jwn4MKdbgLEFbi}q|uW5rWk=aFwD$_tp0G$FxM zddxlpqXl$4?+=t)!6~5pi`I5+Csm8e_sB5(InsKVkE*OS3%PY`ZNPc%^8F@E_ANuzaDDAfXv?sV+W`W3KC(cZ)78F zO5lNL3J`cN7_ry;DhKPX1(>zXIjGtQ!+%vaH9!$I`bP~tg83M-HbSNaQGPeR{Z$39!{#Fcty7m=;PD}N+^QHYom1cLL4CqV|}Th;hqtApAm!zSRvZ_ ziCu*HEnvJ?@ISFaeOlMqQi7ajfALrRuF>>etO)s z_s{v8M?$1ElkA%v)JT5LL`>yORA=z9$Q;A|Eq#Ix@pG_t=OPbMOks>N|0}@q+5hb@ z@l?GtR4Fl~=NVaLn53jM+RN|b$agoow;(9h;2w3IH>$Z;qtjU2LricZ6Y_C!<#rC8anMvw^+7hW*YdLpQ0+(5$NSg4Og-iWe@EIb^u#w1docn3tW zf4G?=Xd+L~6MNi;JJhLPSN*hTfn&_@_>cQw+&pxj*$CRU@g>CUT1TJ>UI*UctWkSw zB-(dP>>y=vjEW8VP8QS&H*SU{6zetyh2bEbIyl1 zOlvWkGM?Got`cx(oHVRoUgYk;YUc0tWMrcv9;S@Ccz$wNBzvW}nWCQR?sjhVnq3Ah z%0C|yBu~kcM9Ym>4|vaeu5A5a62;^(ntoGbtI^v~O1Q&zF%_{Sw&X)teNs!341TGV zp`0TY0k)a>_{XaPGdI(pid*gGehfFev!AM4?q+_(H{GoN=x@APfBdw+G7Ta>0_pm+ zkY-Kq>4T`I4mb<`3C`$`9dJS)bkg;yA=R7SXM^7_(tXe z+B#jdS6YUi-`xuGVGdz;p1ZGkeyJ*Y2w2uNzTsT_L>e6zlIJjEUL={bShfL+A+pgNYG61og^m%OE_kgW>y`z$5aJ)jF|iM zx5?m&5>|GuX2%c9olO0*zd3y(5Koi6ES&bkKxJX;=0(Rd)c4P(EZ%RR-w!ew+HGzX zF52n*n=$j$VG-w_D_WmrS4w-m8_vQocl5yW~FaU-=kBV)?->n=R;6>tA+P60jSx zOq9O|Ztn=MpPhs&p+u2}52mOeT5Ov}7+vh32%?%Zk4&T42M`3{)HZL#3``0&42w*M zy5Y12ocF%X735UvUtV3DB%bi*Ga#wy6jm9iKP%!&qZYYDMAfW_UlJEN=~z+jw2Wp` zzhnm<$Vps~?dV2ug1=;cAIM=|(CoOFRNY`c9FUj8sjc)`u_%p{*yT0lNCUE0f;q~Yz9jg)|XOgB35A;76kL1R@V z0a)Z@74l_3AH(vq2}3hTga*N=W>idQ48l;wUmg+HC&{*vS*R3{2?Pj%2p6KrqBjEt zTCmGSmT5#OR%=FvET&996xE}UXAt{T7xasmNo!3N>Z>!ai?FJBVoZ#nixFfMPiR2v zeX;VhX{6Q*cP?pM6~0yZ)H+BQ6oz9|J-C9{(`+y*ALE*KE{Q~|c|xOAB?Og9J2Wd& z0fnYjJ~&a(N36D29$b6y>!fH@J>Xm9-=f#8a#s!IOefxybc0P<{kUXd4l!7#>fK;; zjF2mS5-iVqk@t^r&BH z9;@&_C0raD?b9Bs$OJd@JyoFa|2Y!=izKs)DKvFAhk7xBVW`@daXlL3t32M$%q~b8 zWR`}Zj#lg|iUiwj*&U$^Xdn~R1iHP~bR32uuUpY#N%MF=IWk2Y!?TOs(_#-gZO{bm z({e&0@Y08OS2fL&v=b0#8~8QJ>FA7#wb%iNM)dA zbk3e)?uE>RYRU;B^sGXNuL|$4>RBnMxTX?A3d|c2^l?il$3-c!+u8i?+EoVnn#5TC?1d+7bo}seMh`Ti|j?IXXh!cj-i{v`_3#cH5C+6eEg$ooH8x!S&HkJ(jdYVg@eox&n zFNezIe~LvR2u4z)-*+Vc#6ZQ%LBBHsi4ADS8gj+_JMkd%MgHRqn_{Bzk%!|m`pyhXv0EqIB32C10Zt-)q@v`*a++C9s@XGHTr)?aPkkPUp?0n%8W60D#^33sj$#%sHVeP55CN_ zQrQ#1W5RcJsx<x7}SwT2drzDTbPU_|NjQtyYV{aU&z3el_1Dn1dDUekl=Rlmig zHB!)_^17`J8Jmk8G_;!=@=YN^ZFJMtsto_Abn;ImmxoqGL-+J3K!N|o7eIxjxIjlP z_Hsmn(q?9bwtS`e?nKk9CRV(r!?Qia4PzvFERdvU*y%iEA&)jR)?$q0Ck`$%X%>`s zyg$zep_Dz!(pvRUI3L&)m4veNfPNIQEqxWPhD%C{Yn>BqBj6e}8{NB=u6>cMw9ojQ zS_+86Sz%A3RFx?vEi$1q*#Bdk6T$Z_%l-j=9HwYjJA;+y(iX=MWp?B-j?Bxw;!PZ9 zqf10VACTKx0g}uCPHIYsX*^U>wdpR;eYNlY$aY^OKWu4U)xMO?DDS6B#>rq`Ih^=% zak>u#xve`z9>I+anggRV;!v4A38ot&?;AWol8?zz-Oned9!k@5Pmnj#yv>(h!L5xW zif{uOrNlf8bC08oWDP~@VDP{>I(hjemflcJ^W_x=Xg(Z+{mFNbmUEj!&Eg;1lh>f`tAKdB?;jER z9n{f}g`y=!hw$c?uL&iYE4EcjuAy#+bp7!@!ayT`1{J~hNNeobTV>!ypSTk~j4z|t zGf~&ZN4^KF^ehL2Ao?+mLLo(8zEyD6iqiR8GvfBH+gPdhwCf3M{GVvX6(Mwuda3Al zdBr<$!iYZ0vNRIPqk;jdEd7kpe#I8YD9>;NEE3!!>bL6f*DT*tP}BV>L7$GJ!9+?$ znNHeoSEr-;P(~k6`mz*==zWmmHPK54z4_~Qf*q=~r~yj8&xSjRVE>=le@~TreuKjj z+7lYe7n85X!57p`YFft{WgJ>VqepP~Oca+*Tl1Ogl>9U-!i7nMTKFOHn!|j(^JzI?kjFt6w2D`Gj|O-B_Uw|V*s-V zivhexbl9ZJ?;Fc>hZU4Zi$-m{6FFz^GoW5-9PbRTudj8K=7%12nX_al!9;8Ip1V8s zMmzZ0w(#(1*`c`$V~y)n1G0K56VF;{a#Ow9LcVv)Sf=`~l4Nqg2Wa0u`be^GDN92X z7yi^M#(u*krkTuHU6weRP`Vn}1TsO$ghw_u6xgKMi4sL!tf{u(oWW5sTMjB*rx#A7 z43&dQ|EMxvV_J|h!Fh%75>;;-uL&=CNqD8a?X^JEuGI5Go668>`(9}o`@rr7N(HZw zmm-RuEPQ493R==T4A4K$G}u<;Qbkl3;|Lwq>TEif;zR7@yahL2_F53v$v>cln?%rQ zRaNVT%m)qNOasuG`$7@EFe}?CmiFIS4+#}E1R8}P)hSPa0$8Ez*Ok}mwIRA-Th9MUhD!(;&DqV-7Pt!$2K9k_0lf#0_48rdDY8@$L%nbq z+85(jz*bON08v4vKu$oS2Ll2z0@8wRfNCN6p}bI@@GJz+=;t5{W`%bH{Yae(1vNk_ zfT`e9fG=RW&{Dv0z`H5<+3W^JEh5ZZV`Jhag zXCd{VK-x0lgT5(FhC{w7o;VACcRu;A-!z0m>ty`*X>NY&AE$#M@1vsV8|fUT<_f*Y z`+y6A%4Nd0v{#fCQdvwwA1^;Sb)BJ722aS7?cO1*9hAyx!Z*-gZE()8^P&Vl_jmOR z^fCeBFE@uTvUaR3q487(`v~ zP{_K{LC{sr{XiLIk3HE?PL7hVz=2pqOTj}&G06{%_#gXb8NLURjZqI-Xv^^XyYQA^ z546x0jeDrDmR^sPu$I#l9(3YssZxXv$W)%a6 zCZ;!722C%&2%J=U?uS==J_&8ft0L%-{|WVG<>_9v!a&%sH=yi1RJ8=MLNj0Z2cSwl(@?4GOPF{PQ!U(;Wqm$o(=iZp zep+^E?F&4)$hOS;Mw(tFECqk((5|pAzkJqfk=zyGykML+{!;6b5|osAc0b4Xf}&p( zEYf*qJmdJX)-KF1NPUlQkrtG4zwlqM3bu?jn%fqqt7Sc~>`j!!joD}!uTaR26?e&> zPr2b#J_jx)=eKAn3Xg^J8n#e~$HrVZ6xY}=ek!OHXWRfh6_>{ZwrpdG^Tr@Q#W1J2 z;T)cG56N`LfNa>xmh+1T=rhq+)H7%6vz;vZnGpBd&=qRLWS_H}fcM(f6oLNX@mgFH zf`sRaxku`?wkdp#v2__+lM0X3dkSofkHcb|5B~%FKE@@Pj}?BdatMXbE>Juh%XlVp z$mMI6Q(zxsaGv3q6xW^6=Zftzh_0~PZ8aZX=k=6aP5gCWCH}iBYtg=r!)0MP?c2e% zOi*w8ETx)r=F(Tw8QyrCJw&fA(Wc9ZdxbslP#2YZ=h!6Pnr77roO@nvV!V!9cauH+ zva9aUs}8p#@DjuBtSc3_`{oF3702#kW9+o^=2&&rBbXykDo%7Neu^IW5O~--p5u|VU zYAih~mwWMQ+IL!DYZq@2bjpZt3~w@c`krr?Zm$qPjL2I4=)l@fIt4>uIdh_P;xogJ z`GDmN9nWrm!siSg^Le8ST=xYe(bMVx0UFq}M1pJQ)llHZwJp3&`5)fxYFBEz@M z*DrP=jF55bIL9}|I_2+J`No`{EzvpnnPi?h>e2Q_Z(#O4=v@7v^0+#Yg0i*9QflgG zs2)jnS{x_I_gczFhdP!^q$Cg03Pe0kOosPFSK;i1+UUNZec4$QDJx(pAZa=#Nm2n? z0XYU+1@sIG4;l+DH%hXLUdB&D7n7nJx3T|H(U3sfnMdPurDSAOaHL%+1X5QCL%4UL z8Wzkt2;%f5jK5x^Pdh%%7lAtk% zqA$hyNTWUAzCfcdcj*Cd+aLKee(Q`_UqQzM)b>#BiEdZH`zGL{PHSDS>h(AdP8muCmjFL8-&A!{Mbz?HI(yFJKzrtTMZbCBDT zmR~&G6Mb{K{e*QJxNcBT?#VdyO)}M&|MEEL5@1jm{E5>$TfZpy2IM@DQ^67X;)@(u;+pv2%C<6MMr{!>e_w}4ul4m!8spu>aPg7br00pQ_Jp)Qhl z+Vn_CWeq}p%z*sxi`b&S+#@b@uH55>tQfb_&F-Ktrgl|0zY`hu^Qn^k z3+cX7o8CAlj(3j}x~N93h-2Hr*|Oxvh@o%19lDPEfXw&4ewxbGm@Mt^_qX%Sv-FMM zc0~}>5io+}U733b{b=d(zz zHFQjo>$P-eZP;rrY(wNJP%8zd(%nhUrC?};;(o+BQI30t8rtVDTPD`GZ zh*ACnPhNl^S15|S%M;C+?Hr^NGYUTF7t}lcvncMqq^po|P~#gDMI>*qL(z#J%;mqF z1}hI$uT3V-;V{ZPY7)dhk3C3wlzEoKUD|v)VHL7`I+0M(=3QgK_coYC&B~~KBQk^AAyi{@9^k?VDm)qw{Hooz}wh+%Ssn@ zv>|$nTZ@OZy?KgUOB7nak1#-1i_fXyt|?eW=?7}UuffY>^znF0(-odcWI`9HX_!z0J&?2zf(d%?{1?Eqfl z84~L5>(oaJFr;?-vYTddk)d=FK0=0K(S*yc*oajz7`3b~4mUVe`HkUTHD!OWyDKF! zM#)F)3$%GXef07Be0UAsdTOrq6`mD0ySpCL`aHlR?b*r8&949k8RZi`XILSNbo(t# z3h9HdM09N-BSv||q25Gv%^_w+4C#XsL^+)}5(H4@VQ*E-Xu+ymbH|g%9^9)|%$!rJ zQIjxTFoU6K4n`UFNbT51!48e&x_BqqBWe(_0S@a{QQ`EJt`RKD9oD7Qfx8$*2!lk@ zgPlfwpq^>$7R2{qo~^~3)2O_W9J$IZ##V*k6}{@e(k)o2WN3?#wYiJ*z~5RjBV3x# zXlyy?S5D@fu4%N(_2gcyoX@eZaW;yli$OPhycD`I?79NtEMfPvR+%kVoom`6P+M_3 z8r?{@9GJK4q1{*P4rE%gJqy}uCV)K>uGND*;OkQn9Nf)T&^_Td$)+x=y%(=dt!RsM zhx(K};iH!nOc7y+PZ7;SR#GTfT6Q$>-xxwxmS+mlsY`yjIZKkj-T?otgQ-P)5MgN% zi0P4fPK$1WdTk_02!Ff3@U1Pzy3UJ8AzrzmRX=Dt$`iUNm6Cr7NDW@|~c(>$j-;O$apB)&8W zY^2^0uS!Sh&P)=81Wb^v>+GhKSaT|WrIfs_M3i+oEZWeX69^CoR)f z+DstqcxNR|GxL{Rlef1a!t_NfH|O(MF&aJh$cnUTSjN0~g)ErZmX1E4T_UZfZD>hj z8uuFuXtPJ_bY>l7b!yZVZYYO#0HRY5lp_JW9>0T2cgW*k2-5C|yM#W>Mayfi{ zKa;LnNL`zFdS@U za{R?(TZ@;(KZ3d}48%ONG<0I?eBcQ~P#BJ8?RE55z;9E3IoJBM`&Q$B`t7n6D)?yY z37Fy*t5=&LXBDg`W3ltFd}EQw6j~z%KSA@PUiUJkR?rx7(zDFMoXc^Q}hBZZ6}p>L`#W8 zpz;k!I*(9B0Y8?8O!*eV-iuJim`xG8Z?RL!T5 z`|-3uPqr*F#AY%&`|Ec5;It9uqMC!F>iM(_)>l@j4#T);ebw;oIS&5hMCdU;G@ZeJh&B&M z&;9`KISH&AH+v?_iI^a7Jm#j~?Mtc-qsM-@w0-1&+#5mlu`RCRYu_y*6I!!v18^-=>F%nmm6_|CDB9Jqo#+jN#SCP|XOG9<2rX7CKc=cb-Yzd@k?2dRP^5{%Jo4$kCLBlgLncVGu1BI z`$r}kjQ8Tb%ATg2d5kzQSi=5JbvU0AC!!>&>bW;-Y1Q+xaa?19lw_d}; zZ*v+mkN-vYF6xuny_}Pa_>RI}W@EIRbLi@Yxw4$IFZ{j$|H2=2w2~=mo74b(-I}CT z)#TEQvph`<>pj*u-*=Ql)bg!4xQt?BWA(CHVG`Knjv?-n_#7!w%)xI+ypRQx+EM1$ zJ@STTRx=gFlv@*j>cW)8b|NIVC(!j9h!KG!i47>9^5(x zez(KR`8$zf8k&&>C-dj-0|SmGJlM4cabJe_vkhc0q5yyUB=8j%?^_vA|Hd@*g#-Wl z?;wu_?J2Crilw%lj_68arq$Uql7vX7dSapyi3=PO2}jEh-hf*g;Xs*;$_D+&_^{(U-$3TjXQ4Bjr)kYOV_!(g67M& zYF7uLJ?0qvO4psU%iXh+O{dourjFYdg|{3wQGn+lT>#^`JXL`2Og@qnKz$;oSxYj>W?(5r-X8D$c<1X|LRBD1(YQR)#uL~ zbJPN1l5hsxwf3 z%ZeD74$fa1Qf!VXw(81k{kGPnTd54~lxx^hB4L6; z9{2ep=B^&WqewO&i~rByhya$!&H$EKLs?|yml1({&pTyQwPmMNg%Sd+)di+ zedUvYMlsx)w-iBw)CL^-eawSiAF!mSQSN5(VY{TOIk%hC_+kB&ml1CAAyTeN|SkfH-C)k$R zfx-^%oPN2>0}^w0?ZdE%j}PH5AV<{y>nkpB{3a&U2dLjnM!Yx+U5|>pl1TC9-YoJm z4dc1+q`(ueK|rD$<^?vKNt^Wol)i2sRCYON!1RLL07X8@?tDUtQI1;pE{{S^M1H3d zK?mtVU|(EJ(+5rq1Os(}LvYLBuEZh!b%UA=#z%vw?T&?NZ16WAaQ&=GAtWc>|MR0+ z1m4T@8xVC=B;pcuGn;lwYefPsPPrzyqk)!{+%aqEcS@uUdo1p-3I;?DFb=-@2BV9Z z2HxRE(R1h14U;6Ac#5ZBikyibIHX&8iVY2`AklW`r47@Wg(46lZPn_>8+Few9MfA_ z$4)^vw8=52m^i4cV@WEzjf0jzVdk=4P(}E354|P!OyE z^>z$oLz*IU5wRQB*-h+O-c7_61l&RdekA1esrmaDW(xQnGT{5u?<>Ow^EzfqOOpwH zFh6=VpQSr!co0lcpxW-EQCscxzB}M2}PFz16?`nqF#NF6zwm>ZP4*J+6m9gD;l7XE9jDo6w zt83DIlexoo;$rRaac!dVhjIiI%7VbXhGu?iCSVwT`$|C{uv^zq7cYOvQ-hu3Q(bkb zbsI}QA7o|XOMOz7Q9ucbDW9zm?HTkvX&{`&x>Qfc!DVtbDYs54Y#EfeAA|j*+jo9y zz$y-|W`cT7bwoB3ej6Nfpc4F>3b7wb2^KycQ99VnU|&C#&O9+P$z~SHYZe?9Ji5)6 zU%xh^1uD8U-(gC36loO+y~q_(|IV6=AB9m`MLjZ)G-?lJ>GTjJOsvmV@Blx7BAyH^ z(k>FnIf~28@NIOV4St2`Ay&`MnMi;5RKehg32Hk;PndMMBHf&k9;?Qcbm}M0H%wFI zI++%f$ofzhN5DGBm1YP4_EMEpk3D>F>R*2UA{2#s%?vKggErA-<;yT=DIqf!^u1}l z9*#jO7x{|WY5DR7g318CTxg6(Ef6I7vE!|-W=vU#TUt4GG?3KH_&+WqYDG9QamMi` zxH>g>G*~4Sw!KmQngqN8akNsLk~Qo5L?MT?*+;t8NYVRvJ>wxksaJr(9`TZpelpdBB0kIZZ2NeJ^7HX17{t(WzcZ{3ZUZ ze0l#TSJ_z6ta{V>aO5o%Sp$%vS{%$xTRnn-e#(AnOXJ$1MT1RB=$=5T)pI}GzwS3j zjL_v2pGgU6ojkKZ>1z}S>$B90Eew=d`SFO@P}22H4z%M$mq^bXbrF{$2ZlaU!J0g* zAIoupT(0D>3$-bITLtEM&jgE1P*G`s>E;1qt{5MjiRoXAQcHCPE7;vR*5!;#;W2vW zpYVaQ4;J{|iGFWnEc(y0o|2d;Vzd2sQP)7oO;P?A2x_uirvg04c9k*1?xhZwvdM5L zUN`-JrhY`@QxL@YE=rT4;JqX~@yG|!nT^wR4vr5C<%(nEOUU^xZs47mjFbh{&O^i6 z^Zixhi{2E@YzFk=z6qe-3JL{>kMb)!AmpD$*a=-8 z?MoWB3(lc=<(q1HF}AAz(saM#|9D53w<=sMA+6Ud7B?$5s6zrMx?A1(Sy$gEwhw5o z77f8|SDlu-w!jee2sf=_DC^TnFLPzZwc;FNF42mh>usE6%tZ6kxtx{BQqnx61QVfc z=bd07EpSAsvQr~j#7u8Ks{C3r*&*nX=oPesT8}9Wq|)f{t2tFw4LSo(NLZrQt$M&f z3d?r807*P+_s{2#19ff#nIpLFBV>1y8!j)e2VZZ+RfNni|ka1X=WDO$?tic}R0#`RwFuZWaV+Gz@CRW%Gc zBgO|QSR~NoHw8{p7f_&j1j~{_b^+eAv4TAZW4YLSBk! z>hbKck8K+A93btvz}X-u@1yIl1}~(Bn1q>-Nay~AXy5Do^9Cn4I=Mh)%OJ5Yc1SVe ziGV&K!~>HX;%Mb4yug@-?kP^cUl`V}&B@{yV4`bsa%S``WV+npsl6>sVzJT5LOWtH z<^|T_lA)3bv-MH*?in6yG)lnlErjy{y|8+dI`Q4>`ApI@qeE)qvoJE+(|B@&!1t4j zACks5e#p<36a_}F!kPe4Fa{N+OrE4a2oah-X79}*7Lnj)KffoX1U^WnlGs;1!I};z zep6}!GtV#GZDyw|Ph&(PMzLi;8??<&&rh!74X15}q3sPpv(sE$x!8dgJ}^`r`~4q!T$OCUoN8YmD&Vhzurx)F#l=S`_C?-|Ie=XKl@yl znuq7&QqoWM7~#Wcj0)bVZ_F)BLSQLxED&Ed0vI1yAP7`V=9e{gu=C~AIuxR(1}fj({Z0IqVhbS$D@b~*i82BfK?0^=K}R`1i; zI42FWf*@`4a8C*(ZS|b%xDo0&_~VKdNsVZB7K}%-a?>eENnNC~&PR|W5nB~D1`f57 zM6UDscY@c~EtLe%-K-fG&0a+GtCfJfjg>Y2VXlP~c@7QuWS0jQi%LrTCcjubh{km3|Oxs=T*J2?$AQ30KtKuaVT2oEE-@*8QA z)%FiY3aV(V3%_mZ-z&T^2PTk#%#v3w4`8D4mf%0<%I)g$G6%+!^-~?#rD8{DkO`Gi z6>&gAsJ0?pe5yt~`I8M;j-OuaUW53n3Nj%{a&wKVnhq1=GVc@k?>DP53av_1H;4Ha z9YF^mR#+b!LuS+!p%K_2TjAW~Gp8KqO*A;1CI(ft3ae>Nz{RAs_r}vz_MpwhMXpNP z9Go4^Ib$$qYHp*;TrshU|82<=XtPF*+(3yw<}C`CMsYSp=%`K5yqvZ*Cqq|1btEo0 zbBs`EC@Tq(ht6l^F6T(IHvs+B#gFgr-}6+t9fj43W{WDF%M8^+SZ5|jdsFh18uBH;KhQgJ#N9%ojgd_OmD>0T7{t9 z8LX9V_kga{vsbcO^m696q!HK%hu7Xu&UZ~a zx=gN^`HZ+@4rMaao=~obO_-dn_1teni81Qu7|7XH#e$j@UQ}Q!7o;0*zbl-$tutFB zAJ?zan)wfmyRgkSaLl7t&q%v=!h&cZh3yySWy`HT;zcX1NX|q~YNZ0^_&7^-AK}VC ztKDuz>0rtVCPL)&1*ly{5VwZE=AJ{dYHw2k2K79H-j?$2PN{2F7(D=d^68nHX7 zfDR5TVD{h<*5{ldeGWKrjlSku^W;o1On9;u0<^b&2&>|_%eA*8^#`cGdO1yHU`wnZ zN#e`=&YD~?1(*wX6Rr)q3qdFd!C+4M@W&T84g~I82{((oRnJ75|1B4Z5@eWdH#&}) zs#ChqduCbHhKPG1?#zdNFy|zoYtYr?^fi=UxG?%(%z%96^tvSN>_8f4?h(UgyO>V} zci9=w@s#uK47`M8XF9aoK=L>m|AYmjPg9qBEnL$|B^-UyD3*F@1Xg>?X?*~A4=S?c zPP%^83GYI_ifvy6CQ#L_PFKI`7Sp`lDtwCec;~yND@>f;?@1}||7;N!T?U=({tjnsVI?m1nJtcU%v(Txy)#*ErC1EkiEKn$DJ7I|&?e8ny% z!%We?s#h^B*LWp(KKsl`T~sdv-MYBuq_7H6>E%5&!|cY#1mUXqzS-3py8LZ; z-4`RB#}W@@T8>AdnSz+z*B^p`RXhl2_50Jtk-UlyZlSZb7)!%`k6goGRKsNHsa=h6 zD(B(ym$acz@kd8JuT-p-E`~LrTuQ`--oZARUm9BF}+}alJKB*y^kMcC_$abpGAH^ zWifgYFccPDEiG@fgEwl}#}-gCCehv>=ghGeSLU5o{L1=|Bx}6b)hJk7c;8OLBc}YG zbLA3W!7N$PyclRqi5%#p%xgQMRvg@i(X@VtD$e^qqZE8b%xxIxFX-gy7 zDz(cVUXBFW;T5VIs*tGR5FxF~@&u|~^tc-@7NbWp&dvYKt>!F1V8Sx(W<`CZ%3P;1|9@!ibejg3y^VX5Me@mB@z$Ei`VKm2sHFG@!X0)wld! z#8?mqe3hAs8`?c-(fAcgB?_RPt!rHAw+L-i5Gcn*?KvF7WDP$|kGn#EN# zk~Ae)C0jZXSJ&CbF+j{Q9G{ztVUjxqyE!Ukn{pPU!S*3NMIUc`A{7a63|TU=XYGdu zb`$IyV61nhnJ@>OnP)7pCbE90K)0^D4}5u*1gh~61Wdi+q~zrl@zx#-RJkINX4kp| z8EB1RrFluMsU%$&O+#l@1#hh`t&Lw~i5J*#IuuFBMB}oK!O765KFNjaZ9kb$?AnAo z5v{K(3tLL+ha7|CAp?`nvBduIk)TESM;5JxHnJwqa6_==nmLd}&AkO((|tW$s5{n% ze4+%r>DSLIM?(zaL0dNH1UBTAIzJzAMiNbmxn_jc@n&U!)V!zZmf_BSS>BBjS60CC2p5YpBC zZ85|x@nYVf^vL#aNDB5q{^jMq?hzg31O%6#rC*EzAxgrNxTFvP@GH>qt}(%<`$??# z-ibb&5DJ4llcsT@IZ~>elKN|#a1{UVjqpj)rCZw<2+cVgla{<1Na@N;A+KA~<;UDJ zGfU3!>|q$Sr|>C1Kas=U`t$X%;fqPAVL zFSsVn$~Yq=z&gCppdY|81LlQE+*Jh}7F$@`MFVb4LFC)%z8#=1AP`A1FJ&f*^8f^A zh6lSJZ(l~jw|wm1e3bnHszD)j=rOzISo8=pc~+=$Av1IQ*45F=FyRgkv|03?bFDrW z>bNvi??lz%mtq&^vRfkLDcx_5j!DAyS&ebX7%! z2L_sigj4bhTrwL*>6; zar#Gf%SJLUs_k5I+B+7#a5qKTWwvH-hKLpsSchY|V0gNRX@A&{4=^)*!p&}_822>5 z_BOx{2%QhqJfU{<&OK3E_T7ZHUu;3UZ7f@&I!+3*vB<|N!pi1G;!-?F;tYuLNG1%ul=XhA+DCra*Gh^=8CN3Q;UYO!0xqQSOKidI!Mckvi#tSD@r6h!5usvb}~ zakx3%7;U#ZyjCbCz&8-ol=T;(Y2hp5Xbjznc&r0k+c0juIAe z&^ue_Wku0-*e$NfdcsMGKk>sX^%$2v?(JZScmQNK7Lc5o_8|6Zo5Zx_T$SOv7&Hv5 zv4>J5J;*q)_GC`HnV5{V>8O>zAR8E)Qae95_~$6TvpIp}RKMJbVYdxYZQWRp?T>gL z6WubrKlZ4}c=x&AO9+qF*y4LnvASmQzJna^wL}iGfUnxn8GFxMegN*j68y$LwvgM# zik$+7ZW*Ny)Y*e%oCCRT(m*t!kTha{wc%N`4{k2xNr~hM6Mo4kWXU3jnrwuKN41)G zF%S0z@K`3<)dgg#Zaf2z+JzmT5uiWyA7qU{Utq%VU;|6IhmUZD3+ib<6zX9Y{m_ z$@~g&>K}G?3|E&$*9mrQueIswAa-T1VQs*vQRa25_Lz&52ay6bzzecscERGpXpmh3 zGwqA~*N~|fi7QIfO+vs-+43?z{W^yF8wFvPOQ}D7rZ;?&u&zvqp2&Z7ViFhM0l#_Y z@FPnhUOfsKcWbE5hcS^i3H`!F?!v7NmU*1vu=}~hz2ni3c*qeKZZB3sAkDqr8OoM- zyv~n&Z_p)g63D2$=&OoUier-QapW44&+F{zLb&K#RH(W7ZXzmA>Iq z(lNwT5F(ut3YTVe`t6(0*2`e14~rYrRC2)EzUlBoGh3gJ|MUt>S6eMrlSUgZCvXU&cCLqF}Pz%{R$3H@vKd)rcp? z58rkU-sO8Hk|y+K#1D4VhroBL5RW?13t7jCx5?T>NVjs!q}{D)E$e9<$P1 zBVn1i`rM|;N#Hode{1yAx=uv2PwAv|nW(r|bCbA^b2-#rQFQBN5`anX^ax;Oi(oBd zJv0D`iK7+qc6LxO1a+93k=ztVcX|@Cr0t4~0c)Dvjm=SIm-$ynVXQqBFI}zPIO4W= ziaI&;ZyaL*g8E~1hI4pH|6aZ1C#X+Eqk7h-Z@0v&njU$RqNe_wqrygx+T_WIGJ*AK zf5~!6_uqqZ9sgu$DB3PPflw#_gM6TEM%+I^dzSvH)ab6056A#Y)iyL<)$k ziRj2flbW`&)?6R_b4bgGs-Mz-IhrQ#vNQi9cZ}WdD8>Hzw^I`TC%J?1KZ^X4HU@f@ z%6j%@dis_|4hlB*j{gVyn57Et@k^-lmND*ug5xKqO#=$>mktgj6&(aZ1OP&t6h`=0 zK`%)?wrfZ{Ey-_dR#m({RHS54QH80jfLxYKs7PySQKhlfLQTC`w7h&`=EH08D{5qk z;US(ckZfk&WP41vbnhT&f6gQn{F&}c0f0ORs}6sS)^cZU(%6xM7k^d^JmBKGQ?1X( z$AJ;z;13fu6;YIF9zrDJ+Vh2Dwc5`T=32tOxeO&FC}V|H1L|C>rrAV3hXt23)2^%b zHu@mC%1}QCHfE7LTT)+pm!Vxo2fq;W%cSD->wGjJlGxr$Nz=e6 zObjiK7W{4LpUS#{**HN9y9qZjf6EXO&48!l?v(GMNLq1HjvVuLrog`I5 zYhBL|5Ki?R_S@%WD>a%Enk|(q)}#Iz#uX@2%iY|FF)v%NwuqrTE`nDj@gYh@DvV$~-U!pvtmqFt?m6p*4j)zwD-v{z$MJ z^DKAz%+SYq!eHZkT%h9T$QBLV>mSFcUeDme3$|NIXyw-}+y0|`3P5Yq)PH64EX8`| zg(wh6hM*aMCJRrF_FDNBH6k%Zl8i|oBpCATM)ZU2bzl)p#>;I0F!UA?n$;9Kpj)NC z=-df;md#*#C4lQ$Rx?ht^C;T}opd1)P=m2l->6*jD?DAy^o-@wL^}gEEb9Am1M({K z?b`gj?M)rC%Nl)JWfsPjri_h>s4J#GxmvO=bVlZtHoX)@7z`lkoIhEO9K(4fVQy~q zGRlua`C0Xxji#zJcZ^(U7qCJESwwf+ww($zcKK5LL1P#fnS&LG&635B=OB)v-KgM5 zZviFTtztNvk`fAb2L-&{KKsboTj5ssmqP&Amgl6BRx7hm%9I)9jN+e$bt!Z(1q#M> z*TT@|L|9~7bGYJYdrg?#x|wZ5ma=v*!uopXrY!lxNjSmj9!R1s3CblH0)S#H?oo&- zbM4u)e;U|5$zWp@%fuRw%LYgY%Xt|ioOCQq^7Ekcu-zT+VIfKoUV^)f)CxGw&M$|3 zC1bg)AMPyZEROcI*U_CXjmi&iS&<`yhi{WI-E zm3oxdqC_!?BkTsY&SV^>%2RZ4YCdE+%-)wsZmwm^pcsA>U14ScxwATpx>#*d#l|8d zpD({j1Y=Rk7b=lg&9$|kBIG6$`zvIb?8O@-tw61wCA&>y06adg*l;EGr*dYQRD8eg zG#g=!++AS|!7G<#P}MQ{G7%x3=)15wrBr&kJS24t@`9y#k*TWP(8)r}z)PbHu_bdB zb>o>(!951B1s*+5@LwYd*3A|H+^vZm{e-gY@$=PdT`=w*38j)(SJq{W)cds~2J&k| z`tfkqYuV&Y4!jp4_IhPK$FC(YkgkUVB*zmgb)TyEjXcx2_U1`H*Q&%y1I9{CnT^xI z$?!HHP!;*6H558WkFKcUp38xr!2$d-e8F+YU1?p@kKhTZE88ua-;5$-V~VcrL2jI0 z%!7nHOTL9PFYq^IbUX@fe{G}dU=;3d2tsgA{!GD{-Nhhx4tjHDT{lib9hG^d{RE{d zz26Z#0nU{rHcu~+QCQ@-T8yCNPF3ip<2|#HE4zVlDUj#)*hJl$KR6GIw+Z9U33N{7 zI25^cCuv77n`;>BE-HGFASIGjzQyKi*WDHJbg6;zGEss%zp<&;KYWv|6~@kLc5U?v z;qnQv);r?tgl>-rs;p~kG>7%Fb}+ARnC+yOZ3O{yki>;yMN>m{j$4xc$fli4xK*$1 z5m1cpNZ7Sm*BYh?%S&<4V8^{y2E<{Di6VBy@pQ$9h^Va2m>cKf#v8_$S`;?5h$!>QY(q!>IN+Q|OSOi7D6>02sQ*r8{0#k!@(2k#w%@Bt@JLq|?e zkXNKz@Q1Xa6MF83x6A#5qX#MOq~o@SNe783hm(wx@<|8Su_rubM(DhAyz@3n?$9R9 zahQF6>Ic~TxQR>x(``qf3-sOP&SyQ#M`(iyT59yZXoJ5xxuLwPZ2s4DJxX)1yR(a7 zgj`AaA#fTFt)j|bwHd5;ygOg+Qa6I95|B2 zl8lLl&muF;!aHOYHOJuXRTr$|Xj}$xS;Zlhz7q`wjBnzT8ZD(vYYW6YJP zC5n#cI;-cpZr!zTsCc!Sg0xARY;YD+19Ct-$AMB-sH0lH>muRnb^pf5PI5zdCI(-M zkgY&)7DJsEwW6m6+{hwJK}@GAOX#9UR}yu0*GN_r@v)FDn48T)k2k7g9Lg6jk)y66 zI}rrj?9Rvo@V0wmY|J-tp8OMGHXhi_yl_oF4tMI#^q^HLme{T$=g8)LBdt(K(vnB1 z$@&q7J%CX&9}lrZy@)TGKeI!*8oD~dImstaS#g4U;qkRL)=nbU!SRGs2%RLi0(-ju z!hh;k?xu;m`B?mbc;nXT{*mumnQ)0&d4hu3^efX|SzxtAlTrMANh5npr#3YfKp|oh zFqAvTQXx@I3+-L=bf<=l&gkcA^FoQ zHOt3#%I(3i8EgAt&3QFAP_LZSO(Lh!yJNm9)B4;XI~!_vegu(|awvNyXm2_Pl$;Zz zJTpA+I=oCIVeFlQJQX^^h$JB}o&FJbYUw>u1Mr&~Qv;baMzxms6At|`w8E(r+hfVZxxKU4bA?>KUktptD;0Jq<&aMC9 zq^|-P>dlo7JuNo z-pao-6ke(l8ZUUKS=-Fj?~tP3)GKmIi0j|CxK3OCgD&?02!IT}>mMLTR*lt5Mk*l7 z{9L^MJwCwKJ2b!{`a}t^X4D?YkGndsW$hjB6YQk4O&`9Kt3>~)X%OhNqwI}pu>cs- z{Dvc?CYTO?G0Ja?{=#}?Nd|{ZUKpVW!nOzmyawDHq$f4BE7&1_DUOjvqsoD=pVvf0zo&=8_*+^>k9Z@E(BjItgT)vtTsD)kczF!^I zRUMEAkc%nPXDW_pA~h7BF>22uq8>yjo`#qUZOTWd$`7*DjH${;)|(Rsv*wl8EbOdH z#?kOkdtJ4}{6e>RG%5D?X3z}EG~<@rPL<&GE}!oRa@a8`Jgj^%X1A(a%S69F8npFG zS3pfQFrQ2PE-#6osIOH#w8B;r8V>8pUrl6CIRkCI=Qc5M#fkz& zYNr=9!~_1$16u!v{I9eyAZE+fFw}2a_&>rWe-BZAZ0t>FZ1l~I3>;mI^l9`QtY{2u ztgLLT9cZMC98GNu|0frmq@w1ExPtsGf}v)h#>}tl55-7mh3E#C8e5M}fMVbe1_Ihq z99$cD#D@|`WW=ZsZY7pLJT)IgEQKiQOG)U64-FIx&B)6*s{-D@Ae>LO&><3&@$tA#OvN&bGy?@? zINw(6ymdMA=!P!_b~*QKE=5L_Wx8&-=DwFKYoIZS7=duu$eb$yW{p;N#TaGCUMJ~a zBQrA;Ww<=|XcIziU()rCcKot+MHW7R9{@t<>L{VJsh49hz%Fyuw<~QvE;hTsUDg14Fm;39K}w1P{eWwyxnLT!MaCC z5IllBvkpA2xz+z*8Qk^#j;S#;p|;bKdL2x=Qa6BT!R!57s)LQPziv1cx1x4EB*`>s z7kmUuDr2^i2$}${PElOOv`lHb%xnX9rNNj!;aNWmmQHe?Z0yLxK^bov=&w@P?MEG- zZcBuk5h3X3D&e~u5j)`~^SYX4h&*Pi3K{XbPr2`e8Qg&a<-u6Z5>@RoHa8XBV=hKZzawim2?+~_ zw@6EKrQ~M$o~%J2f~Sy(6}Yep%dD*uWyK)hT5*uIV&82b_r#WtU22Lp%P9zmEq{jl z=$W-_Dydi`(vHD|NO-RW8Q*QCP!05JuQPdnwvwi3u-h|*$@+;PB1A|IeYnZ013-as zQ1w33c!NUn1)iy>1kt$1X~Ayq4-PyeD6kgjS81?}rv1*5^mw%<4Nej01m#|}_*$gW z+Z`HCP2bC{mpo&A`L0+tjKEB>XtQW*6MxLy8yP3ny}PhutcEAHIIthaK8XSllxw=%0d0@}48(KujC^8Kuix zyQ?qPzck^pGMl%C8p{WN8=ui(x7G`A9dUljT;IJ8c{C1G9aeKw_` zFBZZ642q59t|`##DPu3irViQVOb`&8FV~8~49HM&4a$8)#)*;-A1x59z(4sn9DKV}*`XRlA75mx1YVBcu~ejss})#Giwi^vf!oM(hb; zjl2XLq(e~ZQ@kC+0)D)9e(y3IBsH{xqnWLNdlNf_n z1o(rgpe4<)TPTg@87O%c;j>Io9wA0r0UUQq#j;Z#FBj6W#_!-2y+*C>ivY)^0;waS zCgE}Al}}m9NIg~&#FHmAy=@`N047}l3M97vF9=3;0sGW^V#&FSdf)|sKGX}8M>SLL z0FXXu2`8QrSo@{d_<|xPEj2(b;cISLm+F=_XM_z8axOy9lhnFX_DpcuYQ0|f)ukAw znL=i9oC{6>O%2hx?b^;=;pr2hPf)*Y-%C;hQBych#hn((n<8z#py?IV1ql;cQ`@mD zaMZgR8jHMx{c`8X?J^1`OB2mkk@%denqCkKW%A-mPY?qkoq6W~&erhSEY)z8ak}_1 zwQ%Nq#--$kRJkpc#2l-Hy$hQs45^VOYc)KA1m1(@pMg*~$EojR8#ip6z9(x{H2J7B zdAK66{S%{mq%ijB*!|#~VF!=iQ8+fU`-DB)gB-3C`V14^YcuCV=tb$uP0@lV*ug=I zpjlWRbfH_Kp+C2`%mhTIE4-bAL}}<;eK?Q(1DVhIutns?%)TM1F)3|aqHKMDyNEZa zCHfO)T0>wX{^-s|*I=CI=pm2JE{f2{W6$1hDl(6(<^+CL`9LMsp9)S3uN!dy-3Mo= zP3FlvLwT{D@G`Bo&=eV5_%lxHA)Nl33ZcRPn1LpuFp~xvo&IMG(fz34-@KF}{Pk8$ zZ2y)4rGPmt&HyI@VFMnckqo(JIBlaJGfAuhQvLC9h9WqvQ)p3d^nlCOLn}P7H3ytM zdDpoGF>w2OM?5(^{YUP|B%awKZi9rp7q>Yl%n`jN@!cUHsZAZ=zsOKD;kx{~gXlpsStzFzag9N}m9@^@Da(RJeiHyxbR;ZgEl0dMuM^*dDAC zHK89O9z3{Z&L$$&N7B9^ob(Ai{g6tUyXt(q3J{;8r8%A3J$d3anVYOEfol+!hTEn~ z^{qyXI;H)$TXmqj(K(fRYg$VCS^{oX``32aG+N=X8iOMGCYo=xZ^NlHA-#1Wae-?# z`fvPm)ce`6*flzVQD{+h@f}nL#p+TS^uc3BMCqrUa8HXr`moDZg!s`dfw&!0HN|0Fk4|9^y0{}(e<#mZH|1igFb zn2?N!YBoN(F)?O5S874I?q4$|wJaLC74JAZ=z`rk&N^@UA|X}9fS2FG*)iycZN|=S zrGvLGVE^ouJ`WPjXTkSf`(upzn@`I3ZHar&jfZ`FGl^_0&zOVs_KDl|$D4bO=Fd!$ z%U@406(IG6w7TlYTR96tmraao`UXTTg0rwNNAe9O-J{`!f{!Y22mAT)SA3vlYR)Pd zXrlTs&GZmX04E1zj+pd?VqT+RZ*Q#qkiDQk z2>MVEu9IVdzMKmGqsIVxSKyds8j-}1cEAE!NOb@vj)O#UOPX|0>{aF^qnx0R z>BAOPZ~BIU#B-01cfU-LZxyZ^>IncawKkimJdt_Pu9Qp#2z{eg2_NRjWSPV<(*_Ik zH9KS@q6vHU3WxMrN28T2VJ9Wkiz0Cyry@Chp;;15CJ6Cp8ymAG}g@EUpZ&Emq99W+oCCOvyr< zCAC6m2e)A05dr_fLt=hfT^Tq?nJuW7a#=M<&56oIQjz`Eaob|Je1LO#V-uzZT%^=84&Bj7LP@7I5*r8OE%qx_ zJ$)GBVR>U~a)Ys@xu<)lvqaoI=ruAPnB9=nq(JX}2_lWgL#aaHDv>sDNEC6yyt1l+U;-$`Vj;PvQS(qM$1Mf+#GmO@UQBrnC z2Z9*nMH?botdF7c_)@k!_K`T{-U$)+)m{ybHx2lTa+An?DfdhW#Niv+3b-x>tPfNQ zS=9olT!4{pe6j)Xl&DyGa`Y?g2=gbcjKqkaE#g!)l#8aI*PL@yeN%+{i=07AJ?`=e z_J{eM$}`}&LQs4m3GB{2Y|xciXiD;@l@#lYRqYqX=T$@L2hlPoQn#}!50=x3b9P&+WLo|X3He{w*J}B77 z-*EvVK^8Vamc4*aAF9MgblhU&C}@6!qi>4G&$cRXA&PZ0)VMk?CA`7z})xBF^6~cf&4wrl|o2#wWB5!}J^JM4+-h zzq#J!+-k2OggqNj(fyu!cT2}@&Fn;?%G9HMulOs)hcf}0IPU>H&+wL}Pv z%snApHTnb-=57lduY#QWXSa-6!vT^F;iNK}L)#Lptghp54L@Df7c}&c1qEos($9#u zKwms!i!uq{V$aiLjC&8N6G&FQsA%;jV`qf#x0#5?MUpT0m@b=o7$&$D#deQ~NL{@!Y9N-}uGeQBxF*T&(RwzQ5XnMB&@amfV4OWzg&m z?vmj~9N@Yu#;qhU_hfQ0N^1@+)c=)6HVa}y_G?Mqf~@?ED0K9@xd(DgbGl>3*U~FG zQCsVgUvx&ClwVG$L=&^`#b?U}11CaOcl2#~iTuabd%jU{9hOy@#%1nn>(VH8-9S^2 zt}lM?YW*GMh`i)lb0}PH=efd)EH4l^-x3>9Y~@8FBk^_K55*HVvT}_1!&H;Hlc))~ z6n$sznKeXK18kiNqZSKpt)kinr z>kekh!@7dGTWmd^Y8}lwMQcEf(AaHfBWqyM%fy@Td(z{IhG=T*bk}syWlf1+Y^UV+ zBV$P96koSud0ER4K6%mzpVmRo>WSOgxsi2j&0l}j){PjAwt{IvwH5$Q$a7;b9L=6O zD0#Tac`3V>+2;At&)qIr^WoSM7J#WVE*VMB!m${hu~eNRPYjMXB<&J^Z#!4SUy;V# zMQ#G2M|MX$hYRwgkNoD`J}-k(8mCoG4z9E3L$fF%!IvfA{3ZOU5`ZC(Y| zZ-5)I#A(Z>c7#3p_isuSq9Pw#4^5R2qMPzOIptEAomd6+e*AZYhhE#*7YzRAPtJc7 z%9#FhglA*uWN9R-=U{5&z~|^_Z>I0$X!O5zGi4121tp|!=lNqok`fg##v)%*eHvcD zTzw4+tG}31W%HOtzS)H(X5!ROhk@#ff>hB?o^m-^XS4^m`+$?89I7FAQ|LavKD|Hq z-X1xOR9506A=%Yk)jR4t>mK(jJw051Z2??>|FLnPj}4hr1~Qlo5g2nLiXGCYX)@!Y zk4mA;EBB=3G~aVY873*9HA5Z{Y|H_)B8RO$~%Yc(h?Ff zUNIE49Gf-iY#~aFTs`1DZ#oBd8LXdJfCiy{@;60YF4P38ttZEcv&{HoLI2JO(saoK z^bNlA0>NDOf;Jo%7vH0FJQqcvKMgjTy`U5q8v@J-;(o{+5?3L>1{D1nLq{#O^WX3BeQmKK zY930Q?sH#M0iMgmK(Ecmm(2Q)97SJ)8~APUw=70oOCOujK9@9g+kkdxuHndY{Q!fm z8pg@H${T$SYAlG~YN(v)_v$JY#uZ=-p)Ip^X4Jz?2Ot(FdOvj|M8y$;P<6>y6dR9; zGx#$iYDKo!rfLS3sxN_FRqzKOV0e^x5aKYOXebAfAo}kp^Gkam+4c_Ld=Ndcoh7Bu zG&IE^RjGE9VBY)>w)N4i&j7tVPAbL#+2F8LWSarr-#*%BEzb7ZT+bCO---i z++(fXkq>Bt!MyUw_wM`0JW^$DP@C5-)TaqTgTtL?ud%#^?_9*@P>;BTXT7*1E+B3; zR9TML9F8HtW3}kWi#eq=s^F}{D9?M&%%`4m8uKtN<_N}xw=vhanBuAd1;rmO@lBCo;KsN|bM z*}W=DHHiEh!pnts?8-EV(rJVj2q-1Wfhr%->mJb>ayd$$VSk!i;O;)I?1H`@67MD# zIZ0p;Bmgk5ceMck|NG~!@;~Sa{&kA{O;4btt%|9Pw85IjM1(Eo_dzn^TE7gRXaGn! z2*Z**X*rOf?7>fR39i_l?90HHkSbg43ZFhzT`w1E>qQ4@_ftWi&{s(3EzX3(!0CIx zlr+bS%!cngPuZMPZ!b4+J<47ra1B`oqnjJ7kWIJ~8;SDNMG)^HNhuX&nO&;9bS>lY z@@1(qZ~}VIZp|4@*2-1s6GWeTE@%4MybJWfZrL|AzB=3+&8jSf_oSVutdtjlE*f$} zL|;~S!t9JUakU#0*r%4GaH%D)K5}{jihiEHB@((D+4ajlG?Y7R;ED^(fhU_ z0%9+YH}bGq5KeAaggSdgjcvPAMK?rOZHRgOPzc+Wr z^cDCbF$O8ElKmKVIGWX$)zee+ispf6qpJEgdD^q|Np3^cbdJO($f4fmZ8e88>);!g z4f52MDqzF}EC=Z8;G7i3DYAi9S#C$IjcwJ>>rt>lrijwFZ$m+_m|mltP*e<$?^>U9 zJ4AY4u-tq{G@{5zqDG>fh3~$f^_z(ncT>PTd9t5@39(NBgPaqbD=J%yE_ZD{Vd@TJ zw&q?s5AG?(8C^T3EcF{|>}q^Ei5d189ywK%VxnKz7~+s*3^y5&wwb%#wbmj@j7`}k z8c{>MvKhg`XO;2Iyu)*cMQJRsfJeMyZsLcA^9?I^gx9z)!|s8u`T zwoIUxXVM9_Aa5H!W?bU=6qAu#;^V(8U(%Y(Q}c7u5EY~oi3>5e)5rPb&qVpGc4jun zat@#-H8As>bgDo{-f%~Sqz)4j8^s~vzYZ3CbO1tKjYr`UXK3&LOG? zIUP+8#?u^K?+%_E>HDGA%!^KkC^v7L-3g02&XneCTCB&UxtmxyNN63GSU9uw zHPNRWBSnUH`}Lsa-cas|LC{UUSAM>i@Tp+Tq(!A5wk|494!`p%)1gv6xh_;GHC_7l z*yms(T){xcEM`=;`<|u1qF72e$aG(TMv;0?Sj2aGXA}KyUm@*lPO=5Mv{A^1uVsVl z5-f_!5i!Cdf&BI!d+2@Np~o(h(FDMqtB33!E*=TcOxd!h2b{9b~m0GPtFDXk$?NCjUvjyBh6-;bU z1S@`wC3!iUkWN8VSl&|^TgyK&w>g$+ZfGM106Jl}H?X}_pp_jL1d=`Drs|(=HgwCx z|6F2KLC`B+W2&r-O(b*QHEg-J=D$Dw=}Lb*0y0CT))x~hjum@K^-yXD?}!Y=UJ_~Z zl~6lniD&k4K-?2QB9`n#vhWc?Wc5c!cnPa6V`OaEinKOZF_VY4c?>KDdvXEo!W?x? zaR#;p;^-F}!*u;CgOZJ}GRn58P7E|xmhFaMTf9mXF2m;6#{GM@q7c*30D`GPXtx>s zDpV{4doj0<5RV1kpAw(da(qImG#Kj+jAnwT8AUe{!$FU*rK52-__^3$KoN6{gtN0l z@D{s;vU1>mI3kTixZZ&KK*TPlo)XHHc+Y1f_8(!(d~mgMK$VSaqBTor4nsaOc~rw6 z-${)58c(`B)J<6H;(kC$12;X4Bd3PKLOhaSV-O<;g=#N8WGE&_g;&L1?>{TCQ=iBb zOzFfzR8`R`l8Rqww?TU8_YK76nGKy+>eVrh~c*#t-P9hdwq08#DL&8qIqT zzyHr`^#A7SsHE>;YV7p)tD};pEFwSBYw>p*)pF$?2jr&J2nBh#Lbp8TK{lIAuuev&4igRPU@;x5BIqt{SyZwL?J2s4#q_h{mq2}{PYju4^rZnufMgUvU=){p z%G&|FV5lN!TrLGG`f4L@hk*k<*s_U80`lO4J3napGalelGxJPNYDfpc0Gbu9FG#dnN%%q zvjESH(7Scmu%abe2)5L3Xh{3Ej7C#7utOXh~-=b^BBvx<=4D zn%IzD44pvnG;=_FE#2$%t+Ex@-X5C(0zoXh+Oj4O*A?yAx_c|Z`N(@tX`Ha?E6sUW z#aa_2^j!YT;m#qwvOO*=NX(#5$;^qzkU1O2bQ2;4Q{L zIDwDSLrX-GL#RAHHS!SKChXAsDE}gM1cw@5b^+!?ycJ~H7~La%f}qSJ1U9BdYFn8S z6VVDHCi#^i48vXyl{{o-Da9zH)hn`OWR>(%VX?h3NgXEnqbl7uJSTF|T4>zfriAox z4;VUeIo%&}JnH4*sS`RDISOcssmWJ#CUle;!S+#9EsY0u+TjR8(5p8RCnN@e$Gz0+ zE@WQ$R(_bA0tSb0Wy-qqDbK-|v=19O@Dkup0FWQmR-=DJhutwz#`XzYG%)kgEs~-U za;FgYqN!YpAw=pg;G+o!Q^hnc67}Li-=;bt3Yr>|Ug-W@Ni$U44TnGg07!paNo0RK z?S2=Wvs59y6c?~xWzw0f!5WnykTgK~p~NLf*%DPMm~&Okdr`(9WV)nj_XRu@6Oi<6 z92H4rvK$R-+8-$-yrrsaip`LXVV!Iy**Bib)-r7-xi`kjo+jCkt;H0m`fA$VeU*5( z9&;|VKcFl3&!ZyPv1eAa+p8eIOcZR)_);_8Y|hgw%f$fJqE=K5s%vUTb&9 zNxOvi)!4EqEfRtXq7p~9l{=~SG&^|kQ5%Ty#&7BDh_NeGq!oveSQn%ZbQ?m}`mz9P z&YMgy=w3{a3R=p@2P_x8^tLxB%_y>aq>8w*TZs#wj!;hTJ+Gxml9qe4Zw=>Id;av| z{{8B1SfWAKN(`ZWVkW1oo=Wwd`HM=WrpT=sF3LzNnQNuaoQy`KAMWr`TLhW}I#h>d zE(hEfS9)L}SztA)I)9+K&?X8K1gie~%pQC)@B)?UMxk661^P*yD{hCuT@VQcd+wuQ z2JvMeELu4c*7UQ)wAv`OiW$ovby^ATK;Q;wFKT{e3>bGFPa2c6l)N&tfV^phjaKxE z8M_+{8lN)r4>QXTkKnlvnYc*_@Tgvy8707}_s>uHRHa)9!}Y8LnztCtk)j$%3FLch zv6=FS3KUE<@M`M-DnNe}vMnqwf?>()tw%V5aLuT#vp6o4rx6NpE<(`g5{D?};L?6*Lzxu#C+5hCd9C{<}oC|__fEI17gq%ZD28I&n zAW}&_Gsjyzz6X-N##W~xZ57XdKC^AhsQ3b|8L~CIy+t6mT37784|>9}RDDet+#tEK zM)_4^UEZHf(AdbGFUJGhK8oDPf|N{)E-hVh4@!Q5#9-)n$_D^c<~X zXV6GPML3|WLGa+&#mhHh#Hn?e1@V)Y+`+humskpFmT1bi?wBKNl1tpLj+&Kx*1Fs9EPcdTYtUJ5%} zv~;{V17MQIqqT~ZuFE1d$agz)K%#MRb30c^hHN7Jse1%hpE&o2O^GHtF4Y$Y!>o%k zGawI^53fMky?bIlStUSu$#+l2@j{JY#cx^JM%Xel${36842TQo<6W@sqO>hmQCU37 zj5XxR1uYTmo^G^C|8VW-Y5x+YFHji;N>tOwM1oo(f)G~9xbjJY$ze1mj}lW-nCFa25-&YB)_?nE6Z*}B{%4bteAf&)~^ zB)=6Sv@^2XbVy@md_qPOkABf!Wfu<@5iMLpKKPtintJIE6jHlSc@YYL12B~4b+5>s zJlK8fG4fmlO^;-hMetGS-f5#A>)X|m*xbRx#E?(>O``mdSI!%E&~37t6cP!$aj6tj z`;{YL*_y^*0^IlE8QEDI-33|v58P(KRx`oo5+3E%9Ndg*V~>3;K)!vUH~+@+BTSOsJy3V#3t38-?}p;iZhv>!GhPf0P-V)en0xKn zU6iP9^q^uUC0O!7_PO4Uag+X5|5TW1L8(~OgjV5ZWUq?~S zVnxRD$3xY`@eP@#c9KlXxY~hL+R##yh*QOk;Wrp(=up@1!weVaVx1W=^$W??&G+A3 z(!!iYRHYU=-R47`(ZD6UO*y=G{dbbuq85^HNf{Qgtn1I*M#a9sB4acUKOxHBI8mCk zA2vX=;=f6U#NuW>dnedBdqMDU_rfP`P6b2SUbUz>2Vb%Hyu9;;No^~RtO=W3mo>VG zN9dW+Mx*ssG9ADi>SgBAnOJl{1zRZ>1n<&3uB7mLVhfKBN(z{df0j(U!ulxjNNTEl zQSc(Lcc+RJme-;S`Ef`~#TVt&5XJ|3XOiUnv@IdiYs^Ed%3g~~QA!%4 z3e>|(hvj!e7MD1L180RDM+*X8i>Y03go`43N3i#LreH5ITZCHt3pz|*6}kYWfNT$8 zFmY9s1tDp)CyVrUrffM4-k=Cd7cz_sD0ij&GWEdxa*TrxeGVz4@On3Ypdhp4$wn`Q zD~9C>w{kXcD*PuPMKQ7AT{BDY_sGyyD4jQ&isT)9XbG6Gqv#iJ~Vz;Nb$9GjSkzk4zsqBS;b=7HZ^4~ng~j+ z^_2*w%~g#jfK%>NjOwEVV8K$T6x!l!|E7--WUAOH^64oJ&cue@3Erw#Yi^{Uooh_i zYw$0YX75gFL67KN(hQgXJG_j7m z8dDFL<{VQHNdt4^{RA+1aB`n4Z*@`FkOJ~}qyIsL`|-Q{t9IOwvcq@>=A8eJmv8t| zUzjo;T5Ujb;_W&<*x_uuG}T@>Mlr|qY1bTAq7R%>xE7J3Ro@oc3u5S6s0wvU^<$oJ z7c4K3Z`+jb9O=ou>QHZepN`#BZWFaLbx9{yQrQ|X+l+Krm(Yf)H)TE8WufXjBeH^R zq7(97=SN-_7r4m3byfVKJ4CWB__86{wILcF{CMold+g(z2zw*AQ_%_tyMv-5dp-o_ zd2fKbg}WOi_Msq3Nrh0LvE%p)%(ybfEu1ZO+=ad_Zo-pJ(U`T;H*X<3#49xA7A^)b znTLDFjgLz8-a!=>K|HDA&Bz>aqH*U?QF?{WNU(KI+?ik6z3;LuhU!#iZ=3KF%ZFI^ zNBr!=QObZGh*I8A@IOxw{eUsqH78kdt%IAQ`;u)O&wWUQj_RzX=|`GaZ*(F)>1yu+ zCktN`igpur%Vd9;7p^u{YV?eQvz@vw;9ZP@JOn{Atdj~8}XI@Z) zcdSHHN0@Ps=~{a7CTiz#5)L*ScR&AgdeFJ!v^Pf9o6mUWoLWI+oM*Hc?b2dL#X2&t z^ll2Un#w+nZt76PIb@L)ami=Q0V(ngCY_ZCUf5hE@bAPMci*>H?Mb7HIeb}5N8hem zy%OksA{x7*jBl-j?DE80vD+)k!hFciroo37z+@Svy+GcK#)>rF6heGcjCZ!mAs`+n zvR6jby+-GzkSFm4l}elZJ?7PWgWil(?8=(7%9X2B;I1>~*$aZotE%N_&f_3lvvDT+ zyf=EQR9b=FvI0}`T(|czWrTIBExhq*Q%uG2w~IQ1%1L59A8(=mLkntsWC z1O6!uqha~Av_b#?u>H{_$?->NSkd@ByxB^{*un8VC#+B~ld<)`?UGrF zoVJMkaIZsC%UEGIFwx+EK+C2Gq(p(DKnh5KM&$l|y`adZp2oUHTR|O+x6hE*AI)a* z;_&40%oMLE0A_s69uPxUx(IC{6xPqjPba^7Gd8r`JuO%QD7H$Z)@6D0R#%3We^*n2 z2wtO5I#U^IUKbE&E1sc(9A>sY(Yaa_s3OU%%O};ahuiL*4Zj*8V}h>GX{`V_a1lm1 zTP)v3ODay)<$xGmpI{fT;1$Gz7ueFLvL66D7Q70Z14AgWUSDtctFxqUCx*);N;7(QJLK{s2-?pl*%){&w7n&*I z@4o^OK%1TpqcMjz7kjK@I=RLmVVuIL8VnRtW|pH`3$$D*$lD9|{II`-Fie*B7F+Kq z3{A+EFkqf({8DUTI}UHtaa@Ow(;QXYLCfr>-S)(ArxY(a1)tx%1UI>v27(HX4c%`| zwaT1_F`BrW8k-p8gXahi|K_n2Zyv^ZrXtKXcC9TA)G=Cwxejn2kgL*2wN1qWy@X7~ zD$j6|yxoM&BawXCtcct)QQSjh8RZWrnp!f{u(w4+Oj>rIcwO-9To7WbZBX$A9e(ra zHsxsP1`}-pSLR2k&W}KJp1BtUQ+!{(OXos@tc;gI?Oa?r#jy8*V^l)7Uo+qoF7n8-FU*fae21k zKJ%h02e`fL&8^0n_BvOHGG;B;)aEXNZ7A^ciVUNqEE`p#kG+cAB{e;lT00_2+Tis@EBP5-N}No z&G{`3=*B$(HoE{40g3Bt9WZ~XgRA+O9eWgFH++@z^j#G~p>~GvD!&}~8>3qZTwQ@LIoTx4uRxQ7$wEk-h;9+) zRNNPr{=tjcizGIJP-lFCTT_eY7G%SY#k!^iq^EW(*O; za~8%T6nJSLWt2<{yL3NByW(hiHpyH9Msy-A>%7q0#Y{)xh86t0IXV@*E!#7VqW&0w z80rO_;`1SGQ35AI+` zM8G;n^{SS+V1xCp-N6Xw>sVpKXl2BtJ?8u}TqXML(HvTOdSDWJ<&a@sBnYO&2zk;` z+eEUa$$O~6ws*j_Y-5Bg7Cp&Wp75U1MrZ7S%53&NC$fC|;O&<0royCKiJMf*i!n4pV_nCM3u{283j*P;X zcS}Xc70z+RWt^RXe4rHduS-pSwY3%q}6P=lKaW;o!+fCX|9_84J>jXnx1`O#VHQgn+Rou8MvhtmC zS>l^J6mKm1eJiFi*W99*Y5hh|j4{AwM9w9R#Nb>AzIBZT_gYVan?&}&Tw@n+(czQ@ zcuShN#_4rUc2(i0;2g<`sZ6*yNWn4}=qY-m0(~7nnaw9`{ppp`*6sV2aj%>dVS zZABc*l))MHQk-7=5I=cvuO8RT#=BOa-uPYAL&9$TA%X8PECMB-P0-pTpijC#2b`s% z6AyA)PHJd>;CpfDItN<4Pp__Xr{Cu*w8|U0OIUX(+pjr5hK%2m2i0ty==#Q!g)2D) zW|yfdwv3`5W%-rf7Ozk?56(6pdhPHGs@i~W8X+IQgP9fUQrL)A@S2|Qp)p?4L^CR) ztEATdxTTsE$_`nOq^3Pfpq>kC;A^#$lgOm?6opEyr&$P`tc0jQRX;nnrn<0hMi+CZ z-3Jm47UCKNHjNIVt|wEP%95jMTBl&;l4JlaE8yAeGqE#dGhuNSSxOHpVgN9bMzAd= z$Hy43^_0s=P&S9=mN!ro{hSy_u3!qI%*2t#)+&-jk?o;yQJvBAK^2Vl^R?dP zu!hdv$2IB`w}tw8RccD7g?gaFcKmYQ$j{r&owhx0E8trnV7ssg*$A2{g?K~(b$d7+ zv|uTKH`vxPTu~uBwsltm?7hE#G0so)=^Fit%{80Fbj)Jo8iF<&mzN9_DaxGdfhgB6 zjdh)5YKyqX@@Un>_xOO5nIKh47;-=OCwk_uj?RWd@bhQG<9xIxb8SCfQWK6R z$D9KEuHhGWLZ*%#@4gbE8v=g=fSJzyc;rnhvcuoa4?9!apBm1?^c9TqR@4q0M|pC* zB~p^J;X_n2qvd?wLD_qv9?#B+-W zfR*f>4mj`z=5zBW;Swj!HbCO(H}ml0>kPGj;Qn@nu;GP{-Cp`cx5cVTJN_&`O-7FjmjsEm}Fj0Ba%6fxZ$vNx6jW6Oag*a zi1bj37_^r5n8}w>Wg3}FtTBJUB-$MnQC9_N$|TW!G}t7Sd(xTnZRoJD*Q)&rbar&Y+YiU?whQ2V8RgY^~J zU5<#Uek@u<9sxkkCE_lH6!JnVpOn~~Bszs1q>VDmRP75~VSZM#cf8GBrXof&D|F~M zX6Ug*ls@=!1om~6F|Cd)Ayzn0M6l)x;vmvVc(c(Vacrx|UxZRH0j0TuTfI=3V%E8o)5lpbUp<9oUT!kWHIQjXQw(^$sH<)01*&yfweUY3d;#& zRkh$HbFVe1*?tALZ-UeF-B|JPz72NC2KK0?~VMO4^@X=Dp4PHcb5rWGS(@Xk$Yy@z!y%1vcG($L^z z#a}hUS%iJik0mIsaRZGJL^|=zf7rnYIX2UILJwKq%A@VE1N>6~}Wu^fe^e|mA z)f>WoaM*|IXG$pw?e#F#tB>d}1~J$#?glN$F9xX+Y`vAPBckzHE|zEUxdTr>0H3qg z?`ymvJ+Bre7C&CxmKh~E&sehX1Xyjfw_<`C*mA5vkU2xX7A%($Ww{a?&8L(Krc80~ zRlFEAi;LJo@8SBp$i)uDggzHr90)T5_t>{Crs@J-+TE5(dRh584(eqMx%Aj75SOpmYg8Oq7+@KSlE|jcdMk47fdgEF6#b=@E z5(?^WkT>ClyCYsKgF<%SkO^D2o?bVy2sF~PK{ zmAgb*M41vh%5?TPQeRl~t}t&^U6Hf0Xdw-K0*VjJDVbBvy&p8ieq;6wirWHIW6ZaG zs=T4RhoNFXE7#ME{;~_`t~i9ew#?s_C&kOi17w$cp+0z_(FD8^N}OV*vZ^HCySPjT zZI(Jipi-pMUmCXGo?q(&Hgke*!Ibd8pyZDjqTnimr~8& zn15cc&37t$Q9Yr0*e$s!{_&}g9<_uR3|9kGMX6N#-56!jU%j1LvdGiK;mFV~xb-8kk{ zhl>k4K{6|p9z7VkY+PaE6tyYXnR78MPIFu=(kT~*JPh_U?^CgGq= z#v9Y)f$ij&-&xlE12IE~#;^&?a8#wWv!u)+;;UUad_*&!4x*<~RGj1?1$)&q6U@l3 zU8a91OWqvBQSUD>$HskNv=S9)*eT}OwX&win{KodePUE6%=x6 zij9Rh(7N-=_88aeRD}n*#1l7vT zstBp$>WEkJ;gYWt^{_?=&z2ao(AI1j*+#+j7Y<2AI~EkYA2;>wm=c(GS97yxYyCLq zhhw~`)At>U=BZRE-z@i5_do7CimJFxx)_q@e0QtQ(P?_N4P|0=cH$Abxrkoz=Gj*T zS{6w?d+?w2Sc0RhMX)167h{WuA_l+Q-2v2WOb%Qnu!gOpxCYBJgsr;=TomTO)$=Yq z0c4>Gv6SJvPz}TyXy$iQHw29? z@anL9F1dHPy0z^675+!6y^kqOz!=LuoZ);g77UbR2aWhJV{9Y`wn#O$wadfadt%?y z%aCV$U6_z=k%DL5YsAD@-Bs+ntmCo-^q^;IXZFnT?W&-__7!`*#QB)ZH71eKUA92* z%pUp70~N^~w#gf798z~k8FugsM@4cXuYO54VompS1?V`LuTVuA26uc#d%NPKB;=1_ z3xRB$ilR9}d63?>74`=aO6vY)vyTcZ?O*c4QKwY9cfOR{d62IoZO6;{?ylZ^ZDzl? zO|oMzBqjKq^fil6XS7#QOA=OgWJ4`XNfYK!Qap<^R6Qv1%e4f83$sGQexXSit7_c5 z7IPxxK3PhrLmR>9paogVsC+fTzJ_q(*n-?9wP>4oq9(F@wUS_)Mzli+S&ouWn+o)P zfJ36EP@69Nz6Wz+#y;5=-2PfP*>kNM88?nZSH!ja@w(SA<)b&eh&TL@HLPI|X19p# z!+E0Oqo3iu;miXw%1}+*zQgc^jo z%Qv5&Dr$wPV3lw0`nJG7W*zynzq6vbwVl=9PLV8SZCgZ9ByK}adxJ$1YB;b!1TttH z&gd~!OuGjOJh{X|1QGa7rPXD^hT6@hMaz7ytDczcrX)Ns@le*n*V1xR6IRSM`jMSp zPS^8w-k^Xj*ki+)moLwi-ci^r(?mPe&Uf9f{%=G6&@2}>647VYZQiDW|Dk>Ujl zab9SAyMvP%PkV7c!LGI&*{Z{2K8-W07JNH9W%tpn9+y!|l?np8wxtF%8|*Rb#0tNu z!qHDt&IeI6tJTPhM28JHi2^o?Q#7JJBMcg4Qu@=>@Mw17fX z^h=1QA71z4QLYnu2BvTi>)U4_&#_VIHKOm0^f<0S5T8^(mK?~hT+lxm(bI($pkwvY z>x3T8FI5#6dOUr(Tu##5woi_#{PHynHE0XBJPQyS#-DxlLi5|QjJEV_8I(!vJ~1Ww zMmwK5!1-&sJdY-KK#p=)1JK;#zU{}!@*YPZLqAj;2&_riua-SR{DUa$gwoEi4T5n7 z2H-d7(Q@i~18WXNQ}PZ?nQ84-OI{twZnx;4*jVD`hua?ez0bK5T3XPpm)bA%^;_#O z3fp_zDVx`^eXXVv3+sB$F&K_cs$GlQwLetnI{>KGlF`k;rhL$y-eYW|rqgM{tVVY7 zGAK^&YFEMqUQ0U3Iw-!y)yRm>7O62|$4s`Z@ZQTjb+&17fn`vx*1(v2u}=qlJQV@N4980 z4Dt|j4e(XcE5*Re_!&Yi$)K22_h*!n2+jv%gHInH*)fP;UHDFxD$2^{Q40@s^o=O) zT&3^|)-;Q}EHR!H)TlntUQH2z&~E#GP+b((5I;bRS@!~f~ogW z?uzi=W+nMy=p?mwcg60He-i%a{%lrqde4JrC~jl!ByIfevgq(%#v~_jUY|^WbSN0GM&^W^~*Op+Nfu8-`)e0Uoi93|Dtlrp!;Sz6@OtPPRwZXb zKxq=G+R5-((QOJn+irVZCC8_1f^z|&ZjSrZrzt+rXZ8Syp!IELi(4>w%e^gp;Qx$+ zB*NS-z$o>ZhP_{T$BQD^mIzKnLKsRSvsH#J@U~rCnhVYbYS1Y!=ZE6y>8(vzVhTO6 zf=or|5ArPoIhfYn^k(6B=l-uWNfcDYf%xa?$dcbNq8l-t&yn^&^)+&xpMKku0-hyB z?q@IS!37W2*doc6A0ii_Z8jTm??M+$CV4V~0%b=S%VE8x07pB)nQ}&Fo9?lQF<7g3cYMxr2y0-$&yQV;iMa4%^9*BeM z%Bx^Zqj~1tYxbo|FqpcBMW-qB#NX@i@96uU9ey$rivOTA$X-eSuYFUtgrwX{7@SvK zj6#({LgKSHWD}8Jm6zH>v1r~-wW$RYEQ`OE)6lEI3Yy-*;0irl`NaD?{na_^;cZU=xXNj}kjZbFp+p|BtVOYeFr$(r9M%TT0c_;Mg6vs+!6eH7N=CBH%+;LjO${K6D+?JgVLA)8YP2IBCMLZ)W(Nvpl z*4bHfd02tBX|gK`dV-|4mJ%N%dSSt#68dtror5-G#+hIoc^`c#XBGVwnOb#(b-r&m zhrUwUC|bYlh!*=xx)moWLkCfZKl`aZ_)}}d#U;B1S%1DZCQkO4!)g2*9`u=MBgG!K ztPX^;PZ)tUAJ+y^xngB86@0>CQ!b}87kK!>DN;okEf{VdRURG$A~5c)jpRK-D#Gk* zPixJkFyvYvMBIRFBTF{+cYCeH7hiu?dVfK!zVA#BykdamxD>e~V!3?6um8$srWbVF zF9HGpfcVF-hdK52SgtqlF*@uw3lBq%Kd7q znkGd!o*LOb>o!J`Gzv@DBP%3tPYgmsc#;gG9a}$Fb_=I3IY(evT^+-=aDHc^oPBcX z2vL|gW7DDBST)z-j5%?c+GG?oU*Ky{O(j!F-D-CVphaLWug{K>0P8D2nj=ZzwprKX z%Z4492MZ6JhpsoiD2c5YJfR(MG<-du}iRk|;Fj;9!5kVg5wHgns+Mkz#Qkqyn zZ5sJWKS*J884CJ1AiArWN>xqUC1WFE;cZ@$v6zvYiTk@Kb5<9f2^cY*=LNUv)JwNx zx8ud@^W7PzFIF=e({Po!%zh~54seZG`#UXl$&8(q?3ybtva|kt3)L{&rlVHxh7k?a zP^~V{tgO?->{)s<<@W>4>|#3Vsw1Y&lWH0)*Dfz)?bggU=&oHQ_wHEJP}lrmc%#(Q zU@VbP{c_3Ru}@6>3cAKY@cL*R^xTS8Ys$fV6yCXdXb^&8^U}0!0s_uu`?#@6GG-f% z((-z0(syl3rntgX{(zB`p@Lxsa0yWSyy(GNK6YQQh!I%|T{5?=TdX{s_J713BlO!1 zvW~4+hjBFJ!e%>(_hPR{DfG@k?dCJ$4d?3MR$=y01Q@Jl+hqjPiIW9C>i80`HH;OL zUPBzjh2n)jL6x1K95I?xLlgA?aO_{qD5m?^GlN!|Sb z(7J!fRBSzCy+hC1$PbK4lFqnb!bCnlKS7S*+BF`Yt^(d*_I{7Lk!YUS$S?B5DbX2h zw(fV}nyc>G&Oe_W^_o+=N9`8MjpkVh223!v~srlH8h ztlZ1Gp9|T{frdS*8N|81O1J9KM&)>z4Ikzb@z@kcUbevw(wA}adB#esXL{Ut_0+WP z0Tv4MXtH6$zGk9|Re?4=>927{QTjkJSAi~@1)K>Dq zoej0gQsG)LjpY7BHMGbHJCC1H-y`TlQyhE%G8}OJ9hcFN5lpl6?hp|CM{jb*KMFek zuyX#rZo1xYD44=OZz!8aXT@bV{8}Z@#eghp#gY*FV|jeqDK;mCz6E@NflTT#nbarR z4V*ARra12W&%i_jj0n)}j4nK`Qq-=G+0rpU^ zpsVD!?h0|X1d{S1aKgy8N25A-$fvSpTn#(ZbZw0B?|Dy$8;~0SN9K7f3l9mfod}$Z zoJEyVLm8nT#9Z?FL|oW^IMfBz)?kh`9jSTDqot(}RJp13!SEWB^+F$HZYcv|2ZZI6 zksSK8T=s%E<{2VArm2nwAZXO~X1Po-Bu^K|AE$5e@Fb1B*+bOtCOYELlMtxCs)4gT zJ){Az$fm!;CIJ=EkGp{fhmF%nl#*}1hRA&^n&*ceT$v=2#Yi79jOO65L~3&w+K4+_ zh0$MkZl-LehojE+jpjR7o`OD&FpRq@T_Vg@ka3jBc^gJ zp~Yyee%qUKL^e}gzamuHxeh!E3Q4Kqn3Ck?O_`u4#b=Ralhnk5B7z`Aazou8esi~o z;x8J#?)&F-T5J{rxGJ|w^ zNEbJ5y#vCXV&Ys!hF^_^k9-JjFI$Bxx08S@as|_iwu$hQIXO~~FBOX4b9XjfFa+GO zrhEYwFLoV84i@;lRNUs=-`pyl7nXIaJ%~wy(aM6Bk29$4af_VCRkIt+p)Z}z@lB;# zMjtJj^+nF=wu6&kbC1(6yMJW27bV8~j++i;gAS>V$HITrygC2VX;{T4JUQY?toekZ z2tzEy+ir1PUAW>75akY|Y;862!%@TiXTa!{r&Jo_Zh>talNMOIw_Vmo@&MLj?O7q3 zteun8VQ8*s=T6~dOLF*8wlZL4`CgzP`6DEmgcgB_M&1hfBsrM^Qm`m8dGa!Ti)D^Y?2hIA`0?|riVS4<|gxs8eKzxR{BSN~b#fA{_Op5MIx`Dd`_pK83T zV}2>5?+@{Nc<7(%BK%Sl0KoYFsQZ%|_)qmQeyd;dkM;jIwea6@V$$);R^HRPK)y2) zQ~!o@^+z0jBNuZ+5t&%H89? z6T$y8xYBr9!jJd&V(~r;8GZw&e7{KlKK8$Z+t~iRO557}ZbkX~xOhVjU_!pj!e8E9 zL4O~Yp!f6ZKjRDj%v1koXxZrw4TSe@3%(EgPm9lA<%H{x(6&a#isl~1!Y=w&&VR|) zfA6{J_AO=m`^c2MAHu))TubOr@FM2MRz`pBd2C4qCm}unz_~O4z)y9>U&UVZPtgB; z8~EdVv7kGYIK~427?b(?E4?=R6S}yKqmzTP;lBc{jr8sQJEzd!2jtdaWencJo@MP`D?nQ-(NC)-2YQ!{|x^t%lOYr*ffkJ$gHz5YA; zuZox7H?_ByKcW9;z0==Y`1OMN``d+h`(q3LS)KFuCVmxBf2LQl-|1p9D03iSHF5d$DFI|sIi~s-t literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-debug-all-5.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-debug-all-5.1.jar deleted file mode 100644 index 34b7bfada6987fb51fe4441a682e15361ed8d5be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 387750 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

n8#1vr6p29Y3OQ*AN^L;w(q4 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..031674ab644472caec03d0815a30f17d80b22c98 GIT binary patch literal 50283 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�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 literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar new file mode 100644 index 0000000000000000000000000000000000000000..1047ab3e01fe00d4dae636329e4a66337022978e GIT binary patch literal 80707 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

A)$R(z(Gu+HwsmC$c!y`EFs7If={K*Aclx26V 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 E0FcirZvX%Q literal 0 HcmV?d00001 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.2.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.1.jar rename to src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.2.jar index 19714bc92e42e00f664c91e6147fc106aa6b3b01..6e4f6e6c79e1cb510949b79f65d6d5c120ff0d76 100644 GIT binary patch delta 1389 zcmaEMlkxdYM&1B#W)?061`ZB}Jd>)4ylT8aDxlKWH>Ze^fnm`^2if|KdAAJ&?y|m+ z=P1bxm@v)9b=u9P9l|2M!WA0=S#J7W@>Ft|$mGfT_Wt*zKE|eiac60ap}qJg+>;OdIeUV_--W?a^`2;f<}Q-VSyUsj+1BhZj(Q>#D2Yt z=Ct=#@u~3-R!7c0QQmUS(J)u}Tm8QSHjd%@MXH&!ZdGXImUrFFwEk}+7FEYP@s7^s z)MLgcr$4pRo~kn?rt|8q2=PybzWb^&c=z?{xB5)(b$^w^Z(O8lG_gKvbAL2{uj97D zx*~Ud@#T)&Kd_{qoN#1scKW5eJ8zmlNi>vumza3qTMbk0OChl-$F)meo4PKESpT?Q z-0E;l_p#nrs>hGcuM}#`;Zt#YbVF41+NVt~Q`mCDx0J@Egm#KL+)dMdb86kW;+qqr zyH-p7TmHB)|BglGr|swAet&*>{9Nbb;r~Q;S#JNEcRGL1?wyX++uFTE&i{WM z?_|v#ED;m3hFRFa_tFz{M4a>+S8cw@IESCP&A4iEh2Sn`50k3Nrb3EfI#Ngg3(QDpsk;GlLl?yDpTPoF(`Yvh!jN)a zBMKH_71o5PIT^7U;-Ui<`yh-CV_jBWMkWzvcp{v9EZGD#6;5VPF=Yk@#bo;wX~wgY zqf?Z@;n4`>nI0Fy>-3$gSP?~{3fZ?yBrVs-|eo?x9fH%S(bR9q?Pyo{5 zJ6RxAQ6625G)xKD)cVN*sahc4O|DIqX4)k*d7`G`>G-;+K5@7uwEchnpi||g)%z>Emq^6hu8_+lNxfvKN zQOt3ZgKFTKd>}_i3%Ad-;Mzbwo2(4frlW%%6scF=HS7U~-X)-$J>VKZ?!61vFu6Yi z;@5z5X{P^bATuUwD@#q5Rp6PtKb;5c4V_GBCUq^Kl-uO~Oo-5)3~8o!+F;fF8A6jg zGljq^=K)nN(FF=SO#Yn-34?P$b1Mv?<|=>;0Egp_M}8VCK>z;(rVdXOcNrOj6~||3 zgN^jhmS&o34ir+H3<}z5*$|sn1BK0O;KHA>A-0_Y#@N$9urNoOGS~p#9BC%OV7SVV z97VA3yDVv@{Si=Mk;x9(5Rdf&g&X2vsukTbQ*%=El5-M^ivzq_*+34J1VK&)h8@Wu F9sqnI#N_}0 delta 1442 zcmaEUlkwS2M&1B#W)?061`ZAeO{Un1ylT8aD&WIKl{bZq3=B&qI>^=^^m}X|u-E;R zeZ;NPN-5XNJT6!1YjZ_0y4r4W>bPxED(u}Sdy_BfU)^%uR;3%v?DBu^otgdId>?!I zHY>GX3!F{vX(~ya-#mNW_Fb3t9Gxbt^Vt+7C@-~4_ejdC6^d7MU%$N|@m=}bv+$$G zd}?0ROs-w3&z>wCt7Prs+T*>8v;Oxf<->?&6EQuPiyl^NQ(+~&7%Lh{$&KMW`D{emBF`t0~W% z-}C34>sy@nP||Oc=BGFJ^4UV-ekopgk#yzl`@)oird!w_e-Lt?aU%Mqk_3TW&6r=wc38dZA|5H5sosPg_lGyLA_;q-JTw)9F{fu6*lXUAKNV|JE|~*)ukD-{t>3 z|H36l`RMr~H=BB`&VPC%kBE|0jIjZmZ!^y3XI{=2JGoMD7xQBvZ6>4$rlW-P!E}$1 z1(-fAWFrWa515m&zw!nH149@v2F)fX$|+6m%@&_*8T1IGYV$^k`K(|DoA3%SWAXxJ zcd!7Dx+*i6(Q3Gz5zKg{EDsU+t-To{Vxn~f!q}*L5h7)8oWTNC+#9FM$_-0QAe+ua z?1R{}%6u9NAIN35uW4+H6=h&xHJ&Uethc$wrdSlLRW5inL}jp?6DuzxlL#|BNlreV zY=W95Cv&8jG6O?qvO|hAqM?^z{=U76xJ%Skjn1d0vWAAjp1@ z7!y>21*U*OfZ?yBh7bcoeo?x9fH%T+bR9q?Pyo{5Gg&ZIQ6625G)xKD)Vj%msahZ( zPOeLpX50zn$xTksVwt=rl?N>9pDoS!11{Q|tqc~`O_OF)5t+;wq&WF}7U$$w5<>iF z&YFBWRhsFTBwUHTFwbPUG>DmhfVvCiCl{vcVCXuPF3q$XB&9d`ZKlLz-3$o@ko&iv zJ#7>OOe@B~pz(scpMhaZ<6|YLVlA-3)T{3r_5c-KVr5|PKv6hX1*k9#?D}09(oFl+ zfn2-EOEZMP`of+vd`ksdkO|c5f}*cf6R1#Ua=w<-E-_hOlkAE85k^46lcZ372in{7GY%r$x4DCCj-OwWDpMk)uG(v diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.2.jar similarity index 93% rename from src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.1.jar rename to src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.2.jar index 42374bf1781b7c7f5054cf53a93c68e7f3ed8452..34e9474468b55533fb520697e8cd6aa168374e85 100644 GIT binary patch delta 14114 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 Thj76xv6Qr&1Zzcea3Ax3^BKpv diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties index 715613ee5..b5bb4c414 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=An easy, safe and fast scripting language for Elasticsearch # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=lang-painless @@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties index 22068bb58..14a39cb7b 100644 --- a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds advanced field mappers # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=mapper-extras @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties index 898bff7b7..2f51173a5 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=The Reindex module adds APIs to reindex from one index to another or update documents in place. # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=reindex @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties index c2fe80f0b..cec2d76a4 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for URL repository # # 'version': plugin's version -version=7.6.1 +version=7.6.2 # # 'name': the plugin name name=repository-url @@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.1 +elasticsearch.version=7.6.2 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.1.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.2.jar similarity index 81% rename from src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.1.jar rename to src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.2.jar index 1ebc7e363e4f4e3f9ffd98986aa915f61893d81c..99a221f2a2bc80ce4ca801e7a34ebfb50c38591f 100644 GIT binary patch delta 1056 zcmbPUJfoO5z?+$ci-CcIgQ3)?L|)kFuaddFEtqLFF(u5%V; z%sRj>?Rep~SCl77dwWx_#(%l0A&HSsra;%fRx#sbLGwkh~ziLH%_gH*6K5R|W>2ei)uJa#K zL#!^uIxU{=GP9xCx@6vh)9&@2atflp7E`xbd*)5)+~42Y7w714Y+B7pP4SY*x0R}{ znn%0VUVFMrWdEl(yPN$UudX@jGA~zV*~xbc0y&OFeysGh%ah$Ab@JG*n{s<=tT5hGuKFPOdpu{L$?CmHG)b zeF<$xdTJw+mGy4L6}bGiF}Kf1ne_KiiBzguQa^{@V>zi4jb&3-eFOU>VAq*s1p zM?^!vaaF*UEsxrA`574EbQl;mKV$6YXKpjDnp`2ciy0U@lTC#b!E~gMKA7$nvH{cD ziprA>gas%66XF5!H}eWV;sr}g)-wasXY?Gww1B=VSV4sTJQi-G=$|}UPkFMRBKu?+ zMX(8zwG|z}8uAofz#8&36_ zKp*o?UT+F?aLKA5oJBr}L8znL@>qcF&v$qr@)3ZMke00c}R0th4_6p$2P`0Myg z0j%)79{c1h3yA(o3uz{KMX0dQ5gfO3_0N6*0meNeC5yHLtvN~w4$76el z8qgZ)$*Z9*2l=NLB6MGoYw{ncFt@oh(*>9?A4cGu21<*ogAKZ`C^~taCO3wX1fUXY a9jFo&u>fyYHc%)C0bwsI1H)Hi5Dx&%C}7n9 delta 1117 zcmbPHJiVAVz?+$ci-CcIgF%leb|SADFOUkjcv3~Ikdc95%|r*SdWTs{luoDVyUtm3 zg4^zfM%TS-pQ4l;CNjx8e)_)jtwrI4Zx@*P=iIz2$@iUc&Ar5qFY3P*%nfxhh!ZnE zoKfH)t(Z1pU8%{6j?c2r%!;qf6n<<=U+g(|+kBfoy%#V382jF<$-Ob9lixW`H15Uf zCB92mpINq`W1FCL{R*4F@bg{uHco80HjbyKDt*7TY`OA=rPl>E8=h2M9us64U%bv` zZOYj!%Y3PiyLIX+Zb;Qko^P~sdVIy1y|e1%g%WNv2PRifheX?Lj`^n!Haj&PvJ>MYmvgFS+|M_NXN}H=ZOFr4%jG0hx z`z>L&jpTxrte<|eSzg&Q(PFiSHE|@<)8m2tbBgdmh}4u$ zJ>o~i!YantfGt}dwdL|NFvRIFFoWZvTjmne# z71<}tDnfMVC^~}03lv?!I(I0}W8r0F5@Cj?oXIRECa6hgva5+HGtf7aYfYpX&rF_a zq73%LejqP<@@*3(kU^77rA;)17#Q-4()9zpQ49=V00Jfu0R%uLP$0nY*U?94@-tp`V z40S-i*}{!wVA#^Q0<3oO2Md|W?K=Fxq=6DHllKFSOVWfm)4~{R7H%iD=>Zk0gT1#K z=)L_QuJq*D=G>G2nL*slYc9>itPd6D#|YG@+lPO9u`n>W@G>wsqBzqVrb$bLl?@~# O1cbe;3=Ch4K|BC#C|olD From 3afd6fd4279722846a4f665db3e0c82482d97518 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 4 Apr 2020 19:19:26 +0200 Subject: [PATCH 0113/1191] DATAES-782 - Make underlying TransportClient accessible. Original PR: #421 --- .../data/elasticsearch/core/ElasticsearchTemplate.java | 4 ++++ .../core/ElasticsearchTransportTemplateTests.java | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 740a6c5c5..6b94aadeb 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -343,5 +343,9 @@ protected String getClusterVersion() { } catch (Exception ignored) {} return null; } + + public Client getClient() { + return client; + } // endregion } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 6f3126627..401b3f19c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -131,6 +131,13 @@ void shouldUseAllOptionsFromUpdateQuery() { assertThat(fetchSourceContext.excludes()).containsExactlyInAnyOrder("excl"); } + @Test // DATAES-782 + void shouldProvideClient() { + Client client = ((ElasticsearchTemplate) operations).getClient(); + + assertThat(client).isNotNull(); + } + @Data @Document(indexName = "test-index-sample-core-transport-template", replicas = 0, refreshInterval = "-1") static class SampleEntity { From bbc9ec213aae154d2383d7f0638d12f7474c9852 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 7 Apr 2020 14:40:41 +0200 Subject: [PATCH 0114/1191] DATAES-784 - MappingBuilder should use @Field annotation with custom value objects. Original PR: #423 --- .../core/index/MappingBuilder.java | 30 ++++++++--------- .../core/index/MappingBuilderTests.java | 32 +++++++++++++++++++ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 9846e8f6c..9b47ce583 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -197,37 +197,35 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject, } } - boolean isGeoPointProperty = isGeoPointProperty(property); + if (isGeoPointProperty(property)) { + applyGeoPointFieldMapping(builder, property); + return; + } + + Field fieldAnnotation = property.findAnnotation(Field.class); boolean isCompletionProperty = isCompletionProperty(property); boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property); - Field fieldAnnotation = property.findAnnotation(Field.class); - if (!isGeoPointProperty && !isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) { + if (!isCompletionProperty && property.isEntity() && hasRelevantAnnotation(property)) { if (fieldAnnotation == null) { return; } - Iterator> iterator = property.getPersistentEntityTypes().iterator(); - ElasticsearchPersistentEntity persistentEntity = iterator.hasNext() - ? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next()) - : null; - - mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty, - fieldAnnotation.type(), fieldAnnotation, property.findAnnotation(DynamicMapping.class)); - if (isNestedOrObjectProperty) { + Iterator> iterator = property.getPersistentEntityTypes().iterator(); + ElasticsearchPersistentEntity persistentEntity = iterator.hasNext() + ? elasticsearchConverter.getMappingContext().getPersistentEntity(iterator.next()) + : null; + + mapEntity(builder, persistentEntity, false, property.getFieldName(), isNestedOrObjectProperty, + fieldAnnotation.type(), fieldAnnotation, property.findAnnotation(DynamicMapping.class)); return; } } MultiField multiField = property.findAnnotation(MultiField.class); - if (isGeoPointProperty) { - applyGeoPointFieldMapping(builder, property); - return; - } - if (isCompletionProperty) { CompletionField completionField = property.findAnnotation(CompletionField.class); applyCompletionFieldMapping(builder, property, completionField); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 2427311f7..eb1de495c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -545,6 +545,21 @@ void shouldWriteDynamicMappingSettings() throws JSONException { assertEquals(expected, mapping, true); } + @Test // DATAES-784 + void shouldMapPropertyObjectsToFieldDefinition() throws JSONException { + String expected = "{\n" + // + " properties: {\n" + // + " valueObject: {\n" + // + " type: \"text\"\n" + // + " }\n" + // + " }\n" + // + "}"; + + String mapping = getMappingBuilder().buildPropertyMapping(ValueDoc.class); + + assertEquals(expected, mapping, true); + } + /** * @author Xiao Yu */ @@ -997,4 +1012,21 @@ public void setAuthor(Author author) { this.author = author; } } + + static class ValueObject { + private String value; + + public ValueObject(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + @Document(indexName = "valueDoc") + static class ValueDoc { + @Field(type = Text) private ValueObject valueObject; + } } From 89944b66c4b9c701877160dfa378ba114c3aa5c7 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 11 Apr 2020 11:50:31 +0200 Subject: [PATCH 0115/1191] DATAES-788 - Add missing path mapping to completion context. Original PR: #424 --- .../annotations/CompletionContext.java | 5 +-- .../core/index/MappingBuilder.java | 7 ++++ .../core/index/MappingBuilderTests.java | 33 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java index 2039f488c..fff649dea 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionContext.java @@ -1,7 +1,5 @@ package org.springframework.data.elasticsearch.annotations; -import org.elasticsearch.search.suggest.completion.context.ContextMapping; - import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -9,6 +7,8 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.elasticsearch.search.suggest.completion.context.ContextMapping; + /** * Based on reference doc - https://www.elastic.co/guide/en/elasticsearch/reference/current/suggester-context.html * @@ -26,4 +26,5 @@ String precision() default ""; + String path() default ""; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 9b47ce583..d9ccdbab4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -81,6 +81,7 @@ public class MappingBuilder { private static final String FIELD_PARENT = "_parent"; private static final String FIELD_CONTEXT_NAME = "name"; private static final String FIELD_CONTEXT_TYPE = "type"; + private static final String FIELD_CONTEXT_PATH = "path"; private static final String FIELD_CONTEXT_PRECISION = "precision"; private static final String FIELD_DYNAMIC_TEMPLATES = "dynamic_templates"; @@ -279,9 +280,15 @@ private void applyCompletionFieldMapping(XContentBuilder builder, ElasticsearchP builder.startObject(); builder.field(FIELD_CONTEXT_NAME, context.name()); builder.field(FIELD_CONTEXT_TYPE, context.type().name().toLowerCase()); + if (context.precision().length() > 0) { builder.field(FIELD_CONTEXT_PRECISION, context.precision()); } + + if (StringUtils.hasText(context.path())) { + builder.field(FIELD_CONTEXT_PATH, context.path()); + } + builder.endObject(); } builder.endArray(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index eb1de495c..3969bb537 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -43,6 +43,7 @@ import java.util.Set; import org.assertj.core.data.Percentage; +import org.elasticsearch.search.suggest.completion.context.ContextMapping; import org.json.JSONException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -560,6 +561,28 @@ void shouldMapPropertyObjectsToFieldDefinition() throws JSONException { assertEquals(expected, mapping, true); } + @Test // DATAES-788 + void shouldWriteCompletionContextInfo() throws JSONException { + String expected = "{\n" + // + " \"properties\": {\n" + // + " \"suggest\": {\n" + // + " \"type\": \"completion\",\n" + // + " \"contexts\": [\n" + // + " {\n" + // + " \"name\": \"location\",\n" + // + " \"type\": \"geo\",\n" + // + " \"path\": \"proppath\"\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + "}"; + + String mapping = getMappingBuilder().buildPropertyMapping(CompletionDocument.class); + + assertEquals(expected, mapping, false); + } + /** * @author Xiao Yu */ @@ -1029,4 +1052,14 @@ public String getValue() { static class ValueDoc { @Field(type = Text) private ValueObject valueObject; } + + @Getter + @Setter + @Document(indexName = "completion") + static class CompletionDocument { + @Id private String id; + + @CompletionField(contexts = { @CompletionContext(name = "location", type = ContextMapping.Type.GEO, + path = "proppath") }) private Completion suggest; + } } From 771d8fb5e76a4e6c4f050d9505a8ba9e3c40cf52 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 12 Apr 2020 07:40:52 +0200 Subject: [PATCH 0116/1191] DATAES-790 - Deprecate noRefresh repository method. Original PR: #426 --- .../data/elasticsearch/repository/ElasticsearchRepository.java | 3 +++ .../repository/support/AbstractElasticsearchRepository.java | 1 + 2 files changed, 4 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java index e56fdec44..56b970a6a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/ElasticsearchRepository.java @@ -48,7 +48,10 @@ default S index(S entity) { * This method is intended to be used when many single inserts must be made that cannot be aggregated to be inserted * with {@link #saveAll(Iterable)}. This might lead to a temporary inconsistent state until {@link #refresh()} is * called. + * + * @deprecated since 4.0, use a custom repository implementation instead */ + @Deprecated S indexWithoutRefresh(S entity); /** diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 92c6adc9b..864e7c8c3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -182,6 +182,7 @@ public List save(List entities) { } @Override + @Deprecated public S indexWithoutRefresh(S entity) { Assert.notNull(entity, "Cannot save 'null' entity."); operations.save(entity); From 41fffc0fa51c9142e17ee66c5824ec9d7dd67cbf Mon Sep 17 00:00:00 2001 From: alesharik Date: Tue, 14 Apr 2020 23:02:16 +0300 Subject: [PATCH 0117/1191] DATAES-789 - Make ElasticsearchRestTemplate.ClientCallback public. Original PR: #425 --- .../data/elasticsearch/core/ElasticsearchRestTemplate.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index cb8596c10..9ce3c5285 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -320,7 +320,7 @@ protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest req * @since 4.0 */ @FunctionalInterface - interface ClientCallback { + public interface ClientCallback { T doWithClient(RestHighLevelClient client) throws IOException; } From 39fb25cbb9d9dedde4d45d87a8065318a91a59ce Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 14 Apr 2020 22:12:19 +0200 Subject: [PATCH 0118/1191] DATAES-791 - DocumentOperations.multiGet() implementations must return null values for not found entities. Original PR: #428 --- .../core/DocumentOperations.java | 3 +- .../core/document/DocumentAdapters.java | 9 +++-- .../core/ElasticsearchTemplateTests.java | 33 +++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index f664f38c9..1c05cd801 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.core; import java.util.List; -import java.util.Optional; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; @@ -121,7 +120,7 @@ public interface DocumentOperations { * @param query the query defining the ids of the objects to get * @param clazz the type of the object to be returned * @param index the index(es) from which the objects are read. - * @return list of objects + * @return list of objects, contains null values for ids that are not found */ List multiGet(Query query, Class clazz, IndexCoordinates index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index b4226908a..fb1a491a8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -118,16 +118,16 @@ public static Document from(GetResult source) { * Creates a List of {@link Document}s from {@link MultiGetResponse}. * * @param source the source {@link MultiGetResponse}, not {@literal null}. - * @return a possibly empty list of the Documents. + * @return a list of Documents, contains null values for not found Documents. */ public static List from(MultiGetResponse source) { Assert.notNull(source, "MultiGetResponse must not be null"); - //noinspection ReturnOfNull + // noinspection ReturnOfNull return Arrays.stream(source.getResponses()) // .map(itemResponse -> itemResponse.isFailed() ? null : DocumentAdapters.from(itemResponse.getResponse())) // - .filter(Objects::nonNull).collect(Collectors.toList()); + .collect(Collectors.toList()); } /** @@ -299,8 +299,7 @@ public boolean containsValue(Object value) { public Object get(Object key) { return documentFields.stream() // .filter(documentField -> documentField.getName().equals(key)) // - .map(DocumentField::getValue) - .findFirst() // + .map(DocumentField::getValue).findFirst() // .orElse(null); // } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index fa83206ba..145a8784f 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -240,6 +240,39 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { assertThat(sampleEntities.get(1)).isEqualTo(sampleEntity2); } + @Test // DATAES-791 + public void shouldReturnNullObjectForNotExistingIdUsingMultiGet() { + + // given + // first document + String documentId = randomNumeric(5); + SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") + .version(System.currentTimeMillis()).build(); + + // second document + String documentId2 = randomNumeric(5); + SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") + .version(System.currentTimeMillis()).build(); + + List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); + + operations.bulkIndex(indexQueries, index); + indexOperations.refresh(); + + // when + List idsToSearch = Arrays.asList(documentId, randomNumeric(5), documentId2); + assertThat(idsToSearch).hasSize(3); + + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(idsToSearch).build(); + List sampleEntities = operations.multiGet(query, SampleEntity.class, index); + + // then + assertThat(sampleEntities).hasSize(3); + assertThat(sampleEntities.get(0)).isEqualTo(sampleEntity1); + assertThat(sampleEntities.get(1)).isNull(); + assertThat(sampleEntities.get(2)).isEqualTo(sampleEntity2); + } + @Test public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { From ff08d06c457c541c796149463c1250bc33d1505a Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Thu, 16 Apr 2020 08:50:16 +0400 Subject: [PATCH 0119/1191] DATAES-786 - Move the creation of SearchHit(s) from ElasticsearchConverter closer to ElasticsearchTemplate.. Original PR: #427 --- .../core/AbstractElasticsearchTemplate.java | 112 ++++++++++++++- .../core/ElasticsearchRestTemplate.java | 25 +++- .../core/ElasticsearchTemplate.java | 26 +++- .../core/ReactiveElasticsearchTemplate.java | 77 +++++++++-- .../elasticsearch/core/SearchHitMapping.java | 127 ++++++++++++++++++ .../core/convert/ElasticsearchConverter.java | 70 +--------- .../MappingElasticsearchConverter.java | 97 +------------ .../core/ElasticsearchTemplateTests.java | 34 +++-- ...appingElasticsearchConverterUnitTests.java | 4 +- 9 files changed, 365 insertions(+), 207 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index acc20ed63..3f81731ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -1,3 +1,18 @@ +/* + * Copyright 2013-2020 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; import java.util.ArrayList; @@ -13,14 +28,17 @@ import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.data.convert.EntityReader; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; @@ -38,6 +56,7 @@ import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.Streamable; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -235,7 +254,7 @@ public SearchHitsIterator searchForStream(Query query, Class clazz, In return StreamQueries.streamResults( // searchScrollStart(scrollTimeInMillis, query, clazz, index), // - scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz), // + scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz, index), // this::searchScrollClear); } @@ -262,10 +281,11 @@ public List> multiSearch(List queries, Class< MultiSearchResponse.Item[] items = getMultiSearchResult(request); + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>(clazz, index); List> res = new ArrayList<>(queries.size()); int c = 0; for (Query query : queries) { - res.add(elasticsearchConverter.read(clazz, SearchDocumentResponse.from(items[c++].getResponse()))); + res.add(callback.doWith(SearchDocumentResponse.from(items[c++].getResponse()))); } return res; } @@ -285,7 +305,13 @@ public List> multiSearch(List queries, List> it1 = classes.iterator(); for (Query query : queries) { - res.add(elasticsearchConverter.read(it1.next(), SearchDocumentResponse.from(items[c++].getResponse()))); + Class entityClass = it1.next(); + + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>( + entityClass, index); + + SearchResponse response = items[c++].getResponse(); + res.add(callback.doWith(SearchDocumentResponse.from(response))); } return res; } @@ -305,7 +331,7 @@ abstract protected SearchScrollHits searchScrollStart(long scrollTimeInMi * internal use only, not for public API */ abstract protected SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz); + Class clazz, IndexCoordinates index); /* * internal use only, not for public API @@ -497,4 +523,82 @@ protected void maybeCallbackAfterSaveWithQueries(List queries) { // endregion + protected interface DocumentCallback { + + @Nullable + T doWith(@Nullable Document document); + } + + protected static class ReadDocumentCallback implements DocumentCallback { + private final EntityReader reader; + private final Class type; + private final IndexCoordinates index; + + public ReadDocumentCallback(EntityReader reader, Class type, IndexCoordinates index) { + Assert.notNull(reader, "reader is null"); + Assert.notNull(type, "type is null"); + + this.reader = reader; + this.type = type; + this.index = index; + } + + @Nullable + public T doWith(@Nullable Document document) { + if (document == null) { + return null; + } + + return reader.read(type, document); + } + } + + protected interface SearchDocumentResponseCallback { + + @NonNull + T doWith(@NonNull SearchDocumentResponse response); + } + + protected class ReadSearchDocumentResponseCallback implements SearchDocumentResponseCallback> { + private final DocumentCallback delegate; + private final Class type; + + public ReadSearchDocumentResponseCallback(Class type, IndexCoordinates index) { + Assert.notNull(type, "type is null"); + + this.delegate = new ReadDocumentCallback<>(elasticsearchConverter, type, index); + this.type = type; + } + + @Override + public SearchHits doWith(SearchDocumentResponse response) { + List entities = response.getSearchDocuments().stream() + .map(delegate::doWith) + .collect(Collectors.toList()); + return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()) + .mapHits(response, entities); + } + } + + protected class ReadSearchScrollDocumentResponseCallback + implements SearchDocumentResponseCallback> { + private final DocumentCallback delegate; + private final Class type; + + public ReadSearchScrollDocumentResponseCallback(Class type, IndexCoordinates index) { + Assert.notNull(type, "type is null"); + + this.delegate = new ReadDocumentCallback<>(elasticsearchConverter, type, index); + this.type = type; + } + + @Override + public SearchScrollHits doWith(SearchDocumentResponse response) { + List entities = response.getSearchDocuments().stream() + .map(delegate::doWith) + .collect(Collectors.toList()); + return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()) + .mapScrollHits(response, entities); + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 9ce3c5285..7a3a70be3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.List; +import java.util.stream.Collectors; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; @@ -156,7 +157,9 @@ public String index(IndexQuery query, IndexCoordinates index) { public T get(String id, Class clazz, IndexCoordinates index) { GetRequest request = requestFactory.getRequest(id, index); GetResponse response = execute(client -> client.get(request, RequestOptions.DEFAULT)); - return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); + + DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); + return callback.doWith(DocumentAdapters.from(response)); } @Override @@ -167,7 +170,11 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) MultiGetRequest request = requestFactory.multiGetRequest(query, index); MultiGetResponse result = execute(client -> client.mget(request, RequestOptions.DEFAULT)); - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(result), clazz); + + DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); + return DocumentAdapters.from(result).stream() + .map(callback::doWith) + .collect(Collectors.toList()); } @Override @@ -258,7 +265,9 @@ public long count(Query query, @Nullable Class clazz, IndexCoordinates index) public SearchHits search(Query query, Class clazz, IndexCoordinates index) { SearchRequest searchRequest = requestFactory.searchRequest(query, clazz, index); SearchResponse response = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); - return elasticsearchConverter.read(clazz, SearchDocumentResponse.from(response)); + + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>(clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override @@ -272,19 +281,23 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query SearchResponse response = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); - return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( + clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz) { + Class clazz, IndexCoordinates index) { SearchScrollRequest request = new SearchScrollRequest(scrollId); request.scroll(TimeValue.timeValueMillis(scrollTimeInMillis)); SearchResponse response = execute(client -> client.scroll(request, RequestOptions.DEFAULT)); - return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); + SearchDocumentResponseCallback> callback = // + new ReadSearchScrollDocumentResponseCallback<>(clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 6b94aadeb..72fee6f88 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core; import java.util.List; +import java.util.stream.Collectors; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoAction; @@ -37,6 +38,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -161,7 +163,9 @@ public String index(IndexQuery query, IndexCoordinates index) { public T get(String id, Class clazz, IndexCoordinates index) { GetRequestBuilder getRequestBuilder = requestFactory.getRequestBuilder(client, id, index); GetResponse response = getRequestBuilder.execute().actionGet(); - return elasticsearchConverter.mapDocument(DocumentAdapters.from(response), clazz); + + DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); + return callback.doWith(DocumentAdapters.from(response)); } @Override @@ -172,7 +176,11 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); - return elasticsearchConverter.mapDocuments(DocumentAdapters.from(builder.execute().actionGet()), clazz); + DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); + List documents = DocumentAdapters.from(builder.execute().actionGet()); + return documents.stream() + .map(callback::doWith) + .collect(Collectors.toList()); } @Override @@ -265,7 +273,9 @@ public long count(Query query, @Nullable Class clazz, IndexCoordinates index) public SearchHits search(Query query, Class clazz, IndexCoordinates index) { SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, query, clazz, index); SearchResponse response = getSearchResponse(searchRequestBuilder); - return elasticsearchConverter.read(clazz, SearchDocumentResponse.from(response)); + + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>(clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override @@ -281,12 +291,14 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query SearchResponse response = getSearchResponseWithTimeout(action); - return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( + clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override public SearchScrollHits searchScrollContinue(@Nullable String scrollId, long scrollTimeInMillis, - Class clazz) { + Class clazz, IndexCoordinates index) { ActionFuture action = client // .prepareSearchScroll(scrollId) // @@ -295,7 +307,9 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l SearchResponse response = getSearchResponseWithTimeout(action); - return elasticsearchConverter.readScroll(clazz, SearchDocumentResponse.from(response)); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( + clazz, index); + return callback.doWith(SearchDocumentResponse.from(response)); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 2e1de1507..6a6d65fc6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -59,6 +59,7 @@ import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.data.convert.EntityReader; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.NoSuchIndexException; @@ -87,6 +88,7 @@ import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; +import org.springframework.lang.NonNull; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -232,16 +234,11 @@ public Flux multiGet(Query query, Class clazz, IndexCoordinates index) Assert.notNull(query, "Query must not be null"); Assert.notEmpty(query.getIds(), "No Id define for Query"); + DocumentCallback callback = new ReadDocumentCallback<>(converter, clazz, index); + MultiGetRequest request = requestFactory.multiGetRequest(query, index); return Flux.from(execute(client -> client.multiGet(request))) // - .handle((result, sink) -> { - - Document document = DocumentAdapters.from(result); - T entity = converter.mapDocument(document, clazz); - if (entity != null) { - sink.next(entity); - } - }); + .concatMap(result -> callback.doWith(DocumentAdapters.from(result))); } @Override @@ -389,8 +386,10 @@ public Mono get(String id, Class entityType, IndexCoordinates index) { Assert.notNull(id, "Id must not be null!"); + DocumentCallback callback = new ReadDocumentCallback<>(converter, entityType, index); + return doGet(id, getPersistentEntityFor(entityType), index) - .map(it -> converter.mapDocument(DocumentAdapters.from(it), entityType)); + .flatMap(it -> callback.doWith(DocumentAdapters.from(it))); } private Mono doGet(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { @@ -581,8 +580,8 @@ protected > R prepareWriteRequest(R request) { // region SearchOperations @Override public Flux> search(Query query, Class entityType, Class resultType, IndexCoordinates index) { - - return doFind(query, entityType, index).map(searchDocument -> converter.read(resultType, searchDocument)); + SearchDocumentCallback callback = new ReadSearchDocumentCallback<>(resultType, index); + return doFind(query, entityType, index).concatMap(callback::doWith); } @Override @@ -894,4 +893,60 @@ protected Mono maybeCallAfterSave(T entity) { return Mono.just(entity); } // endregion + + protected interface DocumentCallback { + + @NonNull + Mono doWith(@Nullable Document document); + } + + protected static class ReadDocumentCallback implements DocumentCallback { + private final EntityReader reader; + private final Class type; + private final IndexCoordinates index; + + public ReadDocumentCallback(EntityReader reader, Class type, IndexCoordinates index) { + Assert.notNull(reader, "reader is null"); + Assert.notNull(type, "type is null"); + + this.reader = reader; + this.type = type; + this.index = index; + } + + @NonNull + public Mono doWith(@Nullable Document document) { + if (document == null) { + return Mono.empty(); + } + + T entity = reader.read(type, document); + return Mono.just(entity); + } + } + + protected interface SearchDocumentCallback { + + @NonNull + Mono> doWith(@NonNull SearchDocument response); + } + + protected class ReadSearchDocumentCallback implements SearchDocumentCallback { + private final DocumentCallback delegate; + private final Class type; + + public ReadSearchDocumentCallback(Class type, IndexCoordinates index) { + Assert.notNull(type, "type is null"); + + this.delegate = new ReadDocumentCallback<>(converter, type, index); + this.type = type; + } + + @Override + public Mono> doWith(SearchDocument response) { + return delegate.doWith(response) + .map(entity -> SearchHitMapping.mappingFor(type, converter.getMappingContext()) + .mapHit(response, entity)); + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java new file mode 100644 index 000000000..43524ac92 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -0,0 +1,127 @@ +/* + * Copyright 2020 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; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.data.elasticsearch.core.document.SearchDocument; +import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.mapping.context.MappingContext; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * @author Rizwan Idrees + * @author Mohsin Husen + * @author Christoph Strobl + * @author Peter-Josef Meisch + * @author Mark Paluch + * @author Roman Puchkovskiy + * @since 4.0 + */ +class SearchHitMapping { + private final Class type; + private final MappingContext, ElasticsearchPersistentProperty> mappingContext; + + private SearchHitMapping(Class type, + MappingContext, ElasticsearchPersistentProperty> context) { + + Assert.notNull(type, "type is null"); + Assert.notNull(context, "context is null"); + + this.type = type; + this.mappingContext = context; + } + + static SearchHitMapping mappingFor(Class entityClass, + MappingContext, ElasticsearchPersistentProperty> context) { + return new SearchHitMapping<>(entityClass, context); + } + + SearchHit mapHit(SearchDocument searchDocument, T content) { + + Assert.notNull(searchDocument, "searchDocument is null"); + Assert.notNull(content, "content is null"); + + String id = searchDocument.hasId() ? searchDocument.getId() : null; + float score = searchDocument.getScore(); + Object[] sortValues = searchDocument.getSortValues(); + Map> highlightFields = getHighlightsAndRemapFieldNames(searchDocument); + + return new SearchHit<>(id, score, sortValues, highlightFields, content); + } + + SearchHits mapHits(SearchDocumentResponse searchDocumentResponse, List contents) { + return mapHitsFromResponse(searchDocumentResponse, contents); + } + + SearchScrollHits mapScrollHits(SearchDocumentResponse searchDocumentResponse, List contents) { + return mapHitsFromResponse(searchDocumentResponse, contents); + } + + private SearchHitsImpl mapHitsFromResponse(SearchDocumentResponse searchDocumentResponse, List contents) { + + Assert.notNull(searchDocumentResponse, "searchDocumentResponse is null"); + Assert.notNull(contents, "contents is null"); + + Assert.isTrue(searchDocumentResponse.getSearchDocuments().size() == contents.size(), + "Count of documents must match the count of entities"); + + long totalHits = searchDocumentResponse.getTotalHits(); + float maxScore = searchDocumentResponse.getMaxScore(); + String scrollId = searchDocumentResponse.getScrollId(); + + List> searchHits = new ArrayList<>(); + List searchDocuments = searchDocumentResponse.getSearchDocuments(); + for (int i = 0; i < searchDocuments.size(); i++) { + SearchDocument document = searchDocuments.get(i); + T content = contents.get(i); + SearchHit hit = mapHit(document, content); + searchHits.add(hit); + } + Aggregations aggregations = searchDocumentResponse.getAggregations(); + TotalHitsRelation totalHitsRelation = TotalHitsRelation + .valueOf(searchDocumentResponse.getTotalHitsRelation()); + + return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); + } + + @Nullable + private Map> getHighlightsAndRemapFieldNames(SearchDocument searchDocument) { + Map> highlightFields = searchDocument.getHighlightFields(); + + if (highlightFields == null) { + return null; + } + + ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(type); + if (persistentEntity == null) { + return highlightFields; + } + + return highlightFields.entrySet().stream().collect(Collectors.toMap(entry -> { + ElasticsearchPersistentProperty property = persistentEntity.getPersistentPropertyWithFieldName + (entry.getKey()); + return property != null ? property.getName() : entry.getKey(); + }, Map.Entry::getValue)); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index eeac39123..435763f82 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -15,16 +15,8 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.List; -import java.util.stream.Collectors; - import org.springframework.data.convert.EntityConverter; -import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.SearchScrollHits; 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.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; @@ -39,6 +31,7 @@ * @author Christoph Strobl * @author Peter-Josef Meisch * @author Sasch Woo + * @author Roman Puchkovskiy */ public interface ElasticsearchConverter extends EntityConverter, ElasticsearchPersistentProperty, Object, Document> { @@ -53,67 +46,6 @@ default ProjectionFactory getProjectionFactory() { return new SpelAwareProxyProjectionFactory(); } - // region read - /** - * Map a single {@link Document} to an instance of the given type. - * - * @param document the document to map - * @param type must not be {@literal null}. - * @param the class of type - * @return can be {@literal null} if the document is null or {@link Document#isEmpty()} is true. - * @since 4.0 - */ - @Nullable - T mapDocument(@Nullable Document document, Class type); - - /** - * Map a list of {@link Document}s to a list of instance of the given type. - * - * @param documents must not be {@literal null}. - * @param type must not be {@literal null}. - * @param the class of type - * @return a list obtained by calling {@link #mapDocument(Document, Class)} on the elements of the list. - * @since 4.0 - */ - default List mapDocuments(List documents, Class type) { - return documents.stream().map(document -> mapDocument(document, type)).collect(Collectors.toList()); - } - - /** - * builds a {@link SearchHits} from a {@link SearchDocumentResponse}. - * - * @param the clazz of the type, must not be {@literal null}. - * @param type the type of the returned data, must not be {@literal null}. - * @param searchDocumentResponse the response to read from, must not be {@literal null}. - * @return a SearchHits object - * @since 4.0 - */ - SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse); - - /** - * builds a {@link SearchScrollHits} from a {@link SearchDocumentResponse}. - * - * @param the clazz of the type, must not be {@literal null}. - * @param type the type of the returned data, must not be {@literal null}. - * @param searchDocumentResponse the response to read from, must not be {@literal null}. - * @return a {@link SearchScrollHits} object - * @since 4.0 - */ - SearchScrollHits readScroll(Class type, SearchDocumentResponse searchDocumentResponse); - - /** - * builds a {@link SearchHit} from a {@link SearchDocument}. - * - * @param the clazz of the type, must not be {@literal null}. - * @param type the type of the returned data, must not be {@literal null}. - * @param searchDocument must not be {@literal null} - * @return SearchHit with all available information filled in - * @since 4.0 - */ - SearchHit read(Class type, SearchDocument searchDocument); - - // endregion - // region write /** * Convert a given {@literal idValue} to its {@link String} representation taking potentially registered diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 566bf765b..6691656cf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,20 +15,9 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import org.elasticsearch.search.aggregations.Aggregations; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -40,14 +29,8 @@ import org.springframework.data.convert.CustomConversions; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.annotations.ScriptedField; -import org.springframework.data.elasticsearch.core.SearchScrollHits; -import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.SearchHitsImpl; -import org.springframework.data.elasticsearch.core.TotalHitsRelation; 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.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; @@ -77,6 +60,7 @@ * @author Christoph Strobl * @author Peter-Josef Meisch * @author Mark Paluch + * @author Roman Puchkovskiy * @since 3.2 */ public class MappingElasticsearchConverter @@ -146,83 +130,6 @@ public void afterPropertiesSet() { // region read - @Override - public SearchHits read(Class type, SearchDocumentResponse searchDocumentResponse) { - return readResponse(type, searchDocumentResponse); - } - - @Override - public SearchHit read(Class type, SearchDocument searchDocument) { - - Assert.notNull(type, "type must not be null"); - Assert.notNull(searchDocument, "searchDocument must not be null"); - - String id = searchDocument.hasId() ? searchDocument.getId() : null; - float score = searchDocument.getScore(); - Object[] sortValues = searchDocument.getSortValues(); - Map> highlightFields = getHighlightsAndRemapFieldNames(type, searchDocument); - T content = mapDocument(searchDocument, type); - - return new SearchHit(id, score, sortValues, highlightFields, content); - } - - @Override - public SearchScrollHits readScroll(Class type, SearchDocumentResponse searchDocumentResponse) { - return readResponse(type, searchDocumentResponse); - } - - private SearchHitsImpl readResponse(Class type, SearchDocumentResponse searchDocumentResponse) { - - Assert.notNull(type, "type must not be null"); - Assert.notNull(searchDocumentResponse, "searchDocumentResponse must not be null"); - - long totalHits = searchDocumentResponse.getTotalHits(); - float maxScore = searchDocumentResponse.getMaxScore(); - String scrollId = searchDocumentResponse.getScrollId(); - List> searchHits = searchDocumentResponse.getSearchDocuments().stream() // - .map(searchDocument -> read(type, searchDocument)) // - .collect(Collectors.toList()); - Aggregations aggregations = searchDocumentResponse.getAggregations(); - TotalHitsRelation totalHitsRelation = TotalHitsRelation - .valueOf(searchDocumentResponse.getTotalHitsRelation()); - - return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); - } - - @Nullable - private Map> getHighlightsAndRemapFieldNames(Class type, SearchDocument searchDocument) { - Map> highlightFields = searchDocument.getHighlightFields(); - - if (highlightFields == null) { - return null; - } - - ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(type); - if (persistentEntity == null) { - return highlightFields; - } - - return highlightFields.entrySet().stream().collect(Collectors.toMap(entry -> { - ElasticsearchPersistentProperty property = persistentEntity.getPersistentPropertyWithFieldName(entry.getKey()); - return property != null ? property.getName() : entry.getKey(); - }, Entry::getValue)); - } - - @Override - @Nullable - public T mapDocument(@Nullable Document document, Class type) { - - if (document == null) { - return null; - } - - T mappedResult = read(type, document); - - return type.isInterface() || !ClassUtils.isAssignableValue(type, mappedResult) - ? getProjectionFactory().createProjection(type, mappedResult) - : type.cast(mappedResult); - } - @SuppressWarnings("unchecked") @Override public R read(Class type, Document source) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 145a8784f..d94ccc17f 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -1093,7 +1093,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQuery() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); @@ -1120,7 +1120,7 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQuery() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(30); @@ -1148,7 +1148,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1175,7 +1176,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1202,7 +1204,8 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1229,7 +1232,8 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1256,7 +1260,8 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1283,7 +1288,8 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1568,7 +1574,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { while (scroll.hasSearchHits()) { scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), - scrollTimeInMillis, SampleEntity.class); + scrollTimeInMillis, SampleEntity.class, index); entities.addAll(scroll.getSearchHits()); } @@ -2469,7 +2475,7 @@ public void shouldApplyCriteriaQueryToScanAndScrollForGivenCriteriaQuery() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); @@ -2507,7 +2513,7 @@ public void shouldApplySearchQueryToScanAndScrollForGivenSearchQuery() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); @@ -2540,7 +2546,7 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scroll.getScrollId()); assertThat(sampleEntities).hasSize(3); @@ -2587,7 +2593,7 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } // then @@ -2636,7 +2642,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scroll.getScrollId(), 1000, - SampleEntity.class); + SampleEntity.class, index); } // then diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index b3bb07cc1..aaf5e76fe 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -253,11 +253,11 @@ public void shouldMapObjectToJsonString() { } @Test // DATAES-530 - public void shouldMapJsonStringToObject() { + public void shouldReadJsonStringToObject() { // Given // When - Car result = mappingElasticsearchConverter.mapDocument(Document.parse(JSON_STRING), Car.class); + Car result = mappingElasticsearchConverter.read(Car.class, Document.parse(JSON_STRING)); // Then assertThat(result).isNotNull(); From 99bf2fc0cbdb5a9e8357fd97501dcc5bbbb1084d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 16 Apr 2020 07:06:19 +0200 Subject: [PATCH 0120/1191] DATAES-786 - Polishing. --- .../core/AbstractElasticsearchTemplate.java | 32 +++++----- .../core/ElasticsearchRestTemplate.java | 10 ++- .../core/ElasticsearchTemplate.java | 12 ++-- .../core/ReactiveElasticsearchTemplate.java | 3 +- .../elasticsearch/core/SearchHitMapping.java | 6 +- .../MappingElasticsearchConverter.java | 11 +++- .../core/ElasticsearchTemplateTests.java | 24 +++---- ...appingElasticsearchConverterUnitTests.java | 62 +++++++++---------- 8 files changed, 80 insertions(+), 80 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 3f81731ae..66883022f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2019-2020 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. @@ -123,7 +123,6 @@ public void setEntityCallbacks(EntityCallbacks entityCallbacks) { // endregion // region DocumentOperations - @Override public T save(T entity) { @@ -307,8 +306,8 @@ public List> multiSearch(List queries, List> callback = new ReadSearchDocumentResponseCallback<>( - entityClass, index); + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>(entityClass, + index); SearchResponse response = items[c++].getResponse(); res.add(callback.doWith(SearchDocumentResponse.from(response))); @@ -464,7 +463,7 @@ private IndexQuery getIndexQuery(T entity) { // endregion - // region callbacks + // region Entity callbacks protected T maybeCallbackBeforeConvert(T entity) { if (entityCallbacks != null) { @@ -523,8 +522,8 @@ protected void maybeCallbackAfterSaveWithQueries(List queries) { // endregion + // region Document callbacks protected interface DocumentCallback { - @Nullable T doWith(@Nullable Document document); } @@ -535,6 +534,7 @@ protected static class ReadDocumentCallback implements DocumentCallback { private final IndexCoordinates index; public ReadDocumentCallback(EntityReader reader, Class type, IndexCoordinates index) { + Assert.notNull(reader, "reader is null"); Assert.notNull(type, "type is null"); @@ -545,6 +545,7 @@ public ReadDocumentCallback(EntityReader reader, Class t @Nullable public T doWith(@Nullable Document document) { + if (document == null) { return null; } @@ -554,7 +555,6 @@ public T doWith(@Nullable Document document) { } protected interface SearchDocumentResponseCallback { - @NonNull T doWith(@NonNull SearchDocumentResponse response); } @@ -564,6 +564,7 @@ protected class ReadSearchDocumentResponseCallback implements SearchDocumentR private final Class type; public ReadSearchDocumentResponseCallback(Class type, IndexCoordinates index) { + Assert.notNull(type, "type is null"); this.delegate = new ReadDocumentCallback<>(elasticsearchConverter, type, index); @@ -572,11 +573,8 @@ public ReadSearchDocumentResponseCallback(Class type, IndexCoordinates index) @Override public SearchHits doWith(SearchDocumentResponse response) { - List entities = response.getSearchDocuments().stream() - .map(delegate::doWith) - .collect(Collectors.toList()); - return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()) - .mapHits(response, entities); + List entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList()); + return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()).mapHits(response, entities); } } @@ -586,6 +584,7 @@ protected class ReadSearchScrollDocumentResponseCallback private final Class type; public ReadSearchScrollDocumentResponseCallback(Class type, IndexCoordinates index) { + Assert.notNull(type, "type is null"); this.delegate = new ReadDocumentCallback<>(elasticsearchConverter, type, index); @@ -594,11 +593,10 @@ public ReadSearchScrollDocumentResponseCallback(Class type, IndexCoordinates @Override public SearchScrollHits doWith(SearchDocumentResponse response) { - List entities = response.getSearchDocuments().stream() - .map(delegate::doWith) - .collect(Collectors.toList()); - return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()) - .mapScrollHits(response, entities); + List entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList()); + return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()).mapScrollHits(response, + entities); } } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 7a3a70be3..308aaed3b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -172,9 +172,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) MultiGetResponse result = execute(client -> client.mget(request, RequestOptions.DEFAULT)); DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); - return DocumentAdapters.from(result).stream() - .map(callback::doWith) - .collect(Collectors.toList()); + return DocumentAdapters.from(result).stream().map(callback::doWith).collect(Collectors.toList()); } @Override @@ -281,8 +279,8 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query SearchResponse response = execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); - SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( - clazz, index); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz, + index); return callback.doWith(SearchDocumentResponse.from(response)); } @@ -325,7 +323,7 @@ protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest req } // endregion - // region clientcallback + // region ClientCallback /** * Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on * {@link RestHighLevelClient}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 72fee6f88..80273668a 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -178,9 +178,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); List documents = DocumentAdapters.from(builder.execute().actionGet()); - return documents.stream() - .map(callback::doWith) - .collect(Collectors.toList()); + return documents.stream().map(callback::doWith).collect(Collectors.toList()); } @Override @@ -291,8 +289,8 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query SearchResponse response = getSearchResponseWithTimeout(action); - SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( - clazz, index); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz, + index); return callback.doWith(SearchDocumentResponse.from(response)); } @@ -307,8 +305,8 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l SearchResponse response = getSearchResponseWithTimeout(action); - SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>( - clazz, index); + SearchDocumentResponseCallback> callback = new ReadSearchScrollDocumentResponseCallback<>(clazz, + index); return callback.doWith(SearchDocumentResponse.from(response)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 6a6d65fc6..b1c7efe7b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -945,8 +945,7 @@ public ReadSearchDocumentCallback(Class type, IndexCoordinates index) { @Override public Mono> doWith(SearchDocument response) { return delegate.doWith(response) - .map(entity -> SearchHitMapping.mappingFor(type, converter.getMappingContext()) - .mapHit(response, entity)); + .map(entity -> SearchHitMapping.mappingFor(type, converter.getMappingContext()).mapHit(response, entity)); } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index 43524ac92..2a9a2973b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -99,8 +99,7 @@ private SearchHitsImpl mapHitsFromResponse(SearchDocumentResponse searchDocum searchHits.add(hit); } Aggregations aggregations = searchDocumentResponse.getAggregations(); - TotalHitsRelation totalHitsRelation = TotalHitsRelation - .valueOf(searchDocumentResponse.getTotalHitsRelation()); + TotalHitsRelation totalHitsRelation = TotalHitsRelation.valueOf(searchDocumentResponse.getTotalHitsRelation()); return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); } @@ -119,8 +118,7 @@ private Map> getHighlightsAndRemapFieldNames(SearchDocument } return highlightFields.entrySet().stream().collect(Collectors.toMap(entry -> { - ElasticsearchPersistentProperty property = persistentEntity.getPersistentPropertyWithFieldName - (entry.getKey()); + ElasticsearchPersistentProperty property = persistentEntity.getPersistentPropertyWithFieldName(entry.getKey()); return property != null ? property.getName() : entry.getKey(); }, Map.Entry::getValue)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 6691656cf..83acc9e25 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,8 +15,17 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index d94ccc17f..928d3a7fa 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -1148,8 +1148,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForCriteriaQue while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1176,8 +1176,8 @@ public void shouldReturnResultsWithScanAndScrollForSpecifiedFieldsForSearchCrite while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1204,8 +1204,8 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenCri while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1232,8 +1232,8 @@ public void shouldReturnResultsForScanAndScrollWithCustomResultMapperForGivenSea while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1260,8 +1260,8 @@ public void shouldReturnResultsWithScanAndScrollForGivenCriteriaQueryAndClass() while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); @@ -1288,8 +1288,8 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { while (scroll.hasSearchHits()) { sampleEntities.addAll(scroll.getSearchHits()); scrollId = scroll.getScrollId(); - scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, - SampleEntity.class, index); + scroll = ((AbstractElasticsearchTemplate) operations).searchScrollContinue(scrollId, 1000, SampleEntity.class, + index); } ((AbstractElasticsearchTemplate) operations).searchScrollClear(scrollId); assertThat(sampleEntities).hasSize(30); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index aaf5e76fe..0b730c71a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -194,17 +194,17 @@ public void init() { shotGunAsMap = Document.create(); shotGunAsMap.put("model", "Ithaca 37 Pump Shotgun"); shotGunAsMap.put("_class", ShotGun.class.getName()); - + notificationAsMap = Document.create(); - notificationAsMap.put("id",1L); - notificationAsMap.put("fromEmail","from@email.com"); - notificationAsMap.put("toEmail","to@email.com"); - Map data = new HashMap<>(); - data.put("documentType","abc"); - data.put("content",null); - notificationAsMap.put("params",data); + notificationAsMap.put("id", 1L); + notificationAsMap.put("fromEmail", "from@email.com"); + notificationAsMap.put("toEmail", "to@email.com"); + Map data = new HashMap<>(); + data.put("documentType", "abc"); + data.put("content", null); + notificationAsMap.put("params", data); notificationAsMap.put("_class", - "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$Notification"); + "org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverterUnitTests$Notification"); } @Test @@ -627,37 +627,37 @@ void shouldReadLocalDate() { assertThat(person.getBirthDate()).isEqualTo(LocalDate.of(2000, 8, 22)); assertThat(person.getGender()).isEqualTo(Gender.MAN); } - - @Test //DATAES-763 + + @Test // DATAES-763 void writeEntityWithMapDataType() { Notification notification = new Notification(); - notification.fromEmail="from@email.com"; - notification.toEmail="to@email.com"; - Map data = new HashMap<>(); - data.put("documentType","abc"); - data.put("content",null); - notification.params= data; - notification.id= 1L; + notification.fromEmail = "from@email.com"; + notification.toEmail = "to@email.com"; + Map data = new HashMap<>(); + data.put("documentType", "abc"); + data.put("content", null); + notification.params = data; + notification.id = 1L; Document document = Document.create(); - mappingElasticsearchConverter.write(notification,document); + mappingElasticsearchConverter.write(notification, document); assertThat(document).isEqualTo(notificationAsMap); } - @Test //DATAES-763 + @Test // DATAES-763 void readEntityWithMapDataType() { Document document = Document.create(); - document.put("id",1L); - document.put("fromEmail","from@email.com"); - document.put("toEmail","to@email.com"); - Map data = new HashMap<>(); - data.put("documentType","abc"); - data.put("content",null); - document.put("params",data); - - Notification notification = mappingElasticsearchConverter.read(Notification.class,document); + document.put("id", 1L); + document.put("fromEmail", "from@email.com"); + document.put("toEmail", "to@email.com"); + Map data = new HashMap<>(); + data.put("documentType", "abc"); + data.put("content", null); + document.put("params", data); + + Notification notification = mappingElasticsearchConverter.read(Notification.class, document); assertThat(notification.params.get("documentType")).isEqualTo("abc"); assertThat(notification.params.get("content")).isNull(); } @@ -794,14 +794,14 @@ static class Skynet { List objectList; Map objectMap; } - + @Data static class Notification { Long id; String fromEmail; String toEmail; - Map params; + Map params; } @WritingConverter From 539c1ee6e75968b5874cd05a99be78079ecd9cc9 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 16 Apr 2020 21:44:53 +0200 Subject: [PATCH 0121/1191] DATAES-778 - Fix SSL setup in the reactive client. Original PR: #429 --- .../DefaultReactiveElasticsearchClient.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 6ac72da1b..b63861c1b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -16,7 +16,9 @@ package org.springframework.data.elasticsearch.client.reactive; import io.netty.channel.ChannelOption; +import io.netty.handler.ssl.ApplicationProtocolConfig; import io.netty.handler.ssl.ClientAuth; +import io.netty.handler.ssl.IdentityCipherSuiteFilter; import io.netty.handler.ssl.JdkSslContext; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; @@ -249,11 +251,16 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client if (clientConfiguration.useSsl()) { - httpClient = httpClient.secure(sslConfig -> { + Optional sslContext = clientConfiguration.getSslContext(); - Optional sslContext = clientConfiguration.getSslContext(); - sslContext.ifPresent(it -> sslConfig.sslContext(new JdkSslContext(it, true, ClientAuth.NONE))); - }); + if (sslContext.isPresent()) { + httpClient = httpClient.secure(sslContextSpec -> { + sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null, IdentityCipherSuiteFilter.INSTANCE, + ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false)); + }); + } else { + httpClient = httpClient.secure(); + } scheme = "https"; } From 76e91c3366caae915b7b4a8eae6c0d585cde9657 Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Fri, 17 Apr 2020 23:29:39 +0400 Subject: [PATCH 0122/1191] DATAES-772 - Add after-convert entity callbacks support. Original PR: #422 --- .../core/AbstractElasticsearchTemplate.java | 17 +- .../core/ElasticsearchTemplate.java | 2 +- .../core/ReactiveElasticsearchTemplate.java | 15 +- .../elasticsearch/core/SearchHitSupport.java | 26 + .../core/event/AfterConvertCallback.java | 42 ++ .../event/ReactiveAfterConvertCallback.java | 43 ++ ...actElasticsearchTemplateCallbackTests.java | 570 ++++++++++++++++++ ...lasticsearchRestTemplateCallbackTests.java | 259 ++------ .../core/ElasticsearchTemplateTests.java | 6 +- ...csearchTransportTemplateCallbackTests.java | 284 +++------ ...iveElasticsearchTemplateCallbackTests.java | 307 ++++++++++ .../core/SearchHitSupportTest.java | 89 +++ 12 files changed, 1227 insertions(+), 433 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 66883022f..3f4a96e14 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; +import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; @@ -236,8 +237,6 @@ public long count(Query query, Class clazz) { @Override public CloseableIterator stream(Query query, Class clazz, IndexCoordinates index) { - - long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); return (CloseableIterator) SearchHitSupport.unwrapSearchHits(searchForStream(query, clazz, index)); } @@ -520,6 +519,15 @@ protected void maybeCallbackAfterSaveWithQueries(List queries) { queries.forEach(this::maybeCallbackAfterSaveWithQuery); } + protected T maybeCallbackAfterConvert(T entity, Document document, IndexCoordinates index) { + + if (entityCallbacks != null) { + return entityCallbacks.callback(AfterConvertCallback.class, entity, document, index); + } + + return entity; + } + // endregion // region Document callbacks @@ -528,7 +536,7 @@ protected interface DocumentCallback { T doWith(@Nullable Document document); } - protected static class ReadDocumentCallback implements DocumentCallback { + protected class ReadDocumentCallback implements DocumentCallback { private final EntityReader reader; private final Class type; private final IndexCoordinates index; @@ -550,7 +558,8 @@ public T doWith(@Nullable Document document) { return null; } - return reader.read(type, document); + T entity = reader.read(type, document); + return maybeCallbackAfterConvert(entity, document, index); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 80273668a..467e1f585 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -172,7 +172,7 @@ public T get(String id, Class clazz, IndexCoordinates index) { public List multiGet(Query query, Class clazz, IndexCoordinates index) { Assert.notNull(index, "index must not be null"); - Assert.notEmpty(query.getIds(), "No Id define for Query"); + Assert.notEmpty(query.getIds(), "No Ids defined for Query"); MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index b1c7efe7b..7b49f8dba 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -71,6 +71,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocument; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback; import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; @@ -892,6 +893,16 @@ protected Mono maybeCallAfterSave(T entity) { return Mono.just(entity); } + + protected Mono maybeCallAfterConvert(T entity, Document document, IndexCoordinates index) { + + if (null != entityCallbacks) { + return entityCallbacks.callback(ReactiveAfterConvertCallback.class, entity, document, index); + } + + return Mono.just(entity); + } + // endregion protected interface DocumentCallback { @@ -900,7 +911,7 @@ protected interface DocumentCallback { Mono doWith(@Nullable Document document); } - protected static class ReadDocumentCallback implements DocumentCallback { + protected class ReadDocumentCallback implements DocumentCallback { private final EntityReader reader; private final Class type; private final IndexCoordinates index; @@ -921,7 +932,7 @@ public Mono doWith(@Nullable Document document) { } T entity = reader.read(type, document); - return Mono.just(entity); + return maybeCallAfterConvert(entity, document, index); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 9d99ff014..271af8554 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -26,6 +26,7 @@ import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl; import org.springframework.data.repository.util.ReactiveWrappers; +import org.springframework.data.util.CloseableIterator; import org.springframework.lang.Nullable; /** @@ -33,6 +34,7 @@ * * @author Peter-Josef Meisch * @author Sascha Woo + * @author Roman Puchkovskiy * @since 4.0 */ public final class SearchHitSupport { @@ -79,6 +81,10 @@ public static Object unwrapSearchHits(Object result) { return unwrapSearchHits(searchHits.getSearchHits()); } + if (result instanceof SearchHitsIterator) { + return unwrapSearchHitsIterator((SearchHitsIterator) result); + } + if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) { if (result instanceof Flux) { @@ -90,6 +96,26 @@ public static Object unwrapSearchHits(Object result) { return result; } + private static CloseableIterator unwrapSearchHitsIterator(SearchHitsIterator iterator) { + + return new CloseableIterator() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public Object next() { + return unwrapSearchHits(iterator.next()); + } + + @Override + public void close() { + iterator.close(); + } + }; + } + /** * Builds an {@link AggregatedPage} with the {@link SearchHit} objects from a {@link SearchHits} object. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java new file mode 100644 index 000000000..53e110c31 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java @@ -0,0 +1,42 @@ +/* + * Copyright 2020 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.event; + +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.mapping.callback.EntityCallback; + +/** + * Callback being invoked after a domain object is materialized from a {@link Document} when reading results. + * + * @author Roman Puchkovskiy + * @since 4.0 + * @see org.springframework.data.mapping.callback.EntityCallbacks + */ +@FunctionalInterface +public interface AfterConvertCallback extends EntityCallback { + + /** + * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either + * the same or a modified instance of the domain object. + * + * @param entity the domain object (the result of the conversion). + * @param document must not be {@literal null}. + * @param indexCoordinates must not be {@literal null}. + * @return the domain object that is the result of reading it from the {@link Document}. + */ + T onAfterConvert(T entity, Document document, IndexCoordinates indexCoordinates); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java new file mode 100644 index 000000000..62aa3abb2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java @@ -0,0 +1,43 @@ +/* + * Copyright 2020 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.event; + +import org.reactivestreams.Publisher; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.mapping.callback.EntityCallback; + +/** + * Callback being invoked after a domain object is materialized from a {@link Document} when reading results. + * + * @author Roman Puchkovskiy + * @since 4.0 + * @see org.springframework.data.mapping.callback.ReactiveEntityCallbacks + */ +@FunctionalInterface +public interface ReactiveAfterConvertCallback extends EntityCallback { + + /** + * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either + * the same or a modified instance of the domain object. + * + * @param entity the domain object (the result of the conversion). + * @param document must not be {@literal null}. + * @param indexCoordinates must not be {@literal null}. + * @return a {@link Publisher} emitting the domain object that is the result of reading it from the {@link Document}. + */ + Publisher onAfterConvert(T entity, Document document, IndexCoordinates indexCoordinates); +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java new file mode 100644 index 000000000..4c17bfdb2 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java @@ -0,0 +1,570 @@ +/* + * Copyright 2020 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; + +import static java.util.Collections.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.lucene.search.TotalHits; +import org.elasticsearch.action.search.SearchResponse; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Spy; +import org.springframework.data.annotation.Id; +import org.springframework.data.domain.Page; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; +import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.BulkOptions; +import org.springframework.data.elasticsearch.core.query.GetQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.mapping.callback.EntityCallbacks; +import org.springframework.data.util.CloseableIterator; +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +/** + * @author Roman Puchkovskiy + */ +abstract class AbstractElasticsearchTemplateCallbackTests { + + protected AbstractElasticsearchTemplate template; + + @Mock protected SearchResponse searchResponse; + @Mock protected org.elasticsearch.search.SearchHit searchHit; + + private final IndexCoordinates index = IndexCoordinates.of("index"); + + @Spy private ValueCapturingAfterSaveCallback afterSaveCallback = new ValueCapturingAfterSaveCallback(); + @Spy private ValueCapturingAfterConvertCallback afterConvertCallback = new ValueCapturingAfterConvertCallback(); + + protected final void initTemplate(AbstractElasticsearchTemplate template) { + this.template = template; + + this.template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback, afterConvertCallback)); + } + + protected final org.elasticsearch.search.SearchHits nSearchHits(int count) { + org.elasticsearch.search.SearchHit[] hits = new org.elasticsearch.search.SearchHit[count]; + Arrays.fill(hits, searchHit); + return new org.elasticsearch.search.SearchHits(hits, new TotalHits(count, TotalHits.Relation.EQUAL_TO), 1.0f); + } + + @Test // DATAES-771 + void saveOneShouldInvokeAfterSaveCallbacks() { + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + Person entity = new Person("init", "luke"); + + Person saved = template.save(entity, index); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + assertThat(saved.id).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveArrayShouldInvokeAfterSaveCallbacks() { + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(entity1, entity2); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableShouldInvokeAfterSaveCallbacks() { + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2)); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2), index); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Iterator savedIterator = saved.iterator(); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void indexShouldInvokeAfterSaveCallbacks() { + + Person entity = new Person("init", "luke"); + + IndexQuery indexQuery = indexQueryForEntity(entity); + template.index(indexQuery, index); + + verify(afterSaveCallback).onAfterSave(eq(entity)); + Person savedPerson = (Person) indexQuery.getObject(); + assertThat(savedPerson.id).isEqualTo("after-save"); + } + + private IndexQuery indexQueryForEntity(Person entity) { + IndexQuery indexQuery = new IndexQuery(); + indexQuery.setObject(entity); + return indexQuery; + } + + @Test // DATAES-771 + void bulkIndexShouldInvokeAfterSaveCallbacks() { + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), index); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Test // DATAES-771 + void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + IndexQuery query1 = indexQueryForEntity(entity1); + IndexQuery query2 = indexQueryForEntity(entity2); + template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), index); + + verify(afterSaveCallback, times(2)).onAfterSave(any()); + Person savedPerson1 = (Person) query1.getObject(); + Person savedPerson2 = (Person) query2.getObject(); + assertThat(savedPerson1.getId()).isEqualTo("after-save"); + assertThat(savedPerson2.getId()).isEqualTo("after-save"); + } + + @Test // DATAES-772 + void getShouldInvokeAfterConvertCallback() { + + Person result = template.get("init", Person.class); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(result.id).isEqualTo("after-convert"); + } + + private Document lukeDocument() { + return Document.create() + .append("id", "init") + .append("firstname", "luke"); + } + + @Test // DATAES-772 + void getWithCoordinatesShouldInvokeAfterConvertCallback() { + + Person result = template.get("init", Person.class, index); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void getViaQueryShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + Person result = template.get(new GetQuery("init"), Person.class, index); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void multiGetShouldInvokeAfterConvertCallback() { + + List results = template.multiGet(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + private Query queryForTwo() { + return new NativeSearchQueryBuilder().withIds(Arrays.asList("init1", "init2")).build(); + } + + @Test // DATAES-772 + void queryForObjectShouldInvokeAfterConvertCallback() { + + doReturn(nSearchHits(1)).when(searchResponse).getHits(); + + @SuppressWarnings("deprecation") // we know what we test + Person result = template.queryForObject(queryForOne(), Person.class, index); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.id).isEqualTo("after-convert"); + } + + private Query queryForOne() { + return new NativeSearchQueryBuilder().withIds(singletonList("init")).build(); + } + + @Test // DATAES-772 + void queryForPageShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + AggregatedPage results = template.queryForPage(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); + assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void queryForPageWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + List> results = template.queryForPage(singletonList(queryForTwo()), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List persons = results.get(0).getContent(); + assertThat(persons.get(0).id).isEqualTo("after-convert"); + assertThat(persons.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void queryForPageWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + List> results = template.queryForPage(singletonList(queryForTwo()), + singletonList(Person.class), index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List persons = results.get(0).getContent().stream() + .map(Person.class::cast) + .collect(Collectors.toList()); + assertThat(persons.get(0).id).isEqualTo("after-convert"); + assertThat(persons.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void streamShouldInvokeAfterConvertCallback() { + + CloseableIterator results = template.stream(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.next().id).isEqualTo("after-convert"); + assertThat(results.next().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchScrollContinueShouldInvokeAfterConvertCallback() { + + CloseableIterator results = template.stream(queryForTwo(), Person.class, index); + + skipItemsFromScrollStart(results); + assertThat(results.next().id).isEqualTo("after-convert"); + assertThat(results.next().id).isEqualTo("after-convert"); + + verify(afterConvertCallback, times(4)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + } + + private void skipItemsFromScrollStart(CloseableIterator results) { + results.next(); + results.next(); + } + + @Test // DATAES-772 + void queryForListShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + List results = template.queryForList(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void queryForListWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + List> results = template.queryForList(singletonList(queryForTwo()), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List persons = results.get(0); + assertThat(persons.get(0).id).isEqualTo("after-convert"); + assertThat(persons.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void queryForListWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + List> results = template.queryForList(singletonList(queryForTwo()), singletonList(Person.class), index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List persons = results.get(0).stream() + .map(Person.class::cast) + .collect(Collectors.toList()); + assertThat(persons.get(0).id).isEqualTo("after-convert"); + assertThat(persons.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void moreLikeThisShouldInvokeAfterConvertCallback() { + + @SuppressWarnings("deprecation") // we know what we test + AggregatedPage results = template.moreLikeThis(moreLikeThisQuery(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); + assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); + } + + private MoreLikeThisQuery moreLikeThisQuery() { + MoreLikeThisQuery query = new MoreLikeThisQuery(); + query.setId("init"); + query.addFields("id"); + return query; + } + + @Test // DATAES-772 + void searchOneShouldInvokeAfterConvertCallback() { + + doReturn(nSearchHits(1)).when(searchResponse).getHits(); + + SearchHit result = template.searchOne(queryForOne(), Person.class); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(result.getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchOneWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + + doReturn(nSearchHits(1)).when(searchResponse).getHits(); + + SearchHit result = template.searchOne(queryForOne(), Person.class, index); + + verify(afterConvertCallback) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void multiSearchShouldInvokeAfterConvertCallback() { + + List> results = template.multiSearch(singletonList(queryForTwo()), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List> hits = results.get(0).getSearchHits(); + assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void multiSearchWithMultipleEntityClassesShouldInvokeAfterConvertCallback() { + + List> results = template.multiSearch(singletonList(queryForTwo()), + singletonList(Person.class), index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List> hits = results.get(0).getSearchHits(); + assertThat(((Person) hits.get(0).getContent()).id).isEqualTo("after-convert"); + assertThat(((Person) hits.get(1).getContent()).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchShouldInvokeAfterConvertCallback() { + + SearchHits results = template.search(queryForTwo(), Person.class); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + List> hits = results.getSearchHits(); + assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + + SearchHits results = template.search(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List> hits = results.getSearchHits(); + assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchViaMoreLikeThisShouldInvokeAfterConvertCallback() { + + SearchHits results = template.search(moreLikeThisQuery(), Person.class); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + List> hits = results.getSearchHits(); + assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchViaMoreLikeThisWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + + SearchHits results = template.search(moreLikeThisQuery(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + List> hits = results.getSearchHits(); + assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchForStreamShouldInvokeAfterConvertCallback() { + + SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.next().getContent().id).isEqualTo("after-convert"); + assertThat(results.next().getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchForStreamWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + + SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class, index); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.next().getContent().id).isEqualTo("after-convert"); + assertThat(results.next().getContent().id).isEqualTo("after-convert"); + } + + @Data + @AllArgsConstructor + @NoArgsConstructor + static class Person { + + @Id String id; + String firstname; + } + + static class ValueCapturingEntityCallback { + + private final List values = new ArrayList<>(1); + + protected void capture(T value) { + values.add(value); + } + + public List getValues() { + return values; + } + + @Nullable + public T getValue() { + return CollectionUtils.lastElement(values); + } + + } + + static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback + implements AfterSaveCallback { + + @Override + public Person onAfterSave(Person entity) { + + capture(entity); + return new Person() { + { + id = "after-save"; + firstname = entity.firstname; + } + }; + } + } + + static class ValueCapturingAfterConvertCallback extends ValueCapturingEntityCallback + implements AfterConvertCallback { + + @Override + public Person onAfterConvert(Person entity, Document document, IndexCoordinates indexCoordinates) { + + capture(entity); + return new Person() { + { + id = "after-convert"; + firstname = entity.firstname; + } + }; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java index 609144bc0..4cabf0c7e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java @@ -15,59 +15,55 @@ */ package org.springframework.data.elasticsearch.core; -import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; +import java.util.HashMap; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.MultiGetItemResponse; +import org.elasticsearch.action.get.MultiGetRequest; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.MultiSearchRequest; +import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.search.SearchScrollRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.common.bytes.BytesArray; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.mapping.callback.EntityCallbacks; -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; /** * @author Roman Puchkovskiy */ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class ElasticsearchRestTemplateCallbackTests { - - private ElasticsearchRestTemplate template; +class ElasticsearchRestTemplateCallbackTests extends AbstractElasticsearchTemplateCallbackTests { @Mock private RestHighLevelClient client; @Mock private IndexResponse indexResponse; @Mock private BulkResponse bulkResponse; @Mock private BulkItemResponse bulkItemResponse; + @Mock private GetResponse getResponse; + @Mock private MultiGetResponse multiGetResponse; + @Mock private MultiGetItemResponse multiGetItemResponse; + @Mock private MultiSearchResponse.Item multiSearchResponseItem; + @SuppressWarnings("deprecation") // we know what we test @BeforeEach public void setUp() throws Exception { - template = new ElasticsearchRestTemplate(client); + initTemplate(new ElasticsearchRestTemplate(client)); doReturn(indexResponse).when(client).index(any(IndexRequest.class), any(RequestOptions.class)); doReturn("response-id").when(indexResponse).getId(); @@ -75,198 +71,39 @@ public void setUp() throws Exception { doReturn(bulkResponse).when(client).bulk(any(BulkRequest.class), any(RequestOptions.class)); doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn("response-id").when(bulkItemResponse).getId(); - } - - @Test // DATAES-771 - void saveOneShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - Person saved = template.save(entity); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - Person saved = template.save(entity, IndexCoordinates.of("index")); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveArrayShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(entity1, entity2); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveIterableShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(Arrays.asList(entity1, entity2)); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - @Test // DATAES-771 - void indexShouldInvokeAfterSaveCallbacks() { + doReturn(getResponse).when(client).get(any(GetRequest.class), any(RequestOptions.class)); - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - IndexQuery indexQuery = indexQueryForEntity(entity); - template.index(indexQuery, IndexCoordinates.of("index")); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - Person newPerson = (Person) indexQuery.getObject(); - assertThat(newPerson.id).isEqualTo("after-save"); - } - - private IndexQuery indexQueryForEntity(Person entity) { - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setObject(entity); - return indexQuery; - } - - @Test // DATAES-771 - void bulkIndexShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - IndexQuery query1 = indexQueryForEntity(entity1); - IndexQuery query2 = indexQueryForEntity(entity2); - template.bulkIndex(Arrays.asList(query1, query2), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Person savedPerson1 = (Person) query1.getObject(); - Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - IndexQuery query1 = indexQueryForEntity(entity1); - IndexQuery query2 = indexQueryForEntity(entity2); - template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Person savedPerson1 = (Person) query1.getObject(); - Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Person { - - @Id String id; - String firstname; - } - - static class ValueCapturingEntityCallback { - - private final List values = new ArrayList<>(1); - - protected void capture(T value) { - values.add(value); - } - - public List getValues() { - return values; - } - - @Nullable - public T getValue() { - return CollectionUtils.lastElement(values); - } - - } - - static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback - implements AfterSaveCallback { - - @Override - public Person onAfterSave(Person entity) { - - capture(entity); - return new Person() { + doReturn(true).when(getResponse).isExists(); + doReturn(false).when(getResponse).isSourceEmpty(); + doReturn(new HashMap() { { - id = "after-save"; - firstname = entity.firstname; + put("id", "init"); + put("firstname", "luke"); } - }; - } + }).when(getResponse).getSourceAsMap(); + + doReturn(multiGetResponse).when(client).mget(any(MultiGetRequest.class), any(RequestOptions.class)); + doReturn(new MultiGetItemResponse[]{multiGetItemResponse, multiGetItemResponse}) + .when(multiGetResponse).getResponses(); + doReturn(getResponse).when(multiGetItemResponse).getResponse(); + + doReturn(searchResponse).when(client).search(any(SearchRequest.class), any(RequestOptions.class)); + doReturn(nSearchHits(2)).when(searchResponse).getHits(); + doReturn("scroll-id").when(searchResponse).getScrollId(); + doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); + doReturn(new HashMap() { + { + put("id", "init"); + put("firstname", "luke"); + } + }).when(searchHit).getSourceAsMap(); + + MultiSearchResponse multiSearchResponse = new MultiSearchResponse( + new MultiSearchResponse.Item[]{ multiSearchResponseItem }, 1L); + doReturn(multiSearchResponse).when(client).multiSearch(any(MultiSearchRequest.class), any()); + doReturn(searchResponse).when(multiSearchResponseItem).getResponse(); + + doReturn(searchResponse).when(client).scroll(any(SearchScrollRequest.class), any(RequestOptions.class)); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 928d3a7fa..3e1c0696f 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -2561,7 +2561,6 @@ public void shouldRespectSourceFilterWithScanAndScrollForGivenSearchQuery() { public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { // given - List indexQueries = new ArrayList<>(); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) @@ -2577,7 +2576,7 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(10) .version(System.currentTimeMillis()).build(); - indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); + List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); indexOperations.refresh(); @@ -2609,7 +2608,6 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { // given - List indexQueries = new ArrayList<>(); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) @@ -2625,7 +2623,7 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(10) .version(System.currentTimeMillis()).build(); - indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); + List indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); operations.bulkIndex(indexQueries, index); indexOperations.refresh(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java index eca544fc4..32fdca749 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java @@ -15,49 +15,43 @@ */ package org.springframework.data.elasticsearch.core; -import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; +import java.util.HashMap; import org.elasticsearch.action.ActionFuture; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.get.GetRequestBuilder; +import org.elasticsearch.action.get.GetResponse; +import org.elasticsearch.action.get.MultiGetItemResponse; +import org.elasticsearch.action.get.MultiGetRequestBuilder; +import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.MultiSearchRequest; +import org.elasticsearch.action.search.MultiSearchResponse; +import org.elasticsearch.action.search.SearchRequestBuilder; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.action.search.SearchScrollRequestBuilder; +import org.elasticsearch.action.search.SearchType; import org.elasticsearch.client.Client; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.common.unit.TimeValue; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; -import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.mapping.callback.EntityCallbacks; -import org.springframework.lang.Nullable; -import org.springframework.util.CollectionUtils; /** * @author Roman Puchkovskiy */ @ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) -public class ElasticsearchTransportTemplateCallbackTests { - - private ElasticsearchTemplate template; +class ElasticsearchTransportTemplateCallbackTests extends AbstractElasticsearchTemplateCallbackTests { @Mock private Client client; @@ -68,10 +62,23 @@ public class ElasticsearchTransportTemplateCallbackTests { @Mock private ActionFuture bulkResponseActionFuture; @Mock private BulkResponse bulkResponse; @Mock private BulkItemResponse bulkItemResponse; + @Mock private GetRequestBuilder getRequestBuilder; + @Mock private ActionFuture getResponseActionFuture; + @Mock private GetResponse getResponse; + @Mock private MultiGetRequestBuilder multiGetRequestBuilder; + @Mock private ActionFuture multiGetResponseActionFuture; + @Mock private MultiGetResponse multiGetResponse; + @Mock private MultiGetItemResponse multiGetItemResponse; + @Mock private SearchRequestBuilder searchRequestBuilder; + @Mock private ActionFuture searchResponseActionFuture; + @Mock private ActionFuture multiSearchResponseActionFuture; + @Mock private MultiSearchResponse.Item multiSearchResponseItem; + @Mock private SearchScrollRequestBuilder searchScrollRequestBuilder; @BeforeEach + @SuppressWarnings("deprecation") // we know what we are testing public void setUp() { - template = new ElasticsearchTemplate(client); + initTemplate(new ElasticsearchTemplate(client)); when(client.prepareIndex(anyString(), anyString(), anyString())).thenReturn(indexRequestBuilder); doReturn(indexResponseActionFuture).when(indexRequestBuilder).execute(); @@ -83,198 +90,53 @@ public void setUp() { when(bulkResponseActionFuture.actionGet()).thenReturn(bulkResponse); doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn("response-id").when(bulkItemResponse).getId(); - } - - @Test // DATAES-771 - void saveOneShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - Person saved = template.save(entity); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - Person saved = template.save(entity, IndexCoordinates.of("index")); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveArrayShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(entity1, entity2); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveIterableShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(Arrays.asList(entity1, entity2)); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - Iterable saved = template.save(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - } - @Test // DATAES-771 - void indexShouldInvokeAfterSaveCallbacks() { + when(client.prepareGet(anyString(), any(), any())).thenReturn(getRequestBuilder); + doReturn(getResponseActionFuture).when(getRequestBuilder).execute(); + when(getResponseActionFuture.actionGet()).thenReturn(getResponse); - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity = new Person("init", "luke"); - - IndexQuery indexQuery = indexQueryForEntity(entity); - template.index(indexQuery, IndexCoordinates.of("index")); - - verify(afterSaveCallback).onAfterSave(eq(entity)); - Person savedPerson = (Person) indexQuery.getObject(); - assertThat(savedPerson.id).isEqualTo("after-save"); - } - - private IndexQuery indexQueryForEntity(Person entity) { - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setObject(entity); - return indexQuery; - } - - @Test // DATAES-771 - void bulkIndexShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - IndexQuery query1 = indexQueryForEntity(entity1); - IndexQuery query2 = indexQueryForEntity(entity2); - template.bulkIndex(Arrays.asList(query1, query2), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Person savedPerson1 = (Person) query1.getObject(); - Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); - } - - @Test // DATAES-771 - void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { - - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - - template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); - - Person entity1 = new Person("init1", "luke1"); - Person entity2 = new Person("init2", "luke2"); - - IndexQuery query1 = indexQueryForEntity(entity1); - IndexQuery query2 = indexQueryForEntity(entity2); - template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), IndexCoordinates.of("index")); - - verify(afterSaveCallback, times(2)).onAfterSave(any()); - Person savedPerson1 = (Person) query1.getObject(); - Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); - } - - @Data - @AllArgsConstructor - @NoArgsConstructor - static class Person { - - @Id String id; - String firstname; - } - - static class ValueCapturingEntityCallback { - - private final List values = new ArrayList<>(1); - - protected void capture(T value) { - values.add(value); - } - - public List getValues() { - return values; - } - - @Nullable - public T getValue() { - return CollectionUtils.lastElement(values); - } - - } - - static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallback - implements AfterSaveCallback { - - @Override - public Person onAfterSave(Person entity) { - - capture(entity); - return new Person() { + doReturn(true).when(getResponse).isExists(); + doReturn(false).when(getResponse).isSourceEmpty(); + doReturn(new HashMap() { { - id = "after-save"; - firstname = entity.firstname; + put("id", "init"); + put("firstname", "luke"); } - }; - } + }).when(getResponse).getSourceAsMap(); + + when(client.prepareMultiGet()).thenReturn(multiGetRequestBuilder); + doReturn(multiGetResponseActionFuture).when(multiGetRequestBuilder).execute(); + when(multiGetResponseActionFuture.actionGet()).thenReturn(multiGetResponse); + doReturn(new MultiGetItemResponse[]{ multiGetItemResponse, multiGetItemResponse }) + .when(multiGetResponse).getResponses(); + doReturn(getResponse).when(multiGetItemResponse).getResponse(); + + when(client.prepareSearch(anyVararg())).thenReturn(searchRequestBuilder); + doReturn(searchRequestBuilder).when(searchRequestBuilder).setSearchType(any(SearchType.class)); + doReturn(searchRequestBuilder).when(searchRequestBuilder).setVersion(anyBoolean()); + doReturn(searchRequestBuilder).when(searchRequestBuilder).setTrackScores(anyBoolean()); + doReturn(searchRequestBuilder).when(searchRequestBuilder).setScroll(any(TimeValue.class)); + doReturn(searchResponseActionFuture).when(searchRequestBuilder).execute(); + when(searchResponseActionFuture.actionGet()).thenReturn(searchResponse); + when(searchResponseActionFuture.actionGet(anyString())).thenReturn(searchResponse); + doReturn(nSearchHits(2)).when(searchResponse).getHits(); + doReturn("scroll-id").when(searchResponse).getScrollId(); + doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); + doReturn(new HashMap() { + { + put("id", "init"); + put("firstname", "luke"); + } + }).when(searchHit).getSourceAsMap(); + + when(client.multiSearch(any(MultiSearchRequest.class))).thenReturn(multiSearchResponseActionFuture); + MultiSearchResponse multiSearchResponse = new MultiSearchResponse( + new MultiSearchResponse.Item[]{ multiSearchResponseItem }, 1L); + when(multiSearchResponseActionFuture.actionGet()).thenReturn(multiSearchResponse); + doReturn(searchResponse).when(multiSearchResponseItem).getResponse(); + + when(client.prepareSearchScroll(anyString())).thenReturn(searchScrollRequestBuilder); + doReturn(searchScrollRequestBuilder).when(searchScrollRequestBuilder).setScroll(any(TimeValue.class)); + doReturn(searchResponseActionFuture).when(searchScrollRequestBuilder).execute(); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java index d49faa62e..aa3aed781 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -21,11 +21,13 @@ import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -33,8 +35,13 @@ import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.common.bytes.BytesArray; +import org.elasticsearch.index.get.GetResult; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,9 +50,14 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; import org.springframework.data.annotation.Id; +import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback; import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; import org.springframework.lang.Nullable; import org.springframework.util.CollectionUtils; @@ -65,6 +77,10 @@ public class ReactiveElasticsearchTemplateCallbackTests { @Mock private BulkResponse bulkResponse; @Mock private BulkItemResponse bulkItemResponse; @Mock private DocWriteResponse docWriteResponse; + @Mock private GetResult getResult; + @Mock private org.elasticsearch.search.SearchHit searchHit; + + private final IndexCoordinates index = IndexCoordinates.of("index"); @BeforeEach public void setUp() { @@ -77,6 +93,30 @@ public void setUp() { doReturn(new BulkItemResponse[] { bulkItemResponse, bulkItemResponse }).when(bulkResponse).getItems(); doReturn(docWriteResponse).when(bulkItemResponse).getResponse(); doReturn("response-id").when(docWriteResponse).getId(); + + when(client.multiGet(any(MultiGetRequest.class))).thenReturn(Flux.just(getResult, getResult)); + + doReturn(true).when(getResult).isExists(); + doReturn(false).when(getResult).isSourceEmpty(); + doReturn(new HashMap() { + { + put("id", "init"); + put("firstname", "luke"); + } + }).when(getResult).getSource(); + + doReturn(Mono.just(getResult)).when(client).get(any(GetRequest.class)); + + when(client.search(any(SearchRequest.class))).thenReturn(Flux.just(searchHit, searchHit)); + doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); + doReturn(new HashMap() { + { + put("id", "init"); + put("firstname", "luke"); + } + }).when(searchHit).getSourceAsMap(); + + when(client.scroll(any(SearchRequest.class))).thenReturn(Flux.just(searchHit, searchHit)); } @Test // DATAES-771 @@ -175,6 +215,254 @@ void saveFromMonoAllShouldInvokeAfterSaveCallbacks() { assertThat(saved.get(1).getId()).isEqualTo("after-save"); } + @Test // DATAES-772 + void multiGetShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + List results = template.multiGet(pagedQueryForTwo(), Person.class, index) + .timeout(Duration.ofSeconds(1)) + .toStream().collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void findByIdShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + Person result = template.findById("init", Person.class).block(Duration.ofSeconds(1)); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void findByIdWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + Person result = template.findById("init", Person.class, index).block(Duration.ofSeconds(1)); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void getShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + Person result = template.get("init", Person.class).block(Duration.ofSeconds(1)); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void getWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + Person result = template.get("init", Person.class, index).block(Duration.ofSeconds(1)); + + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(result.id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void findUsingPageableShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + List results = template.find(pagedQueryForTwo(), Person.class) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + private Query pagedQueryForTwo() { + return new NativeSearchQueryBuilder() + .withIds(Arrays.asList("init1", "init2")) + .withPageable(PageRequest.of(0, 10)) + .build(); + } + + private Document lukeDocument() { + return Document.create() + .append("id", "init") + .append("firstname", "luke"); + } + + @Test // DATAES-772 + void findUsingScrollShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + List results = template.find(scrollingQueryForTwo(), Person.class) + .timeout(Duration.ofSeconds(1)) + .toStream().collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + private Query scrollingQueryForTwo() { + return new NativeSearchQueryBuilder() + .withIds(Arrays.asList("init1", "init2")) + .build(); + } + + @Test // DATAES-772 + void findWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + List results = template.find(pagedQueryForTwo(), Person.class, index) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void findWithReturnTypeShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + List results = template.find(pagedQueryForTwo(), Person.class, Person.class) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void findWithReturnTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + @SuppressWarnings("deprecation") // we know what we test + List results = template.find(pagedQueryForTwo(), Person.class, Person.class, index) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).id).isEqualTo("after-convert"); + assertThat(results.get(1).id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + List> results = template.search(pagedQueryForTwo(), Person.class) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + List> results = template.search(pagedQueryForTwo(), Person.class, index) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchWithResultTypeShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + List> results = template.search(pagedQueryForTwo(), Person.class, Person.class) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + } + + @Test // DATAES-772 + void searchWithResultTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { + + ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); + + List> results = template.search(pagedQueryForTwo(), Person.class, Person.class, index) + .timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); + + verify(afterConvertCallback, times(2)) + .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + } + @Data @AllArgsConstructor @NoArgsConstructor @@ -221,4 +509,23 @@ public Mono onAfterSave(Person entity) { }); } } + + static class ValueCapturingAfterConvertCallback extends ValueCapturingEntityCallback + implements ReactiveAfterConvertCallback { + + @Override + public Mono onAfterConvert(Person entity, Document document, IndexCoordinates index) { + + return Mono.defer(() -> { + capture(entity); + Person newPerson = new Person() { + { + id = "after-convert"; + firstname = entity.firstname; + } + }; + return Mono.just(newPerson); + }); + } + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java new file mode 100644 index 000000000..b73645dd8 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java @@ -0,0 +1,89 @@ +/* + * Copyright 2020 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; + +import static java.util.Collections.*; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Arrays; +import java.util.Iterator; + +import org.elasticsearch.search.aggregations.Aggregations; +import org.junit.jupiter.api.Test; +import org.springframework.data.util.CloseableIterator; + +/** + * @author Roman Puchkovskiy + */ +class SearchHitSupportTest { + @Test // DATAES-772 + void unwrapsSearchHitsIteratorToCloseableIteratorOfEntities() { + TestStringSearchHitsIterator searchHitsIterator = new TestStringSearchHitsIterator(); + + @SuppressWarnings("unchecked") CloseableIterator unwrappedIterator = + (CloseableIterator) SearchHitSupport.unwrapSearchHits(searchHitsIterator); + + assertThat(unwrappedIterator.next()).isEqualTo("one"); + assertThat(unwrappedIterator.next()).isEqualTo("two"); + assertThat(unwrappedIterator.hasNext()).isFalse(); + + unwrappedIterator.close(); + + assertThat(searchHitsIterator.closed).isTrue(); + } + + private static class TestStringSearchHitsIterator implements SearchHitsIterator { + private final Iterator iterator = Arrays.asList("one", "two").iterator(); + private boolean closed = false; + + @Override + public Aggregations getAggregations() { + return mock(Aggregations.class); + } + + @Override + public float getMaxScore() { + return 0; + } + + @Override + public long getTotalHits() { + return 2; + } + + @Override + public TotalHitsRelation getTotalHitsRelation() { + return mock(TotalHitsRelation.class); + } + + @Override + public void close() { + closed = true; + } + + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public SearchHit next() { + String nextString = iterator.next(); + return new SearchHit<>("id", 1.0f, new Object[0], emptyMap(), nextString); + } + } +} \ No newline at end of file From f6a37f4601c2f0c1e46d5c83406c685d0abe1f2c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 17 Apr 2020 21:40:54 +0200 Subject: [PATCH 0123/1191] DATAES-772 - Polishing. --- .../elasticsearch/core/SearchHitSupport.java | 2 +- .../core/event/AfterConvertCallback.java | 4 +- .../event/ReactiveAfterConvertCallback.java | 4 +- ...actElasticsearchTemplateCallbackTests.java | 96 ++++++++-------- ...lasticsearchRestTemplateCallbackTests.java | 22 ++-- ...csearchTransportTemplateCallbackTests.java | 22 ++-- ...iveElasticsearchTemplateCallbackTests.java | 103 +++++++----------- .../core/SearchHitSupportTest.java | 7 +- 8 files changed, 115 insertions(+), 145 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index 271af8554..bc6298889 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -97,7 +97,7 @@ public static Object unwrapSearchHits(Object result) { } private static CloseableIterator unwrapSearchHitsIterator(SearchHitsIterator iterator) { - + return new CloseableIterator() { @Override public boolean hasNext() { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java index 53e110c31..f6998d4dc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterConvertCallback.java @@ -30,8 +30,8 @@ public interface AfterConvertCallback extends EntityCallback { /** - * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either - * the same or a modified instance of the domain object. + * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the + * same or a modified instance of the domain object. * * @param entity the domain object (the result of the conversion). * @param document must not be {@literal null}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java index 62aa3abb2..abeac0014 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterConvertCallback.java @@ -31,8 +31,8 @@ public interface ReactiveAfterConvertCallback extends EntityCallback { /** - * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either - * the same or a modified instance of the domain object. + * Entity callback method invoked after a domain object is materialized from a {@link Document}. Can return either the + * same or a modified instance of the domain object. * * @param entity the domain object (the result of the conversion). * @param document must not be {@literal null}. diff --git a/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java index 4c17bfdb2..8f732fe84 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java @@ -69,7 +69,7 @@ abstract class AbstractElasticsearchTemplateCallbackTests { protected final void initTemplate(AbstractElasticsearchTemplate template) { this.template = template; - + this.template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback, afterConvertCallback)); } @@ -206,9 +206,7 @@ void getShouldInvokeAfterConvertCallback() { } private Document lukeDocument() { - return Document.create() - .append("id", "init") - .append("firstname", "luke"); + return Document.create().append("id", "init").append("firstname", "luke"); } @Test // DATAES-772 @@ -235,8 +233,8 @@ void multiGetShouldInvokeAfterConvertCallback() { List results = template.multiGet(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -267,8 +265,8 @@ void queryForPageShouldInvokeAfterConvertCallback() { @SuppressWarnings("deprecation") // we know what we test AggregatedPage results = template.queryForPage(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); } @@ -279,8 +277,8 @@ void queryForPageWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCa @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForPage(singletonList(queryForTwo()), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List persons = results.get(0).getContent(); assertThat(persons.get(0).id).isEqualTo("after-convert"); assertThat(persons.get(1).id).isEqualTo("after-convert"); @@ -290,14 +288,12 @@ void queryForPageWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCa void queryForPageWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCallback() { @SuppressWarnings("deprecation") // we know what we test - List> results = template.queryForPage(singletonList(queryForTwo()), - singletonList(Person.class), index); - - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - List persons = results.get(0).getContent().stream() - .map(Person.class::cast) - .collect(Collectors.toList()); + List> results = template.queryForPage(singletonList(queryForTwo()), singletonList(Person.class), + index); + + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); + List persons = results.get(0).getContent().stream().map(Person.class::cast).collect(Collectors.toList()); assertThat(persons.get(0).id).isEqualTo("after-convert"); assertThat(persons.get(1).id).isEqualTo("after-convert"); } @@ -307,8 +303,8 @@ void streamShouldInvokeAfterConvertCallback() { CloseableIterator results = template.stream(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.next().id).isEqualTo("after-convert"); assertThat(results.next().id).isEqualTo("after-convert"); } @@ -322,8 +318,8 @@ void searchScrollContinueShouldInvokeAfterConvertCallback() { assertThat(results.next().id).isEqualTo("after-convert"); assertThat(results.next().id).isEqualTo("after-convert"); - verify(afterConvertCallback, times(4)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(4)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); } private void skipItemsFromScrollStart(CloseableIterator results) { @@ -337,8 +333,8 @@ void queryForListShouldInvokeAfterConvertCallback() { @SuppressWarnings("deprecation") // we know what we test List results = template.queryForList(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -349,8 +345,8 @@ void queryForListWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCa @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForList(singletonList(queryForTwo()), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List persons = results.get(0); assertThat(persons.get(0).id).isEqualTo("after-convert"); assertThat(persons.get(1).id).isEqualTo("after-convert"); @@ -362,11 +358,9 @@ void queryForListWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCall @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForList(singletonList(queryForTwo()), singletonList(Person.class), index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - List persons = results.get(0).stream() - .map(Person.class::cast) - .collect(Collectors.toList()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); + List persons = results.get(0).stream().map(Person.class::cast).collect(Collectors.toList()); assertThat(persons.get(0).id).isEqualTo("after-convert"); assertThat(persons.get(1).id).isEqualTo("after-convert"); } @@ -377,8 +371,8 @@ void moreLikeThisShouldInvokeAfterConvertCallback() { @SuppressWarnings("deprecation") // we know what we test AggregatedPage results = template.moreLikeThis(moreLikeThisQuery(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); } @@ -408,8 +402,7 @@ void searchOneWithIndexCoordinatesShouldInvokeAfterConvertCallback() { SearchHit result = template.searchOne(queryForOne(), Person.class, index); - verify(afterConvertCallback) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); assertThat(result.getContent().id).isEqualTo("after-convert"); } @@ -418,8 +411,8 @@ void multiSearchShouldInvokeAfterConvertCallback() { List> results = template.multiSearch(singletonList(queryForTwo()), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List> hits = results.get(0).getSearchHits(); assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); @@ -428,11 +421,11 @@ void multiSearchShouldInvokeAfterConvertCallback() { @Test // DATAES-772 void multiSearchWithMultipleEntityClassesShouldInvokeAfterConvertCallback() { - List> results = template.multiSearch(singletonList(queryForTwo()), - singletonList(Person.class), index); + List> results = template.multiSearch(singletonList(queryForTwo()), singletonList(Person.class), + index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List> hits = results.get(0).getSearchHits(); assertThat(((Person) hits.get(0).getContent()).id).isEqualTo("after-convert"); assertThat(((Person) hits.get(1).getContent()).id).isEqualTo("after-convert"); @@ -443,8 +436,7 @@ void searchShouldInvokeAfterConvertCallback() { SearchHits results = template.search(queryForTwo(), Person.class); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); List> hits = results.getSearchHits(); assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); @@ -455,8 +447,8 @@ void searchWithIndexCoordinatesShouldInvokeAfterConvertCallback() { SearchHits results = template.search(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List> hits = results.getSearchHits(); assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); @@ -467,8 +459,7 @@ void searchViaMoreLikeThisShouldInvokeAfterConvertCallback() { SearchHits results = template.search(moreLikeThisQuery(), Person.class); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); List> hits = results.getSearchHits(); assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); @@ -479,8 +470,8 @@ void searchViaMoreLikeThisWithIndexCoordinatesShouldInvokeAfterConvertCallback() SearchHits results = template.search(moreLikeThisQuery(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); List> hits = results.getSearchHits(); assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); @@ -491,8 +482,7 @@ void searchForStreamShouldInvokeAfterConvertCallback() { SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.next().getContent().id).isEqualTo("after-convert"); assertThat(results.next().getContent().id).isEqualTo("after-convert"); } @@ -502,8 +492,8 @@ void searchForStreamWithIndexCoordinatesShouldInvokeAfterConvertCallback() { SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class, index); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.next().getContent().id).isEqualTo("after-convert"); assertThat(results.next().getContent().id).isEqualTo("after-convert"); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java index 4cabf0c7e..a2a3ec577 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateCallbackTests.java @@ -77,15 +77,15 @@ public void setUp() throws Exception { doReturn(true).when(getResponse).isExists(); doReturn(false).when(getResponse).isSourceEmpty(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(getResponse).getSourceAsMap(); doReturn(multiGetResponse).when(client).mget(any(MultiGetRequest.class), any(RequestOptions.class)); - doReturn(new MultiGetItemResponse[]{multiGetItemResponse, multiGetItemResponse}) - .when(multiGetResponse).getResponses(); + doReturn(new MultiGetItemResponse[] { multiGetItemResponse, multiGetItemResponse }).when(multiGetResponse) + .getResponses(); doReturn(getResponse).when(multiGetItemResponse).getResponse(); doReturn(searchResponse).when(client).search(any(SearchRequest.class), any(RequestOptions.class)); @@ -93,14 +93,14 @@ public void setUp() throws Exception { doReturn("scroll-id").when(searchResponse).getScrollId(); doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(searchHit).getSourceAsMap(); MultiSearchResponse multiSearchResponse = new MultiSearchResponse( - new MultiSearchResponse.Item[]{ multiSearchResponseItem }, 1L); + new MultiSearchResponse.Item[] { multiSearchResponseItem }, 1L); doReturn(multiSearchResponse).when(client).multiSearch(any(MultiSearchRequest.class), any()); doReturn(searchResponse).when(multiSearchResponseItem).getResponse(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java index 32fdca749..7078d627d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateCallbackTests.java @@ -98,17 +98,17 @@ public void setUp() { doReturn(true).when(getResponse).isExists(); doReturn(false).when(getResponse).isSourceEmpty(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(getResponse).getSourceAsMap(); when(client.prepareMultiGet()).thenReturn(multiGetRequestBuilder); doReturn(multiGetResponseActionFuture).when(multiGetRequestBuilder).execute(); when(multiGetResponseActionFuture.actionGet()).thenReturn(multiGetResponse); - doReturn(new MultiGetItemResponse[]{ multiGetItemResponse, multiGetItemResponse }) - .when(multiGetResponse).getResponses(); + doReturn(new MultiGetItemResponse[] { multiGetItemResponse, multiGetItemResponse }).when(multiGetResponse) + .getResponses(); doReturn(getResponse).when(multiGetItemResponse).getResponse(); when(client.prepareSearch(anyVararg())).thenReturn(searchRequestBuilder); @@ -123,15 +123,15 @@ public void setUp() { doReturn("scroll-id").when(searchResponse).getScrollId(); doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(searchHit).getSourceAsMap(); when(client.multiSearch(any(MultiSearchRequest.class))).thenReturn(multiSearchResponseActionFuture); MultiSearchResponse multiSearchResponse = new MultiSearchResponse( - new MultiSearchResponse.Item[]{ multiSearchResponseItem }, 1L); + new MultiSearchResponse.Item[] { multiSearchResponseItem }, 1L); when(multiSearchResponseActionFuture.actionGet()).thenReturn(multiSearchResponse); doReturn(searchResponse).when(multiSearchResponseItem).getResponse(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java index aa3aed781..b682f074b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -99,10 +99,10 @@ public void setUp() { doReturn(true).when(getResult).isExists(); doReturn(false).when(getResult).isSourceEmpty(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(getResult).getSource(); doReturn(Mono.just(getResult)).when(client).get(any(GetRequest.class)); @@ -110,10 +110,10 @@ public void setUp() { when(client.search(any(SearchRequest.class))).thenReturn(Flux.just(searchHit, searchHit)); doReturn(new BytesArray(new byte[8])).when(searchHit).getSourceRef(); doReturn(new HashMap() { - { - put("id", "init"); - put("firstname", "luke"); - } + { + put("id", "init"); + put("firstname", "luke"); + } }).when(searchHit).getSourceAsMap(); when(client.scroll(any(SearchRequest.class))).thenReturn(Flux.just(searchHit, searchHit)); @@ -222,12 +222,11 @@ void multiGetShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); - List results = template.multiGet(pagedQueryForTwo(), Person.class, index) - .timeout(Duration.ofSeconds(1)) + List results = template.multiGet(pagedQueryForTwo(), Person.class, index).timeout(Duration.ofSeconds(1)) .toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -294,27 +293,21 @@ void findUsingPageableShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test - List results = template.find(pagedQueryForTwo(), Person.class) - .timeout(Duration.ofSeconds(1)).toStream() + List results = template.find(pagedQueryForTwo(), Person.class).timeout(Duration.ofSeconds(1)).toStream() .collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } - + private Query pagedQueryForTwo() { - return new NativeSearchQueryBuilder() - .withIds(Arrays.asList("init1", "init2")) - .withPageable(PageRequest.of(0, 10)) + return new NativeSearchQueryBuilder().withIds(Arrays.asList("init1", "init2")).withPageable(PageRequest.of(0, 10)) .build(); } private Document lukeDocument() { - return Document.create() - .append("id", "init") - .append("firstname", "luke"); + return Document.create().append("id", "init").append("firstname", "luke"); } @Test // DATAES-772 @@ -325,20 +318,16 @@ void findUsingScrollShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test - List results = template.find(scrollingQueryForTwo(), Person.class) - .timeout(Duration.ofSeconds(1)) - .toStream().collect(Collectors.toList()); + List results = template.find(scrollingQueryForTwo(), Person.class).timeout(Duration.ofSeconds(1)).toStream() + .collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } private Query scrollingQueryForTwo() { - return new NativeSearchQueryBuilder() - .withIds(Arrays.asList("init1", "init2")) - .build(); + return new NativeSearchQueryBuilder().withIds(Arrays.asList("init1", "init2")).build(); } @Test // DATAES-772 @@ -349,12 +338,11 @@ void findWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test - List results = template.find(pagedQueryForTwo(), Person.class, index) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + List results = template.find(pagedQueryForTwo(), Person.class, index).timeout(Duration.ofSeconds(1)) + .toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -367,12 +355,10 @@ void findWithReturnTypeShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test - List results = template.find(pagedQueryForTwo(), Person.class, Person.class) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + List results = template.find(pagedQueryForTwo(), Person.class, Person.class).timeout(Duration.ofSeconds(1)) + .toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -386,11 +372,10 @@ void findWithReturnTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { @SuppressWarnings("deprecation") // we know what we test List results = template.find(pagedQueryForTwo(), Person.class, Person.class, index) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + .timeout(Duration.ofSeconds(1)).toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).id).isEqualTo("after-convert"); assertThat(results.get(1).id).isEqualTo("after-convert"); } @@ -402,12 +387,10 @@ void searchShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); - List> results = template.search(pagedQueryForTwo(), Person.class) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + List> results = template.search(pagedQueryForTwo(), Person.class).timeout(Duration.ofSeconds(1)) + .toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); } @@ -420,11 +403,10 @@ void searchWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, index) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + .timeout(Duration.ofSeconds(1)).toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); } @@ -437,11 +419,9 @@ void searchWithResultTypeShouldInvokeAfterConvertCallbacks() { template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, Person.class) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + .timeout(Duration.ofSeconds(1)).toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); } @@ -454,11 +434,10 @@ void searchWithResultTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, Person.class, index) - .timeout(Duration.ofSeconds(1)).toStream() - .collect(Collectors.toList()); + .timeout(Duration.ofSeconds(1)).toStream().collect(Collectors.toList()); - verify(afterConvertCallback, times(2)) - .onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); + verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), + eq(index)); assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java index b73645dd8..6ef6f8cc4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java @@ -34,8 +34,9 @@ class SearchHitSupportTest { void unwrapsSearchHitsIteratorToCloseableIteratorOfEntities() { TestStringSearchHitsIterator searchHitsIterator = new TestStringSearchHitsIterator(); - @SuppressWarnings("unchecked") CloseableIterator unwrappedIterator = - (CloseableIterator) SearchHitSupport.unwrapSearchHits(searchHitsIterator); + @SuppressWarnings("unchecked") + CloseableIterator unwrappedIterator = (CloseableIterator) SearchHitSupport + .unwrapSearchHits(searchHitsIterator); assertThat(unwrappedIterator.next()).isEqualTo("one"); assertThat(unwrappedIterator.next()).isEqualTo("two"); @@ -86,4 +87,4 @@ public SearchHit next() { return new SearchHit<>("id", 1.0f, new Object[0], emptyMap(), nextString); } } -} \ No newline at end of file +} From e49f140233cc74f1f992f52e927615ea8a4a1281 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 19 Apr 2020 22:58:02 +0200 Subject: [PATCH 0124/1191] DATAES-792 - Add java.util.Date to the supported types for Field annotation date times. Original PR: #432 --- .../convert/ElasticsearchDateConverter.java | 28 ++++++++++++ ...SimpleElasticsearchPersistentProperty.java | 20 +++++++-- .../ElasticsearchDateConverterTests.java | 32 +++++++++++--- ...sticsearchPersistentPropertyUnitTests.java | 44 ++++++++++++++----- 4 files changed, 104 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java index a09c95ab7..6f2a0630d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverter.java @@ -17,7 +17,9 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.time.Instant; import java.time.temporal.TemporalAccessor; +import java.util.Date; import java.util.concurrent.ConcurrentHashMap; import org.elasticsearch.common.time.DateFormatter; @@ -73,9 +75,25 @@ private ElasticsearchDateConverter(DateFormatter dateFormatter) { * @return the formatted object */ public String format(TemporalAccessor accessor) { + + Assert.notNull(accessor, "accessor must not be null"); + return dateFormatter.format(accessor); } + /** + * Formats the given {@link TemporalAccessor} int a String + * + * @param date must not be {@literal null} + * @return the formatted object + */ + public String format(Date date) { + + Assert.notNull(date, "accessor must not be null"); + + return dateFormatter.format(Instant.ofEpochMilli(date.getTime())); + } + /** * Parses a String into an object * @@ -96,4 +114,14 @@ public T parse(String input, Class type) { throw new ConversionException("could not create object of class " + type.getName(), e); } } + + /** + * Parses a String into a Date. + * + * @param input the String to parse, must not be {@literal null}. + * @return the new created object + */ + public Date parse(String input) { + return new Date(Instant.from(dateFormatter.parse(input)).toEpochMilli()); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index 5239b9107..a69f6fa20 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -17,6 +17,7 @@ import java.time.temporal.TemporalAccessor; import java.util.Arrays; +import java.util.Date; import java.util.List; import org.springframework.data.elasticsearch.annotations.DateFormat; @@ -95,11 +96,14 @@ public ElasticsearchPersistentPropertyConverter getPropertyConverter() { /** * Initializes an {@link ElasticsearchPersistentPropertyConverter} if this property is annotated as a Field with type * {@link FieldType#Date}, has a {@link DateFormat} set and if the type of the property is one of the Java8 temporal - * classes. + * classes or java.util.Date. */ private void initDateConverter() { Field field = findAnnotation(Field.class); - if (field != null && field.type() == FieldType.Date && TemporalAccessor.class.isAssignableFrom(getType())) { + boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(getType()); + boolean isDate = Date.class.isAssignableFrom(getType()); + + if (field != null && field.type() == FieldType.Date && (isTemporalAccessor || isDate)) { DateFormat dateFormat = field.format(); ElasticsearchDateConverter converter = null; @@ -119,13 +123,21 @@ private void initDateConverter() { propertyConverter = new ElasticsearchPersistentPropertyConverter() { @Override public String write(Object property) { - return dateConverter.format((TemporalAccessor) property); + if (isTemporalAccessor) { + return dateConverter.format((TemporalAccessor) property); + } else { // must be Date + return dateConverter.format((Date) property); + } } @SuppressWarnings("unchecked") @Override public Object read(String s) { - return dateConverter.parse(s, (Class) getType()); + if (isTemporalAccessor) { + return dateConverter.parse(s, (Class) getType()); + } else { // must be date + return dateConverter.parse(s); + } } }; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index a05f734b5..62ccd35b8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -3,6 +3,8 @@ import static org.assertj.core.api.Assertions.*; import java.time.LocalDate; +import java.util.Date; +import java.util.GregorianCalendar; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -14,7 +16,7 @@ */ class ElasticsearchDateConverterTests { - @ParameterizedTest + @ParameterizedTest // DATAES-716 @EnumSource(DateFormat.class) void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) { @@ -28,8 +30,8 @@ void shouldCreateConvertersForAllKnownFormats(DateFormat dateFormat) { assertThat(converter).isNotNull(); } - @Test - void shouldConvertToString() { + @Test // DATAES-716 + void shouldConvertTemporalAccessorToString() { LocalDate localDate = LocalDate.of(2019, 12, 27); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date); @@ -38,8 +40,8 @@ void shouldConvertToString() { assertThat(formatted).isEqualTo("20191227"); } - @Test - void shouldParseFromString() { + @Test // DATAES-716 + void shouldParseTemporalAccessorFromString() { LocalDate localDate = LocalDate.of(2019, 12, 27); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date); @@ -47,4 +49,24 @@ void shouldParseFromString() { assertThat(parsed).isEqualTo(localDate); } + + @Test // DATAES-792 + void shouldConvertLegacyDateToString() { + Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); + + String formatted = converter.format(date); + + assertThat(formatted).isEqualTo("20200419T194400.000Z"); + } + + @Test // DATAES-792 + void shouldParseLegacyDateFromString() { + Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); + + Date parsed = converter.parse("20200419T194400.000Z"); + + assertThat(parsed).isEqualTo(date); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index a64ddb0f6..79f45312b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -20,6 +20,7 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.Date; +import java.util.GregorianCalendar; import org.junit.jupiter.api.Test; import org.springframework.data.elasticsearch.annotations.DateFormat; @@ -69,25 +70,25 @@ public void fieldAnnotationWithValueSetsFieldname() { assertThat(persistentProperty.getFieldName()).isEqualTo("by-value"); } - @Test - // DATAES-716 + @Test // DATAES-716, DATAES-792 void shouldSetPropertyConverters() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); - ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("date"); - assertThat(persistentProperty.hasPropertyConverter()).isFalse(); - - persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); assertThat(persistentProperty.hasPropertyConverter()).isTrue(); assertThat(persistentProperty.getPropertyConverter()).isNotNull(); persistentProperty = persistentEntity.getRequiredPersistentProperty("localDateTime"); assertThat(persistentProperty.hasPropertyConverter()).isTrue(); assertThat(persistentProperty.getPropertyConverter()).isNotNull(); + + persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate"); + assertThat(persistentProperty.hasPropertyConverter()).isTrue(); + assertThat(persistentProperty.getPropertyConverter()).isNotNull(); + } - @Test - // DATAES-716 + @Test // DATAES-716 void shouldConvertFromLocalDate() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); @@ -98,8 +99,7 @@ void shouldConvertFromLocalDate() { assertThat(converted).isEqualTo("27.12.2019"); } - @Test - // DATAES-716 + @Test // DATAES-716 void shouldConvertToLocalDate() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("localDate"); @@ -110,6 +110,28 @@ void shouldConvertToLocalDate() { assertThat(converted).isEqualTo(LocalDate.of(2019, 12, 27)); } + @Test // DATAES_792 + void shouldConvertFromLegacyDate() { + SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate"); + Date legacyDate = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + + String converted = persistentProperty.getPropertyConverter().write(legacyDate); + + assertThat(converted).isEqualTo("20200419T194400.000Z"); + } + + @Test // DATES-792 + void shouldConvertToLegacyDate() { + SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate"); + + Object converted = persistentProperty.getPropertyConverter().read("20200419T194400.000Z"); + + assertThat(converted).isInstanceOf(Date.class); + assertThat(converted).isEqualTo(new GregorianCalendar(2020, 3, 19, 21, 44).getTime()); + } + static class InvalidScoreProperty { @Nullable @Score String scoreProperty; } @@ -123,8 +145,8 @@ static class FieldValueProperty { } static class DatesProperty { - @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date) Date date; @Nullable @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate; @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; + @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) Date legacyDate; } } From 0afa37c8eaf6ecaa50349cc534c9446aeeb61ee0 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 19 Apr 2020 23:34:44 +0200 Subject: [PATCH 0125/1191] DATAES-792 - Fix tests with timezone. Original PR: #433 --- .../convert/ElasticsearchDateConverterTests.java | 15 +++++++++++---- ...eElasticsearchPersistentPropertyUnitTests.java | 12 ++++++++++-- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index 62ccd35b8..58890750e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -3,6 +3,9 @@ import static org.assertj.core.api.Assertions.*; import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Date; import java.util.GregorianCalendar; @@ -52,21 +55,25 @@ void shouldParseTemporalAccessorFromString() { @Test // DATAES-792 void shouldConvertLegacyDateToString() { - Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + GregorianCalendar calendar = GregorianCalendar + .from(ZonedDateTime.of(LocalDateTime.of(2020, 04, 19, 19, 44), ZoneId.of("UTC"))); + Date legacyDate = calendar.getTime(); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); - String formatted = converter.format(date); + String formatted = converter.format(legacyDate); assertThat(formatted).isEqualTo("20200419T194400.000Z"); } @Test // DATAES-792 void shouldParseLegacyDateFromString() { - Date date = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + GregorianCalendar calendar = GregorianCalendar + .from(ZonedDateTime.of(LocalDateTime.of(2020, 04, 19, 19, 44), ZoneId.of("UTC"))); + Date legacyDate = calendar.getTime(); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); Date parsed = converter.parse("20200419T194400.000Z"); - assertThat(parsed).isEqualTo(date); + assertThat(parsed).isEqualTo(legacyDate); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 79f45312b..fa195c87c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -19,8 +19,11 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Date; import java.util.GregorianCalendar; +import java.util.TimeZone; import org.junit.jupiter.api.Test; import org.springframework.data.elasticsearch.annotations.DateFormat; @@ -114,7 +117,9 @@ void shouldConvertToLocalDate() { void shouldConvertFromLegacyDate() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate"); - Date legacyDate = new GregorianCalendar(2020, 3, 19, 21, 44).getTime(); + GregorianCalendar calendar = GregorianCalendar + .from(ZonedDateTime.of(LocalDateTime.of(2020, 4, 19, 19, 44), ZoneId.of("UTC"))); + Date legacyDate = calendar.getTime(); String converted = persistentProperty.getPropertyConverter().write(legacyDate); @@ -129,7 +134,10 @@ void shouldConvertToLegacyDate() { Object converted = persistentProperty.getPropertyConverter().read("20200419T194400.000Z"); assertThat(converted).isInstanceOf(Date.class); - assertThat(converted).isEqualTo(new GregorianCalendar(2020, 3, 19, 21, 44).getTime()); + GregorianCalendar calendar = GregorianCalendar + .from(ZonedDateTime.of(LocalDateTime.of(2020, 4, 19, 19, 44), ZoneId.of("UTC"))); + Date legacyDate = calendar.getTime(); + assertThat(converted).isEqualTo(legacyDate); } static class InvalidScoreProperty { From c2eec8c74a716e09dd3c32b1d75a256aa6f49eb6 Mon Sep 17 00:00:00 2001 From: amordleq <62701743+amordleq@users.noreply.github.com> Date: Mon, 20 Apr 2020 12:33:35 -0400 Subject: [PATCH 0126/1191] DATAES-567 - Add aggregation support to reactive client. (#430) Original PR: #430 --- .../DefaultReactiveElasticsearchClient.java | 23 ++- .../reactive/ReactiveElasticsearchClient.java | 41 +++++ .../client/util/NamedXContents.java | 163 ++++++++++++++++++ .../core/ReactiveElasticsearchTemplate.java | 39 +++++ .../core/ReactiveSearchOperations.java | 23 +++ .../ReactiveElasticsearchClientTests.java | 26 +++ .../ReactiveElasticsearchClientUnitTests.java | 82 +++++++++ .../ReactiveElasticsearchTemplateTests.java | 38 ++++ .../client/aggregate-ok-multiple-results.json | 35 ++++ .../client/aggregate-ok-no-results.json | 22 +++ .../client/aggregate-ok-single-result.json | 31 ++++ 11 files changed, 521 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java create mode 100644 src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-multiple-results.json create mode 100644 src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-no-results.json create mode 100644 src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-single-result.json diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index b63861c1b..71936494c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -94,6 +94,7 @@ import org.elasticsearch.search.Scroll; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; +import org.elasticsearch.search.aggregations.Aggregation; import org.reactivestreams.Publisher; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; @@ -101,6 +102,7 @@ import org.springframework.data.elasticsearch.client.NoReachableHostException; import org.springframework.data.elasticsearch.client.reactive.HostProvider.Verification; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices; +import org.springframework.data.elasticsearch.client.util.NamedXContents; import org.springframework.data.util.Lazy; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -128,6 +130,7 @@ * @author Huw Ayling-Miller * @author Henrique Amaral * @author Roman Puchkovskiy + * @author Russell Parry * @since 3.2 * @see ClientConfiguration * @see ReactiveRestClients @@ -401,6 +404,23 @@ public Flux search(HttpHeaders headers, SearchRequest searchRequest) .flatMap(Flux::fromIterable); } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#aggregate(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest) + */ + @Override + public Flux aggregate(HttpHeaders headers, SearchRequest searchRequest) { + + Assert.notNull(headers, "headers must not be null"); + Assert.notNull(searchRequest, "searchRequest must not be null"); + + searchRequest.source().size(0); + + return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // + .map(SearchResponse::getAggregations) // + .flatMap(Flux::fromIterable); + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#scroll(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest) @@ -751,10 +771,9 @@ private static Mono doDecode(ClientResponse response, Class responseTy } private static XContentParser createParser(String mediaType, String content) throws IOException { - return XContentType.fromMediaTypeOrFormat(mediaType) // .xContent() // - .createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); + .createParser(new NamedXContentRegistry(NamedXContents.getDefaultNamedXContents()), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); } private static Publisher handleServerError(Request request, ClientResponse response) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 914a43395..708fba9df 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.client.reactive; +import org.elasticsearch.search.aggregations.Aggregation; +import org.springframework.util.Assert; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -411,6 +413,45 @@ default Flux search(SearchRequest searchRequest) { */ Flux search(HttpHeaders headers, SearchRequest searchRequest); + /** + * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. + * + * @param consumer never {@literal null}. + * @see Search API on + * elastic.co + * @return the {@link Flux} emitting {@link Aggregation} one by one. + * @since 4.0 + */ + default Flux aggregate(Consumer consumer) { + Assert.notNull(consumer, "consumer must not be null"); + SearchRequest request = new SearchRequest(); + consumer.accept(request); + return aggregate(request); + } + + /** + * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. + * + * @param searchRequest must not be {@literal null}. + * @see Search API on + * elastic.co + * @return the {@link Flux} emitting {@link Aggregation} one by one. + * @since 4.0 + */ + default Flux aggregate(SearchRequest searchRequest) { return aggregate(HttpHeaders.EMPTY, searchRequest); } + + /** + * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param searchRequest must not be {@literal null}. + * @see Search API on + * elastic.co + * @return the {@link Flux} emitting {@link Aggregation} one by one. + * @since 4.0 + */ + Flux aggregate(HttpHeaders headers, SearchRequest searchRequest); + /** * Execute the given {@link SearchRequest} against the {@literal search scroll} API. * diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java b/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java new file mode 100644 index 000000000..edf5f1f41 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java @@ -0,0 +1,163 @@ +/* + * Copyright 2020 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.client.util; + +import org.elasticsearch.common.ParseField; +import org.elasticsearch.common.xcontent.ContextParser; +import org.elasticsearch.common.xcontent.NamedXContentRegistry; +import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.aggregations.bucket.adjacency.AdjacencyMatrixAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.adjacency.ParsedAdjacencyMatrix; +import org.elasticsearch.search.aggregations.bucket.composite.CompositeAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.composite.ParsedComposite; +import org.elasticsearch.search.aggregations.bucket.filter.FilterAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilter; +import org.elasticsearch.search.aggregations.bucket.filter.ParsedFilters; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoHashGridAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.geogrid.GeoTileGridAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.geogrid.ParsedGeoHashGrid; +import org.elasticsearch.search.aggregations.bucket.geogrid.ParsedGeoTileGrid; +import org.elasticsearch.search.aggregations.bucket.global.GlobalAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.global.ParsedGlobal; +import org.elasticsearch.search.aggregations.bucket.histogram.AutoDateHistogramAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.histogram.ParsedAutoDateHistogram; +import org.elasticsearch.search.aggregations.bucket.histogram.ParsedDateHistogram; +import org.elasticsearch.search.aggregations.bucket.histogram.ParsedHistogram; +import org.elasticsearch.search.aggregations.bucket.missing.MissingAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.missing.ParsedMissing; +import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested; +import org.elasticsearch.search.aggregations.bucket.nested.ParsedReverseNested; +import org.elasticsearch.search.aggregations.bucket.nested.ReverseNestedAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.range.DateRangeAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.range.GeoDistanceAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.range.IpRangeAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.range.ParsedBinaryRange; +import org.elasticsearch.search.aggregations.bucket.range.ParsedDateRange; +import org.elasticsearch.search.aggregations.bucket.range.ParsedGeoDistance; +import org.elasticsearch.search.aggregations.bucket.range.ParsedRange; +import org.elasticsearch.search.aggregations.bucket.range.RangeAggregationBuilder; +import org.elasticsearch.search.aggregations.bucket.sampler.InternalSampler; +import org.elasticsearch.search.aggregations.bucket.sampler.ParsedSampler; +import org.elasticsearch.search.aggregations.bucket.significant.ParsedSignificantLongTerms; +import org.elasticsearch.search.aggregations.bucket.significant.ParsedSignificantStringTerms; +import org.elasticsearch.search.aggregations.bucket.significant.SignificantLongTerms; +import org.elasticsearch.search.aggregations.bucket.significant.SignificantStringTerms; +import org.elasticsearch.search.aggregations.bucket.terms.DoubleTerms; +import org.elasticsearch.search.aggregations.bucket.terms.LongTerms; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedDoubleTerms; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; +import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; +import org.elasticsearch.search.aggregations.metrics.*; +import org.elasticsearch.search.aggregations.pipeline.*; +import org.elasticsearch.search.suggest.Suggest; +import org.elasticsearch.search.suggest.completion.CompletionSuggestion; +import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; +import org.elasticsearch.search.suggest.phrase.PhraseSuggestion; +import org.elasticsearch.search.suggest.phrase.PhraseSuggestionBuilder; +import org.elasticsearch.search.suggest.term.TermSuggestion; +import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * Original implementation source {@link org.elasticsearch.client.RestHighLevelClient#getDefaultNamedXContents()} by {@literal Elasticsearch} + * (https://www.elastic.co) licensed under the Apache License, Version 2.0. + *

+ * Modified for usage with {@link ReactiveElasticsearchClient}. + *

+ * Only intended for internal use. + * + * @author Russell Parry + * @since 4.0 + */ +public class NamedXContents { + + private NamedXContents() { + // contains only utility methods + } + + public static List getDefaultNamedXContents() { + Map> map = new HashMap<>(); + map.put(CardinalityAggregationBuilder.NAME, (p, c) -> ParsedCardinality.fromXContent(p, (String) c)); + map.put(InternalHDRPercentiles.NAME, (p, c) -> ParsedHDRPercentiles.fromXContent(p, (String) c)); + map.put(InternalHDRPercentileRanks.NAME, (p, c) -> ParsedHDRPercentileRanks.fromXContent(p, (String) c)); + map.put(InternalTDigestPercentiles.NAME, (p, c) -> ParsedTDigestPercentiles.fromXContent(p, (String) c)); + map.put(InternalTDigestPercentileRanks.NAME, (p, c) -> ParsedTDigestPercentileRanks.fromXContent(p, (String) c)); + map.put(PercentilesBucketPipelineAggregationBuilder.NAME, (p, c) -> ParsedPercentilesBucket.fromXContent(p, (String) c)); + map.put(MedianAbsoluteDeviationAggregationBuilder.NAME, (p, c) -> ParsedMedianAbsoluteDeviation.fromXContent(p, (String) c)); + map.put(MinAggregationBuilder.NAME, (p, c) -> ParsedMin.fromXContent(p, (String) c)); + map.put(MaxAggregationBuilder.NAME, (p, c) -> ParsedMax.fromXContent(p, (String) c)); + map.put(SumAggregationBuilder.NAME, (p, c) -> ParsedSum.fromXContent(p, (String) c)); + map.put(AvgAggregationBuilder.NAME, (p, c) -> ParsedAvg.fromXContent(p, (String) c)); + map.put(WeightedAvgAggregationBuilder.NAME, (p, c) -> ParsedWeightedAvg.fromXContent(p, (String) c)); + map.put(ValueCountAggregationBuilder.NAME, (p, c) -> ParsedValueCount.fromXContent(p, (String) c)); + map.put(InternalSimpleValue.NAME, (p, c) -> ParsedSimpleValue.fromXContent(p, (String) c)); + map.put(DerivativePipelineAggregationBuilder.NAME, (p, c) -> ParsedDerivative.fromXContent(p, (String) c)); + map.put(InternalBucketMetricValue.NAME, (p, c) -> ParsedBucketMetricValue.fromXContent(p, (String) c)); + map.put(StatsAggregationBuilder.NAME, (p, c) -> ParsedStats.fromXContent(p, (String) c)); + map.put(StatsBucketPipelineAggregationBuilder.NAME, (p, c) -> ParsedStatsBucket.fromXContent(p, (String) c)); + map.put(ExtendedStatsAggregationBuilder.NAME, (p, c) -> ParsedExtendedStats.fromXContent(p, (String) c)); + map.put(ExtendedStatsBucketPipelineAggregationBuilder.NAME, + (p, c) -> ParsedExtendedStatsBucket.fromXContent(p, (String) c)); + map.put(GeoBoundsAggregationBuilder.NAME, (p, c) -> ParsedGeoBounds.fromXContent(p, (String) c)); + map.put(GeoCentroidAggregationBuilder.NAME, (p, c) -> ParsedGeoCentroid.fromXContent(p, (String) c)); + map.put(HistogramAggregationBuilder.NAME, (p, c) -> ParsedHistogram.fromXContent(p, (String) c)); + map.put(DateHistogramAggregationBuilder.NAME, (p, c) -> ParsedDateHistogram.fromXContent(p, (String) c)); + map.put(AutoDateHistogramAggregationBuilder.NAME, (p, c) -> ParsedAutoDateHistogram.fromXContent(p, (String) c)); + map.put(StringTerms.NAME, (p, c) -> ParsedStringTerms.fromXContent(p, (String) c)); + map.put(LongTerms.NAME, (p, c) -> ParsedLongTerms.fromXContent(p, (String) c)); + map.put(DoubleTerms.NAME, (p, c) -> ParsedDoubleTerms.fromXContent(p, (String) c)); + map.put(MissingAggregationBuilder.NAME, (p, c) -> ParsedMissing.fromXContent(p, (String) c)); + map.put(NestedAggregationBuilder.NAME, (p, c) -> ParsedNested.fromXContent(p, (String) c)); + map.put(ReverseNestedAggregationBuilder.NAME, (p, c) -> ParsedReverseNested.fromXContent(p, (String) c)); + map.put(GlobalAggregationBuilder.NAME, (p, c) -> ParsedGlobal.fromXContent(p, (String) c)); + map.put(FilterAggregationBuilder.NAME, (p, c) -> ParsedFilter.fromXContent(p, (String) c)); + map.put(InternalSampler.PARSER_NAME, (p, c) -> ParsedSampler.fromXContent(p, (String) c)); + map.put(GeoHashGridAggregationBuilder.NAME, (p, c) -> ParsedGeoHashGrid.fromXContent(p, (String) c)); + map.put(GeoTileGridAggregationBuilder.NAME, (p, c) -> ParsedGeoTileGrid.fromXContent(p, (String) c)); + map.put(RangeAggregationBuilder.NAME, (p, c) -> ParsedRange.fromXContent(p, (String) c)); + map.put(DateRangeAggregationBuilder.NAME, (p, c) -> ParsedDateRange.fromXContent(p, (String) c)); + map.put(GeoDistanceAggregationBuilder.NAME, (p, c) -> ParsedGeoDistance.fromXContent(p, (String) c)); + map.put(FiltersAggregationBuilder.NAME, (p, c) -> ParsedFilters.fromXContent(p, (String) c)); + map.put(AdjacencyMatrixAggregationBuilder.NAME, (p, c) -> ParsedAdjacencyMatrix.fromXContent(p, (String) c)); + map.put(SignificantLongTerms.NAME, (p, c) -> ParsedSignificantLongTerms.fromXContent(p, (String) c)); + map.put(SignificantStringTerms.NAME, (p, c) -> ParsedSignificantStringTerms.fromXContent(p, (String) c)); + map.put(ScriptedMetricAggregationBuilder.NAME, (p, c) -> ParsedScriptedMetric.fromXContent(p, (String) c)); + map.put(IpRangeAggregationBuilder.NAME, (p, c) -> ParsedBinaryRange.fromXContent(p, (String) c)); + map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c)); + map.put(CompositeAggregationBuilder.NAME, (p, c) -> ParsedComposite.fromXContent(p, (String) c)); + List entries = map.entrySet().stream() + .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) + .collect(Collectors.toList()); + entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(TermSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> TermSuggestion.fromXContent(parser, (String)context))); + entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(PhraseSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> PhraseSuggestion.fromXContent(parser, (String)context))); + entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(CompletionSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> CompletionSuggestion.fromXContent(parser, (String)context))); + return entries; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 7b49f8dba..a19090abc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -17,6 +17,7 @@ import static org.elasticsearch.index.VersionType.*; +import org.elasticsearch.search.aggregations.Aggregation; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -102,6 +103,7 @@ * @author Mathias Teier * @author Aleksei Arsenev * @author Roman Puchkovskiy + * @author Russell Parry * @since 3.2 */ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations, ApplicationContextAware { @@ -608,6 +610,27 @@ private Flux doFind(Query query, Class clazz, IndexCoordinate }); } + @Override + public Flux aggregate(Query query, Class entityType) { + return aggregate(query, entityType, getIndexCoordinatesFor(entityType)); + } + + @Override + public Flux aggregate(Query query, Class entityType, IndexCoordinates index) { + return doAggregate(query, entityType, index); + } + + private Flux doAggregate(Query query, Class entityType, IndexCoordinates index) { + return Flux.defer(() -> { + SearchRequest request = requestFactory.searchRequest(query, entityType, index); + request = prepareSearchRequest(request); + request.source().size(0); + request.source().trackTotalHits(false); + + return doAggregate(request); + }); + } + @Override public Mono count(Query query, Class entityType) { return count(query, entityType, getIndexCoordinatesFor(entityType)); @@ -682,6 +705,22 @@ protected Flux doFind(SearchRequest request) { .onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } + /** + * Customization hook on the actual execution result {@link Publisher}.
+ * + * @param request the already prepared {@link SearchRequest} ready to be executed. + * @return a {@link Flux} emitting the result of the operation. + */ + protected Flux doAggregate(SearchRequest request) { + + if (QUERY_LOGGER.isDebugEnabled()) { + QUERY_LOGGER.debug("Executing doCount: {}", request); + } + + return Flux.from(execute(client -> client.aggregate(request))) // + .onErrorResume(NoSuchIndexException.class, it -> Flux.empty()); + } + /** * Customization hook on the actual execution result {@link Publisher}.
* diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java index 1006b833b..32e3e4edc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core; +import org.elasticsearch.search.aggregations.Aggregation; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -30,6 +31,7 @@ * APIs. * * @author Peter-Josef Meisch + * @author Russell Parry * @since 4.0 */ public interface ReactiveSearchOperations { @@ -183,4 +185,25 @@ default Flux> search(Query query, Class entityType) { default Flux> search(Query query, Class entityType, IndexCoordinates index) { return search(query, entityType, entityType, index); } + + /** + * Perform an aggregation specified by the given {@link Query query}.
+ * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @return a {@link Flux} emitting matching aggregations one by one. + * @since 4.0 + */ + Flux aggregate(Query query, Class entityType); + + /** + * Perform an aggregation specified by the given {@link Query query}.
+ * + * @param query must not be {@literal null}. + * @param entityType must not be {@literal null}. + * @param index the target index, must not be {@literal null} + * @return a {@link Flux} emitting matching aggregations one by one. + * @since 4.0 + */ + Flux aggregate(Query query, Class entityType, IndexCoordinates index); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index 0d7d1858c..fb13bb6bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -19,6 +19,10 @@ import lombok.SneakyThrows; import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.PutMappingRequest; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; +import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import reactor.test.StepVerifier; import java.io.IOException; @@ -67,6 +71,7 @@ * @author Mark Paluch * @author Peter-Josef Meisch * @author Henrique Amaral + * @author Russell Parry */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @@ -656,6 +661,27 @@ public void bulkShouldUpdateExistingDocument() { }).verifyComplete(); } + @Test //DATAES-567 + public void aggregateReturnsAggregationResults() throws IOException { + syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + Map jsonMap = Collections.singletonMap("properties", + Collections.singletonMap("firstname", Collections.singletonMap("type", "keyword"))); + syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); + + addSourceDocument().ofType(TYPE_I).to(INDEX_I); + + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); + searchSourceBuilder.aggregation(AggregationBuilders.terms("terms").field("firstname")); + + SearchRequest request = new SearchRequest(INDEX_I) // + .source(searchSourceBuilder); + + client.aggregate(request) + .as(StepVerifier::create) + .expectNextMatches(aggregation -> aggregation.getType().equals(StringTerms.NAME)) + .verifyComplete(); + } + private AddToIndexOfType addSourceDocument() { return add(DOC_SOURCE); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index 513c23846..feb86a9a6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -19,11 +19,15 @@ import static org.mockito.Mockito.*; import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; +import org.elasticsearch.search.aggregations.metrics.ParsedMax; +import reactor.core.publisher.Hooks; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.io.IOException; import java.net.URI; +import java.time.Instant; import java.util.Collections; import org.elasticsearch.ElasticsearchStatusException; @@ -53,6 +57,7 @@ /** * @author Christoph Strobl * @author Henrique Amaral + * @author Russell Parry */ public class ReactiveElasticsearchClientUnitTests { @@ -577,6 +582,83 @@ public void searchShouldReturnEmptyFluxIfNothingFound() { .verifyComplete(); } + // --> AGGREGATE + + @Test // DATAES-567 + public void aggregateShouldHitSearchEndpoint() { + + hostProvider.when(HOST) // + .receive(Receive::json) // + .body(fromPath("aggregate-ok-no-results")); + + client.search(new SearchRequest("twitter")).as(StepVerifier::create).verifyComplete(); + + verify(hostProvider.client(HOST)).method(HttpMethod.POST); + URI uri = hostProvider.when(HOST).captureUri(); + assertThat(uri.getRawPath()).isEqualTo("/twitter/_search"); + } + + @Test // DATAES-567 + public void aggregateShouldReturnSingleResultCorrectly() { + hostProvider.when(HOST) // + .receive(Receive::json) // + .body(fromPath("aggregate-ok-single-result")); + + client.aggregate(new SearchRequest("twitter")) // + .as(StepVerifier::create) // + .consumeNextWith(aggregation -> { + assertThat(aggregation.getName()).isEqualTo("users"); + assertThat(aggregation instanceof ParsedStringTerms); + ParsedStringTerms parsedStringTerms = (ParsedStringTerms) aggregation; + assertThat(parsedStringTerms.getBuckets().size()).isEqualTo(2); + assertThat(parsedStringTerms.getBucketByKey("kimchy").getDocCount()).isEqualTo(2); + assertThat(parsedStringTerms.getBucketByKey("elastic").getDocCount()).isEqualTo(1); + }).verifyComplete(); + } + + @Test // DATAES-567 + public void aggregateShouldReturnMultipleResultsCorrectly() { + + hostProvider.when(HOST) // + .receive(Receive::json) // + .body(fromPath("aggregate-ok-multiple-results")); + + client.aggregate(new SearchRequest("twitter")) // + .as(StepVerifier::create) // + .consumeNextWith(aggregation -> { + assertThat(aggregation.getName()).isEqualTo("users"); + assertThat(aggregation instanceof ParsedStringTerms); + ParsedStringTerms parsedStringTerms = (ParsedStringTerms) aggregation; + assertThat(parsedStringTerms.getBuckets().size()).isEqualTo(2); + assertThat(parsedStringTerms.getBucketByKey("kimchy").getDocCount()).isEqualTo(2); + assertThat(parsedStringTerms.getBucketByKey("elastic").getDocCount()).isEqualTo(1); + }) // + .consumeNextWith(aggregation -> { + assertThat(aggregation.getName()).isEqualTo("max_post_date"); + assertThat(aggregation instanceof ParsedMax); + ParsedMax parsedMax = (ParsedMax) aggregation; + assertThat(Instant.ofEpochMilli((long)parsedMax.getValue())).isEqualTo(Instant.parse("2010-01-15T01:46:38Z")); + }).verifyComplete(); + } + + @Test // DATAES-567 + public void aggregateShouldReturnAggregationWithNoValuesWhenNoResultsFound() { + + hostProvider.when(HOST) // + .receive(Receive::json) // + .body(fromPath("aggregate-ok-no-results")); + + + client.aggregate(new SearchRequest("twitter")) // + .as(StepVerifier::create) // + .consumeNextWith(aggregation -> { + assertThat(aggregation.getName()).isEqualTo("users"); + assertThat(aggregation instanceof ParsedStringTerms); + ParsedStringTerms parsedStringTerms = (ParsedStringTerms) aggregation; + assertThat(parsedStringTerms.getBuckets().size()).isEqualTo(0); + }).verifyComplete(); + } + // --> SCROLL @Test // DATAES-510 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 34649fe32..f39cbca3f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -24,6 +24,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -78,6 +80,7 @@ * @author Farid Azaza * @author Martin Choraine * @author Aleksei Arsenev + * @author Russell Parry */ @SpringIntegrationTest public class ReactiveElasticsearchTemplateTests { @@ -486,6 +489,41 @@ public void findWithoutPagingShouldReadAll() { .verifyComplete(); } + @Test // DATAES-567 + public void aggregateShouldReturnAggregations() { + + SampleEntity sampleEntity1 = randomEntity("some message"); + SampleEntity sampleEntity2 = randomEntity("some message"); + SampleEntity sampleEntity3 = randomEntity("other message"); + + index(sampleEntity1, sampleEntity2, sampleEntity3); + + NativeSearchQuery query = new NativeSearchQueryBuilder() + .withQuery(matchAllQuery()) + .addAggregation(AggregationBuilders.terms("messages").field("message")) + .build(); + + template.aggregate(query, SampleEntity.class) // + .as(StepVerifier::create) // + .consumeNextWith(aggregation -> { + assertThat(aggregation.getName()).isEqualTo("messages"); + assertThat(aggregation instanceof ParsedStringTerms); + ParsedStringTerms parsedStringTerms = (ParsedStringTerms) aggregation; + assertThat(parsedStringTerms.getBuckets().size()).isEqualTo(3); + assertThat(parsedStringTerms.getBucketByKey("message").getDocCount()).isEqualTo(3); + assertThat(parsedStringTerms.getBucketByKey("some").getDocCount()).isEqualTo(2); + assertThat(parsedStringTerms.getBucketByKey("other").getDocCount()).isEqualTo(1); + }).verifyComplete(); + } + + @Test // DATAES-567 + public void aggregateShouldReturnEmptyWhenIndexDoesNotExist() { + template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + IndexCoordinates.of("no-such-index")) // + .as(StepVerifier::create) // + .verifyComplete(); + } + @Test // DATAES-519 public void countShouldReturnZeroWhenIndexDoesNotExist() { diff --git a/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-multiple-results.json b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-multiple-results.json new file mode 100644 index 000000000..262414083 --- /dev/null +++ b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-multiple-results.json @@ -0,0 +1,35 @@ +{ + "took": 52, + "timed_out": false, + "_shards": { + "total": 5, + "successful": 5, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": 0, + "max_score": null, + "hits": [ ] + }, + "aggregations": { + "sterms#users": { + "doc_count_error_upper_bound": 0, + "sum_other_doc_count": 0, + "buckets": [ + { + "key": "kimchy", + "doc_count": 2 + }, + { + "key": "elastic", + "doc_count": 1 + } + ] + }, + "max#max_post_date": { + "value" : 1.263519998E12, + "value_as_string" : "2010-01-15T01:46:38.000Z" + } + } +} \ No newline at end of file diff --git a/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-no-results.json b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-no-results.json new file mode 100644 index 000000000..157326a81 --- /dev/null +++ b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-no-results.json @@ -0,0 +1,22 @@ +{ + "took" : 226, + "timed_out" : false, + "_shards" : { + "total" : 5, + "successful" : 5, + "skipped" : 0, + "failed" : 0 + }, + "hits" : { + "total" : 0, + "max_score" : null, + "hits" : [ ] + }, + "aggregations" : { + "sterms#users" : { + "doc_count_error_upper_bound" : 0, + "sum_other_doc_count" : 0, + "buckets" : [ ] + } + } +} diff --git a/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-single-result.json b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-single-result.json new file mode 100644 index 000000000..a08726da4 --- /dev/null +++ b/src/test/resources/org/springframework/data/elasticsearch/client/aggregate-ok-single-result.json @@ -0,0 +1,31 @@ +{ + "took": 52, + "timed_out": false, + "_shards": { + "total": 5, + "successful": 5, + "skipped": 0, + "failed": 0 + }, + "hits": { + "total": 0, + "max_score": null, + "hits": [ ] + }, + "aggregations": { + "sterms#users": { + "doc_count_error_upper_bound": 0, + "sum_other_doc_count": 0, + "buckets": [ + { + "key": "kimchy", + "doc_count": 2 + }, + { + "key": "elastic", + "doc_count": 1 + } + ] + } + } +} \ No newline at end of file From 91f442bd2f328bbfc9eed3cd59261dbdf717be35 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 20 Apr 2020 18:56:11 +0200 Subject: [PATCH 0127/1191] DATAES-567 - Polishing. --- .../DefaultReactiveElasticsearchClient.java | 10 +++-- .../reactive/ReactiveElasticsearchClient.java | 17 +++++--- .../client/util/NamedXContents.java | 40 +++++++++++-------- .../core/ReactiveElasticsearchTemplate.java | 5 +-- .../core/ReactiveSearchOperations.java | 2 +- .../ReactiveElasticsearchClientTests.java | 26 +++++------- .../ReactiveElasticsearchClientUnitTests.java | 9 ++--- .../ReactiveElasticsearchTemplateTests.java | 15 ++++--- 8 files changed, 64 insertions(+), 60 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 71936494c..76d4561c6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -410,12 +410,13 @@ public Flux search(HttpHeaders headers, SearchRequest searchRequest) */ @Override public Flux aggregate(HttpHeaders headers, SearchRequest searchRequest) { - + Assert.notNull(headers, "headers must not be null"); Assert.notNull(searchRequest, "searchRequest must not be null"); - + searchRequest.source().size(0); - + searchRequest.source().trackTotalHits(false); + return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // .map(SearchResponse::getAggregations) // .flatMap(Flux::fromIterable); @@ -773,7 +774,8 @@ private static Mono doDecode(ClientResponse response, Class responseTy private static XContentParser createParser(String mediaType, String content) throws IOException { return XContentType.fromMediaTypeOrFormat(mediaType) // .xContent() // - .createParser(new NamedXContentRegistry(NamedXContents.getDefaultNamedXContents()), DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); + .createParser(new NamedXContentRegistry(NamedXContents.getDefaultNamedXContents()), + DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); } private static Publisher handleServerError(Request request, ClientResponse response) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 708fba9df..89602ef1f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -15,8 +15,6 @@ */ package org.springframework.data.elasticsearch.client.reactive; -import org.elasticsearch.search.aggregations.Aggregation; -import org.springframework.util.Assert; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -49,9 +47,11 @@ import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.aggregations.Aggregation; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.http.HttpHeaders; +import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -416,14 +416,17 @@ default Flux search(SearchRequest searchRequest) { /** * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. * - * @param consumer never {@literal null}. - * @see Search API on - * elastic.co + * @param consumer + * never {@literal null}. * @return the {@link Flux} emitting {@link Aggregation} one by one. + * @see Search API on + * elastic.co * @since 4.0 */ default Flux aggregate(Consumer consumer) { + Assert.notNull(consumer, "consumer must not be null"); + SearchRequest request = new SearchRequest(); consumer.accept(request); return aggregate(request); @@ -438,7 +441,9 @@ default Flux aggregate(Consumer consumer) { * @return the {@link Flux} emitting {@link Aggregation} one by one. * @since 4.0 */ - default Flux aggregate(SearchRequest searchRequest) { return aggregate(HttpHeaders.EMPTY, searchRequest); } + default Flux aggregate(SearchRequest searchRequest) { + return aggregate(HttpHeaders.EMPTY, searchRequest); + } /** * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java b/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java index edf5f1f41..482a3b76e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/NamedXContents.java @@ -15,6 +15,11 @@ */ package org.springframework.data.elasticsearch.client.util; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + import org.elasticsearch.common.ParseField; import org.elasticsearch.common.xcontent.ContextParser; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -76,15 +81,11 @@ import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - /** *

- * Original implementation source {@link org.elasticsearch.client.RestHighLevelClient#getDefaultNamedXContents()} by {@literal Elasticsearch} - * (https://www.elastic.co) licensed under the Apache License, Version 2.0. + * Original implementation source {@link org.elasticsearch.client.RestHighLevelClient#getDefaultNamedXContents()} by + * {@literal Elasticsearch} (https://www.elastic.co) licensed under the Apache + * License, Version 2.0. *

* Modified for usage with {@link ReactiveElasticsearchClient}. *

@@ -106,8 +107,10 @@ public static List getDefaultNamedXContents() { map.put(InternalHDRPercentileRanks.NAME, (p, c) -> ParsedHDRPercentileRanks.fromXContent(p, (String) c)); map.put(InternalTDigestPercentiles.NAME, (p, c) -> ParsedTDigestPercentiles.fromXContent(p, (String) c)); map.put(InternalTDigestPercentileRanks.NAME, (p, c) -> ParsedTDigestPercentileRanks.fromXContent(p, (String) c)); - map.put(PercentilesBucketPipelineAggregationBuilder.NAME, (p, c) -> ParsedPercentilesBucket.fromXContent(p, (String) c)); - map.put(MedianAbsoluteDeviationAggregationBuilder.NAME, (p, c) -> ParsedMedianAbsoluteDeviation.fromXContent(p, (String) c)); + map.put(PercentilesBucketPipelineAggregationBuilder.NAME, + (p, c) -> ParsedPercentilesBucket.fromXContent(p, (String) c)); + map.put(MedianAbsoluteDeviationAggregationBuilder.NAME, + (p, c) -> ParsedMedianAbsoluteDeviation.fromXContent(p, (String) c)); map.put(MinAggregationBuilder.NAME, (p, c) -> ParsedMin.fromXContent(p, (String) c)); map.put(MaxAggregationBuilder.NAME, (p, c) -> ParsedMax.fromXContent(p, (String) c)); map.put(SumAggregationBuilder.NAME, (p, c) -> ParsedSum.fromXContent(p, (String) c)); @@ -149,15 +152,18 @@ public static List getDefaultNamedXContents() { map.put(IpRangeAggregationBuilder.NAME, (p, c) -> ParsedBinaryRange.fromXContent(p, (String) c)); map.put(TopHitsAggregationBuilder.NAME, (p, c) -> ParsedTopHits.fromXContent(p, (String) c)); map.put(CompositeAggregationBuilder.NAME, (p, c) -> ParsedComposite.fromXContent(p, (String) c)); - List entries = map.entrySet().stream() - .map(entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) + List entries = map.entrySet().stream().map( + entry -> new NamedXContentRegistry.Entry(Aggregation.class, new ParseField(entry.getKey()), entry.getValue())) .collect(Collectors.toList()); - entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(TermSuggestionBuilder.SUGGESTION_NAME), - (parser, context) -> TermSuggestion.fromXContent(parser, (String)context))); - entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(PhraseSuggestionBuilder.SUGGESTION_NAME), - (parser, context) -> PhraseSuggestion.fromXContent(parser, (String)context))); - entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(CompletionSuggestionBuilder.SUGGESTION_NAME), - (parser, context) -> CompletionSuggestion.fromXContent(parser, (String)context))); + entries.add( + new NamedXContentRegistry.Entry(Suggest.Suggestion.class, new ParseField(TermSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> TermSuggestion.fromXContent(parser, (String) context))); + entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, + new ParseField(PhraseSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> PhraseSuggestion.fromXContent(parser, (String) context))); + entries.add(new NamedXContentRegistry.Entry(Suggest.Suggestion.class, + new ParseField(CompletionSuggestionBuilder.SUGGESTION_NAME), + (parser, context) -> CompletionSuggestion.fromXContent(parser, (String) context))); return entries; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index a19090abc..c9f006b7c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -17,7 +17,6 @@ import static org.elasticsearch.index.VersionType.*; -import org.elasticsearch.search.aggregations.Aggregation; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -50,6 +49,7 @@ import org.elasticsearch.index.query.WrapperQueryBuilder; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; +import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortBuilders; @@ -624,9 +624,6 @@ private Flux doAggregate(Query query, Class entityType, IndexCoo return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, entityType, index); request = prepareSearchRequest(request); - request.source().size(0); - request.source().trackTotalHits(false); - return doAggregate(request); }); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java index 32e3e4edc..47eada0de 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -15,11 +15,11 @@ */ package org.springframework.data.elasticsearch.core; -import org.elasticsearch.search.aggregations.Aggregation; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.aggregations.Aggregation; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Query; diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index fb13bb6bc..c737ec6b9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -18,11 +18,6 @@ import static org.assertj.core.api.Assertions.*; import lombok.SneakyThrows; -import org.elasticsearch.client.indices.GetIndexRequest; -import org.elasticsearch.client.indices.PutMappingRequest; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; -import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; import reactor.test.StepVerifier; import java.io.IOException; @@ -47,12 +42,16 @@ import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.indices.CreateIndexRequest; +import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -218,9 +217,9 @@ public void multiGetShouldSkipNonExistingDocuments() { String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // - .add(INDEX_I,id1) // - .add(INDEX_I,"this-one-does-not-exist") // - .add(INDEX_I,id2); // + .add(INDEX_I, id1) // + .add(INDEX_I, "this-one-does-not-exist") // + .add(INDEX_I, id2); // client.multiGet(request) // .map(GetResult::getId) // @@ -236,8 +235,7 @@ public void multiGetShouldCompleteIfNothingFound() { String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); client.multiGet(new MultiGetRequest() // - .add(INDEX_II, id1) - .add(INDEX_II, id2)) // + .add(INDEX_II, id1).add(INDEX_II, id2)) // .as(StepVerifier::create) // .verifyComplete(); } @@ -661,7 +659,7 @@ public void bulkShouldUpdateExistingDocument() { }).verifyComplete(); } - @Test //DATAES-567 + @Test // DATAES-567 public void aggregateReturnsAggregationResults() throws IOException { syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); Map jsonMap = Collections.singletonMap("properties", @@ -676,10 +674,8 @@ public void aggregateReturnsAggregationResults() throws IOException { SearchRequest request = new SearchRequest(INDEX_I) // .source(searchSourceBuilder); - client.aggregate(request) - .as(StepVerifier::create) - .expectNextMatches(aggregation -> aggregation.getType().equals(StringTerms.NAME)) - .verifyComplete(); + client.aggregate(request).as(StepVerifier::create) + .expectNextMatches(aggregation -> aggregation.getType().equals(StringTerms.NAME)).verifyComplete(); } private AddToIndexOfType addSourceDocument() { diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index feb86a9a6..25b0bdea4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -19,9 +19,6 @@ import static org.mockito.Mockito.*; import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*; -import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; -import org.elasticsearch.search.aggregations.metrics.ParsedMax; -import reactor.core.publisher.Hooks; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -43,6 +40,8 @@ import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.VersionType; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; +import org.elasticsearch.search.aggregations.metrics.ParsedMax; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -637,7 +636,8 @@ public void aggregateShouldReturnMultipleResultsCorrectly() { assertThat(aggregation.getName()).isEqualTo("max_post_date"); assertThat(aggregation instanceof ParsedMax); ParsedMax parsedMax = (ParsedMax) aggregation; - assertThat(Instant.ofEpochMilli((long)parsedMax.getValue())).isEqualTo(Instant.parse("2010-01-15T01:46:38Z")); + assertThat(Instant.ofEpochMilli((long) parsedMax.getValue())) + .isEqualTo(Instant.parse("2010-01-15T01:46:38Z")); }).verifyComplete(); } @@ -648,7 +648,6 @@ public void aggregateShouldReturnAggregationWithNoValuesWhenNoResultsFound() { .receive(Receive::json) // .body(fromPath("aggregate-ok-no-results")); - client.aggregate(new SearchRequest("twitter")) // .as(StepVerifier::create) // .consumeNextWith(aggregation -> { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index f39cbca3f..90d9833d8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -24,8 +24,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.elasticsearch.search.aggregations.AggregationBuilders; -import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -41,6 +39,8 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.elasticsearch.search.aggregations.AggregationBuilders; +import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; import org.elasticsearch.search.sort.FieldSortBuilder; import org.elasticsearch.search.sort.SortOrder; import org.junit.jupiter.api.AfterEach; @@ -498,10 +498,8 @@ public void aggregateShouldReturnAggregations() { index(sampleEntity1, sampleEntity2, sampleEntity3); - NativeSearchQuery query = new NativeSearchQueryBuilder() - .withQuery(matchAllQuery()) - .addAggregation(AggregationBuilders.terms("messages").field("message")) - .build(); + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + .addAggregation(AggregationBuilders.terms("messages").field("message")).build(); template.aggregate(query, SampleEntity.class) // .as(StepVerifier::create) // @@ -518,8 +516,9 @@ public void aggregateShouldReturnAggregations() { @Test // DATAES-567 public void aggregateShouldReturnEmptyWhenIndexDoesNotExist() { - template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, - IndexCoordinates.of("no-such-index")) // + template + .aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .verifyComplete(); } From 16d8cc22d1b5205e0124efbcdc9dfea3e256fca3 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 20 Apr 2020 22:42:04 +0200 Subject: [PATCH 0128/1191] DATAES-794 - MappingBuilder must not write empty mapping properties. Original PR: #434 --- .../elasticsearch/core/index/MappingBuilder.java | 9 +++++++++ .../core/index/MappingBuilderTests.java | 14 ++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index d9ccdbab4..c75e1d332 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -313,6 +313,15 @@ private void applyDefaultIdFieldMapping(XContentBuilder builder, ElasticsearchPe private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property, Field annotation, boolean nestedOrObjectField) throws IOException { + // build the property json, if empty skip it as this is no valid mapping + XContentBuilder propertyBuilder = jsonBuilder().startObject(); + addFieldMappingParameters(propertyBuilder, annotation, nestedOrObjectField); + propertyBuilder.endObject().close(); + + if ("{}".equals(propertyBuilder.getOutputStream().toString())) { + return; + } + builder.startObject(property.getFieldName()); addFieldMappingParameters(builder, annotation, nestedOrObjectField); builder.endObject(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 3969bb537..f652044de 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -380,7 +380,7 @@ public void shouldUseFieldNameOnCircularEntity() throws JSONException { // given String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"circular-property\":{\"type\":\"object\",\"properties\":{\"id-property\":{}}}" + "}}"; + + "\"circular-property\":{\"type\":\"object\",\"properties\":{}}" + "}}"; // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.CircularEntity.class); @@ -438,19 +438,15 @@ public void shouldSetFieldMappingProperties() throws JSONException { " \"storeTrue\": {\n" + // " \"store\": true\n" + // " },\n" + // - " \"storeFalse\": {},\n" + // - " \"indexTrue\": {},\n" + // " \"indexFalse\": {\n" + // " \"index\": false\n" + // " },\n" + // - " \"coerceTrue\": {},\n" + // " \"coerceFalse\": {\n" + // " \"coerce\": false\n" + // " },\n" + // " \"fielddataTrue\": {\n" + // " \"fielddata\": true\n" + // " },\n" + // - " \"fielddataFalse\": {},\n" + // " \"type\": {\n" + // " \"type\": \"integer\"\n" + // " },\n" + // @@ -476,15 +472,12 @@ public void shouldSetFieldMappingProperties() throws JSONException { " \"type\": \"keyword\",\n" + // " \"doc_values\": false\n" + // " },\n" + // - " \"ignoreMalformedFalse\": {},\n" + // " \"ignoreMalformedTrue\": {\n" + // " \"ignore_malformed\": true\n" + // " },\n" + // " \"indexPhrasesTrue\": {\n" + // " \"index_phrases\": true\n" + // " },\n" + // - " \"indexPhrasesFalse\": {},\n" + // - " \"indexOptionsNone\": {},\n" + // " \"indexOptionsPositions\": {\n" + // " \"index_options\": \"positions\"\n" + // " },\n" + // @@ -494,22 +487,18 @@ public void shouldSetFieldMappingProperties() throws JSONException { " \"customIndexPrefixes\": {\n" + // " \"index_prefixes\":{\"min_chars\":1,\"max_chars\":10}" + // " },\n" + // - " \"normsTrue\": {},\n" + // " \"normsFalse\": {\n" + // " \"norms\": false\n" + // " },\n" + // - " \"nullValueNotSet\": {},\n" + // " \"nullValueSet\": {\n" + // " \"null_value\": \"NULLNULL\"\n" + // " },\n" + // " \"positionIncrementGap\": {\n" + // " \"position_increment_gap\": 42\n" + // " },\n" + // - " \"similarityDefault\": {},\n" + // " \"similarityBoolean\": {\n" + // " \"similarity\": \"boolean\"\n" + // " },\n" + // - " \"termVectorDefault\": {},\n" + // " \"termVectorWithOffsets\": {\n" + // " \"term_vector\": \"with_offsets\"\n" + // " },\n" + // @@ -1018,6 +1007,7 @@ static class FieldMappingParameters { @Nullable @Field private String termVectorDefault; @Nullable @Field(termVector = TermVector.with_offsets) private String termVectorWithOffsets; @Nullable @Field(type = FieldType.Scaled_Float, scalingFactor = 100.0) Double scaledFloat; + @Nullable @Field(type = Auto) String autoField; } @Document(indexName = "test-index-configure-dynamic-mapping") From 5019793f172233fbdb1f11f8782107dd984262db Mon Sep 17 00:00:00 2001 From: kkonrad Date: Tue, 21 Apr 2020 20:39:03 +0200 Subject: [PATCH 0129/1191] Fix MappingElasticsearchConverter conversion from Document into Map. Original PR: #436 --- .../MappingElasticsearchConverter.java | 3 ++- ...appingElasticsearchConverterUnitTests.java | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 83acc9e25..be456595b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -70,6 +70,7 @@ * @author Peter-Josef Meisch * @author Mark Paluch * @author Roman Puchkovskiy + * @author Konrad Kurdej * @since 3.2 */ public class MappingElasticsearchConverter @@ -319,7 +320,7 @@ private R readMapValue(@Nullable Map source, ElasticsearchPe target.put(entryKey, null); } else if (isSimpleType(entryValue)) { target.put(entryKey, - readSimpleValue(entryValue, targetType.isMap() ? targetType.getComponentType() : targetType)); + readSimpleValue(entryValue, targetType.isMap() ? targetType.getMapValueType() : targetType)); } else { ElasticsearchPersistentEntity targetEntity = computeGenericValueTypeForRead(property, entryValue); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 0b730c71a..99218cc46 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -68,6 +68,7 @@ * @author Christoph Strobl * @author Mark Paluch * @author Peter-Josef Meisch + * @author Konrad Kurdej */ public class MappingElasticsearchConverterUnitTests { @@ -662,6 +663,20 @@ void readEntityWithMapDataType() { assertThat(notification.params.get("content")).isNull(); } + @Test // DATAES-795 + void readGenericMapWithSimpleTypes() { + Map mapWithSimpleValues = new HashMap<>(); + mapWithSimpleValues.put("int", 1); + mapWithSimpleValues.put("string", "string"); + mapWithSimpleValues.put("boolean", true); + + Document document = Document.create(); + document.put("schemaLessObject", mapWithSimpleValues); + + SchemaLessObjectWrapper wrapper = mappingElasticsearchConverter.read(SchemaLessObjectWrapper.class, document); + assertThat(wrapper.getSchemaLessObject()).isEqualTo(mapWithSimpleValues); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -860,4 +875,12 @@ static class GeoEntity { @GeoPointField private double[] pointD; } + + @Data + @NoArgsConstructor + @AllArgsConstructor + static class SchemaLessObjectWrapper { + + private Map schemaLessObject; + } } From 7501c19be46f3b2d7e3e7dfa9edbf43e86c4eeff Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Tue, 21 Apr 2020 23:24:22 +0400 Subject: [PATCH 0130/1191] DATAES-785 - Various entity callbacks implementation improvements. Original PR: #431 --- .../core/AbstractElasticsearchTemplate.java | 24 +- .../core/ElasticsearchRestTemplate.java | 8 +- .../core/ElasticsearchTemplate.java | 8 +- .../core/ReactiveElasticsearchTemplate.java | 113 +++++--- .../core/event/AfterSaveCallback.java | 4 +- .../core/event/AuditingEntityCallback.java | 4 +- .../core/event/BeforeConvertCallback.java | 5 +- .../core/event/ReactiveAfterSaveCallback.java | 4 +- .../event/ReactiveAuditingEntityCallback.java | 4 +- .../event/ReactiveBeforeConvertCallback.java | 5 +- .../config/AuditingIntegrationTest.java | 6 +- .../ReactiveAuditingIntegrationTest.java | 6 +- ...actElasticsearchTemplateCallbackTests.java | 249 +++++++++++++----- ...iveElasticsearchTemplateCallbackTests.java | 188 +++++++------ .../event/AuditingEntityCallbackTests.java | 6 +- .../ElasticsearchOperationsCallbackTest.java | 4 +- .../ReactiveAuditingEntityCallbackTests.java | 6 +- ...veElasticsearchOperationsCallbackTest.java | 4 +- 18 files changed, 415 insertions(+), 233 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 3f4a96e14..0fa786821 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -463,23 +463,23 @@ private IndexQuery getIndexQuery(T entity) { // endregion // region Entity callbacks - protected T maybeCallbackBeforeConvert(T entity) { + protected T maybeCallbackBeforeConvert(T entity, IndexCoordinates index) { if (entityCallbacks != null) { - return entityCallbacks.callback(BeforeConvertCallback.class, entity); + return entityCallbacks.callback(BeforeConvertCallback.class, entity, index); } return entity; } - protected void maybeCallbackBeforeConvertWithQuery(Object query) { + protected void maybeCallbackBeforeConvertWithQuery(Object query, IndexCoordinates index) { if (query instanceof IndexQuery) { IndexQuery indexQuery = (IndexQuery) query; Object queryObject = indexQuery.getObject(); if (queryObject != null) { - queryObject = maybeCallbackBeforeConvert(queryObject); + queryObject = maybeCallbackBeforeConvert(queryObject, index); indexQuery.setObject(queryObject); } } @@ -487,27 +487,27 @@ protected void maybeCallbackBeforeConvertWithQuery(Object query) { // this can be called with either a List or a List; these query classes // don't have a common base class, therefore the List argument - protected void maybeCallbackBeforeConvertWithQueries(List queries) { - queries.forEach(this::maybeCallbackBeforeConvertWithQuery); + protected void maybeCallbackBeforeConvertWithQueries(List queries, IndexCoordinates index) { + queries.forEach(query -> maybeCallbackBeforeConvertWithQuery(query, index)); } - protected T maybeCallbackAfterSave(T entity) { + protected T maybeCallbackAfterSave(T entity, IndexCoordinates index) { if (entityCallbacks != null) { - return entityCallbacks.callback(AfterSaveCallback.class, entity); + return entityCallbacks.callback(AfterSaveCallback.class, entity, index); } return entity; } - protected void maybeCallbackAfterSaveWithQuery(Object query) { + protected void maybeCallbackAfterSaveWithQuery(Object query, IndexCoordinates index) { if (query instanceof IndexQuery) { IndexQuery indexQuery = (IndexQuery) query; Object queryObject = indexQuery.getObject(); if (queryObject != null) { - queryObject = maybeCallbackAfterSave(queryObject); + queryObject = maybeCallbackAfterSave(queryObject, index); indexQuery.setObject(queryObject); } } @@ -515,8 +515,8 @@ protected void maybeCallbackAfterSaveWithQuery(Object query) { // this can be called with either a List or a List; these query classes // don't have a common base class, therefore the List argument - protected void maybeCallbackAfterSaveWithQueries(List queries) { - queries.forEach(this::maybeCallbackAfterSaveWithQuery); + protected void maybeCallbackAfterSaveWithQueries(List queries, IndexCoordinates index) { + queries.forEach(query -> maybeCallbackAfterSaveWithQuery(query, index)); } protected T maybeCallbackAfterConvert(T entity, Document document, IndexCoordinates index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 308aaed3b..3d6fc25c5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -136,7 +136,7 @@ public IndexOperations indexOps(IndexCoordinates index) { @Override public String index(IndexQuery query, IndexCoordinates index) { - maybeCallbackBeforeConvertWithQuery(query); + maybeCallbackBeforeConvertWithQuery(query, index); IndexRequest request = requestFactory.indexRequest(query, index); String documentId = execute(client -> client.index(request, RequestOptions.DEFAULT).getId()); @@ -147,7 +147,7 @@ public String index(IndexQuery query, IndexCoordinates index) { setPersistentEntityId(queryObject, documentId); } - maybeCallbackAfterSaveWithQuery(query); + maybeCallbackAfterSaveWithQuery(query, index); return documentId; } @@ -232,11 +232,11 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - maybeCallbackBeforeConvertWithQueries(queries); + maybeCallbackBeforeConvertWithQueries(queries, index); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); List ids = checkForBulkOperationFailure( execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); - maybeCallbackAfterSaveWithQueries(queries); + maybeCallbackAfterSaveWithQueries(queries, index); return ids; } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 467e1f585..43ca3b1c5 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -142,7 +142,7 @@ public void setSearchTimeout(String searchTimeout) { @Override public String index(IndexQuery query, IndexCoordinates index) { - maybeCallbackBeforeConvertWithQuery(query); + maybeCallbackBeforeConvertWithQuery(query, index); IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); String documentId = indexRequestBuilder.execute().actionGet().getId(); @@ -153,7 +153,7 @@ public String index(IndexQuery query, IndexCoordinates index) { setPersistentEntityId(queryObject, documentId); } - maybeCallbackAfterSaveWithQuery(query); + maybeCallbackAfterSaveWithQuery(query, index); return documentId; } @@ -196,7 +196,7 @@ public List bulkIndex(List queries, BulkOptions bulkOptions, List ids = doBulkOperation(queries, bulkOptions, index); - maybeCallbackAfterSaveWithQueries(queries); + maybeCallbackAfterSaveWithQueries(queries, index); return ids; } @@ -245,7 +245,7 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { } private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { - maybeCallbackBeforeConvertWithQueries(queries); + maybeCallbackBeforeConvertWithQueries(queries, index); BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); return checkForBulkOperationFailure(bulkRequest.execute().actionGet()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index c9f006b7c..b8054ea5c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -19,12 +19,12 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -187,12 +187,15 @@ public Mono save(T entity, IndexCoordinates index) { Assert.notNull(entity, "Entity must not be null!"); - AdaptibleEntity adaptableEntity = operations.forEntity(entity, converter.getConversionService()); - - return doIndex(entity, adaptableEntity, index) // + return maybeCallBeforeConvert(entity, index) + .flatMap(entityAfterBeforeConversionCallback -> doIndex(entityAfterBeforeConversionCallback, index)) // .map(it -> { - return adaptableEntity.populateIdIfNecessary(it.getId()); - }).flatMap(this::maybeCallAfterSave); + T savedEntity = it.getT1(); + IndexResponse indexResponse = it.getT2(); + AdaptibleEntity adaptableEntity = operations.forEntity(savedEntity, converter.getConversionService()); + return adaptableEntity.populateIdIfNecessary(indexResponse.getId()); + }) + .flatMap(saved -> maybeCallAfterSave(saved, index)); } @Override @@ -201,32 +204,35 @@ public Mono save(T entity) { } @Override - public Flux saveAll(Mono> entities, IndexCoordinates index) { - - Assert.notNull(entities, "Entities must not be null!"); - - return entities.flatMapMany(entityList -> { - - List> adaptibleEntities = entityList.stream() // - .map(e -> operations.forEntity(e, converter.getConversionService())) // - .collect(Collectors.toList()); + public Flux saveAll(Mono> entitiesPublisher, IndexCoordinates index) { + + Assert.notNull(entitiesPublisher, "Entities must not be null!"); + + return entitiesPublisher + .flatMapMany(entities -> { + return Flux.fromIterable(entities) // + .concatMap(entity -> maybeCallBeforeConvert(entity, index)); + }) + .collectList() + .map(Entities::new) + .flatMapMany(entities -> { + if (entities.isEmpty()) { + return Flux.empty(); + } - if (adaptibleEntities.isEmpty()) { - return Flux.empty(); - } + return doBulkOperation(entities.indexQueries(), BulkOptions.defaultOptions(), index) // + .index() + .flatMap(indexAndResponse -> { + T savedEntity = entities.entityAt(indexAndResponse.getT1()); + BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); - Iterator> iterator = adaptibleEntities.iterator(); - List indexRequests = adaptibleEntities.stream() // - .map(e -> getIndexQuery(e.getBean(), e)) // - .collect(Collectors.toList()); - return doBulkOperation(indexRequests, BulkOptions.defaultOptions(), index) // - .flatMap(bulkItemResponse -> { + AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, + converter.getConversionService()); + adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); - AdaptibleEntity mappedEntity = iterator.next(); - mappedEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); - return maybeCallAfterSave(mappedEntity.getBean()); - }); - }); + return maybeCallAfterSave(savedEntity, index); + }); + }); } @Override @@ -332,13 +338,12 @@ protected Mono doExists(GetRequest request) { .onErrorReturn(NoSuchIndexException.class, false); } - private Mono doIndex(Object value, AdaptibleEntity entity, IndexCoordinates index) { + private Mono> doIndex(T entity, IndexCoordinates index) { - return maybeCallBeforeConvert(value).flatMap(it -> { - IndexRequest request = getIndexRequest(value, entity, index); - request = prepareIndexRequest(value, request); - return doIndex(request); - }); + AdaptibleEntity adaptibleEntity = operations.forEntity(entity, converter.getConversionService()); + IndexRequest request = getIndexRequest(entity, adaptibleEntity, index); + request = prepareIndexRequest(entity, request); + return Mono.just(entity).zipWith(doIndex(request)); } private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, IndexCoordinates index) { @@ -361,7 +366,9 @@ private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, In return request; } - private IndexQuery getIndexQuery(Object value, AdaptibleEntity entity) { + private IndexQuery getIndexQuery(Object value) { + AdaptibleEntity entity = operations.forEntity(value, converter.getConversionService()); + Object id = entity.getId(); IndexQuery query = new IndexQuery(); if (id != null) { @@ -912,19 +919,19 @@ private RuntimeException translateException(Throwable throwable) { } // region callbacks - protected Mono maybeCallBeforeConvert(T entity) { + protected Mono maybeCallBeforeConvert(T entity, IndexCoordinates index) { if (null != entityCallbacks) { - return entityCallbacks.callback(ReactiveBeforeConvertCallback.class, entity); + return entityCallbacks.callback(ReactiveBeforeConvertCallback.class, entity, index); } return Mono.just(entity); } - protected Mono maybeCallAfterSave(T entity) { + protected Mono maybeCallAfterSave(T entity, IndexCoordinates index) { if (null != entityCallbacks) { - return entityCallbacks.callback(ReactiveAfterSaveCallback.class, entity); + return entityCallbacks.callback(ReactiveAfterSaveCallback.class, entity, index); } return Mono.just(entity); @@ -995,4 +1002,30 @@ public Mono> doWith(SearchDocument response) { .map(entity -> SearchHitMapping.mappingFor(type, converter.getMappingContext()).mapHit(response, entity)); } } + + private class Entities { + private final List entities; + + private Entities(List entities) { + Assert.notNull(entities, "entities cannot be null"); + + this.entities = entities; + } + + private boolean isEmpty() { + return entities.isEmpty(); + } + + private List indexQueries() { + return entities.stream() + .map(ReactiveElasticsearchTemplate.this::getIndexQuery) + .collect(Collectors.toList()); + } + + private T entityAt(long index) { + // it's safe to cast to int because the original indexed colleciton was fitting in memory + int intIndex = (int) index; + return entities.get(intIndex); + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java index ca9639b8d..e67a354a6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AfterSaveCallback.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.event; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.data.mapping.callback.EntityCallbacks; @@ -33,7 +34,8 @@ public interface AfterSaveCallback extends EntityCallback { * the domain object. * * @param entity the domain object that was saved. + * @param index must not be {@literal null}. * @return the domain object that was persisted. */ - T onAfterSave(T entity); + T onAfterSave(T entity, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java index 779b32ba5..a8e136dbf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallback.java @@ -18,6 +18,7 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.core.Ordered; import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.util.Assert; @@ -25,6 +26,7 @@ * {@link EntityCallback} to populate auditing related fields on an entity about to be saved. * * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ public class AuditingEntityCallback implements BeforeConvertCallback, Ordered { @@ -45,7 +47,7 @@ public AuditingEntityCallback(ObjectFactory auditingH } @Override - public Object onBeforeConvert(Object entity) { + public Object onBeforeConvert(Object entity, IndexCoordinates index) { return auditingHandlerFactory.getObject().markAudited(entity); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java index 85d50706f..f39703b19 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/BeforeConvertCallback.java @@ -15,12 +15,14 @@ */ package org.springframework.data.elasticsearch.core.event; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; /** * Callback being invoked before a domain object is converted to be persisted. * * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ @FunctionalInterface @@ -31,7 +33,8 @@ public interface BeforeConvertCallback extends EntityCallback { * the domain entity class. * * @param entity the entity being converted + * @param index must not be {@literal null}. * @return the entity to be converted */ - T onBeforeConvert(T entity); + T onBeforeConvert(T entity, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java index 032e41962..e6db4214b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAfterSaveCallback.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core.event; import org.reactivestreams.Publisher; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; @@ -34,7 +35,8 @@ public interface ReactiveAfterSaveCallback extends EntityCallback { * the domain object. * * @param entity the domain object that was saved. + * @param index must not be {@literal null}. * @return a {@link Publisher} emitting the domain object to be returned to the caller. */ - Publisher onAfterSave(T entity); + Publisher onAfterSave(T entity, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java index 4051d5f71..68dedec4b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.event; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Mono; import org.springframework.beans.factory.ObjectFactory; @@ -27,6 +28,7 @@ * {@link EntityCallback} to populate auditing related fields on an entity about to be saved. * * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ public class ReactiveAuditingEntityCallback implements ReactiveBeforeConvertCallback, Ordered { @@ -47,7 +49,7 @@ public ReactiveAuditingEntityCallback(ObjectFactory a } @Override - public Mono onBeforeConvert(Object entity) { + public Mono onBeforeConvert(Object entity, IndexCoordinates index) { return Mono.just(auditingHandlerFactory.getObject().markAudited(entity)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java index e09b3ed25..457a69521 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveBeforeConvertCallback.java @@ -16,12 +16,14 @@ package org.springframework.data.elasticsearch.core.event; import org.reactivestreams.Publisher; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; /** * Callback being invoked before a domain object is converted to be persisted. * * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ @FunctionalInterface @@ -32,7 +34,8 @@ public interface ReactiveBeforeConvertCallback extends EntityCallback { * the domain entity class. * * @param entity the entity being converted + * @param index must not be {@literal null}. * @return the entity to be converted */ - Publisher onBeforeConvert(T entity); + Publisher onBeforeConvert(T entity, IndexCoordinates index); } diff --git a/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java index 4c5f80d21..1d9736d47 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/AuditingIntegrationTest.java @@ -31,12 +31,14 @@ import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Persistable; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public abstract class AuditingIntegrationTest { @@ -64,7 +66,7 @@ void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { Entity entity = new Entity(); entity.setId("1"); - entity = callbacks.callback(BeforeConvertCallback.class, entity); + entity = callbacks.callback(BeforeConvertCallback.class, entity, IndexCoordinates.of("index")); assertThat(entity.getCreated()).isNotNull(); assertThat(entity.getModified()).isEqualTo(entity.created); @@ -73,7 +75,7 @@ void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { Thread.sleep(10); - entity = callbacks.callback(BeforeConvertCallback.class, entity); + entity = callbacks.callback(BeforeConvertCallback.class, entity, IndexCoordinates.of("index")); assertThat(entity.getCreated()).isNotNull(); assertThat(entity.getModified()).isNotEqualTo(entity.created); diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java index a9bf3541c..29436c001 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java @@ -33,6 +33,7 @@ import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Persistable; import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -42,6 +43,7 @@ /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ @SpringIntegrationTest @ContextConfiguration(classes = { ReactiveAuditingIntegrationTest.Config.class }) @@ -81,7 +83,7 @@ void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { Entity entity = new Entity(); entity.setId("1"); - entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity).block(); + entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity, IndexCoordinates.of("index")).block(); assertThat(entity.getCreated()).isNotNull(); assertThat(entity.getModified()).isEqualTo(entity.created); @@ -90,7 +92,7 @@ void shouldEnableAuditingAndSetAuditingDates() throws InterruptedException { Thread.sleep(10); - entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity).block(); + entity = callbacks.callback(ReactiveBeforeConvertCallback.class, entity, IndexCoordinates.of("index")).block(); assertThat(entity.getCreated()).isNotNull(); assertThat(entity.getModified()).isNotEqualTo(entity.created); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java index 8f732fe84..34c6dc107 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplateCallbackTests.java @@ -40,6 +40,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; +import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.GetQuery; @@ -66,11 +67,10 @@ abstract class AbstractElasticsearchTemplateCallbackTests { @Spy private ValueCapturingAfterSaveCallback afterSaveCallback = new ValueCapturingAfterSaveCallback(); @Spy private ValueCapturingAfterConvertCallback afterConvertCallback = new ValueCapturingAfterConvertCallback(); + @Spy private ValueCapturingBeforeConvertCallback beforeConvertCallback = new ValueCapturingBeforeConvertCallback(); protected final void initTemplate(AbstractElasticsearchTemplate template) { this.template = template; - - this.template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback, afterConvertCallback)); } protected final org.elasticsearch.search.SearchHits nSearchHits(int count) { @@ -82,78 +82,90 @@ protected final org.elasticsearch.search.SearchHits nSearchHits(int count) { @Test // DATAES-771 void saveOneShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity = new Person("init", "luke"); Person saved = template.save(entity); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), any()); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity = new Person("init", "luke"); Person saved = template.save(entity, index); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), eq(index)); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveArrayShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); Iterable saved = template.save(entity1, entity2); - verify(afterSaveCallback, times(2)).onAfterSave(any()); + verify(afterSaveCallback, times(2)).onAfterSave(any(), any()); Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveIterableShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); Iterable saved = template.save(Arrays.asList(entity1, entity2)); - verify(afterSaveCallback, times(2)).onAfterSave(any()); + verify(afterSaveCallback, times(2)).onAfterSave(any(), any()); Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveIterableWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); Iterable saved = template.save(Arrays.asList(entity1, entity2), index); - verify(afterSaveCallback, times(2)).onAfterSave(any()); + verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); Iterator savedIterator = saved.iterator(); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); - assertThat(savedIterator.next().getId()).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); + assertThat(savedIterator.next().firstname).isEqualTo("after-save"); } @Test // DATAES-771 void indexShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity = new Person("init", "luke"); IndexQuery indexQuery = indexQueryForEntity(entity); template.index(indexQuery, index); - verify(afterSaveCallback).onAfterSave(eq(entity)); + verify(afterSaveCallback).onAfterSave(eq(entity), eq(index)); Person savedPerson = (Person) indexQuery.getObject(); - assertThat(savedPerson.id).isEqualTo("after-save"); + assertThat(savedPerson.firstname).isEqualTo("after-save"); } private IndexQuery indexQueryForEntity(Person entity) { @@ -165,6 +177,8 @@ private IndexQuery indexQueryForEntity(Person entity) { @Test // DATAES-771 void bulkIndexShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); @@ -172,16 +186,18 @@ void bulkIndexShouldInvokeAfterSaveCallbacks() { IndexQuery query2 = indexQueryForEntity(entity2); template.bulkIndex(Arrays.asList(query1, query2), index); - verify(afterSaveCallback, times(2)).onAfterSave(any()); + verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); Person savedPerson1 = (Person) query1.getObject(); Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); + assertThat(savedPerson1.firstname).isEqualTo("after-save"); + assertThat(savedPerson2.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { + template.setEntityCallbacks(EntityCallbacks.create(afterSaveCallback)); + Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); @@ -189,20 +205,22 @@ void bulkIndexWithOptionsShouldInvokeAfterSaveCallbacks() { IndexQuery query2 = indexQueryForEntity(entity2); template.bulkIndex(Arrays.asList(query1, query2), BulkOptions.defaultOptions(), index); - verify(afterSaveCallback, times(2)).onAfterSave(any()); + verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); Person savedPerson1 = (Person) query1.getObject(); Person savedPerson2 = (Person) query2.getObject(); - assertThat(savedPerson1.getId()).isEqualTo("after-save"); - assertThat(savedPerson2.getId()).isEqualTo("after-save"); + assertThat(savedPerson1.firstname).isEqualTo("after-save"); + assertThat(savedPerson2.firstname).isEqualTo("after-save"); } @Test // DATAES-772 void getShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + Person result = template.get("init", Person.class); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } private Document lukeDocument() { @@ -212,31 +230,37 @@ private Document lukeDocument() { @Test // DATAES-772 void getWithCoordinatesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + Person result = template.get("init", Person.class, index); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void getViaQueryShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test Person result = template.get(new GetQuery("init"), Person.class, index); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void multiGetShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + List results = template.multiGet(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } private Query queryForTwo() { @@ -246,13 +270,15 @@ private Query queryForTwo() { @Test // DATAES-772 void queryForObjectShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + doReturn(nSearchHits(1)).when(searchResponse).getHits(); @SuppressWarnings("deprecation") // we know what we test Person result = template.queryForObject(queryForOne(), Person.class, index); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } private Query queryForOne() { @@ -262,31 +288,37 @@ private Query queryForOne() { @Test // DATAES-772 void queryForPageShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test AggregatedPage results = template.queryForPage(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); - assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); + assertThat(results.getContent().get(0).firstname).isEqualTo("after-convert"); + assertThat(results.getContent().get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void queryForPageWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForPage(singletonList(queryForTwo()), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List persons = results.get(0).getContent(); - assertThat(persons.get(0).id).isEqualTo("after-convert"); - assertThat(persons.get(1).id).isEqualTo("after-convert"); + assertThat(persons.get(0).firstname).isEqualTo("after-convert"); + assertThat(persons.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void queryForPageWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForPage(singletonList(queryForTwo()), singletonList(Person.class), index); @@ -294,29 +326,33 @@ void queryForPageWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCall verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List persons = results.get(0).getContent().stream().map(Person.class::cast).collect(Collectors.toList()); - assertThat(persons.get(0).id).isEqualTo("after-convert"); - assertThat(persons.get(1).id).isEqualTo("after-convert"); + assertThat(persons.get(0).firstname).isEqualTo("after-convert"); + assertThat(persons.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void streamShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + CloseableIterator results = template.stream(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.next().id).isEqualTo("after-convert"); - assertThat(results.next().id).isEqualTo("after-convert"); + assertThat(results.next().firstname).isEqualTo("after-convert"); + assertThat(results.next().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchScrollContinueShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + CloseableIterator results = template.stream(queryForTwo(), Person.class, index); skipItemsFromScrollStart(results); - assertThat(results.next().id).isEqualTo("after-convert"); - assertThat(results.next().id).isEqualTo("after-convert"); + assertThat(results.next().firstname).isEqualTo("after-convert"); + assertThat(results.next().firstname).isEqualTo("after-convert"); verify(afterConvertCallback, times(4)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); @@ -330,51 +366,59 @@ private void skipItemsFromScrollStart(CloseableIterator results) { @Test // DATAES-772 void queryForListShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test List results = template.queryForList(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void queryForListWithMultipleQueriesAndSameEntityClassShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForList(singletonList(queryForTwo()), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List persons = results.get(0); - assertThat(persons.get(0).id).isEqualTo("after-convert"); - assertThat(persons.get(1).id).isEqualTo("after-convert"); + assertThat(persons.get(0).firstname).isEqualTo("after-convert"); + assertThat(persons.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void queryForListWithMultipleQueriesAndEntityClassesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test List> results = template.queryForList(singletonList(queryForTwo()), singletonList(Person.class), index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List persons = results.get(0).stream().map(Person.class::cast).collect(Collectors.toList()); - assertThat(persons.get(0).id).isEqualTo("after-convert"); - assertThat(persons.get(1).id).isEqualTo("after-convert"); + assertThat(persons.get(0).firstname).isEqualTo("after-convert"); + assertThat(persons.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void moreLikeThisShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + @SuppressWarnings("deprecation") // we know what we test AggregatedPage results = template.moreLikeThis(moreLikeThisQuery(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.getContent().get(0).id).isEqualTo("after-convert"); - assertThat(results.getContent().get(1).id).isEqualTo("after-convert"); + assertThat(results.getContent().get(0).firstname).isEqualTo("after-convert"); + assertThat(results.getContent().get(1).firstname).isEqualTo("after-convert"); } private MoreLikeThisQuery moreLikeThisQuery() { @@ -387,115 +431,164 @@ private MoreLikeThisQuery moreLikeThisQuery() { @Test // DATAES-772 void searchOneShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + doReturn(nSearchHits(1)).when(searchResponse).getHits(); SearchHit result = template.searchOne(queryForOne(), Person.class); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(result.getContent().id).isEqualTo("after-convert"); + assertThat(result.getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchOneWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + doReturn(nSearchHits(1)).when(searchResponse).getHits(); SearchHit result = template.searchOne(queryForOne(), Person.class, index); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.getContent().id).isEqualTo("after-convert"); + assertThat(result.getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void multiSearchShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + List> results = template.multiSearch(singletonList(queryForTwo()), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List> hits = results.get(0).getSearchHits(); - assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void multiSearchWithMultipleEntityClassesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + List> results = template.multiSearch(singletonList(queryForTwo()), singletonList(Person.class), index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List> hits = results.get(0).getSearchHits(); - assertThat(((Person) hits.get(0).getContent()).id).isEqualTo("after-convert"); - assertThat(((Person) hits.get(1).getContent()).id).isEqualTo("after-convert"); + assertThat(((Person) hits.get(0).getContent()).firstname).isEqualTo("after-convert"); + assertThat(((Person) hits.get(1).getContent()).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHits results = template.search(queryForTwo(), Person.class); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); List> hits = results.getSearchHits(); - assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHits results = template.search(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List> hits = results.getSearchHits(); - assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchViaMoreLikeThisShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHits results = template.search(moreLikeThisQuery(), Person.class); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); List> hits = results.getSearchHits(); - assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchViaMoreLikeThisWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHits results = template.search(moreLikeThisQuery(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); List> hits = results.getSearchHits(); - assertThat(hits.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(hits.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(hits.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(hits.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchForStreamShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.next().getContent().id).isEqualTo("after-convert"); - assertThat(results.next().getContent().id).isEqualTo("after-convert"); + assertThat(results.next().getContent().firstname).isEqualTo("after-convert"); + assertThat(results.next().getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchForStreamWithIndexCoordinatesShouldInvokeAfterConvertCallback() { + template.setEntityCallbacks(EntityCallbacks.create(afterConvertCallback)); + SearchHitsIterator results = template.searchForStream(queryForTwo(), Person.class, index); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.next().getContent().id).isEqualTo("after-convert"); - assertThat(results.next().getContent().id).isEqualTo("after-convert"); + assertThat(results.next().getContent().firstname).isEqualTo("after-convert"); + assertThat(results.next().getContent().firstname).isEqualTo("after-convert"); + } + + @Test // DATAES-785 + void saveOneShouldInvokeBeforeConvertCallbacks() { + + template.setEntityCallbacks(EntityCallbacks.create(beforeConvertCallback)); + + Person entity = new Person("init1", "luke1"); + + Person saved = template.save(entity, index); + + verify(beforeConvertCallback).onBeforeConvert(any(), eq(index)); + assertThat(saved.firstname).isEqualTo("before-convert"); + } + + @Test // DATAES-785 + void saveAllShouldInvokeBeforeConvertCallbacks() { + + template.setEntityCallbacks(EntityCallbacks.create(beforeConvertCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + Iterable saved = template.save(Arrays.asList(entity1, entity2), index); + + verify(beforeConvertCallback, times(2)).onBeforeConvert(any(), eq(index)); + Iterator iterator = saved.iterator(); + assertThat(iterator.next().firstname).isEqualTo("before-convert"); + assertThat(iterator.next().firstname).isEqualTo("before-convert"); } @Data @@ -530,13 +623,13 @@ static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallbac implements AfterSaveCallback { @Override - public Person onAfterSave(Person entity) { + public Person onAfterSave(Person entity, IndexCoordinates index) { capture(entity); return new Person() { { - id = "after-save"; - firstname = entity.firstname; + id = entity.id; + firstname = "after-save"; } }; } @@ -551,8 +644,24 @@ public Person onAfterConvert(Person entity, Document document, IndexCoordinates capture(entity); return new Person() { { - id = "after-convert"; - firstname = entity.firstname; + id = entity.id; + firstname = "after-convert"; + } + }; + } + } + + static class ValueCapturingBeforeConvertCallback extends ValueCapturingEntityCallback + implements BeforeConvertCallback { + + @Override + public Person onBeforeConvert(Person entity, IndexCoordinates indexCoordinates) { + + capture(entity); + return new Person() { + { + id = entity.id; + firstname = "before-convert"; } }; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java index b682f074b..666fcbf9e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -46,6 +46,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -55,6 +56,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.event.ReactiveAfterConvertCallback; import org.springframework.data.elasticsearch.core.event.ReactiveAfterSaveCallback; +import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; @@ -82,6 +84,10 @@ public class ReactiveElasticsearchTemplateCallbackTests { private final IndexCoordinates index = IndexCoordinates.of("index"); + @Spy private ValueCapturingAfterSaveCallback afterSaveCallback = new ValueCapturingAfterSaveCallback(); + @Spy private ValueCapturingAfterConvertCallback afterConvertCallback = new ValueCapturingAfterConvertCallback(); + @Spy private ValueCapturingBeforeConvertCallback beforeConvertCallback = new ValueCapturingBeforeConvertCallback(); + @BeforeEach public void setUp() { template = new ReactiveElasticsearchTemplate(client); @@ -122,104 +128,90 @@ public void setUp() { @Test // DATAES-771 void saveOneShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity = new Person("init", "luke"); Person saved = template.save(entity).block(Duration.ofSeconds(1)); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), any()); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveOneFromPublisherShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity = new Person("init", "luke"); Person saved = template.save(Mono.just(entity)).block(Duration.ofSeconds(1)); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), any()); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity = new Person("init", "luke"); - Person saved = template.save(entity, IndexCoordinates.of("index")).block(Duration.ofSeconds(1)); + Person saved = template.save(entity, index).block(Duration.ofSeconds(1)); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), eq(index)); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveFromPublisherWithIndexCoordinatesShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity = new Person("init", "luke"); - Person saved = template.save(Mono.just(entity), IndexCoordinates.of("index")).block(Duration.ofSeconds(1)); + Person saved = template.save(Mono.just(entity), index).block(Duration.ofSeconds(1)); - verify(afterSaveCallback).onAfterSave(eq(entity)); - assertThat(saved.id).isEqualTo("after-save"); + verify(afterSaveCallback).onAfterSave(eq(entity), eq(index)); + assertThat(saved.firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveAllShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); - List saved = template.saveAll(Arrays.asList(entity1, entity2), IndexCoordinates.of("index")).toStream() + List saved = template.saveAll(Arrays.asList(entity1, entity2), index).toStream() .collect(Collectors.toList()); - verify(afterSaveCallback, times(2)).onAfterSave(any()); - assertThat(saved.get(0).getId()).isEqualTo("after-save"); - assertThat(saved.get(1).getId()).isEqualTo("after-save"); + verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); + assertThat(saved.get(0).firstname).isEqualTo("after-save"); + assertThat(saved.get(1).firstname).isEqualTo("after-save"); } @Test // DATAES-771 void saveFromMonoAllShouldInvokeAfterSaveCallbacks() { - ValueCapturingAfterSaveCallback afterSaveCallback = spy(new ValueCapturingAfterSaveCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterSaveCallback)); Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); - List saved = template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), IndexCoordinates.of("index")) + List saved = template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), index) .toStream().collect(Collectors.toList()); - verify(afterSaveCallback, times(2)).onAfterSave(any()); - assertThat(saved.get(0).getId()).isEqualTo("after-save"); - assertThat(saved.get(1).getId()).isEqualTo("after-save"); + verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); + assertThat(saved.get(0).firstname).isEqualTo("after-save"); + assertThat(saved.get(1).firstname).isEqualTo("after-save"); } @Test // DATAES-772 void multiGetShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List results = template.multiGet(pagedQueryForTwo(), Person.class, index).timeout(Duration.ofSeconds(1)) @@ -227,69 +219,59 @@ void multiGetShouldInvokeAfterConvertCallbacks() { verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void findByIdShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test Person result = template.findById("init", Person.class).block(Duration.ofSeconds(1)); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void findByIdWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test Person result = template.findById("init", Person.class, index).block(Duration.ofSeconds(1)); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void getShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); Person result = template.get("init", Person.class).block(Duration.ofSeconds(1)); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void getWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); Person result = template.get("init", Person.class, index).block(Duration.ofSeconds(1)); verify(afterConvertCallback).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(result.id).isEqualTo("after-convert"); + assertThat(result.firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void findUsingPageableShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test @@ -297,8 +279,8 @@ void findUsingPageableShouldInvokeAfterConvertCallbacks() { .collect(Collectors.toList()); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } private Query pagedQueryForTwo() { @@ -313,8 +295,6 @@ private Document lukeDocument() { @Test // DATAES-772 void findUsingScrollShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test @@ -322,8 +302,8 @@ void findUsingScrollShouldInvokeAfterConvertCallbacks() { .collect(Collectors.toList()); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } private Query scrollingQueryForTwo() { @@ -333,8 +313,6 @@ private Query scrollingQueryForTwo() { @Test // DATAES-772 void findWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test @@ -343,15 +321,13 @@ void findWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void findWithReturnTypeShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test @@ -359,15 +335,13 @@ void findWithReturnTypeShouldInvokeAfterConvertCallbacks() { .toStream().collect(Collectors.toList()); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void findWithReturnTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); @SuppressWarnings("deprecation") // we know what we test @@ -376,30 +350,26 @@ void findWithReturnTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).id).isEqualTo("after-convert"); - assertThat(results.get(1).id).isEqualTo("after-convert"); + assertThat(results.get(0).firstname).isEqualTo("after-convert"); + assertThat(results.get(1).firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class).timeout(Duration.ofSeconds(1)) .toStream().collect(Collectors.toList()); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, index) @@ -407,30 +377,26 @@ void searchWithIndexCoordinatesShouldInvokeAfterConvertCallbacks() { verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchWithResultTypeShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, Person.class) .timeout(Duration.ofSeconds(1)).toStream().collect(Collectors.toList()); verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), any()); - assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().firstname).isEqualTo("after-convert"); } @Test // DATAES-772 void searchWithResultTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() { - ValueCapturingAfterConvertCallback afterConvertCallback = spy(new ValueCapturingAfterConvertCallback()); - template.setEntityCallbacks(ReactiveEntityCallbacks.create(afterConvertCallback)); List> results = template.search(pagedQueryForTwo(), Person.class, Person.class, index) @@ -438,8 +404,37 @@ void searchWithResultTypeAndIndexCoordinatesShouldInvokeAfterConvertCallbacks() verify(afterConvertCallback, times(2)).onAfterConvert(eq(new Person("init", "luke")), eq(lukeDocument()), eq(index)); - assertThat(results.get(0).getContent().id).isEqualTo("after-convert"); - assertThat(results.get(1).getContent().id).isEqualTo("after-convert"); + assertThat(results.get(0).getContent().firstname).isEqualTo("after-convert"); + assertThat(results.get(1).getContent().firstname).isEqualTo("after-convert"); + } + + @Test // DATAES-785 + void saveOneShouldInvokeBeforeConvertCallbacks() { + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(beforeConvertCallback)); + + Person entity = new Person("init1", "luke1"); + + Person saved = template.save(entity, index).block(Duration.ofSeconds(1)); + + verify(beforeConvertCallback).onBeforeConvert(any(), eq(index)); + assertThat(saved.firstname).isEqualTo("before-convert"); + } + + @Test // DATAES-785 + void saveAllShouldInvokeBeforeConvertCallbacks() { + + template.setEntityCallbacks(ReactiveEntityCallbacks.create(beforeConvertCallback)); + + Person entity1 = new Person("init1", "luke1"); + Person entity2 = new Person("init2", "luke2"); + + List saved = template.saveAll(Arrays.asList(entity1, entity2), index).toStream() + .collect(Collectors.toList()); + + verify(beforeConvertCallback, times(2)).onBeforeConvert(any(), eq(index)); + assertThat(saved.get(0).firstname).isEqualTo("before-convert"); + assertThat(saved.get(1).firstname).isEqualTo("before-convert"); } @Data @@ -474,14 +469,14 @@ static class ValueCapturingAfterSaveCallback extends ValueCapturingEntityCallbac implements ReactiveAfterSaveCallback { @Override - public Mono onAfterSave(Person entity) { + public Mono onAfterSave(Person entity, IndexCoordinates index) { return Mono.defer(() -> { capture(entity); Person newPerson = new Person() { { - id = "after-save"; - firstname = entity.firstname; + id = entity.id; + firstname = "after-save"; } }; return Mono.just(newPerson); @@ -499,8 +494,27 @@ public Mono onAfterConvert(Person entity, Document document, IndexCoordi capture(entity); Person newPerson = new Person() { { - id = "after-convert"; - firstname = entity.firstname; + id = entity.id; + firstname = "after-convert"; + } + }; + return Mono.just(newPerson); + }); + } + } + + static class ValueCapturingBeforeConvertCallback extends ValueCapturingEntityCallback + implements ReactiveBeforeConvertCallback { + + @Override + public Mono onBeforeConvert(Person entity, IndexCoordinates index) { + + return Mono.defer(() -> { + capture(entity); + Person newPerson = new Person() { + { + id = entity.id; + firstname = "before-convert"; } }; return Mono.just(newPerson); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java index 52dad6ea9..67fe22e4b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/AuditingEntityCallbackTests.java @@ -30,12 +30,14 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ @ExtendWith(MockitoExtension.class) class AuditingEntityCallbackTests { @@ -66,7 +68,7 @@ void shouldHaveOrder100() { void shouldCallHandler() { Sample entity = new Sample(); entity.setId("42"); - callback.onBeforeConvert(entity); + callback.onBeforeConvert(entity, IndexCoordinates.of("index")); verify(handler).markAudited(eq(entity)); } @@ -79,7 +81,7 @@ void shouldReturnObjectFromHandler() { sample2.setId("2"); doReturn(sample2).when(handler).markAudited(any()); - Sample result = (Sample) callback.onBeforeConvert(sample1); + Sample result = (Sample) callback.onBeforeConvert(sample1, IndexCoordinates.of("index")); assertThat(result).isSameAs(sample2); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java index 0637711c0..0e3755ffb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java @@ -26,10 +26,12 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.stereotype.Component; /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ abstract class ElasticsearchOperationsCallbackTest { @@ -41,7 +43,7 @@ static class Config { @Component static class SampleEntityBeforeConvertCallback implements BeforeConvertCallback { @Override - public SampleEntity onBeforeConvert(SampleEntity entity) { + public SampleEntity onBeforeConvert(SampleEntity entity, IndexCoordinates index) { entity.setText("converted"); return entity; } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java index 4d15016c8..3a5c6d3bd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.test.StepVerifier; import java.time.LocalDateTime; @@ -38,6 +39,7 @@ /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ @ExtendWith(MockitoExtension.class) class ReactiveAuditingEntityCallbackTests { @@ -68,7 +70,7 @@ void shouldHaveOrder100() { void shouldCallHandler() { Sample entity = new Sample(); entity.setId("42"); - callback.onBeforeConvert(entity); + callback.onBeforeConvert(entity, IndexCoordinates.of("index")); verify(handler).markAudited(eq(entity)); } @@ -81,7 +83,7 @@ void shouldReturnObjectFromHandler() { sample2.setId("2"); doReturn(sample2).when(handler).markAudited(any()); - callback.onBeforeConvert(sample1) // + callback.onBeforeConvert(sample1, IndexCoordinates.of("index")) // .as(StepVerifier::create) // .consumeNextWith(it -> { // assertThat(it).isSameAs(sample2); // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java index 4ca299b7a..035d4f059 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java @@ -31,6 +31,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -39,6 +40,7 @@ /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ @SpringIntegrationTest @ContextConfiguration(classes = { ReactiveElasticsearchOperationsCallbackTest.Config.class }) @@ -50,7 +52,7 @@ static class Config { @Component static class SampleEntityBeforeConvertCallback implements ReactiveBeforeConvertCallback { @Override - public Mono onBeforeConvert(SampleEntity entity) { + public Mono onBeforeConvert(SampleEntity entity, IndexCoordinates index) { entity.setText("reactive-converted"); return Mono.just(entity); } From 60cbb6787757e6c0a41da72fd03693f04fba73f5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 21 Apr 2020 21:57:31 +0200 Subject: [PATCH 0131/1191] DATAES-785 - Polishing. --- .../core/AbstractElasticsearchTemplate.java | 2 +- .../core/ReactiveElasticsearchTemplate.java | 45 ++++++++----------- .../event/ReactiveAuditingEntityCallback.java | 2 +- ...iveElasticsearchTemplateCallbackTests.java | 4 +- .../ReactiveAuditingEntityCallbackTests.java | 2 +- 5 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 0fa786821..5aa64604a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -593,7 +593,7 @@ protected class ReadSearchScrollDocumentResponseCallback private final Class type; public ReadSearchScrollDocumentResponseCallback(Class type, IndexCoordinates index) { - + Assert.notNull(type, "type is null"); this.delegate = new ReadDocumentCallback<>(elasticsearchConverter, type, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index b8054ea5c..8d5e859f7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -194,8 +194,7 @@ public Mono save(T entity, IndexCoordinates index) { IndexResponse indexResponse = it.getT2(); AdaptibleEntity adaptableEntity = operations.forEntity(savedEntity, converter.getConversionService()); return adaptableEntity.populateIdIfNecessary(indexResponse.getId()); - }) - .flatMap(saved -> maybeCallAfterSave(saved, index)); + }).flatMap(saved -> maybeCallAfterSave(saved, index)); } @Override @@ -208,31 +207,25 @@ public Flux saveAll(Mono> entitiesPubli Assert.notNull(entitiesPublisher, "Entities must not be null!"); - return entitiesPublisher - .flatMapMany(entities -> { - return Flux.fromIterable(entities) // - .concatMap(entity -> maybeCallBeforeConvert(entity, index)); - }) - .collectList() - .map(Entities::new) - .flatMapMany(entities -> { - if (entities.isEmpty()) { - return Flux.empty(); - } + return entitiesPublisher.flatMapMany(entities -> { + return Flux.fromIterable(entities) // + .concatMap(entity -> maybeCallBeforeConvert(entity, index)); + }).collectList().map(Entities::new).flatMapMany(entities -> { + if (entities.isEmpty()) { + return Flux.empty(); + } - return doBulkOperation(entities.indexQueries(), BulkOptions.defaultOptions(), index) // - .index() - .flatMap(indexAndResponse -> { - T savedEntity = entities.entityAt(indexAndResponse.getT1()); - BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); + return doBulkOperation(entities.indexQueries(), BulkOptions.defaultOptions(), index) // + .index().flatMap(indexAndResponse -> { + T savedEntity = entities.entityAt(indexAndResponse.getT1()); + BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); - AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, - converter.getConversionService()); - adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); + AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, converter.getConversionService()); + adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); - return maybeCallAfterSave(savedEntity, index); - }); - }); + return maybeCallAfterSave(savedEntity, index); + }); + }); } @Override @@ -1017,9 +1010,7 @@ private boolean isEmpty() { } private List indexQueries() { - return entities.stream() - .map(ReactiveElasticsearchTemplate.this::getIndexQuery) - .collect(Collectors.toList()); + return entities.stream().map(ReactiveElasticsearchTemplate.this::getIndexQuery).collect(Collectors.toList()); } private T entityAt(long index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java index 68dedec4b..69a803684 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java @@ -15,12 +15,12 @@ */ package org.springframework.data.elasticsearch.core.event; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Mono; import org.springframework.beans.factory.ObjectFactory; import org.springframework.core.Ordered; import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.util.Assert; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java index 666fcbf9e..93724559a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateCallbackTests.java @@ -201,8 +201,8 @@ void saveFromMonoAllShouldInvokeAfterSaveCallbacks() { Person entity1 = new Person("init1", "luke1"); Person entity2 = new Person("init2", "luke2"); - List saved = template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), index) - .toStream().collect(Collectors.toList()); + List saved = template.saveAll(Mono.just(Arrays.asList(entity1, entity2)), index).toStream() + .collect(Collectors.toList()); verify(afterSaveCallback, times(2)).onAfterSave(any(), eq(index)); assertThat(saved.get(0).firstname).isEqualTo("after-save"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java index 3a5c6d3bd..364b2b9af 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java @@ -18,7 +18,6 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.test.StepVerifier; import java.time.LocalDateTime; @@ -33,6 +32,7 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.lang.Nullable; From 4876a0e3abce26e81d31dc1b2b278c18d2ac2078 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 23 Apr 2020 08:01:46 +0200 Subject: [PATCH 0132/1191] DATAES-797 - Fix MappingElasticsearchConverter recursive descent when reading Map objects. Original PR: #437 --- .../convert/MappingElasticsearchConverter.java | 2 ++ ...MappingElasticsearchConverterUnitTests.java | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index be456595b..786566093 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -288,6 +288,8 @@ private R readCollectionValue(@Nullable List source, ElasticsearchPersist if (value instanceof List) { target.add(readValue(value, property, property.getTypeInformation().getActualType())); + } else if (value instanceof Map) { + target.add(readMapValue((Map) value, property, property.getTypeInformation().getActualType())); } else { target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value)); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 99218cc46..1347f9880 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -677,6 +677,24 @@ void readGenericMapWithSimpleTypes() { assertThat(wrapper.getSchemaLessObject()).isEqualTo(mapWithSimpleValues); } + @Test // DATAES-797 + void readGenericListWithMaps() { + Map simpleMap = new HashMap<>(); + simpleMap.put("int", 1); + + List> listWithSimpleMap = new ArrayList<>(); + listWithSimpleMap.add(simpleMap); + + Map>> mapWithSimpleList = new HashMap<>(); + mapWithSimpleList.put("someKey", listWithSimpleMap); + + Document document = Document.create(); + document.put("schemaLessObject", mapWithSimpleList); + + SchemaLessObjectWrapper wrapper = mappingElasticsearchConverter.read(SchemaLessObjectWrapper.class, document); + assertThat(wrapper.getSchemaLessObject()).isEqualTo(mapWithSimpleList); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } From da31b978bccfcf265f7be02111ae5a923592e073 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 23 Apr 2020 23:23:58 +0200 Subject: [PATCH 0133/1191] DATAES-800 - Delombok production code. Original PR: #438 --- .../client/RestClientFactoryBean.java | 11 ++--- .../ElasticsearchConfigurationSupport.java | 28 ++++++------ .../elasticsearch/core/EntityOperations.java | 32 ++++++++++---- .../core/client/support/AliasData.java | 44 +++++++++++++++---- ...eactiveElasticsearchRepositoryFactory.java | 17 +++++-- 5 files changed, 91 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java index f32d301cc..f4b5b6530 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClientFactoryBean.java @@ -15,14 +15,14 @@ */ package org.springframework.data.elasticsearch.client; -import lombok.extern.slf4j.Slf4j; - import java.net.URL; import java.util.ArrayList; import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBeanNotInitializedException; @@ -36,9 +36,10 @@ * @author Don Wellington * @author Peter-Josef Meisch */ -@Slf4j public class RestClientFactoryBean implements FactoryBean, InitializingBean, DisposableBean { + private static final Logger LOGGER = LoggerFactory.getLogger(RestClientFactoryBean.class); + private @Nullable RestHighLevelClient client; private String hosts = "http://localhost:9200/"; static final String COMMA = ","; @@ -46,12 +47,12 @@ public class RestClientFactoryBean implements FactoryBean, @Override public void destroy() { try { - log.info("Closing elasticSearch client"); + LOGGER.info("Closing elasticSearch client"); if (client != null) { client.close(); } } catch (final Exception e) { - log.error("Error closing ElasticSearch client: ", e); + LOGGER.error("Error closing ElasticSearch client: ", e); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java index e120bc20d..7be1c98c7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchConfigurationSupport.java @@ -15,8 +15,6 @@ */ package org.springframework.data.elasticsearch.config; -import lombok.SneakyThrows; - import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -62,7 +60,6 @@ public ElasticsearchConverter elasticsearchEntityMapper( * @return never {@literal null}. */ @Bean - @SneakyThrows public SimpleElasticsearchMappingContext elasticsearchMappingContext() { SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext(); @@ -103,9 +100,8 @@ protected Collection getMappingBasePackages() { * * @see #getMappingBasePackages() * @return never {@literal null}. - * @throws ClassNotFoundException */ - protected Set> getInitialEntitySet() throws ClassNotFoundException { + protected Set> getInitialEntitySet() { Set> initialEntitySet = new HashSet<>(); @@ -122,9 +118,8 @@ protected Set> getInitialEntitySet() throws ClassNotFoundException { * * @param basePackage must not be {@literal null}. * @return never {@literal null}. - * @throws ClassNotFoundException */ - protected Set> scanForEntities(String basePackage) throws ClassNotFoundException { + protected Set> scanForEntities(String basePackage) { if (!StringUtils.hasText(basePackage)) { return Collections.emptySet(); @@ -132,17 +127,20 @@ protected Set> scanForEntities(String basePackage) throws ClassNotFound Set> initialEntitySet = new HashSet<>(); - if (StringUtils.hasText(basePackage)) { + ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider( + false); + componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); + componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class)); - ClassPathScanningCandidateComponentProvider componentProvider = new ClassPathScanningCandidateComponentProvider( - false); - componentProvider.addIncludeFilter(new AnnotationTypeFilter(Document.class)); - componentProvider.addIncludeFilter(new AnnotationTypeFilter(Persistent.class)); + for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { - for (BeanDefinition candidate : componentProvider.findCandidateComponents(basePackage)) { + String beanClassName = candidate.getBeanClassName(); - initialEntitySet.add(ClassUtils.forName(candidate.getBeanClassName(), - AbstractReactiveElasticsearchConfiguration.class.getClassLoader())); + if (beanClassName != null) { + try { + initialEntitySet.add( + ClassUtils.forName(beanClassName, AbstractReactiveElasticsearchConfiguration.class.getClassLoader())); + } catch (ClassNotFoundException | LinkageError ignored) {} } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 160f89941..1a8567d9a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -15,10 +15,6 @@ */ package org.springframework.data.elasticsearch.core; -import lombok.AccessLevel; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; - import java.util.Map; import org.springframework.core.convert.ConversionService; @@ -46,11 +42,14 @@ class EntityOperations { private static final String ID_FIELD = "id"; public EntityOperations( - @NonNull MappingContext, ElasticsearchPersistentProperty> context) { + MappingContext, ElasticsearchPersistentProperty> context) { + + Assert.notNull(context, "context must not be null"); + this.context = context; } - private final @NonNull MappingContext, ElasticsearchPersistentProperty> context; + private final MappingContext, ElasticsearchPersistentProperty> context; /** * Creates a new {@link Entity} for the given bean. @@ -264,9 +263,15 @@ interface AdaptibleEntity extends Entity { * @author Christoph Strobl * @since 3.2 */ - @RequiredArgsConstructor private static class MapBackedEntity> implements AdaptibleEntity { + public MapBackedEntity(T map) { + + Assert.notNull(map, "map must not be null"); + + this.map = map; + } + private final T map; /* @@ -406,13 +411,24 @@ public Object getId() { * @param * @since 3.2 */ - @RequiredArgsConstructor(access = AccessLevel.PROTECTED) private static class MappedEntity implements Entity { private final ElasticsearchPersistentEntity entity; private final IdentifierAccessor idAccessor; private final PersistentPropertyAccessor propertyAccessor; + private MappedEntity(ElasticsearchPersistentEntity entity, IdentifierAccessor idAccessor, + PersistentPropertyAccessor propertyAccessor) { + + Assert.notNull(entity, "entity must not ne null"); + Assert.notNull(idAccessor, "idAccessor must not ne null"); + Assert.notNull(propertyAccessor, "propertyAccessor must not ne null"); + + this.entity = entity; + this.idAccessor = idAccessor; + this.propertyAccessor = propertyAccessor; + } + private static MappedEntity of(T bean, MappingContext, ElasticsearchPersistentProperty> context) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java index 14cbda75d..3fda69c8c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java @@ -15,15 +15,41 @@ */ package org.springframework.data.elasticsearch.core.client.support; -import lombok.Data; +public class AliasData { + private String filter = null; + private String routing = null; + private String search_routing = null; + private String index_routing = null; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + public String getFilter() { + return filter; + } -@JsonIgnoreProperties(ignoreUnknown = true) -@Data -public class AliasData { - String filter = null; - String routing = null; - String search_routing = null; - String index_routing = null; + public void setFilter(String filter) { + this.filter = filter; + } + + public String getRouting() { + return routing; + } + + public void setRouting(String routing) { + this.routing = routing; + } + + public String getSearch_routing() { + return search_routing; + } + + public void setSearch_routing(String search_routing) { + this.search_routing = search_routing; + } + + public String getIndex_routing() { + return index_routing; + } + + public void setIndex_routing(String index_routing) { + this.index_routing = index_routing; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java index 72025e88f..d7f2b9788 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java @@ -15,9 +15,6 @@ */ package org.springframework.data.elasticsearch.repository.support; -import lombok.AccessLevel; -import lombok.RequiredArgsConstructor; - import java.io.Serializable; import java.lang.reflect.Method; import java.util.Optional; @@ -128,13 +125,25 @@ protected RepositoryMetadata getRepositoryMetadata(Class repositoryInterface) /** * @author Christoph Strobl */ - @RequiredArgsConstructor(access = AccessLevel.PACKAGE) private static class ElasticsearchQueryLookupStrategy implements QueryLookupStrategy { private final ReactiveElasticsearchOperations operations; private final QueryMethodEvaluationContextProvider evaluationContextProvider; private final MappingContext, ElasticsearchPersistentProperty> mappingContext; + public ElasticsearchQueryLookupStrategy(ReactiveElasticsearchOperations operations, + QueryMethodEvaluationContextProvider evaluationContextProvider, + MappingContext, ElasticsearchPersistentProperty> mappingContext) { + + Assert.notNull(operations, "operations must not be null"); + Assert.notNull(evaluationContextProvider, "evaluationContextProvider must not be null"); + Assert.notNull(mappingContext, "mappingContext must not be null"); + + this.operations = operations; + this.evaluationContextProvider = evaluationContextProvider; + this.mappingContext = mappingContext; + } + /* * (non-Javadoc) * @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.projection.ProjectionFactory, org.springframework.data.repository.core.NamedQueries) From 65f89f9480d8b6324a14145b4c42304c62c4f122 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 24 Apr 2020 18:00:29 +0200 Subject: [PATCH 0134/1191] DATAES-803 - Move count request setup from reactive template to reactive client. Original PR: #439 --- .../DefaultReactiveElasticsearchClient.java | 3 + .../core/ReactiveElasticsearchTemplate.java | 2 - ...efaultReactiveElasticsearchClientTest.java | 82 +++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClientTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 76d4561c6..bd3389735 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -386,6 +386,9 @@ public Mono delete(HttpHeaders headers, DeleteRequest deleteRequ */ @Override public Mono count(HttpHeaders headers, SearchRequest searchRequest) { + searchRequest.source().trackTotalHits(true); + searchRequest.source().size(0); + searchRequest.source().fetchSource(false); return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // .map(SearchResponse::getHits) // .map(searchHits -> searchHits.getTotalHits().value) // diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8d5e859f7..83ec43dc7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -643,8 +643,6 @@ private Mono doCount(Query query, Class entityType, IndexCoordinates in SearchRequest request = requestFactory.searchRequest(query, entityType, index); request = prepareSearchRequest(request); - request.source().size(0); - request.source().trackTotalHits(true); return doCount(request); }); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClientTest.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClientTest.java new file mode 100644 index 000000000..7e7000bd1 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClientTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2020 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.client.reactive; + +import static org.assertj.core.api.Assertions.*; +import static org.elasticsearch.search.internal.SearchContext.*; +import static org.mockito.Mockito.*; + +import org.elasticsearch.search.fetch.subphase.FetchSourceContext; +import reactor.core.publisher.Mono; + +import java.util.function.Function; + +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.client.Request; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.web.reactive.function.client.ClientResponse; +import reactor.test.StepVerifier; + +/** + * @author Peter-Josef Meisch + */ +@ExtendWith(MockitoExtension.class) +class DefaultReactiveElasticsearchClientTest { + + @Mock private HostProvider hostProvider; + + @Mock private Function searchRequestConverter; + + private DefaultReactiveElasticsearchClient client; + + @BeforeEach + void setUp() { + client = new DefaultReactiveElasticsearchClient(hostProvider, new RequestCreator() { + @Override + public Function search() { + return searchRequestConverter; + } + }) { + @Override + public Mono execute(ReactiveElasticsearchClientCallback callback) { + return Mono.empty(); + } + }; + } + + @Test + void shouldSetAppropriateRequestParametersOnCount() { + + SearchRequest searchRequest = new SearchRequest("someindex") // + .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); + + client.count(searchRequest).as(StepVerifier::create).verifyComplete(); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SearchRequest.class); + verify(searchRequestConverter).apply(captor.capture()); + SearchSourceBuilder source = captor.getValue().source(); + assertThat(source.size()).isEqualTo(0); + assertThat(source.trackTotalHitsUpTo()).isEqualTo(TRACK_TOTAL_HITS_ACCURATE); + assertThat(source.fetchSource()).isEqualTo(FetchSourceContext.DO_NOT_FETCH_SOURCE); + } +} From a4ec819e7d008c070089361e7bd68898ae641a6a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 26 Apr 2020 17:30:46 +0200 Subject: [PATCH 0135/1191] DATAES-801 - Implement callback to enable adding custom headers in the REST HTTP request. Original PR: #442 --- pom.xml | 2 +- .../reference/elasticsearch-clients.adoc | 33 +-- .../client/ClientConfiguration.java | 19 ++ .../client/ClientConfigurationBuilder.java | 18 +- .../elasticsearch/client/ClientLogger.java | 3 +- .../client/DefaultClientConfiguration.java | 14 +- .../elasticsearch/client/RestClients.java | 62 ++++-- .../DefaultReactiveElasticsearchClient.java | 25 ++- .../client/reactive/HostProvider.java | 10 +- .../reactive/MultiNodeHostProvider.java | 11 +- .../reactive/SingleNodeHostProvider.java | 11 +- .../elasticsearch/client/RestClientsTest.java | 205 ++++++++++++++++-- .../ReactiveMockClientTestsUtils.java | 4 +- 13 files changed, 347 insertions(+), 70 deletions(-) diff --git a/pom.xml b/pom.xml index abf197b27..979515864 100644 --- a/pom.xml +++ b/pom.xml @@ -252,7 +252,7 @@ com.github.tomakehurst wiremock-jre8 - 2.25.1 + 2.26.3 test diff --git a/src/main/asciidoc/reference/elasticsearch-clients.adoc b/src/main/asciidoc/reference/elasticsearch-clients.adoc index a9f7d7ea2..2f90a4e89 100644 --- a/src/main/asciidoc/reference/elasticsearch-clients.adoc +++ b/src/main/asciidoc/reference/elasticsearch-clients.adoc @@ -143,40 +143,47 @@ NOTE: The ReactiveClient response, especially for search operations, is bound to [[elasticsearch.clients.configuration]] == Client Configuration -Client behaviour can be changed via the `ClientConfiguration` that allows to set options for SSL, connect and socket timeouts. +Client behaviour can be changed via the `ClientConfiguration` that allows to set options for SSL, connect and socket timeouts, headers and other parameters. .Client Configuration ==== [source,java] ---- -// optional if Basic Auhtentication is needed HttpHeaders httpHeaders = new HttpHeaders(); -httpHeaders.add("es-security-runas-user", "some-user") <1> +httpHeaders.add("some-header", "on every request") <1> ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200", "localhost:9291") <2> - .withProxy("localhost:8888") <3> - .withPathPrefix("ela") <4> - .withConnectTimeout(Duration.ofSeconds(5)) <5> - .withSocketTimeout(Duration.ofSeconds(3)) <6> - .useSsl() <7> + .useSsl() <3> + .withProxy("localhost:8888") <4> + .withPathPrefix("ela") <5> + .withConnectTimeout(Duration.ofSeconds(5)) <6> + .withSocketTimeout(Duration.ofSeconds(3)) <7> .withDefaultHeaders(defaultHeaders) <8> .withBasicAuth(username, password) <9> + .withHeaders(() -> { <10> + HttpHeaders headers = new HttpHeaders(); + headers.add("currentTime", LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); + return headers; + }) . // ... other options .build(); ---- <1> Define default headers, if they need to be customized <2> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL. -<3> Optionally set a proxy footnote:notreactive[not yet implemented for the reactive client]. -<4> Optionally set a path prefix, mostly used when different clusters a behind some reverse proxy. -<5> Set the connection timeout. Default is 10 sec. -<6> Set the socket timeout. Default is 5 sec. -<7> Optionally enable SSL. +<3> Optionally enable SSL. +<4> Optionally set a proxy. +<5> Optionally set a path prefix, mostly used when different clusters a behind some reverse proxy. +<6> Set the connection timeout. Default is 10 sec. +<7> Set the socket timeout. Default is 5 sec. <8> Optionally set headers. <9> Add basic authentication. +<10> A `Supplier
` function can be specified which is called every time before a request is sent to Elasticsearch - here, as an example, the current time is written in a header. ==== +IMPORTANT: Adding a Header supplier as shown in above example allows to inject headers that may change over the time, like authentication JWT tokens. If this is used in the reactive setup, the supplier function *must not* block! + [[elasticsearch.clients.logging]] == Client Logging diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java index 916cbdcdc..3200577e2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfiguration.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; +import java.util.function.Supplier; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; @@ -170,6 +171,11 @@ static ClientConfiguration create(InetSocketAddress socketAddress) { */ Function getWebClientConfigurer(); + /** + * @return the supplier for custom headers. + */ + Supplier getHeadersSupplier(); + /** * @author Christoph Strobl */ @@ -335,6 +341,19 @@ default TerminalClientConfigurationBuilder withSocketTimeout(long millis) { */ TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer); + /** + * set a supplier for custom headers. This is invoked for every HTTP request to Elasticsearch to retrieve headers + * that should be sent with the request. A common use case is passing in authentication headers that may change. + *
+ * Note: When used in a reactive environment, the calling of {@link Supplier#get()} function must not do any + * blocking operations. It may return {@literal null}. + * + * @param headers supplier function for headers, must not be {@literal null} + * @return the {@link TerminalClientConfigurationBuilder}. + * @since 4.0 + */ + TerminalClientConfigurationBuilder withHeaders(Supplier headers); + /** * Build the {@link ClientConfiguration} object. * diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java index 61ae39b35..07c01ec32 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientConfigurationBuilder.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.List; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.net.ssl.HostnameVerifier; @@ -58,7 +59,8 @@ class ClientConfigurationBuilder private @Nullable String password; private @Nullable String pathPrefix; private @Nullable String proxy; - private @Nullable Function webClientConfigurer; + private Function webClientConfigurer = Function.identity(); + private Supplier headersSupplier = () -> HttpHeaders.EMPTY; /* * (non-Javadoc) @@ -196,7 +198,8 @@ public TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix) { } @Override - public TerminalClientConfigurationBuilder withWebClientConfigurer(Function webClientConfigurer) { + public TerminalClientConfigurationBuilder withWebClientConfigurer( + Function webClientConfigurer) { Assert.notNull(webClientConfigurer, "webClientConfigurer must not be null"); @@ -204,6 +207,15 @@ public TerminalClientConfigurationBuilder withWebClientConfigurer(Function headers) { + + Assert.notNull(headers, "headersSupplier must not be null"); + + this.headersSupplier = headers; + return this; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build() @@ -219,7 +231,7 @@ public ClientConfiguration build() { } return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix, - hostnameVerifier, proxy, webClientConfigurer); + hostnameVerifier, proxy, webClientConfigurer, headersSupplier); } private static InetSocketAddress parse(String hostAndPort) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java b/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java index 50d7d68ef..ac2dfe99d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/ClientLogger.java @@ -20,6 +20,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; +import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -90,7 +91,7 @@ public static void logRequest(String logId, String method, String endpoint, Obje * @param logId the correlation Id, see {@link #newLogId()}. * @param statusCode the HTTP status code. */ - public static void logRawResponse(String logId, HttpStatus statusCode) { + public static void logRawResponse(String logId, @Nullable HttpStatus statusCode) { if (isEnabled()) { WIRE_LOGGER.trace("[{}] Received raw response: {}", logId, statusCode); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java index af7d745e2..ab43f15a8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/DefaultClientConfiguration.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Optional; import java.util.function.Function; +import java.util.function.Supplier; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; @@ -50,12 +51,13 @@ class DefaultClientConfiguration implements ClientConfiguration { private final @Nullable String pathPrefix; private final @Nullable HostnameVerifier hostnameVerifier; private final @Nullable String proxy; - private final @Nullable Function webClientConfigurer; + private final Function webClientConfigurer; + private final Supplier headersSupplier; DefaultClientConfiguration(List hosts, HttpHeaders headers, boolean useSsl, @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix, @Nullable HostnameVerifier hostnameVerifier, @Nullable String proxy, - @Nullable Function webClientConfigurer) { + Function webClientConfigurer, Supplier headersSupplier) { this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.headers = new HttpHeaders(headers); @@ -67,6 +69,7 @@ class DefaultClientConfiguration implements ClientConfiguration { this.hostnameVerifier = hostnameVerifier; this.proxy = proxy; this.webClientConfigurer = webClientConfigurer; + this.headersSupplier = headersSupplier; } @Override @@ -117,6 +120,11 @@ public Optional getProxy() { @Override public Function getWebClientConfigurer() { - return webClientConfigurer != null ? webClientConfigurer : Function.identity(); + return webClientConfigurer; + } + + @Override + public Supplier getHeadersSupplier() { + return headersSupplier; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java index 38abe6bce..63f22ffa0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/RestClients.java @@ -20,13 +20,11 @@ import java.io.IOException; import java.net.InetSocketAddress; import java.time.Duration; +import java.util.Arrays; import java.util.List; -import java.util.Optional; +import java.util.function.Supplier; import java.util.stream.Collectors; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLContext; - import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; @@ -87,31 +85,23 @@ public static ElasticsearchRestClient create(ClientConfiguration clientConfigura HttpHeaders headers = clientConfiguration.getDefaultHeaders(); if (!headers.isEmpty()) { - - Header[] httpHeaders = headers.toSingleValueMap().entrySet().stream() - .map(it -> new BasicHeader(it.getKey(), it.getValue())).toArray(Header[]::new); - builder.setDefaultHeaders(httpHeaders); + builder.setDefaultHeaders(toHeaderArray(headers)); } builder.setHttpClientConfigCallback(clientBuilder -> { - - Optional sslContext = clientConfiguration.getSslContext(); - Optional hostNameVerifier = clientConfiguration.getHostNameVerifier(); - sslContext.ifPresent(clientBuilder::setSSLContext); - hostNameVerifier.ifPresent(clientBuilder::setSSLHostnameVerifier); + clientConfiguration.getSslContext().ifPresent(clientBuilder::setSSLContext); + clientConfiguration.getHostNameVerifier().ifPresent(clientBuilder::setSSLHostnameVerifier); + clientBuilder.addInterceptorLast(new CustomHeaderInjector(clientConfiguration.getHeadersSupplier())); if (ClientLogger.isEnabled()) { - HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); clientBuilder.addInterceptorLast((HttpRequestInterceptor) interceptor); clientBuilder.addInterceptorLast((HttpResponseInterceptor) interceptor); } - Duration connectTimeout = clientConfiguration.getConnectTimeout(); - Duration timeout = clientConfiguration.getSocketTimeout(); - Builder requestConfigBuilder = RequestConfig.custom(); + Duration connectTimeout = clientConfiguration.getConnectTimeout(); if (!connectTimeout.isNegative()) { @@ -119,6 +109,8 @@ public static ElasticsearchRestClient create(ClientConfiguration clientConfigura requestConfigBuilder.setConnectionRequestTimeout(Math.toIntExact(connectTimeout.toMillis())); } + Duration timeout = clientConfiguration.getSocketTimeout(); + if (!timeout.isNegative()) { requestConfigBuilder.setSocketTimeout(Math.toIntExact(timeout.toMillis())); } @@ -134,8 +126,16 @@ public static ElasticsearchRestClient create(ClientConfiguration clientConfigura return () -> client; } + private static Header[] toHeaderArray(HttpHeaders headers) { + return headers.entrySet().stream() // + .flatMap(entry -> entry.getValue().stream() // + .map(value -> new BasicHeader(entry.getKey(), value))) // + .toArray(Header[]::new); + } + private static List formattedHosts(List hosts, boolean useSsl) { - return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ":" + it.getPort()).collect(Collectors.toList()); + return hosts.stream().map(it -> (useSsl ? "https" : "http") + "://" + it.getHostString() + ":" + it.getPort()) + .collect(Collectors.toList()); } /** @@ -180,7 +180,6 @@ public void process(HttpRequest request, HttpContext context) throws IOException String logId = (String) context.getAttribute(RestClients.LOG_ID_ATTRIBUTE); if (logId == null) { - logId = ClientLogger.newLogId(); context.setAttribute(RestClients.LOG_ID_ATTRIBUTE, logId); } @@ -205,10 +204,31 @@ public void process(HttpRequest request, HttpContext context) throws IOException @Override public void process(HttpResponse response, HttpContext context) { - String logId = (String) context.getAttribute(RestClients.LOG_ID_ATTRIBUTE); - ClientLogger.logRawResponse(logId, HttpStatus.resolve(response.getStatusLine().getStatusCode())); } } + + /** + * Interceptor to inject custom supplied headers. + * + * @since 4.0 + */ + private static class CustomHeaderInjector implements HttpRequestInterceptor { + + public CustomHeaderInjector(Supplier headersSupplier) { + this.headersSupplier = headersSupplier; + } + + private final Supplier headersSupplier; + + @Override + public void process(HttpRequest request, HttpContext context) { + HttpHeaders httpHeaders = headersSupplier.get(); + + if (httpHeaders != null && httpHeaders != HttpHeaders.EMPTY) { + Arrays.stream(toHeaderArray(httpHeaders)).forEach(request::addHeader); + } + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index bd3389735..266118d34 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -44,6 +44,7 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.function.Supplier; import javax.net.ssl.SSLContext; @@ -138,8 +139,8 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearchClient, Indices { private final HostProvider hostProvider; - private final RequestCreator requestCreator; + private Supplier headersSupplier = () -> HttpHeaders.EMPTY; /** * Create a new {@link DefaultReactiveElasticsearchClient} using the given {@link HostProvider} to obtain server @@ -167,6 +168,13 @@ public DefaultReactiveElasticsearchClient(HostProvider hostProvider, RequestCrea this.requestCreator = requestCreator; } + public void setHeadersSupplier(Supplier headersSupplier) { + + Assert.notNull(headersSupplier, "headersSupplier must not be null"); + + this.headersSupplier = headersSupplier; + } + /** * Create a new {@link DefaultReactiveElasticsearchClient} aware of the given nodes in the cluster.
* NOTE If the cluster requires authentication be sure to provide the according {@link HttpHeaders} @@ -216,9 +224,14 @@ public static ReactiveElasticsearchClient create(ClientConfiguration clientConfi WebClientProvider provider = getWebClientProvider(clientConfiguration); - HostProvider hostProvider = HostProvider.provider(provider, + HostProvider hostProvider = HostProvider.provider(provider, clientConfiguration.getHeadersSupplier(), clientConfiguration.getEndpoints().toArray(new InetSocketAddress[0])); - return new DefaultReactiveElasticsearchClient(hostProvider, requestCreator); + + DefaultReactiveElasticsearchClient client = new DefaultReactiveElasticsearchClient(hostProvider, requestCreator); + + client.setHeadersSupplier(clientConfiguration.getHeadersSupplier()); + + return client; } private static WebClientProvider getWebClientProvider(ClientConfiguration clientConfiguration) { @@ -698,6 +711,12 @@ private Mono sendRequest(WebClient webClient, String logId, Requ request.getOptions().getHeaders().forEach(it -> theHeaders.add(it.getName(), it.getValue())); } } + + // plus the ones from the supplier + HttpHeaders suppliedHeaders = headersSupplier.get(); + if (suppliedHeaders != null && suppliedHeaders != HttpHeaders.EMPTY) { + theHeaders.addAll(suppliedHeaders); + } }); if (request.getEntity() != null) { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java index b742c2b03..2474315dc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/HostProvider.java @@ -20,9 +20,11 @@ import java.net.InetSocketAddress; import java.util.Collections; import java.util.Set; +import java.util.function.Supplier; import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.NoReachableHostException; +import org.springframework.http.HttpHeaders; import org.springframework.util.Assert; import org.springframework.web.reactive.function.client.WebClient; @@ -40,18 +42,20 @@ public interface HostProvider { * Create a new {@link HostProvider} best suited for the given {@link WebClientProvider} and number of hosts. * * @param clientProvider must not be {@literal null} . + * @param headersSupplier to supply custom headers, must not be {@literal null} * @param endpoints must not be {@literal null} nor empty. * @return new instance of {@link HostProvider}. */ - static HostProvider provider(WebClientProvider clientProvider, InetSocketAddress... endpoints) { + static HostProvider provider(WebClientProvider clientProvider, Supplier headersSupplier, + InetSocketAddress... endpoints) { Assert.notNull(clientProvider, "WebClientProvider must not be null"); Assert.notEmpty(endpoints, "Please provide at least one endpoint to connect to."); if (endpoints.length == 1) { - return new SingleNodeHostProvider(clientProvider, endpoints[0]); + return new SingleNodeHostProvider(clientProvider, headersSupplier, endpoints[0]); } else { - return new MultiNodeHostProvider(clientProvider, endpoints); + return new MultiNodeHostProvider(clientProvider,headersSupplier, endpoints); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java index 6930a4a32..cac75f0b1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.client.reactive; +import org.springframework.http.HttpHeaders; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -27,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.ElasticsearchHost.State; @@ -45,11 +47,13 @@ class MultiNodeHostProvider implements HostProvider { private final WebClientProvider clientProvider; + private final Supplier headersSupplier; private final Map hosts; - MultiNodeHostProvider(WebClientProvider clientProvider, InetSocketAddress... endpoints) { + MultiNodeHostProvider(WebClientProvider clientProvider, Supplier headersSupplier, InetSocketAddress... endpoints) { this.clientProvider = clientProvider; + this.headersSupplier = headersSupplier; this.hosts = new ConcurrentHashMap<>(); for (InetSocketAddress endpoint : endpoints) { this.hosts.put(endpoint, new ElasticsearchHost(endpoint, State.UNKNOWN)); @@ -133,8 +137,9 @@ private Flux> nodes(@Nullable State st .flatMap(host -> { Mono exchange = createWebClient(host) // - .head().uri("/").exchange().doOnError(throwable -> { - + .head().uri("/") // + .headers(httpHeaders -> httpHeaders.addAll(headersSupplier.get())) // + .exchange().doOnError(throwable -> { hosts.put(host, new ElasticsearchHost(host, State.OFFLINE)); clientProvider.getErrorListener().accept(throwable); }); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java index 428f3daeb..eae140c90 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java @@ -15,10 +15,12 @@ */ package org.springframework.data.elasticsearch.client.reactive; +import org.springframework.http.HttpHeaders; import reactor.core.publisher.Mono; import java.net.InetSocketAddress; import java.util.Collections; +import java.util.function.Supplier; import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.ElasticsearchHost.State; @@ -35,12 +37,14 @@ class SingleNodeHostProvider implements HostProvider { private final WebClientProvider clientProvider; + private final Supplier headersSupplier; private final InetSocketAddress endpoint; private volatile ElasticsearchHost state; - SingleNodeHostProvider(WebClientProvider clientProvider, InetSocketAddress endpoint) { + SingleNodeHostProvider(WebClientProvider clientProvider, Supplier headersSupplier, InetSocketAddress endpoint) { this.clientProvider = clientProvider; + this.headersSupplier = headersSupplier; this.endpoint = endpoint; this.state = new ElasticsearchHost(this.endpoint, State.UNKNOWN); } @@ -53,9 +57,10 @@ class SingleNodeHostProvider implements HostProvider { public Mono clusterInfo() { return createWebClient(endpoint) // - .head().uri("/").exchange() // + .head().uri("/") + .headers(httpHeaders -> httpHeaders.addAll(headersSupplier.get())) // + .exchange() // .flatMap(it -> { - if (it.statusCode().isError()) { state = ElasticsearchHost.offline(endpoint); } else { diff --git a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java index f460f748c..23f3a5704 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java @@ -4,44 +4,221 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.stream.Stream; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; +import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients; +import org.springframework.http.HttpHeaders; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.matching.AnythingPattern; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; /** * @author Peter-Josef Meisch */ public class RestClientsTest { - @Test // DATAES-700 - void shouldUseConfiguredProxy() throws IOException { + @ParameterizedTest // DATAES-700 + @MethodSource("clientUnderTestFactorySource") + @DisplayName("should use configured proxy") + void shouldUseConfiguredProxy(ClientUnderTestFactory clientUnderTestFactory) throws IOException { - WireMockServer wireMockServer = new WireMockServer(options() // - .dynamicPort() // - .usingFilesUnderDirectory("src/test/resources/wiremock-mappings")); // needed, otherwise Wiremock goes to - // test/resources/mappings - wireMockServer.start(); - try { - WireMock.configureFor(wireMockServer.port()); + if (clientUnderTestFactory instanceof ReactiveElasticsearchClientUnderTestFactory) { + // although the reactive code is using the proxy for every call - tested with an intercepting + // proxy - somehow in this test wiremock fails to register this. So we skip it here + // + return; + } + + wireMockServer(server -> { + + WireMock.configureFor(server.port()); + + stubFor(head(urlEqualTo("/")).willReturn(aResponse() // + .withHeader("Content-Type", "application/json; charset=UTF-8"))); ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder(); ClientConfiguration clientConfiguration = configurationBuilder // - .connectedTo("localhost:9200")// - .withProxy("localhost:" + wireMockServer.port()) // + .connectedTo("localhost:4711")// + .withProxy("localhost:" + server.port()) // .build(); + ClientUnderTest clientUnderTest = clientUnderTestFactory.create(clientConfiguration); - RestHighLevelClient restClient = RestClients.create(clientConfiguration).rest(); - restClient.ping(RequestOptions.DEFAULT); + clientUnderTest.ping(); verify(headRequestedFor(urlEqualTo("/"))); + }); + } + + @ParameterizedTest // DATAES-801 + @MethodSource("clientUnderTestFactorySource") + @DisplayName("should set all required headers") + void shouldSetAllRequiredHeaders(ClientUnderTestFactory clientUnderTestFactory) { + wireMockServer(server -> { + + WireMock.configureFor(server.port()); + + stubFor(head(urlEqualTo("/")).willReturn(aResponse() // + .withHeader("Content-Type", "application/json; charset=UTF-8"))); + + HttpHeaders defaultHeaders = new HttpHeaders(); + defaultHeaders.addAll("def1", Arrays.asList("def1-1", "def1-2")); + defaultHeaders.add("def2", "def2-1"); + AtomicInteger supplierCount = new AtomicInteger(1); + + ClientConfigurationBuilder configurationBuilder = new ClientConfigurationBuilder(); + ClientConfiguration clientConfiguration = configurationBuilder // + .connectedTo("localhost:" + server.port()) // + .withBasicAuth("user", "password") // + .withDefaultHeaders(defaultHeaders) // + .withHeaders(() -> { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("supplied", "val0"); + httpHeaders.add("supplied", "val" + supplierCount.getAndIncrement()); + return httpHeaders; + }).build(); + + ClientUnderTest clientUnderTest = clientUnderTestFactory.create(clientConfiguration); + + // do several calls to check that the headerSupplier provided values are set + for (int i = 1; i <= 3; i++) { + clientUnderTest.ping(); + + verify(headRequestedFor(urlEqualTo("/")).withHeader("Authorization", new AnythingPattern()) // + .withHeader("def1", new EqualToPattern("def1-1")) // + .withHeader("def1", new EqualToPattern("def1-2")) // + .withHeader("def2", new EqualToPattern("def2-1")) // + .withHeader("supplied", new EqualToPattern("val0")) // + .withHeader("supplied", new EqualToPattern("val" + i)) // + ); + } + }); + } + + /** + * Consumer extension that catches checked exceptions and wraps them in a RuntimeException. + */ + @FunctionalInterface + interface WiremockConsumer extends Consumer { + @Override + default void accept(WireMockServer wiremockConsumer) { + try { + acceptThrows(wiremockConsumer); + } catch (final Exception e) { + throw new RuntimeException(e); + } + } + + void acceptThrows(WireMockServer wiremockConsumer) throws Exception; + } + + /** + * starts a Wiremock server and calls consumer with the server as argument. Stops the server after consumer execution. + * + * @param consumer the consumer + */ + private void wireMockServer(WiremockConsumer consumer) { + WireMockServer wireMockServer = new WireMockServer(options() // + .dynamicPort() // + .usingFilesUnderDirectory("src/test/resources/wiremock-mappings")); // needed, otherwise Wiremock goes to + // test/resources/mappings + try { + wireMockServer.start(); + consumer.accept(wireMockServer); } finally { wireMockServer.shutdown(); } } + /** + * The client to be tested. Abstraction to be able to test reactive and non-reactive clients. + */ + interface ClientUnderTest { + /** + * Pings the configured server. + * + * @return + */ + boolean ping() throws Exception; + } + + /** + * base class to create {@link ClientUnderTest} implementations. + */ + static abstract class ClientUnderTestFactory { + abstract ClientUnderTest create(ClientConfiguration clientConfiguration); + + @Override + public String toString() { + return getDisplayName(); + } + + protected abstract String getDisplayName(); + } + + /** + * {@link ClientUnderTestFactory} implementation for the Standard {@link RestHighLevelClient}. + */ + static class RestClientUnderTestFactory extends ClientUnderTestFactory { + + @Override + protected String getDisplayName() { + return "RestHighLevelClient"; + } + + @Override + ClientUnderTest create(ClientConfiguration clientConfiguration) { + RestHighLevelClient client = RestClients.create(clientConfiguration).rest(); + return new ClientUnderTest() { + + @Override + public boolean ping() throws Exception { + return client.ping(RequestOptions.DEFAULT); + } + }; + } + + } + + /** + * {@link ClientUnderTestFactory} implementation for the {@link ReactiveElasticsearchClient}. + */ + static class ReactiveElasticsearchClientUnderTestFactory extends ClientUnderTestFactory { + + @Override + protected String getDisplayName() { + return "ReactiveElasticsearchClient"; + } + + @Override + ClientUnderTest create(ClientConfiguration clientConfiguration) { + ReactiveElasticsearchClient client = ReactiveRestClients.create(clientConfiguration); + return new ClientUnderTest() { + @Override + public boolean ping() throws Exception { + return client.ping().block(); + } + }; + } + } + + /** + * Provides the factories to use in the parameterized tests + * + * @return stream of factories + */ + static Stream clientUnderTestFactorySource() { + return Stream.of(new RestClientUnderTestFactory(), new ReactiveElasticsearchClientUnderTestFactory()); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index 6b58dc37b..6fedf27a5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -83,10 +83,10 @@ public static MockDelegatingElasticsearchHostProvider Date: Sun, 26 Apr 2020 16:40:30 +0100 Subject: [PATCH 0136/1191] DATAES-802 - Update documentation for using scroll API with repository methods. Original PR: #440 --- src/main/asciidoc/reference/elasticsearch-misc.adoc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index 41527cbed..b4bcbbc1a 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -80,6 +80,17 @@ while (scroll.hasSearchHits()) { template.searchScrollClear(scrollId); ---- +Additionally, the scroll API can be used by defining the return type as `Stream` in the Elasticsearch Repository. + +[source,java] +---- +interface SampleEntityRepository extends Repository { + + Stream findBy(); + +} +---- + [[elasticsearch.misc.sorts]] == Sort options From efbe7237f2a3f1c73799c6f6d5acc425bf46f063 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 26 Apr 2020 17:45:40 +0200 Subject: [PATCH 0137/1191] DATAES-802 - Polishing. --- src/main/asciidoc/reference/elasticsearch-misc.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index b4bcbbc1a..9df0d064f 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -80,7 +80,7 @@ while (scroll.hasSearchHits()) { template.searchScrollClear(scrollId); ---- -Additionally, the scroll API can be used by defining the return type as `Stream` in the Elasticsearch Repository. +To use the Scroll API with repository methods, the return type must defined as `Stream` in the Elasticsearch Repository. The implementation of the method will then use the scroll methods from the ElasticsearchTemplate. [source,java] ---- From 04b739e63761825b9b1959c842f9ee8cc1afbcd1 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 11:32:25 +0200 Subject: [PATCH 0138/1191] DATAES-755 - Updated changelog. --- src/main/resources/changelog.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index d677cfbbf..bfffc68d3 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,12 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.17.RELEASE (2020-04-28) +---------------------------------------------- +* DATAES-793 - Upgrade to Elasticsearch 6.2.4. +* DATAES-755 - Release 3.1.17 (Lovelace SR17). + + Changes in version 4.0.0.RC1 (2020-03-31) ----------------------------------------- * DATAES-771 - Add after-save entity callbacks support. @@ -1073,3 +1079,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 5beaf561df9eb394f9ccf4b4ce1d2e744f8fd848 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 14:35:23 +0200 Subject: [PATCH 0139/1191] DATAES-770 - Updated changelog. --- src/main/resources/changelog.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index bfffc68d3..e01a19fac 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,13 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.7.RELEASE (2020-04-28) +--------------------------------------------- +* DATAES-780 - Upgrade 3.2.x to Elasticsearch 6.8.8. +* DATAES-778 - Fix SSL setup in the reactive client. +* DATAES-770 - Release 3.2.7 (Moore SR7). + + Changes in version 3.1.17.RELEASE (2020-04-28) ---------------------------------------------- * DATAES-793 - Upgrade to Elasticsearch 6.2.4. @@ -1080,3 +1087,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 051af10402a7ab027b0b57543ebeb61e0dabd923 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 15:03:32 +0200 Subject: [PATCH 0140/1191] DATAES-774 - Updated changelog. --- src/main/resources/changelog.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index e01a19fac..cb5832ba4 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,36 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.RC2 (2020-04-28) +----------------------------------------- +* DATAES-803 - Move count request setup from reactive template to reactive client. +* DATAES-802 - Update documentation for using scroll API with repository methods. +* DATAES-801 - Implement callback to enable adding custom headers in the REST HTTP request. +* DATAES-800 - De-Lombok production code. +* DATAES-797 - Fix MappingElasticsearchConverter recursive descent when reading Map objetcsa. +* DATAES-795 - Fix MappingElasticsearchConverter conversion from Document into Map. +* DATAES-794 - MappingBuilder must not write empty mapping properties. +* DATAES-792 - Add java.util.Date to the supported types for Field annonation date times. +* DATAES-791 - DocumentOperations.multiGet() implementations must return null values for not found entities. +* DATAES-790 - Deprecate noRefresh repository method. +* DATAES-789 - Make ElasticsearchRestTemplate.ClientCallback public. +* DATAES-788 - Add missing path mapping to completion context. +* DATAES-787 - Use JDK 14 for Java.NEXT CI testing. +* DATAES-786 - Move the creation of SearchHit(s) from ElasticsearchConverter closer to ElasticsearchTemplate. +* DATAES-785 - Various entity callbacks implementation improvements. +* DATAES-784 - MappingBuilder should use @Field annotation with custom value objects. +* DATAES-782 - Make underlying TransportClient accessible. +* DATAES-781 - Upgrade to Elasticsearch 7.6.2. +* DATAES-778 - Fix SSL setup in the reactive client. +* DATAES-777 - SearchHitsSupport must preserve pageable when unwrapping to AggregatedPage. +* DATAES-776 - Adapt RestClients class to change in InetSocketAddress class in JDK14. +* DATAES-775 - Fix test runner setup. +* DATAES-774 - Release 4.0 RC2 (Neumann). +* DATAES-773 - Add search-as-you-type field support to index mappings. +* DATAES-772 - Add after-convert entity callbacks support. +* DATAES-567 - Unable to read aggregations via Reactive*Operations. + + Changes in version 3.2.7.RELEASE (2020-04-28) --------------------------------------------- * DATAES-780 - Upgrade 3.2.x to Elasticsearch 6.8.8. @@ -1088,3 +1118,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 1d4adadaa78d842f4cef566cacddbf3415198517 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 15:03:33 +0200 Subject: [PATCH 0141/1191] DATAES-774 - Prepare 4.0 RC2 (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 979515864..a4731c6f8 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RC2 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.2 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RC2 4.1.39.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index acc9f97c5..081bded18 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 RC1 +Spring Data Elasticsearch 4.0 RC2 Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -13,3 +13,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 6277330017aa3db783d413d5646a507bfc94c001 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 15:03:53 +0200 Subject: [PATCH 0142/1191] DATAES-774 - Release version 4.0 RC2 (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a4731c6f8..1b7abc696 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.RC2 org.springframework.data.build From 2e346a4e4aea0c83921d1029f80f3492351e9ead Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 15:11:42 +0200 Subject: [PATCH 0143/1191] DATAES-774 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1b7abc696..a4731c6f8 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.RC2 + 4.0.0.BUILD-SNAPSHOT org.springframework.data.build From 853980cdfd70c73481d4fd2685ce50345e195cee Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Apr 2020 15:11:43 +0200 Subject: [PATCH 0144/1191] DATAES-774 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index a4731c6f8..979515864 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.RC2 + 2.3.0.BUILD-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.2 2.9.1 - 2.3.0.RC2 + 2.3.0.BUILD-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 9b620b31bd4e89145a218137eb52ced4dcd59f7c Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Wed, 29 Apr 2020 22:11:14 +0400 Subject: [PATCH 0145/1191] DATAES-799 - Support optimistic locking for full update scenario using seq_no + primary_term. Original PR: #441 --- .../core/AbstractElasticsearchTemplate.java | 31 +++- .../core/DocumentOperations.java | 2 +- .../ElasticsearchExceptionTranslator.java | 29 ++++ .../core/ElasticsearchTemplate.java | 30 +++- .../elasticsearch/core/EntityOperations.java | 40 +++++ .../core/ReactiveElasticsearchTemplate.java | 16 +- .../elasticsearch/core/RequestFactory.java | 36 ++++- .../MappingElasticsearchConverter.java | 30 ++-- .../elasticsearch/core/document/Document.java | 65 ++++++++ .../core/document/DocumentAdapters.java | 130 +++++++++++++++- .../core/document/MapDocument.java | 65 ++++++++ .../core/index/MappingBuilder.java | 9 ++ .../ElasticsearchPersistentEntity.java | 39 +++++ .../ElasticsearchPersistentProperty.java | 17 ++ .../SimpleElasticsearchPersistentEntity.java | 47 ++++++ ...SimpleElasticsearchPersistentProperty.java | 23 +++ .../elasticsearch/core/query/IndexQuery.java | 22 ++- .../core/query/IndexQueryBuilder.java | 11 ++ .../core/query/SeqNoPrimaryTerm.java | 99 ++++++++++++ .../core/DocumentAdaptersUnitTests.java | 66 +++++++- ...ElasticsearchExceptionTranslatorTests.java | 61 ++++++++ .../core/ElasticsearchTemplateTests.java | 145 ++++++++++++++++++ .../ReactiveElasticsearchTemplateTests.java | 139 ++++++++++++++++- .../core/RequestFactoryTests.java | 105 ++++++++++++- ...appingElasticsearchConverterUnitTests.java | 30 ++++ .../core/index/MappingBuilderTests.java | 18 +++ ...pleElasticsearchPersistentEntityTests.java | 56 +++++++ ...sticsearchPersistentPropertyUnitTests.java | 42 ++++- .../core/query/SeqNoPrimaryTermTests.java | 52 +++++++ 29 files changed, 1414 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 5aa64604a..16d85ad74 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -53,6 +53,7 @@ import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.util.CloseableIterator; @@ -438,6 +439,22 @@ private Long getEntityVersion(Object entity) { return null; } + @Nullable + private SeqNoPrimaryTerm getEntitySeqNoPrimaryTerm(Object entity) { + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + ElasticsearchPersistentProperty property = persistentEntity.getSeqNoPrimaryTermProperty(); + + if (property != null) { + Object seqNoPrimaryTerm = persistentEntity.getPropertyAccessor(entity).getProperty(property); + + if (seqNoPrimaryTerm != null && SeqNoPrimaryTerm.class.isAssignableFrom(seqNoPrimaryTerm.getClass())) { + return (SeqNoPrimaryTerm) seqNoPrimaryTerm; + } + } + + return null; + } + private IndexQuery getIndexQuery(T entity) { String id = getEntityId(entity); @@ -445,11 +462,17 @@ private IndexQuery getIndexQuery(T entity) { id = elasticsearchConverter.convertId(id); } - return new IndexQueryBuilder() // + IndexQueryBuilder builder = new IndexQueryBuilder() // .withId(id) // - .withVersion(getEntityVersion(entity)) // - .withObject(entity) // - .build(); + .withObject(entity); + SeqNoPrimaryTerm seqNoPrimaryTerm = getEntitySeqNoPrimaryTerm(entity); + if (seqNoPrimaryTerm != null) { + builder.withSeqNoPrimaryTerm(seqNoPrimaryTerm); + } else { + // version cannot be used together with seq_no and primary_term + builder.withVersion(getEntityVersion(entity)); + } + return builder.build(); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 1c05cd801..279f2156e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -250,7 +250,7 @@ default void bulkUpdate(List queries, IndexCoordinates index) { * @param clazz the type of the object to be returned * @param index the index from which the object is read. * @return the found object - * @deprecated since 4.0, use {@link #getById(String, Class, IndexCoordinates)} + * @deprecated since 4.0, use {@link #get(String, Class, IndexCoordinates)} */ @Deprecated @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index f4aeb1c00..77a8de10d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -22,9 +22,12 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.common.ValidationException; +import org.elasticsearch.index.engine.VersionConflictEngineException; +import org.elasticsearch.rest.RestStatus; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.dao.support.PersistenceExceptionTranslator; import org.springframework.data.elasticsearch.NoSuchIndexException; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; @@ -35,6 +38,7 @@ /** * @author Christoph Strobl * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 3.2 */ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator { @@ -50,6 +54,12 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return new NoSuchIndexException(ObjectUtils.nullSafeToString(elasticsearchException.getMetadata("es.index")), ex); } + + if (isSeqNoConflict(elasticsearchException)) { + return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict", + elasticsearchException); + } + return new UncategorizedElasticsearchException(ex.getMessage(), ex); } @@ -65,6 +75,25 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return null; } + private boolean isSeqNoConflict(ElasticsearchException exception) { + + if (exception instanceof ElasticsearchStatusException) { + ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception; + return statusException.status() == RestStatus.CONFLICT + && statusException.getMessage() != null + && statusException.getMessage().contains("type=version_conflict_engine_exception") + && statusException.getMessage().contains("version conflict, required seqNo"); + } + + if (exception instanceof VersionConflictEngineException) { + VersionConflictEngineException versionConflictEngineException = (VersionConflictEngineException) exception; + return versionConflictEngineException.getMessage() != null + && versionConflictEngineException.getMessage().contains("version conflict, required seqNo"); + } + + return false; + } + private boolean indexAvailable(ElasticsearchException ex) { List metadata = ex.getMetadata("es.index_uuid"); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 43ca3b1c5..066fc8bcf 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -27,6 +27,7 @@ import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder; +import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; import org.elasticsearch.action.search.SearchRequestBuilder; @@ -89,6 +90,8 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { private Client client; @Nullable private String searchTimeout; + private final ElasticsearchExceptionTranslator exceptionTranslator = new ElasticsearchExceptionTranslator(); + // region Initialization public ElasticsearchTemplate(Client client) { this.client = client; @@ -145,7 +148,14 @@ public String index(IndexQuery query, IndexCoordinates index) { maybeCallbackBeforeConvertWithQuery(query, index); IndexRequestBuilder indexRequestBuilder = requestFactory.indexRequestBuilder(client, query, index); - String documentId = indexRequestBuilder.execute().actionGet().getId(); + ActionFuture future = indexRequestBuilder.execute(); + IndexResponse response; + try { + response = future.actionGet(); + } catch (RuntimeException e) { + throw translateException(e); + } + String documentId = response.getId(); // We should call this because we are not going through a mapper. Object queryObject = query.getObject(); @@ -360,4 +370,22 @@ public Client getClient() { return client; } // endregion + + /** + * translates an Exception if possible. Exceptions that are no {@link RuntimeException}s are wrapped in a + * RuntimeException + * + * @param exception the Exception to map + * @return the potentially translated RuntimeException. + * @since 4.0 + */ + private RuntimeException translateException(Exception exception) { + + RuntimeException runtimeException = exception instanceof RuntimeException ? (RuntimeException) exception + : new RuntimeException(exception.getMessage(), exception); + RuntimeException potentiallyTranslatedException = exceptionTranslator + .translateExceptionIfPossible(runtimeException); + + return potentiallyTranslatedException != null ? potentiallyTranslatedException : runtimeException; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 1a8567d9a..65467ec0d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -21,6 +21,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.IdentifierAccessor; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; @@ -35,6 +36,7 @@ * @author Mark Paluch * @author Christoph Strobl * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 3.2 */ class EntityOperations { @@ -256,6 +258,21 @@ interface AdaptibleEntity extends Entity { @Override @Nullable Number getVersion(); + + /** + * Returns whether there is a property with type SeqNoPrimaryTerm in this entity. + * + * @return true if there is SeqNoPrimaryTerm property + * @since 4.0 + */ + boolean hasSeqNoPrimaryTerm(); + + /** + * Returns SeqNoPropertyTerm for this entity. + * + * @return SeqNoPrimaryTerm, may be {@literal null} + */ + @Nullable SeqNoPrimaryTerm getSeqNoPrimaryTerm(); } /** @@ -333,6 +350,16 @@ public Number getVersion() { return null; } + @Override + public boolean hasSeqNoPrimaryTerm() { + return false; + } + + @Override + public SeqNoPrimaryTerm getSeqNoPrimaryTerm() { + return null; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#incrementVersion() @@ -588,6 +615,19 @@ public Number getVersion() { return propertyAccessor.getProperty(versionProperty, Number.class); } + @Override + public boolean hasSeqNoPrimaryTerm() { + return entity.hasSeqNoPrimaryTermProperty(); + } + + @Override + public SeqNoPrimaryTerm getSeqNoPrimaryTerm() { + + ElasticsearchPersistentProperty seqNoPrimaryTermProperty = entity.getRequiredSeqNoPrimaryTermProperty(); + + return propertyAccessor.getProperty(seqNoPrimaryTermProperty, SeqNoPrimaryTerm.class); + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#initializeVersionProperty() diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 83ec43dc7..21f6b36fa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -84,6 +84,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.VersionInfo; @@ -347,7 +348,19 @@ private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, In request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); - if (entity.isVersionedEntity()) { + boolean usingSeqNo = false; + if (entity.hasSeqNoPrimaryTerm()) { + SeqNoPrimaryTerm seqNoPrimaryTerm = entity.getSeqNoPrimaryTerm(); + + if (seqNoPrimaryTerm != null) { + request.setIfSeqNo(seqNoPrimaryTerm.getSequenceNumber()); + request.setIfPrimaryTerm(seqNoPrimaryTerm.getPrimaryTerm()); + usingSeqNo = true; + } + } + + // seq_no and version are incompatible in the same request + if (!usingSeqNo && entity.isVersionedEntity()) { Number version = entity.getVersion(); @@ -356,6 +369,7 @@ private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, In request.versionType(EXTERNAL); } } + return request; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 73220fce2..c4361cf32 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -83,6 +83,7 @@ * * @author Peter-Josef Meisch * @author Sascha Woo + * @author Roman Puchkovskiy * @since 4.0 */ class RequestFactory { @@ -342,6 +343,13 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { indexRequest.versionType(versionType); } + if (query.getSeqNo() != null) { + indexRequest.setIfSeqNo(query.getSeqNo()); + } + if (query.getPrimaryTerm() != null) { + indexRequest.setIfPrimaryTerm(query.getPrimaryTerm()); + } + return indexRequest; } @@ -374,6 +382,13 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, indexRequestBuilder.setVersionType(versionType); } + if (query.getSeqNo() != null) { + indexRequestBuilder.setIfSeqNo(query.getSeqNo()); + } + if (query.getPrimaryTerm() != null) { + indexRequestBuilder.setIfPrimaryTerm(query.getPrimaryTerm()); + } + return indexRequestBuilder; } @@ -618,6 +633,9 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); sourceBuilder.version(true); sourceBuilder.trackScores(query.getTrackScores()); + if (hasSeqNoPrimaryTermProperty(clazz)) { + sourceBuilder.seqNoAndPrimaryTerm(true); + } if (query.getSourceFilter() != null) { SourceFilter sourceFilter = query.getSourceFilter(); @@ -681,7 +699,20 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz return request; } - @SuppressWarnings("unchecked") + private boolean hasSeqNoPrimaryTermProperty(@Nullable Class entityClass) { + + if (entityClass == null) { + return false; + } + + if (!elasticsearchConverter.getMappingContext().hasPersistentEntityFor(entityClass)) { + return false; + } + + ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(entityClass); + return entity.hasSeqNoPrimaryTermProperty(); + } + public PutMappingRequest putMappingRequest(IndexCoordinates index, Document mapping) { PutMappingRequest request = new PutMappingRequest(index.getIndexName()); request.source(mapping); @@ -784,6 +815,9 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli .setSearchType(query.getSearchType()) // .setVersion(true) // .setTrackScores(query.getTrackScores()); + if (hasSeqNoPrimaryTermProperty(clazz)) { + searchRequestBuilder.seqNoAndPrimaryTerm(true); + } if (query.getSourceFilter() != null) { SourceFilter sourceFilter = query.getSourceFilter(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 786566093..9e196a273 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,17 +15,8 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; @@ -44,6 +35,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.mapping.model.ConvertingPropertyAccessor; @@ -205,6 +197,14 @@ protected R readEntity(ElasticsearchPersistentEntity entity, Map R readEntity(ElasticsearchPersistentEntity entity, Map= 0; + } + + private boolean isAssignedPrimaryTerm(long primaryTerm) { + return primaryTerm > 0; + } + protected R readProperties(ElasticsearchPersistentEntity entity, R instance, ElasticsearchPropertyValueProvider valueProvider) { @@ -228,7 +236,7 @@ protected R readProperties(ElasticsearchPersistentEntity entity, R instan for (ElasticsearchPersistentProperty prop : entity) { - if (entity.isConstructorArgument(prop) || prop.isScoreProperty()) { + if (entity.isConstructorArgument(prop) || prop.isScoreProperty() || !prop.isReadable()) { continue; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index 82c91ccfc..c6311ed75 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -39,6 +39,7 @@ * * @author Mark Paluch * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ public interface Document extends Map { @@ -165,6 +166,70 @@ default void setVersion(long version) { throw new UnsupportedOperationException(); } + /** + * Return {@literal true} if this {@link Document} is associated with a seq_no. + * + * @return {@literal true} if this {@link Document} is associated with a seq_no, {@literal false} otherwise. + */ + default boolean hasSeqNo() { + return false; + } + + /** + * Retrieve the seq_no associated with this {@link Document}. + *

+ * The default implementation throws {@link UnsupportedOperationException}. It's recommended to check + * {@link #hasSeqNo()} prior to calling this method. + * + * @return the seq_no associated with this {@link Document}. + * @throws IllegalStateException if the underlying implementation supports seq_no's but no seq_no was yet + * associated with the document. + */ + default long getSeqNo() { + throw new UnsupportedOperationException(); + } + + /** + * Set the seq_no for this {@link Document}. + *

+ * The default implementation throws {@link UnsupportedOperationException}. + */ + default void setSeqNo(long seqNo) { + throw new UnsupportedOperationException(); + } + + /** + * Return {@literal true} if this {@link Document} is associated with a primary_term. + * + * @return {@literal true} if this {@link Document} is associated with a primary_term, {@literal false} otherwise. + */ + default boolean hasPrimaryTerm() { + return false; + } + + /** + * Retrieve the primary_term associated with this {@link Document}. + *

+ * The default implementation throws {@link UnsupportedOperationException}. It's recommended to check + * {@link #hasPrimaryTerm()} prior to calling this method. + * + * @return the primary_term associated with this {@link Document}. + * @throws IllegalStateException if the underlying implementation supports primary_term's but no primary_term was + * yet associated with the document. + */ + default long getPrimaryTerm() { + throw new UnsupportedOperationException(); + } + + /** + * Set the primary_term for this {@link Document}. + *

+ * The default implementation throws {@link UnsupportedOperationException}. + */ + default void setPrimaryTerm(long primaryTerm) { + throw new UnsupportedOperationException(); + } + /** * Returns the value to which the specified {@code key} is mapped, or {@literal null} if this document contains no * mapping for the key. The value is casted within the method which makes it useful for calling code as it does not diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index fb1a491a8..0dbc7aed9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -54,6 +54,7 @@ * * @author Mark Paluch * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.0 */ public class DocumentAdapters { @@ -76,12 +77,15 @@ public static Document from(GetResponse source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion()); + return fromDocumentFields(source, source.getId(), source.getVersion(), + source.getSeqNo(), source.getPrimaryTerm()); } Document document = Document.from(source.getSourceAsMap()); document.setId(source.getId()); document.setVersion(source.getVersion()); + document.setSeqNo(source.getSeqNo()); + document.setPrimaryTerm(source.getPrimaryTerm()); return document; } @@ -104,12 +108,15 @@ public static Document from(GetResult source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion()); + return fromDocumentFields(source, source.getId(), source.getVersion(), + source.getSeqNo(), source.getPrimaryTerm()); } Document document = Document.from(source.getSource()); document.setId(source.getId()); document.setVersion(source.getVersion()); + document.setSeqNo(source.getSeqNo()); + document.setPrimaryTerm(source.getPrimaryTerm()); return document; } @@ -150,7 +157,8 @@ public static SearchDocument from(SearchHit source) { if (sourceRef == null || sourceRef.length() == 0) { return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, - fromDocumentFields(source, source.getId(), source.getVersion())); + fromDocumentFields(source, source.getId(), source.getVersion(), + source.getSeqNo(), source.getPrimaryTerm())); } Document document = Document.from(source.getSourceAsMap()); @@ -159,6 +167,8 @@ public static SearchDocument from(SearchHit source) { if (source.getVersion() >= 0) { document.setVersion(source.getVersion()); } + document.setSeqNo(source.getSeqNo()); + document.setPrimaryTerm(source.getPrimaryTerm()); return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, document); @@ -170,10 +180,11 @@ public static SearchDocument from(SearchHit source) { * @param documentFields the {@link DocumentField}s backing the {@link Document}. * @return the adapted {@link Document}. */ - public static Document fromDocumentFields(Iterable documentFields, String id, long version) { + public static Document fromDocumentFields(Iterable documentFields, String id, long version, + long seqNo, long primaryTerm) { if (documentFields instanceof Collection) { - return new DocumentFieldAdapter((Collection) documentFields, id, version); + return new DocumentFieldAdapter((Collection) documentFields, id, version, seqNo, primaryTerm); } List fields = new ArrayList<>(); @@ -181,7 +192,7 @@ public static Document fromDocumentFields(Iterable documentFields fields.add(documentField); } - return new DocumentFieldAdapter(fields, id, version); + return new DocumentFieldAdapter(fields, id, version, seqNo, primaryTerm); } // TODO: Performance regarding keys/values/entry-set @@ -190,11 +201,16 @@ static class DocumentFieldAdapter implements Document { private final Collection documentFields; private final String id; private final long version; + private final long seqNo; + private final long primaryTerm; - DocumentFieldAdapter(Collection documentFields, String id, long version) { + DocumentFieldAdapter(Collection documentFields, String id, long version, + long seqNo, long primaryTerm) { this.documentFields = documentFields; this.id = id; this.version = version; + this.seqNo = seqNo; + this.primaryTerm = primaryTerm; } /* @@ -238,6 +254,52 @@ public long getVersion() { return this.version; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() + */ + @Override + public boolean hasSeqNo() { + return true; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getSeqNo() + */ + @Override + public long getSeqNo() { + + if (!hasSeqNo()) { + throw new IllegalStateException("No seq_no associated with this Document"); + } + + return this.seqNo; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() + */ + @Override + public boolean hasPrimaryTerm() { + return true; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getPrimaryTerm() + */ + @Override + public long getPrimaryTerm() { + + if (!hasPrimaryTerm()) { + throw new IllegalStateException("No primary_term associated with this Document"); + } + + return this.primaryTerm; + } + /* * (non-Javadoc) * @see java.util.Map#size() @@ -556,6 +618,60 @@ public long getVersion() { public void setVersion(long version) { delegate.setVersion(version); } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() + */ + @Override + public boolean hasSeqNo() { + return delegate.hasSeqNo(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getSeqNo() + */ + @Override + public long getSeqNo() { + return delegate.getSeqNo(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#setSeqNo(long) + */ + @Override + public void setSeqNo(long seqNo) { + delegate.setSeqNo(seqNo); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() + */ + @Override + public boolean hasPrimaryTerm() { + return delegate.hasPrimaryTerm(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getPrimaryTerm() + */ + @Override + public long getPrimaryTerm() { + return delegate.getPrimaryTerm(); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#setPrimaryTerm(long) + */ + @Override + public void setPrimaryTerm(long primaryTerm) { + delegate.setPrimaryTerm(primaryTerm); + } /* * (non-Javadoc) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java index a9f114969..fb80c35e1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java @@ -31,6 +31,7 @@ * {@link Document} implementation backed by a {@link LinkedHashMap}. * * @author Mark Paluch + * @author Roman Puchkovskiy * @since 4.0 */ class MapDocument implements Document { @@ -41,6 +42,8 @@ class MapDocument implements Document { private @Nullable String id; private @Nullable Long version; + private @Nullable Long seqNo; + private @Nullable Long primaryTerm; MapDocument() { this(new LinkedHashMap<>()); @@ -114,6 +117,68 @@ public void setVersion(long version) { this.version = version; } + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() + */ + @Override + public boolean hasSeqNo() { + return this.seqNo != null; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getSeqNo() + */ + @Override + public long getSeqNo() { + + if (!hasSeqNo()) { + throw new IllegalStateException("No seq_no associated with this Document"); + } + + return this.seqNo; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#setSeqNo() + */ + public void setSeqNo(long seqNo) { + this.seqNo = seqNo; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() + */ + @Override + public boolean hasPrimaryTerm() { + return this.primaryTerm != null; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#getPrimaryTerm() + */ + @Override + public long getPrimaryTerm() { + + if (!hasPrimaryTerm()) { + throw new IllegalStateException("No primary_term associated with this Document"); + } + + return this.primaryTerm; + } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.document.Document#setPrimaryTerm() + */ + public void setPrimaryTerm(long primaryTerm) { + this.primaryTerm = primaryTerm; + } + /* * (non-Javadoc) * @see java.util.Map#size() diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index c75e1d332..2eea93ca9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -167,6 +167,15 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten return; } + if (property.isSeqNoPrimaryTermProperty()) { + if (property.isAnnotationPresent(Field.class)) { + logger.warn("Property {} of {} is annotated for inclusion in mapping, but its type is " + // + "SeqNoPrimaryTerm that is never mapped, so it is skipped", // + property.getFieldName(), entity.getType()); + } + return; + } + buildPropertyMapping(builder, isRootObject, property); } catch (IOException e) { logger.warn("error mapping property with name {}", property.getName(), e); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 1111d172c..9e2c0d959 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -17,6 +17,7 @@ import org.elasticsearch.index.VersionType; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentEntity; import org.springframework.lang.Nullable; @@ -30,6 +31,7 @@ * @author Oliver Gierke * @author Ivan Greene * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public interface ElasticsearchPersistentEntity extends PersistentEntity { @@ -96,4 +98,41 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity { @@ -64,6 +65,14 @@ public interface ElasticsearchPersistentProperty extends PersistentProperty { INSTANCE; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 7d53d916a..348ac676d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -23,6 +23,8 @@ import java.util.concurrent.atomic.AtomicReference; import org.elasticsearch.index.VersionType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -53,10 +55,13 @@ * @author Sascha Woo * @author Ivan Greene * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntity implements ElasticsearchPersistentEntity, ApplicationContextAware { + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleElasticsearchPersistentEntity.class); + private final StandardEvaluationContext context; private final SpelExpressionParser parser; @@ -70,6 +75,7 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private @Nullable String parentType; private @Nullable ElasticsearchPersistentProperty parentIdProperty; private @Nullable ElasticsearchPersistentProperty scoreProperty; + private @Nullable ElasticsearchPersistentProperty seqNoPrimaryTermProperty; private @Nullable String settingPath; private @Nullable VersionType versionType; private boolean createIndexAndMapping; @@ -231,6 +237,36 @@ public void addPersistentProperty(ElasticsearchPersistentProperty property) { this.scoreProperty = property; } + + if (property.isSeqNoPrimaryTermProperty()) { + + ElasticsearchPersistentProperty seqNoPrimaryTermProperty = this.seqNoPrimaryTermProperty; + + if (seqNoPrimaryTermProperty != null) { + throw new MappingException(String.format( + "Attempt to add SeqNoPrimaryTerm property %s but already have property %s registered " + + "as SeqNoPrimaryTerm property. Check your entity configuration!", + property.getField(), seqNoPrimaryTermProperty.getField())); + } + + this.seqNoPrimaryTermProperty = property; + + if (hasVersionProperty()) { + warnAboutBothSeqNoPrimaryTermAndVersionProperties(); + } + } + + if (property.isVersionProperty()) { + if (hasSeqNoPrimaryTermProperty()) { + warnAboutBothSeqNoPrimaryTermAndVersionProperties(); + } + } + } + + private void warnAboutBothSeqNoPrimaryTermAndVersionProperties() { + LOGGER.warn( + "Both SeqNoPrimaryTerm and @Version properties are defined on {}. Version will not be sent in index requests when seq_no is sent!", + getType()); } /* @@ -262,4 +298,15 @@ public ElasticsearchPersistentProperty getPersistentPropertyWithFieldName(String return propertyRef.get(); }); } + + @Override + public boolean hasSeqNoPrimaryTermProperty() { + return seqNoPrimaryTermProperty != null; + } + + @Override + @Nullable + public ElasticsearchPersistentProperty getSeqNoPrimaryTermProperty() { + return seqNoPrimaryTermProperty; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index a69f6fa20..beab6b433 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -26,6 +26,7 @@ import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.Association; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PersistentEntity; @@ -44,6 +45,7 @@ * @author Sascha Woo * @author Oliver Gierke * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class SimpleElasticsearchPersistentProperty extends AnnotationBasedPersistentProperty implements ElasticsearchPersistentProperty { @@ -53,6 +55,7 @@ public class SimpleElasticsearchPersistentProperty extends private final boolean isScore; private final boolean isParent; private final boolean isId; + private final boolean isSeqNoPrimaryTerm; private final @Nullable String annotatedFieldName; @Nullable private ElasticsearchPersistentPropertyConverter propertyConverter; @@ -65,6 +68,7 @@ public SimpleElasticsearchPersistentProperty(Property property, this.isId = super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()); this.isScore = isAnnotationPresent(Score.class); this.isParent = isAnnotationPresent(Parent.class); + this.isSeqNoPrimaryTerm = SeqNoPrimaryTerm.class.isAssignableFrom(getRawType()); if (isVersionProperty() && !getType().equals(Long.class)) { throw new MappingException(String.format("Version property %s must be of type Long!", property.getName())); @@ -93,6 +97,16 @@ public ElasticsearchPersistentPropertyConverter getPropertyConverter() { return propertyConverter; } + @Override + public boolean isWritable() { + return super.isWritable() && !isSeqNoPrimaryTermProperty(); + } + + @Override + public boolean isReadable() { + return !isTransient() && !isSeqNoPrimaryTermProperty(); + } + /** * Initializes an {@link ElasticsearchPersistentPropertyConverter} if this property is annotated as a Field with type * {@link FieldType#Date}, has a {@link DateFormat} set and if the type of the property is one of the Java8 temporal @@ -209,4 +223,13 @@ public boolean isImmutable() { public boolean isParentProperty() { return isParent; } + + /* + * (non-Javadoc) + * @see org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty#isSeqNoPrimaryTermProperty() + */ + @Override + public boolean isSeqNoPrimaryTermProperty() { + return isSeqNoPrimaryTerm; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index 5865571e4..fa0ba5748 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -23,8 +23,8 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ - public class IndexQuery { @Nullable private String id; @@ -32,6 +32,8 @@ public class IndexQuery { @Nullable private Long version; @Nullable private String source; @Nullable private String parentId; + @Nullable private Long seqNo; + @Nullable private Long primaryTerm; @Nullable public String getId() { @@ -87,4 +89,22 @@ public String getParentId() { public void setParentId(String parentId) { this.parentId = parentId; } + + @Nullable + public Long getSeqNo() { + return seqNo; + } + + public void setSeqNo(Long seqNo) { + this.seqNo = seqNo; + } + + @Nullable + public Long getPrimaryTerm() { + return primaryTerm; + } + + public void setPrimaryTerm(Long primaryTerm) { + this.primaryTerm = primaryTerm; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 33652ba60..588f557d5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -23,6 +23,7 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class IndexQueryBuilder { @@ -31,6 +32,8 @@ public class IndexQueryBuilder { @Nullable private Long version; @Nullable private String source; @Nullable private String parentId; + @Nullable private Long seqNo; + @Nullable private Long primaryTerm; public IndexQueryBuilder withId(String id) { this.id = id; @@ -57,6 +60,12 @@ public IndexQueryBuilder withParentId(String parentId) { return this; } + public IndexQueryBuilder withSeqNoPrimaryTerm(SeqNoPrimaryTerm seqNoPrimaryTerm) { + this.seqNo = seqNoPrimaryTerm.getSequenceNumber(); + this.primaryTerm = seqNoPrimaryTerm.getPrimaryTerm(); + return this; + } + public IndexQuery build() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(id); @@ -64,6 +73,8 @@ public IndexQuery build() { indexQuery.setParentId(parentId); indexQuery.setSource(source); indexQuery.setVersion(version); + indexQuery.setSeqNo(seqNo); + indexQuery.setPrimaryTerm(primaryTerm); return indexQuery; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java new file mode 100644 index 000000000..c7bf434d0 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java @@ -0,0 +1,99 @@ +/* + * Copyright 2020 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.query; + +import java.util.Objects; + +/** + *

A container for seq_no and primary_term values. When an entity class contains a field of this type, + * it will be automatically filled with SeqNoPrimaryTerm instance on read operations (like get or search), + * and also, when the SeqNoPrimaryTerm is not {@literal null} and filled with seq_no and primary_term, + * they will be sent to Elasticsearch when indexing such an entity. + *

+ *

This allows to implement optimistic locking pattern for full-update scenario, when an entity is first + * read from Elasticsearch and then gets reindexed with new _content. + * Index operations will throw an {@link org.springframework.dao.OptimisticLockingFailureException} if the + * seq_no + primary_term pair already has different values for the given document. See Elasticsearch documentation + * for more information: https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html + *

+ *

A property of this type is implicitly @{@link org.springframework.data.annotation.Transient} and never gets included + * into a mapping at Elasticsearch side. + *

+ *

A SeqNoPrimaryTerm instance cannot contain an invalid or unassigned seq_no or primary_term. + *

+ * + * @author Roman Puchkovskiy + * @since 4.0 + */ +public final class SeqNoPrimaryTerm { + private final long sequenceNumber; + private final long primaryTerm; + + /** + * Creates an instance of SeqNoPrimaryTerm with the given seq_no and primary_term. The passed values are validated: + * sequenceNumber must be non-negative, primaryTerm must be positive. If validation fails, + * an IllegalArgumentException is thrown. + * + * @param sequenceNumber seq_no, must not be negative + * @param primaryTerm primary_term, must be positive + * @throws IllegalArgumentException if seq_no or primary_term is not valid + */ + public SeqNoPrimaryTerm(long sequenceNumber, long primaryTerm) { + if (sequenceNumber < 0) { + throw new IllegalArgumentException("seq_no should not be negative, but it's " + sequenceNumber); + } + if (primaryTerm <= 0) { + throw new IllegalArgumentException("primary_term should be positive, but it's " + primaryTerm); + } + + this.sequenceNumber = sequenceNumber; + this.primaryTerm = primaryTerm; + } + + public long getSequenceNumber() { + return sequenceNumber; + } + + public long getPrimaryTerm() { + return primaryTerm; + } + + @Override + public String toString() { + return "SeqNoPrimaryTerm{" + + "sequenceNumber=" + sequenceNumber + + ", primaryTerm=" + primaryTerm + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SeqNoPrimaryTerm that = (SeqNoPrimaryTerm) o; + return sequenceNumber == that.sequenceNumber && + primaryTerm == that.primaryTerm; + } + + @Override + public int hashCode() { + return Objects.hash(sequenceNumber, primaryTerm); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java index 852e8f0da..8568e6d46 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java @@ -38,6 +38,7 @@ * * @author Mark Paluch * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class DocumentAdaptersUnitTests { @@ -47,7 +48,7 @@ public void shouldAdaptGetResponse() { Map fields = Collections.singletonMap("field", new DocumentField("field", Collections.singletonList("value"))); - GetResult getResult = new GetResult("index", "type", "my-id", 1, 1, 42, true, null, fields, null); + GetResult getResult = new GetResult("index", "type", "my-id", 1, 2, 42, true, null, fields, null); GetResponse response = new GetResponse(getResult); Document document = DocumentAdapters.from(response); @@ -57,6 +58,10 @@ public void shouldAdaptGetResponse() { assertThat(document.hasVersion()).isTrue(); assertThat(document.getVersion()).isEqualTo(42); assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); } @Test // DATAES-628 @@ -64,7 +69,7 @@ public void shouldAdaptGetResponseSource() { BytesArray source = new BytesArray("{\"field\":\"value\"}"); - GetResult getResult = new GetResult("index", "type", "my-id", 1, 1, 42, true, source, Collections.emptyMap(), null); + GetResult getResult = new GetResult("index", "type", "my-id", 1, 2, 42, true, source, Collections.emptyMap(), null); GetResponse response = new GetResponse(getResult); Document document = DocumentAdapters.from(response); @@ -74,6 +79,51 @@ public void shouldAdaptGetResponseSource() { assertThat(document.hasVersion()).isTrue(); assertThat(document.getVersion()).isEqualTo(42); assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); + } + + @Test // DATAES-799 + public void shouldAdaptGetResult() { + + Map fields = Collections.singletonMap("field", + new DocumentField("field", Collections.singletonList("value"))); + + GetResult getResult = new GetResult("index", "type", "my-id", 1, 2, 42, true, null, fields, null); + + Document document = DocumentAdapters.from(getResult); + + assertThat(document.hasId()).isTrue(); + assertThat(document.getId()).isEqualTo("my-id"); + assertThat(document.hasVersion()).isTrue(); + assertThat(document.getVersion()).isEqualTo(42); + assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); + } + + @Test // DATAES-799 + public void shouldAdaptGetResultSource() { + + BytesArray source = new BytesArray("{\"field\":\"value\"}"); + + GetResult getResult = new GetResult("index", "type", "my-id", 1, 2, 42, true, source, Collections.emptyMap(), null); + + Document document = DocumentAdapters.from(getResult); + + assertThat(document.hasId()).isTrue(); + assertThat(document.getId()).isEqualTo("my-id"); + assertThat(document.hasVersion()).isTrue(); + assertThat(document.getVersion()).isEqualTo(42); + assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); } @Test // DATAES-628 @@ -83,6 +133,8 @@ public void shouldAdaptSearchResponse() { new DocumentField("field", Collections.singletonList("value"))); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + searchHit.setSeqNo(1); + searchHit.setPrimaryTerm(2); searchHit.score(42); SearchDocument document = DocumentAdapters.from(searchHit); @@ -92,6 +144,10 @@ public void shouldAdaptSearchResponse() { assertThat(document.hasVersion()).isFalse(); assertThat(document.getScore()).isBetween(42f, 42f); assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); } @Test // DATAES-628 @@ -151,6 +207,8 @@ public void shouldAdaptSearchResponseSource() { SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), Collections.emptyMap()); searchHit.sourceRef(source).score(42); searchHit.version(22); + searchHit.setSeqNo(1); + searchHit.setPrimaryTerm(2); SearchDocument document = DocumentAdapters.from(searchHit); @@ -160,5 +218,9 @@ public void shouldAdaptSearchResponseSource() { assertThat(document.getVersion()).isEqualTo(22); assertThat(document.getScore()).isBetween(42f, 42f); assertThat(document.get("field")).isEqualTo("value"); + assertThat(document.hasSeqNo()).isTrue(); + assertThat(document.getSeqNo()).isEqualTo(1); + assertThat(document.hasPrimaryTerm()).isTrue(); + assertThat(document.getPrimaryTerm()).isEqualTo(2); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java new file mode 100644 index 000000000..4f2ec1339 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; + +import org.elasticsearch.ElasticsearchStatusException; +import org.elasticsearch.index.engine.VersionConflictEngineException; +import org.elasticsearch.index.shard.ShardId; +import org.elasticsearch.rest.RestStatus; +import org.junit.jupiter.api.Test; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.OptimisticLockingFailureException; + +import java.util.UUID; + +/** + * @author Roman Puchkovskiy + */ +class ElasticsearchExceptionTranslatorTests { + private final ElasticsearchExceptionTranslator translator = new ElasticsearchExceptionTranslator(); + + @Test // DATAES-799 + void shouldConvertElasticsearchStatusExceptionWithSeqNoConflictToOptimisticLockingFailureException() { + ElasticsearchStatusException ex = new ElasticsearchStatusException( + "Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]", + RestStatus.CONFLICT); + + DataAccessException translated = translator.translateExceptionIfPossible(ex); + + assertThat(translated).isInstanceOf(OptimisticLockingFailureException.class); + assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); + assertThat(translated.getCause()).isSameAs(ex); + } + + @Test // DATAES-799 + void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLockingFailureException() { + VersionConflictEngineException ex = new VersionConflictEngineException( + new ShardId("index", "uuid", 1), "exception-id", + "Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]"); + + DataAccessException translated = translator.translateExceptionIfPossible(ex); + + assertThat(translated).isInstanceOf(OptimisticLockingFailureException.class); + assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); + assertThat(translated.getCause()).isSameAs(ex); + } +} \ No newline at end of file diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 3e1c0696f..e5eed540e 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core; +import static java.util.Collections.*; import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; @@ -58,6 +59,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.PageRequest; @@ -100,6 +102,7 @@ * @author Martin Choraine * @author Farid Azaza * @author Gyula Attila Csorogi + * @author Roman Puchkovskiy */ public abstract class ElasticsearchTemplateTests { @@ -3067,6 +3070,131 @@ void shouldDoExistsWithIndexCoordinates() { assertThat(operations.exists("42", index)).isTrue(); } + @Test // DATAES-799 + void getShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + + OptimisticEntity retrieved = operations.get(saved.getId(), OptimisticEntity.class); + + assertThatSeqNoPrimaryTermIsFilled(retrieved); + } + + private void assertThatSeqNoPrimaryTermIsFilled(OptimisticEntity retrieved) { + assertThat(retrieved.seqNoPrimaryTerm).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getSequenceNumber()).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getSequenceNumber()).isNotNegative(); + assertThat(retrieved.seqNoPrimaryTerm.getPrimaryTerm()).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getPrimaryTerm()).isPositive(); + } + + @Test // DATAES-799 + void multigetShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + operations.refresh(OptimisticEntity.class); + + List retrievedList = operations.multiGet(queryForOne(saved.getId()), OptimisticEntity.class, + operations.getIndexCoordinatesFor(OptimisticEntity.class)); + OptimisticEntity retrieved = retrievedList.get(0); + + assertThatSeqNoPrimaryTermIsFilled(retrieved); + } + + private Query queryForOne(String id) { + return new NativeSearchQueryBuilder().withIds(singletonList(id)).build(); + } + + @Test // DATAES-799 + void searchShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + operations.refresh(OptimisticEntity.class); + + SearchHits retrievedHits = operations.search(queryForOne(saved.getId()), OptimisticEntity.class); + OptimisticEntity retrieved = retrievedHits.getSearchHit(0).getContent(); + + assertThatSeqNoPrimaryTermIsFilled(retrieved); + } + + @Test // DATAES-799 + void multiSearchShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + operations.refresh(OptimisticEntity.class); + + List queries = singletonList(queryForOne(saved.getId())); + List> retrievedHits = operations.multiSearch(queries, + OptimisticEntity.class, operations.getIndexCoordinatesFor(OptimisticEntity.class)); + OptimisticEntity retrieved = retrievedHits.get(0).getSearchHit(0).getContent(); + + assertThatSeqNoPrimaryTermIsFilled(retrieved); + } + + @Test // DATAES-799 + void searchForStreamShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + operations.refresh(OptimisticEntity.class); + + SearchHitsIterator retrievedHits = operations.searchForStream(queryForOne(saved.getId()), + OptimisticEntity.class); + OptimisticEntity retrieved = retrievedHits.next().getContent(); + + assertThatSeqNoPrimaryTermIsFilled(retrieved); + } + + @Test // DATAES-799 + void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnEntityWithSeqNoPrimaryTermProperty() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + + OptimisticEntity forEdit1 = operations.get(saved.getId(), OptimisticEntity.class); + OptimisticEntity forEdit2 = operations.get(saved.getId(), OptimisticEntity.class); + + forEdit1.setMessage("It'll be ok"); + operations.save(forEdit1); + + forEdit2.setMessage("It'll be great"); + assertThatThrownBy(() -> operations.save(forEdit2)) + .isInstanceOf(OptimisticLockingFailureException.class); + } + + @Test // DATAES-799 + void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnVersionedEntityWithSeqNoPrimaryTermProperty() { + OptimisticAndVersionedEntity original = new OptimisticAndVersionedEntity(); + original.setMessage("It's fine"); + OptimisticAndVersionedEntity saved = operations.save(original); + + OptimisticAndVersionedEntity forEdit1 = operations.get(saved.getId(), OptimisticAndVersionedEntity.class); + OptimisticAndVersionedEntity forEdit2 = operations.get(saved.getId(), OptimisticAndVersionedEntity.class); + + forEdit1.setMessage("It'll be ok"); + operations.save(forEdit1); + + forEdit2.setMessage("It'll be great"); + assertThatThrownBy(() -> operations.save(forEdit2)) + .isInstanceOf(OptimisticLockingFailureException.class); + } + + @Test // DATAES-799 + void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { + OptimisticAndVersionedEntity original = new OptimisticAndVersionedEntity(); + original.setMessage("It's fine"); + OptimisticAndVersionedEntity saved = operations.save(original); + + OptimisticAndVersionedEntity forEdit = operations.get(saved.getId(), OptimisticAndVersionedEntity.class); + + forEdit.setMessage("It'll be ok"); + operations.save(forEdit); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @@ -3230,4 +3358,21 @@ static class HighlightEntity { @Id private String id; private String message; } + + @Data + @Document(indexName = "test-index-optimistic-entity-template") + static class OptimisticEntity { + @Id private String id; + private String message; + private SeqNoPrimaryTerm seqNoPrimaryTerm; + } + + @Data + @Document(indexName = "test-index-optimistic-and-versioned-entity-template") + static class OptimisticAndVersionedEntity { + @Id private String id; + private String message; + private SeqNoPrimaryTerm seqNoPrimaryTerm; + @Version private Long version; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 90d9833d8..e78e93853 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core; +import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; @@ -39,6 +40,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.elasticsearch.index.query.IdsQueryBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; import org.elasticsearch.search.sort.FieldSortBuilder; @@ -47,6 +49,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.dao.DataAccessResourceFailureException; +import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Version; import org.springframework.data.domain.PageRequest; @@ -59,14 +62,7 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; 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.IndexQuery; -import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.StringQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; @@ -81,6 +77,7 @@ * @author Martin Choraine * @author Aleksei Arsenev * @author Russell Parry + * @author Roman Puchkovskiy */ @SpringIntegrationTest public class ReactiveElasticsearchTemplateTests { @@ -855,6 +852,115 @@ void shouldReturnEmptyFluxOnSaveAllWithEmptyInput() { .verifyComplete(); } + @Test // DATAES-799 + void getShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = template.save(original).block(); + + template.get(saved.getId(), OptimisticEntity.class) + .as(StepVerifier::create) + .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) + .verifyComplete(); + } + + private void assertThatSeqNoPrimaryTermIsFilled(OptimisticEntity retrieved) { + assertThat(retrieved.seqNoPrimaryTerm).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getSequenceNumber()).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getSequenceNumber()).isNotNegative(); + assertThat(retrieved.seqNoPrimaryTerm.getPrimaryTerm()).isNotNull(); + assertThat(retrieved.seqNoPrimaryTerm.getPrimaryTerm()).isPositive(); + } + + @Test // DATAES-799 + void multiGetShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = template.save(original).block(); + + template.multiGet(multiGetQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class)) + .as(StepVerifier::create) + .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) + .verifyComplete(); + } + + private Query multiGetQueryForOne(String id) { + return new NativeSearchQueryBuilder().withIds(singletonList(id)).build(); + } + + @Test // DATAES-799 + void searchShouldReturnSeqNoPrimaryTerm() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = template.save(original).block(); + restTemplate.refresh(OptimisticEntity.class); + + template.search(searchQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class)) + .map(SearchHit::getContent) + .as(StepVerifier::create) + .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) + .verifyComplete(); + } + + private Query searchQueryForOne(String id) { + return new NativeSearchQueryBuilder() + .withFilter(new IdsQueryBuilder().addIds(id)) + .build(); + } + + @Test // DATAES-799 + void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnEntityWithSeqNoPrimaryTermProperty() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = template.save(original).block(); + + OptimisticEntity forEdit1 = template.get(saved.getId(), OptimisticEntity.class).block(); + OptimisticEntity forEdit2 = template.get(saved.getId(), OptimisticEntity.class).block(); + + forEdit1.setMessage("It'll be ok"); + template.save(forEdit1).block(); + + forEdit2.setMessage("It'll be great"); + template.save(forEdit2) + .as(StepVerifier::create) + .expectError(OptimisticLockingFailureException.class) + .verify(); + } + + @Test // DATAES-799 + void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnVersionedEntityWithSeqNoPrimaryTermProperty() { + OptimisticAndVersionedEntity original = new OptimisticAndVersionedEntity(); + original.setMessage("It's fine"); + OptimisticAndVersionedEntity saved = template.save(original).block(); + + OptimisticAndVersionedEntity forEdit1 = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block(); + OptimisticAndVersionedEntity forEdit2 = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block(); + + forEdit1.setMessage("It'll be ok"); + template.save(forEdit1).block(); + + forEdit2.setMessage("It'll be great"); + template.save(forEdit2) + .as(StepVerifier::create) + .expectError(OptimisticLockingFailureException.class) + .verify(); + } + + @Test // DATAES-799 + void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { + OptimisticAndVersionedEntity original = new OptimisticAndVersionedEntity(); + original.setMessage("It's fine"); + OptimisticAndVersionedEntity saved = template.save(original).block(); + + OptimisticAndVersionedEntity forEdit = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block(); + + forEdit.setMessage("It'll be ok"); + template.save(forEdit) + .as(StepVerifier::create) + .expectNextCount(1) + .verifyComplete(); + } + @Data @Document(indexName = "marvel") static class Person { @@ -928,4 +1034,21 @@ static class SampleEntity { @Version private Long version; @Score private float score; } + + @Data + @Document(indexName = "test-index-reactive-optimistic-entity-template") + static class OptimisticEntity { + @Id private String id; + private String message; + private SeqNoPrimaryTerm seqNoPrimaryTerm; + } + + @Data + @Document(indexName = "test-index-reactive-optimistic-and-versioned-entity-template") + static class OptimisticAndVersionedEntity { + @Id private String id; + private String message; + private SeqNoPrimaryTerm seqNoPrimaryTerm; + @Version private Long version; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index f7d0bb6da..ec4f319e6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -20,8 +20,12 @@ import static org.mockito.Mockito.*; import static org.skyscreamer.jsonassert.JSONAssert.*; -import java.util.Collections; +import java.util.Arrays; +import java.util.HashSet; +import org.elasticsearch.action.index.IndexAction; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.search.SearchAction; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; @@ -44,12 +48,15 @@ import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.GeoDistanceOrder; +import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.lang.Nullable; /** * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ @ExtendWith(MockitoExtension.class) class RequestFactoryTests { @@ -62,7 +69,7 @@ class RequestFactoryTests { @BeforeAll static void setUpAll() { SimpleElasticsearchMappingContext mappingContext = new SimpleElasticsearchMappingContext(); - mappingContext.setInitialEntitySet(Collections.singleton(Person.class)); + mappingContext.setInitialEntitySet(new HashSet<>(Arrays.asList(Person.class, EntityWithSeqNoPrimaryTerm.class))); mappingContext.afterPropertiesSet(); converter = new MappingElasticsearchConverter(mappingContext, new GenericConversionService()); @@ -153,9 +160,103 @@ void shouldAddMaxQueryWindowForUnpagedToRequestBuilder() { assertThat(searchRequestBuilder.request().source().size()).isEqualTo(RequestFactory.INDEX_MAX_RESULT_WINDOW); } + @Test // DATAES-799 + void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequest() { + IndexQuery query = new IndexQuery(); + query.setObject(new Person()); + query.setSeqNo(1L); + query.setPrimaryTerm(2L); + + IndexRequest request = requestFactory.indexRequest(query, IndexCoordinates.of("persons")); + + assertThat(request.ifSeqNo()).isEqualTo(1L); + assertThat(request.ifPrimaryTerm()).isEqualTo(2L); + } + + @Test // DATAES-799 + void shouldIncludeSeqNoAndPrimaryTermFromIndexQueryToIndexRequestBuilder() { + when(client.prepareIndex(anyString(), anyString())) + .thenReturn(new IndexRequestBuilder(client, IndexAction.INSTANCE)); + + IndexQuery query = new IndexQuery(); + query.setObject(new Person()); + query.setSeqNo(1L); + query.setPrimaryTerm(2L); + + IndexRequestBuilder builder = requestFactory.indexRequestBuilder(client, query, IndexCoordinates.of("persons")); + + assertThat(builder.request().ifSeqNo()).isEqualTo(1L); + assertThat(builder.request().ifPrimaryTerm()).isEqualTo(2L); + } + + @Test // DATAES-799 + void shouldNotRequestSeqNoAndPrimaryTermViaSearchRequestWhenEntityClassDoesNotContainSeqNoPrimaryTermProperty() { + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequest request = requestFactory.searchRequest(query, Person.class, IndexCoordinates.of("persons")); + + assertThat(request.source().seqNoAndPrimaryTerm()).isNull(); + } + + @Test // DATAES-799 + void shouldRequestSeqNoAndPrimaryTermViaSearchRequestWhenEntityClassContainsSeqNoPrimaryTermProperty() { + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequest request = requestFactory.searchRequest(query, EntityWithSeqNoPrimaryTerm.class, + IndexCoordinates.of("seqNoPrimaryTerm")); + + assertThat(request.source().seqNoAndPrimaryTerm()).isTrue(); + } + + @Test // DATAES-799 + void shouldNotRequestSeqNoAndPrimaryTermViaSearchRequestWhenEntityClassIsNull() { + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequest request = requestFactory.searchRequest(query, null, IndexCoordinates.of("persons")); + + assertThat(request.source().seqNoAndPrimaryTerm()).isNull(); + } + + @Test // DATAES-799 + void shouldNotRequestSeqNoAndPrimaryTermViaSearchRequestBuilderWhenEntityClassDoesNotContainSeqNoPrimaryTermProperty() { + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, Person.class, + IndexCoordinates.of("persons")); + + assertThat(builder.request().source().seqNoAndPrimaryTerm()).isNull(); + } + + @Test // DATAES-799 + void shouldRequestSeqNoAndPrimaryTermViaSearchRequestBuilderWhenEntityClassContainsSeqNoPrimaryTermProperty() { + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, + EntityWithSeqNoPrimaryTerm.class, IndexCoordinates.of("seqNoPrimaryTerm")); + + assertThat(builder.request().source().seqNoAndPrimaryTerm()).isTrue(); + } + + @Test // DATAES-799 + void shouldNotRequestSeqNoAndPrimaryTermViaSearchRequestBuilderWhenEntityClassIsNull() { + when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); + Query query = new NativeSearchQueryBuilder().build(); + + SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, null, + IndexCoordinates.of("persons")); + + assertThat(builder.request().source().seqNoAndPrimaryTerm()).isNull(); + } + static class Person { @Nullable @Id String id; @Nullable @Field(name = "last-name") String lastName; @Nullable @Field(name = "current-location") GeoPoint location; } + + static class EntityWithSeqNoPrimaryTerm { + @Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 1347f9880..45aac4f9e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.convert; +import static java.util.Collections.*; import static org.assertj.core.api.Assertions.*; import static org.skyscreamer.jsonassert.JSONAssert.*; @@ -55,6 +56,7 @@ import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; import org.springframework.data.geo.Point; @@ -69,6 +71,7 @@ * @author Mark Paluch * @author Peter-Josef Meisch * @author Konrad Kurdej + * @author Roman Puchkovskiy */ public class MappingElasticsearchConverterUnitTests { @@ -695,6 +698,26 @@ void readGenericListWithMaps() { assertThat(wrapper.getSchemaLessObject()).isEqualTo(mapWithSimpleList); } + @Test // DATAES-799 + void shouldNotWriteSeqNoPrimaryTermProperty() { + EntityWithSeqNoPrimaryTerm entity = new EntityWithSeqNoPrimaryTerm(); + entity.seqNoPrimaryTerm = new SeqNoPrimaryTerm(1L, 2L); + Document document = Document.create(); + + mappingElasticsearchConverter.write(entity, document); + + assertThat(document).doesNotContainKey("seqNoPrimaryTerm"); + } + + @Test // DATAES-799 + void shouldNotReadSeqNoPrimaryTermProperty() { + Document document = Document.create().append("seqNoPrimaryTerm", emptyMap()); + + EntityWithSeqNoPrimaryTerm entity = mappingElasticsearchConverter.read(EntityWithSeqNoPrimaryTerm.class, document); + + assertThat(entity.seqNoPrimaryTerm).isNull(); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -901,4 +924,11 @@ static class SchemaLessObjectWrapper { private Map schemaLessObject; } + + @Data + @org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-entity-with-seq-no-primary-term-mapper") + static class EntityWithSeqNoPrimaryTerm { + + @Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index f652044de..5045aa726 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -20,10 +20,12 @@ import static org.elasticsearch.index.query.QueryBuilders.*; import static org.skyscreamer.jsonassert.JSONAssert.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.annotations.FieldType.Object; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; import lombok.AllArgsConstructor; import lombok.Builder; +import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -60,6 +62,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.geo.Box; @@ -79,6 +82,7 @@ * @author Sascha Woo * @author Peter-Josef Meisch * @author Xiao Yu + * @author Roman Puchkovskiy */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) @@ -572,6 +576,13 @@ void shouldWriteCompletionContextInfo() throws JSONException { assertEquals(expected, mapping, false); } + @Test // DATAES-799 + void shouldNotIncludeSeqNoPrimaryTermPropertyInMappingEvenWhenAnnotatedWithField() { + String propertyMapping = getMappingBuilder().buildPropertyMapping(EntityWithSeqNoPrimaryTerm.class); + + assertThat(propertyMapping).doesNotContain("seqNoPrimaryTerm"); + } + /** * @author Xiao Yu */ @@ -1052,4 +1063,11 @@ static class CompletionDocument { @CompletionField(contexts = { @CompletionContext(name = "location", type = ContextMapping.Type.GEO, path = "proppath") }) private Completion suggest; } + + @Data + @Document(indexName = "test-index-entity-with-seq-no-primary-term-mapping-builder") + static class EntityWithSeqNoPrimaryTerm { + + @Field(type = Object) private SeqNoPrimaryTerm seqNoPrimaryTerm; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index 8ca227615..ddb5ea7c8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -22,6 +22,7 @@ import org.springframework.data.annotation.Version; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Score; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.model.Property; import org.springframework.data.mapping.model.SimpleTypeHolder; @@ -36,6 +37,7 @@ * @author Mark Paluch * @author Oliver Gierke * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class SimpleElasticsearchPersistentEntityTests { @@ -95,6 +97,52 @@ void shouldFindPropertiesByMappedName() { assertThat(persistentProperty.getFieldName()).isEqualTo("renamed-field"); } + @Test // DATAES-799 + void shouldReportThatThereIsNoSeqNoPrimaryTermPropertyWhenThereIsNoSuchProperty() { + TypeInformation typeInformation = ClassTypeInformation.from(EntityWithoutSeqNoPrimaryTerm.class); + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( + typeInformation); + + assertThat(entity.hasSeqNoPrimaryTermProperty()).isFalse(); + } + + @Test // DATAES-799 + void shouldReportThatThereIsSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { + TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( + typeInformation); + + entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm")); + + assertThat(entity.hasSeqNoPrimaryTermProperty()).isTrue(); + } + + @Test // DATAES-799 + void shouldReturnSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { + TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( + typeInformation); + entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm")); + EntityWithSeqNoPrimaryTerm instance = new EntityWithSeqNoPrimaryTerm(); + SeqNoPrimaryTerm seqNoPrimaryTerm = new SeqNoPrimaryTerm(1, 2); + + ElasticsearchPersistentProperty property = entity.getSeqNoPrimaryTermProperty(); + entity.getPropertyAccessor(instance).setProperty(property, seqNoPrimaryTerm); + + assertThat(instance.seqNoPrimaryTerm).isSameAs(seqNoPrimaryTerm); + } + + @Test // DATAES-799 + void shouldNotAllowMoreThanOneSeqNoPrimaryTermProperties() { + TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( + typeInformation); + entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm")); + + assertThatThrownBy(() -> entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm2"))) + .isInstanceOf(MappingException.class); + } + private static SimpleElasticsearchPersistentProperty createProperty(SimpleElasticsearchPersistentEntity entity, String field) { @@ -153,4 +201,12 @@ private static class FieldNameEntity { @Nullable @Id private String id; @Nullable @Field(name = "renamed-field") private String renamedField; } + + private static class EntityWithoutSeqNoPrimaryTerm { + } + + private static class EntityWithSeqNoPrimaryTerm { + private SeqNoPrimaryTerm seqNoPrimaryTerm; + private SeqNoPrimaryTerm seqNoPrimaryTerm2; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index fa195c87c..182fb75cd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -23,13 +23,13 @@ import java.time.ZonedDateTime; import java.util.Date; import java.util.GregorianCalendar; -import java.util.TimeZone; import org.junit.jupiter.api.Test; import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Score; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.MappingException; import org.springframework.lang.Nullable; @@ -38,6 +38,7 @@ * * @author Oliver Gierke * @author Peter-Josef Meisch + * @author Roman Puchkovskiy */ public class SimpleElasticsearchPersistentPropertyUnitTests { @@ -126,7 +127,7 @@ void shouldConvertFromLegacyDate() { assertThat(converted).isEqualTo("20200419T194400.000Z"); } - @Test // DATES-792 + @Test // DATAES-792 void shouldConvertToLegacyDate() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); ElasticsearchPersistentProperty persistentProperty = persistentEntity.getRequiredPersistentProperty("legacyDate"); @@ -140,6 +141,38 @@ void shouldConvertToLegacyDate() { assertThat(converted).isEqualTo(legacyDate); } + @Test // DATAES-799 + void shouldReportSeqNoPrimaryTermPropertyWhenTheTypeIsSeqNoPrimaryTerm() { + SimpleElasticsearchPersistentEntity entity = context.getRequiredPersistentEntity(SeqNoPrimaryTermProperty.class); + ElasticsearchPersistentProperty seqNoProperty = entity.getRequiredPersistentProperty("seqNoPrimaryTerm"); + + assertThat(seqNoProperty.isSeqNoPrimaryTermProperty()).isTrue(); + } + + @Test // DATAES-799 + void shouldNotReportSeqNoPrimaryTermPropertyWhenTheTypeIsNotSeqNoPrimaryTerm() { + SimpleElasticsearchPersistentEntity entity = context.getRequiredPersistentEntity(SeqNoPrimaryTermProperty.class); + ElasticsearchPersistentProperty stringProperty = entity.getRequiredPersistentProperty("string"); + + assertThat(stringProperty.isSeqNoPrimaryTermProperty()).isFalse(); + } + + @Test // DATAES-799 + void seqNoPrimaryTermPropertyShouldNotBeWritable() { + SimpleElasticsearchPersistentEntity entity = context.getRequiredPersistentEntity(SeqNoPrimaryTermProperty.class); + ElasticsearchPersistentProperty seqNoProperty = entity.getRequiredPersistentProperty("seqNoPrimaryTerm"); + + assertThat(seqNoProperty.isWritable()).isFalse(); + } + + @Test // DATAES-799 + void seqNoPrimaryTermPropertyShouldNotBeReadable() { + SimpleElasticsearchPersistentEntity entity = context.getRequiredPersistentEntity(SeqNoPrimaryTermProperty.class); + ElasticsearchPersistentProperty seqNoProperty = entity.getRequiredPersistentProperty("seqNoPrimaryTerm"); + + assertThat(seqNoProperty.isReadable()).isFalse(); + } + static class InvalidScoreProperty { @Nullable @Score String scoreProperty; } @@ -157,4 +190,9 @@ static class DatesProperty { @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) Date legacyDate; } + + static class SeqNoPrimaryTermProperty { + SeqNoPrimaryTerm seqNoPrimaryTerm; + String string; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java new file mode 100644 index 000000000..6f31ba6a4 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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.query; + +import static org.assertj.core.api.Assertions.*; + +import org.elasticsearch.index.seqno.SequenceNumbers; +import org.junit.jupiter.api.Test; + +/** + * @author Roman Puchkovskiy + */ +class SeqNoPrimaryTermTests { + @Test + void shouldConstructInstanceWithAssignedSeqNoAndPrimaryTerm() { + SeqNoPrimaryTerm instance = new SeqNoPrimaryTerm(1, 2); + + assertThat(instance.getSequenceNumber()).isEqualTo(1); + assertThat(instance.getPrimaryTerm()).isEqualTo(2); + } + + @Test + void shouldThrowAnExceptionWhenTryingToConstructWithUnassignedSeqNo() { + assertThatThrownBy(() -> new SeqNoPrimaryTerm(SequenceNumbers.UNASSIGNED_SEQ_NO, 2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void shouldThrowAnExceptionWhenTryingToConstructWithSeqNoForNoOpsPerformed() { + assertThatThrownBy(() -> new SeqNoPrimaryTerm(SequenceNumbers.NO_OPS_PERFORMED, 2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @Test + void shouldThrowAnExceptionWhenTryingToConstructWithUnassignedPrimaryTerm() { + assertThatThrownBy(() -> new SeqNoPrimaryTerm(1, SequenceNumbers.UNASSIGNED_PRIMARY_TERM)) + .isInstanceOf(IllegalArgumentException.class); + } +} \ No newline at end of file From 15f51c5151fe20213cfb79c8c904ec22aee7f1d5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 29 Apr 2020 20:30:09 +0200 Subject: [PATCH 0146/1191] DATAES-799 - Polishing. --- .../ElasticsearchExceptionTranslator.java | 3 +- .../elasticsearch/core/EntityOperations.java | 3 +- .../elasticsearch/core/RequestFactory.java | 3 +- .../MappingElasticsearchConverter.java | 14 ++++- .../elasticsearch/core/document/Document.java | 8 +-- .../core/document/DocumentAdapters.java | 23 ++++---- .../core/index/MappingBuilder.java | 2 +- .../ElasticsearchPersistentEntity.java | 13 ++--- .../ElasticsearchPersistentProperty.java | 4 +- .../core/query/SeqNoPrimaryTerm.java | 40 +++++++------- ...ElasticsearchExceptionTranslatorTests.java | 8 ++- .../ReactiveElasticsearchTemplateTests.java | 54 +++++++++---------- .../core/RequestFactoryTests.java | 4 +- ...appingElasticsearchConverterUnitTests.java | 5 +- .../core/index/MappingBuilderTests.java | 2 +- ...pleElasticsearchPersistentEntityTests.java | 15 +++--- .../core/query/SeqNoPrimaryTermTests.java | 2 +- 17 files changed, 106 insertions(+), 97 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index 77a8de10d..bf4738c64 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -79,8 +79,7 @@ private boolean isSeqNoConflict(ElasticsearchException exception) { if (exception instanceof ElasticsearchStatusException) { ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception; - return statusException.status() == RestStatus.CONFLICT - && statusException.getMessage() != null + return statusException.status() == RestStatus.CONFLICT && statusException.getMessage() != null && statusException.getMessage().contains("type=version_conflict_engine_exception") && statusException.getMessage().contains("version conflict, required seqNo"); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 65467ec0d..4f8b45102 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -272,7 +272,8 @@ interface AdaptibleEntity extends Entity { * * @return SeqNoPrimaryTerm, may be {@literal null} */ - @Nullable SeqNoPrimaryTerm getSeqNoPrimaryTerm(); + @Nullable + SeqNoPrimaryTerm getSeqNoPrimaryTerm(); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index c4361cf32..4d1a5c3e6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -709,7 +709,8 @@ private boolean hasSeqNoPrimaryTermProperty(@Nullable Class entityClass) { return false; } - ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(entityClass); + ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() + .getRequiredPersistentEntity(entityClass); return entity.hasSeqNoPrimaryTermProperty(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 9e196a273..034fca418 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,8 +15,17 @@ */ package org.springframework.data.elasticsearch.core.convert; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; @@ -297,7 +306,8 @@ private R readCollectionValue(@Nullable List source, ElasticsearchPersist if (value instanceof List) { target.add(readValue(value, property, property.getTypeInformation().getActualType())); } else if (value instanceof Map) { - target.add(readMapValue((Map) value, property, property.getTypeInformation().getActualType())); + target + .add(readMapValue((Map) value, property, property.getTypeInformation().getActualType())); } else { target.add(readEntity(computeGenericValueTypeForRead(property, value), (Map) value)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index c6311ed75..59af552de 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -182,8 +182,8 @@ default boolean hasSeqNo() { * {@link #hasSeqNo()} prior to calling this method. * * @return the seq_no associated with this {@link Document}. - * @throws IllegalStateException if the underlying implementation supports seq_no's but no seq_no was yet - * associated with the document. + * @throws IllegalStateException if the underlying implementation supports seq_no's but no seq_no was yet associated + * with the document. */ default long getSeqNo() { throw new UnsupportedOperationException(); @@ -214,8 +214,8 @@ default boolean hasPrimaryTerm() { * {@link #hasPrimaryTerm()} prior to calling this method. * * @return the primary_term associated with this {@link Document}. - * @throws IllegalStateException if the underlying implementation supports primary_term's but no primary_term was - * yet associated with the document. + * @throws IllegalStateException if the underlying implementation supports primary_term's but no primary_term was yet + * associated with the document. */ default long getPrimaryTerm() { throw new UnsupportedOperationException(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 0dbc7aed9..95cf06c37 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -77,8 +77,8 @@ public static Document from(GetResponse source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion(), - source.getSeqNo(), source.getPrimaryTerm()); + return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), + source.getPrimaryTerm()); } Document document = Document.from(source.getSourceAsMap()); @@ -108,8 +108,8 @@ public static Document from(GetResult source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion(), - source.getSeqNo(), source.getPrimaryTerm()); + return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), + source.getPrimaryTerm()); } Document document = Document.from(source.getSource()); @@ -157,8 +157,7 @@ public static SearchDocument from(SearchHit source) { if (sourceRef == null || sourceRef.length() == 0) { return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, - fromDocumentFields(source, source.getId(), source.getVersion(), - source.getSeqNo(), source.getPrimaryTerm())); + fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm())); } Document document = Document.from(source.getSourceAsMap()); @@ -180,8 +179,8 @@ public static SearchDocument from(SearchHit source) { * @param documentFields the {@link DocumentField}s backing the {@link Document}. * @return the adapted {@link Document}. */ - public static Document fromDocumentFields(Iterable documentFields, String id, long version, - long seqNo, long primaryTerm) { + public static Document fromDocumentFields(Iterable documentFields, String id, long version, long seqNo, + long primaryTerm) { if (documentFields instanceof Collection) { return new DocumentFieldAdapter((Collection) documentFields, id, version, seqNo, primaryTerm); @@ -204,8 +203,8 @@ static class DocumentFieldAdapter implements Document { private final long seqNo; private final long primaryTerm; - DocumentFieldAdapter(Collection documentFields, String id, long version, - long seqNo, long primaryTerm) { + DocumentFieldAdapter(Collection documentFields, String id, long version, long seqNo, + long primaryTerm) { this.documentFields = documentFields; this.id = id; this.version = version; @@ -618,7 +617,7 @@ public long getVersion() { public void setVersion(long version) { delegate.setVersion(version); } - + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() @@ -645,7 +644,7 @@ public long getSeqNo() { public void setSeqNo(long seqNo) { delegate.setSeqNo(seqNo); } - + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 2eea93ca9..69e0ca806 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -170,7 +170,7 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten if (property.isSeqNoPrimaryTermProperty()) { if (property.isAnnotationPresent(Field.class)) { logger.warn("Property {} of {} is annotated for inclusion in mapping, but its type is " + // - "SeqNoPrimaryTerm that is never mapped, so it is skipped", // + "SeqNoPrimaryTerm that is never mapped, so it is skipped", // property.getFieldName(), entity.getType()); } return; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 9e2c0d959..bc7fed013 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -60,7 +60,8 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends PersistentEntitypotential score property of the owning * {@link ElasticsearchPersistentEntity}. This method is mainly used by {@link ElasticsearchPersistentEntity} * implementation to discover score property candidates on {@link ElasticsearchPersistentEntity} creation you should - * rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the - * current property is the score property of that {@link ElasticsearchPersistentEntity} under consideration. + * rather call {@link ElasticsearchPersistentEntity#getScoreProperty()} to determine whether the current property is + * the score property of that {@link ElasticsearchPersistentEntity} under consideration. * * @return * @since 3.1 diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java index c7bf434d0..10e7fbf8b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTerm.java @@ -18,21 +18,25 @@ import java.util.Objects; /** - *

A container for seq_no and primary_term values. When an entity class contains a field of this type, - * it will be automatically filled with SeqNoPrimaryTerm instance on read operations (like get or search), - * and also, when the SeqNoPrimaryTerm is not {@literal null} and filled with seq_no and primary_term, - * they will be sent to Elasticsearch when indexing such an entity. + *

+ * A container for seq_no and primary_term values. When an entity class contains a field of this type, it will be + * automatically filled with SeqNoPrimaryTerm instance on read operations (like get or search), and also, when the + * SeqNoPrimaryTerm is not {@literal null} and filled with seq_no and primary_term, they will be sent to Elasticsearch + * when indexing such an entity. *

- *

This allows to implement optimistic locking pattern for full-update scenario, when an entity is first - * read from Elasticsearch and then gets reindexed with new _content. - * Index operations will throw an {@link org.springframework.dao.OptimisticLockingFailureException} if the - * seq_no + primary_term pair already has different values for the given document. See Elasticsearch documentation - * for more information: https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html + *

+ * This allows to implement optimistic locking pattern for full-update scenario, when an entity is first read from + * Elasticsearch and then gets reindexed with new _content. Index operations will throw an + * {@link org.springframework.dao.OptimisticLockingFailureException} if the seq_no + primary_term pair already has + * different values for the given document. See Elasticsearch documentation for more information: + * https://www.elastic.co/guide/en/elasticsearch/reference/current/optimistic-concurrency-control.html *

- *

A property of this type is implicitly @{@link org.springframework.data.annotation.Transient} and never gets included + *

+ * A property of this type is implicitly @{@link org.springframework.data.annotation.Transient} and never gets included * into a mapping at Elasticsearch side. *

- *

A SeqNoPrimaryTerm instance cannot contain an invalid or unassigned seq_no or primary_term. + *

+ * A SeqNoPrimaryTerm instance cannot contain an invalid or unassigned seq_no or primary_term. *

* * @author Roman Puchkovskiy @@ -44,11 +48,11 @@ public final class SeqNoPrimaryTerm { /** * Creates an instance of SeqNoPrimaryTerm with the given seq_no and primary_term. The passed values are validated: - * sequenceNumber must be non-negative, primaryTerm must be positive. If validation fails, - * an IllegalArgumentException is thrown. + * sequenceNumber must be non-negative, primaryTerm must be positive. If validation fails, an IllegalArgumentException + * is thrown. * * @param sequenceNumber seq_no, must not be negative - * @param primaryTerm primary_term, must be positive + * @param primaryTerm primary_term, must be positive * @throws IllegalArgumentException if seq_no or primary_term is not valid */ public SeqNoPrimaryTerm(long sequenceNumber, long primaryTerm) { @@ -73,10 +77,7 @@ public long getPrimaryTerm() { @Override public String toString() { - return "SeqNoPrimaryTerm{" + - "sequenceNumber=" + sequenceNumber + - ", primaryTerm=" + primaryTerm + - '}'; + return "SeqNoPrimaryTerm{" + "sequenceNumber=" + sequenceNumber + ", primaryTerm=" + primaryTerm + '}'; } @Override @@ -88,8 +89,7 @@ public boolean equals(Object o) { return false; } SeqNoPrimaryTerm that = (SeqNoPrimaryTerm) o; - return sequenceNumber == that.sequenceNumber && - primaryTerm == that.primaryTerm; + return sequenceNumber == that.sequenceNumber && primaryTerm == that.primaryTerm; } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java index 4f2ec1339..c2ba997e7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java @@ -25,8 +25,6 @@ import org.springframework.dao.DataAccessException; import org.springframework.dao.OptimisticLockingFailureException; -import java.util.UUID; - /** * @author Roman Puchkovskiy */ @@ -48,8 +46,8 @@ void shouldConvertElasticsearchStatusExceptionWithSeqNoConflictToOptimisticLocki @Test // DATAES-799 void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLockingFailureException() { - VersionConflictEngineException ex = new VersionConflictEngineException( - new ShardId("index", "uuid", 1), "exception-id", + VersionConflictEngineException ex = new VersionConflictEngineException(new ShardId("index", "uuid", 1), + "exception-id", "Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]"); DataAccessException translated = translator.translateExceptionIfPossible(ex); @@ -58,4 +56,4 @@ void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLoc assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); assertThat(translated.getCause()).isSameAs(ex); } -} \ No newline at end of file +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index e78e93853..b75beb71b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -62,7 +62,16 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.IndexQuery; +import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; +import org.springframework.data.elasticsearch.core.query.StringQuery; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; @@ -858,10 +867,8 @@ void getShouldReturnSeqNoPrimaryTerm() { original.setMessage("It's fine"); OptimisticEntity saved = template.save(original).block(); - template.get(saved.getId(), OptimisticEntity.class) - .as(StepVerifier::create) - .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) - .verifyComplete(); + template.get(saved.getId(), OptimisticEntity.class).as(StepVerifier::create) + .assertNext(this::assertThatSeqNoPrimaryTermIsFilled).verifyComplete(); } private void assertThatSeqNoPrimaryTermIsFilled(OptimisticEntity retrieved) { @@ -878,10 +885,10 @@ void multiGetShouldReturnSeqNoPrimaryTerm() { original.setMessage("It's fine"); OptimisticEntity saved = template.save(original).block(); - template.multiGet(multiGetQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class)) - .as(StepVerifier::create) - .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) - .verifyComplete(); + template + .multiGet(multiGetQueryForOne(saved.getId()), OptimisticEntity.class, + template.getIndexCoordinatesFor(OptimisticEntity.class)) + .as(StepVerifier::create).assertNext(this::assertThatSeqNoPrimaryTermIsFilled).verifyComplete(); } private Query multiGetQueryForOne(String id) { @@ -895,17 +902,15 @@ void searchShouldReturnSeqNoPrimaryTerm() { OptimisticEntity saved = template.save(original).block(); restTemplate.refresh(OptimisticEntity.class); - template.search(searchQueryForOne(saved.getId()), OptimisticEntity.class, template.getIndexCoordinatesFor(OptimisticEntity.class)) - .map(SearchHit::getContent) - .as(StepVerifier::create) - .assertNext(this::assertThatSeqNoPrimaryTermIsFilled) + template + .search(searchQueryForOne(saved.getId()), OptimisticEntity.class, + template.getIndexCoordinatesFor(OptimisticEntity.class)) + .map(SearchHit::getContent).as(StepVerifier::create).assertNext(this::assertThatSeqNoPrimaryTermIsFilled) .verifyComplete(); } private Query searchQueryForOne(String id) { - return new NativeSearchQueryBuilder() - .withFilter(new IdsQueryBuilder().addIds(id)) - .build(); + return new NativeSearchQueryBuilder().withFilter(new IdsQueryBuilder().addIds(id)).build(); } @Test // DATAES-799 @@ -921,12 +926,9 @@ void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnEnt template.save(forEdit1).block(); forEdit2.setMessage("It'll be great"); - template.save(forEdit2) - .as(StepVerifier::create) - .expectError(OptimisticLockingFailureException.class) - .verify(); + template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify(); } - + @Test // DATAES-799 void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnVersionedEntityWithSeqNoPrimaryTermProperty() { OptimisticAndVersionedEntity original = new OptimisticAndVersionedEntity(); @@ -940,10 +942,7 @@ void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnVer template.save(forEdit1).block(); forEdit2.setMessage("It'll be great"); - template.save(forEdit2) - .as(StepVerifier::create) - .expectError(OptimisticLockingFailureException.class) - .verify(); + template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify(); } @Test // DATAES-799 @@ -955,10 +954,7 @@ void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { OptimisticAndVersionedEntity forEdit = template.get(saved.getId(), OptimisticAndVersionedEntity.class).block(); forEdit.setMessage("It'll be ok"); - template.save(forEdit) - .as(StepVerifier::create) - .expectNextCount(1) - .verifyComplete(); + template.save(forEdit).as(StepVerifier::create).expectNextCount(1).verifyComplete(); } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index ec4f319e6..336261f5d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -233,8 +233,8 @@ void shouldRequestSeqNoAndPrimaryTermViaSearchRequestBuilderWhenEntityClassConta when(client.prepareSearch(any())).thenReturn(new SearchRequestBuilder(client, SearchAction.INSTANCE)); Query query = new NativeSearchQueryBuilder().build(); - SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, - EntityWithSeqNoPrimaryTerm.class, IndexCoordinates.of("seqNoPrimaryTerm")); + SearchRequestBuilder builder = requestFactory.searchRequestBuilder(client, query, EntityWithSeqNoPrimaryTerm.class, + IndexCoordinates.of("seqNoPrimaryTerm")); assertThat(builder.request().source().seqNoAndPrimaryTerm()).isTrue(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 45aac4f9e..486f3b417 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -703,7 +703,7 @@ void shouldNotWriteSeqNoPrimaryTermProperty() { EntityWithSeqNoPrimaryTerm entity = new EntityWithSeqNoPrimaryTerm(); entity.seqNoPrimaryTerm = new SeqNoPrimaryTerm(1L, 2L); Document document = Document.create(); - + mappingElasticsearchConverter.write(entity, document); assertThat(document).doesNotContainKey("seqNoPrimaryTerm"); @@ -926,7 +926,8 @@ static class SchemaLessObjectWrapper { } @Data - @org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-entity-with-seq-no-primary-term-mapper") + @org.springframework.data.elasticsearch.annotations.Document( + indexName = "test-index-entity-with-seq-no-primary-term-mapper") static class EntityWithSeqNoPrimaryTerm { @Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 5045aa726..a59904a64 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -579,7 +579,7 @@ void shouldWriteCompletionContextInfo() throws JSONException { @Test // DATAES-799 void shouldNotIncludeSeqNoPrimaryTermPropertyInMappingEvenWhenAnnotatedWithField() { String propertyMapping = getMappingBuilder().buildPropertyMapping(EntityWithSeqNoPrimaryTerm.class); - + assertThat(propertyMapping).doesNotContain("seqNoPrimaryTerm"); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java index ddb5ea7c8..321fd36d5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntityTests.java @@ -99,7 +99,8 @@ void shouldFindPropertiesByMappedName() { @Test // DATAES-799 void shouldReportThatThereIsNoSeqNoPrimaryTermPropertyWhenThereIsNoSuchProperty() { - TypeInformation typeInformation = ClassTypeInformation.from(EntityWithoutSeqNoPrimaryTerm.class); + TypeInformation typeInformation = ClassTypeInformation + .from(EntityWithoutSeqNoPrimaryTerm.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( typeInformation); @@ -108,7 +109,8 @@ void shouldReportThatThereIsNoSeqNoPrimaryTermPropertyWhenThereIsNoSuchProperty( @Test // DATAES-799 void shouldReportThatThereIsSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { - TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + TypeInformation typeInformation = ClassTypeInformation + .from(EntityWithSeqNoPrimaryTerm.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( typeInformation); @@ -119,7 +121,8 @@ void shouldReportThatThereIsSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { @Test // DATAES-799 void shouldReturnSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { - TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + TypeInformation typeInformation = ClassTypeInformation + .from(EntityWithSeqNoPrimaryTerm.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( typeInformation); entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm")); @@ -134,7 +137,8 @@ void shouldReturnSeqNoPrimaryTermPropertyWhenThereIsSuchProperty() { @Test // DATAES-799 void shouldNotAllowMoreThanOneSeqNoPrimaryTermProperties() { - TypeInformation typeInformation = ClassTypeInformation.from(EntityWithSeqNoPrimaryTerm.class); + TypeInformation typeInformation = ClassTypeInformation + .from(EntityWithSeqNoPrimaryTerm.class); SimpleElasticsearchPersistentEntity entity = new SimpleElasticsearchPersistentEntity<>( typeInformation); entity.addPersistentProperty(createProperty(entity, "seqNoPrimaryTerm")); @@ -202,8 +206,7 @@ private static class FieldNameEntity { @Nullable @Field(name = "renamed-field") private String renamedField; } - private static class EntityWithoutSeqNoPrimaryTerm { - } + private static class EntityWithoutSeqNoPrimaryTerm {} private static class EntityWithSeqNoPrimaryTerm { private SeqNoPrimaryTerm seqNoPrimaryTerm; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java index 6f31ba6a4..524fc45c3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/SeqNoPrimaryTermTests.java @@ -49,4 +49,4 @@ void shouldThrowAnExceptionWhenTryingToConstructWithUnassignedPrimaryTerm() { assertThatThrownBy(() -> new SeqNoPrimaryTerm(1, SequenceNumbers.UNASSIGNED_PRIMARY_TERM)) .isInstanceOf(IllegalArgumentException.class); } -} \ No newline at end of file +} From b278bf981947dcf069e1f9b2f3e71439f6bb9368 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 30 Apr 2020 08:18:29 +0200 Subject: [PATCH 0147/1191] DATAES-809 - Creation of test data may lead to duplicate values. Original PR: #443 --- ...lasticsearchRestTemplateConfiguration.java | 22 +++++++++++++++++++ .../SimpleElasticsearchRepositoryTests.java | 8 +++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java index d7085b24a..a3369cef3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchRestTemplateConfiguration.java @@ -21,9 +21,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.RestClients; import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; +import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; /** * Configuration for Spring Data Elasticsearch using @@ -56,4 +60,22 @@ public RestHighLevelClient elasticsearchClient() { .build()) // .rest(); } + + @Override + public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) { + RestHighLevelClient client = elasticsearchClient(); + return new ElasticsearchRestTemplate(client, elasticsearchConverter) { + @Override + public T execute(ClientCallback callback) { + try { + return super.execute(callback); + } catch (DataAccessResourceFailureException e) { + try { + Thread.sleep(1_000); + } catch (InterruptedException ignored) {} + return super.execute(callback); + } + } + }; + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index e8d6e6cfe..284fa8f66 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -678,14 +678,18 @@ public void shouldNotFailOnIndexingEmptyList() { } private static List createSampleEntitiesWithMessage(String message, int numberOfEntities) { + List sampleEntities = new ArrayList<>(); + long idBase = (long) (Math.random() * 100); + long versionBase = System.currentTimeMillis(); + for (int i = 0; i < numberOfEntities; i++) { - String documentId = randomNumeric(5); + String documentId = String.valueOf(idBase + i); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage(message); sampleEntity.setRate(2); - sampleEntity.setVersion(System.currentTimeMillis()); + sampleEntity.setVersion(versionBase + i); sampleEntities.add(sampleEntity); } return sampleEntities; From 07ee01f435e259c5c2eabd449725ca2b6ee2a61c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 1 May 2020 22:04:01 +0200 Subject: [PATCH 0148/1191] DATAES-750 - Migration guide and documentation update. Original PR: #444 --- src/main/asciidoc/index.adoc | 9 +- src/main/asciidoc/preface.adoc | 1 + .../elasticsearch-entity-callbacks.adoc | 35 +++++ ...elasticsearch-migration-guide-3.2-4.0.adoc | 133 ++++++++++++++++++ .../asciidoc/reference/elasticsearch-new.adoc | 6 +- .../elasticsearch-object-mapping.adoc | 12 +- .../reference/elasticsearch-operations.adoc | 13 +- .../elasticsearch/annotations/FieldType.java | 56 ++++---- .../core/AbstractElasticsearchTemplate.java | 6 + .../core/DocumentOperations.java | 11 ++ .../core/ElasticsearchOperations.java | 22 +-- 11 files changed, 255 insertions(+), 49 deletions(-) create mode 100644 src/main/asciidoc/reference/elasticsearch-entity-callbacks.adoc create mode 100644 src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 8ca2a67b6..20d119585 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -5,13 +5,14 @@ BioMed Central Development Team; Oliver Drotbohm; Greg Turnquist; Christoph Stro ifdef::backend-epub3[:front-cover-image: image:epub-cover.png[Front Cover,1050,1600]] :spring-data-commons-docs: ../../../../spring-data-commons/src/main/asciidoc -(C) 2013-2019 The original author(s). +(C) 2013-2020 The original author(s). NOTE: Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically. toc::[] include::preface.adoc[] + :leveloffset: +1 include::{spring-data-commons-docs}/repositories.adoc[] :leveloffset: -1 @@ -23,9 +24,15 @@ include::{spring-data-commons-docs}/repositories.adoc[] include::reference/elasticsearch-clients.adoc[] include::reference/elasticsearch-object-mapping.adoc[] include::reference/elasticsearch-operations.adoc[] + include::reference/elasticsearch-repositories.adoc[] + include::{spring-data-commons-docs}/auditing.adoc[] include::reference/elasticsearch-auditing.adoc[] + +include::{spring-data-commons-docs}/entity-callbacks.adoc[] +include::reference/elasticsearch-entity-callbacks.adoc[leveloffset=+1] + include::reference/elasticsearch-misc.adoc[] :leveloffset: -1 diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 2b518b027..565700526 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -9,6 +9,7 @@ The Spring Data Elasticsearch project applies core Spring concepts to the develo You will notice similarities to the Spring data solr and mongodb support in the Spring Framework. include::reference/elasticsearch-new.adoc[leveloffset=+1] +include::reference/elasticsearch-migration-guide-3.2-4.0.adoc[leveloffset=+1] [[preface.metadata]] == Project Metadata diff --git a/src/main/asciidoc/reference/elasticsearch-entity-callbacks.adoc b/src/main/asciidoc/reference/elasticsearch-entity-callbacks.adoc new file mode 100644 index 000000000..fda1c1ad8 --- /dev/null +++ b/src/main/asciidoc/reference/elasticsearch-entity-callbacks.adoc @@ -0,0 +1,35 @@ +[[elasticsearch.entity-callbacks]] += Elasticsearch EntityCallbacks + +Spring Data Elasticsearch uses the `EntityCallback` API internally for its auditing support and reacts on the following callbacks: + +.Supported Entity Callbacks +[%header,cols="4"] +|=== +| Callback +| Method +| Description +| Order + +| Reactive/BeforeConvertCallback +| `onBeforeConvert(T entity, IndexCoordinates index)` +| Invoked before a domain object is converted to `org.springframework.data.elasticsearch.core.document.Document`. Can return the `entity` or a modified entity which then will be converted. +| `Ordered.LOWEST_PRECEDENCE` + +| Reactive/AfterConvertCallback +| `onAfterConvert(T entity, Document document, IndexCoordinates indexCoordinates)` +| Invoked after a domain object is converted from `org.springframework.data.elasticsearch.core.document.Document` on reading result data from Elasticsearch. +| `Ordered.LOWEST_PRECEDENCE` + +| Reactive/AuditingEntityCallback +| `onBeforeConvert(Object entity, IndexCoordinates index)` +| Marks an auditable entity _created_ or _modified_ +| 100 + +| Reactive/AfterSaveCallback +| `T onAfterSave(T entity, IndexCoordinates index)` +| Invoked after a domain object is saved. +| `Ordered.LOWEST_PRECEDENCE` + +|=== + diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc new file mode 100644 index 000000000..47fe3b408 --- /dev/null +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc @@ -0,0 +1,133 @@ +[[elasticsearch-migration-guide-3.2-4.0]] +== Upgrading from 3.2.x to 4.0.x + +This section describes breaking changes from version 3.2.x to 4.0.x and how removed features can be replaced by new introduced features. + + +=== Removal of the used Jackson Mapper. + +One of the changes in version 4.0.x is that Spring Data Elasticsearch does not use the Jackson Mapper anymore to map an entity to the JSON representation needed for Elasticsearch (see <>). In version 3.2.x the Jackson Mapper was the default that was used. It was possible to switch to the meta-model based converter (named `ElasticsearchEntityMapper`) by explicitly configuring it (<>). + +In version 4.0.x the meta-model based converter is the only one that is available and does not need to be configured explicitly. If you had a custom configuration to enable the meta-model converter by providing a bean like this: + +[code,java] +---- +@Bean +@Override +public EntityMapper entityMapper() { + + ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper( + elasticsearchMappingContext(), new DefaultConversionService() + ); + entityMapper.setConversions(elasticsearchCustomConversions()); + + return entityMapper; +} +---- + +You now have to remove this bean, the `ElasticsearchEntityMapper` interface has been removed. + +.Entity configuration +Some users had custom Jackson annotations on the entity class, for example in order to define a custom name for the mapped document in Elasticsearch or to configure date conversions. These are not taken into account anymore. The needed functionality is now provided with Spring Data Elasticsearch's `@Field` annotation. Please see <> for detailed information. + + +=== Removal of implicit index name from query objects + +In 3.2.x the different query classes like `IndexQuery` or `SearchQuery` had properties that were taking the index name or index names that they were operating upon. If these were not set, the passed in entity was inspected to retrieve the index name that was set in the `@Document` annotation. + +In 4.0.x the index name(s) must now be provided in an additional parameter of type `IndexCoordinates`. By separating this, it now is possible to use one query object against different indices. + +So for example the following code: + +[code,java] +---- +IndexQuery indexQuery = new IndexQueryBuilder() + .withId(person.getId().toString()) + .withObject(person) + .build(); + +String documentId = elasticsearchOperations.index(indexQuery); +---- + +must be changed to: + +[code,java] +---- +IndexCoordinates indexCoordinates = elasticsearchOperations.getIndexCoordinatesFor(person.getClass()); + +IndexQuery indexQuery = new IndexQueryBuilder() + .withId(person.getId().toString()) + .withObject(person) + .build(); + +String documentId = elasticsearchOperations.index(indexQuery, indexCoordinates); +---- + +To make it easier to work with entities and use the index name that is contained in the entitie's `@Document` annotation, new methods have been added like `DocumentOperations.save(T entity)`; + + +=== The new Operations interfaces + +In version 3.2 there was the `ElasticsearchOperations` interface that defined all the methods for the `ElasticsearchTemplate` class. In version 4 the functions have been split into different interfaces, aligning these interfaces with the Elasticsearch API: + +* `DocumentOperations` are the functions related documents like saving, or deleting +* `SearchOperations` contains the functions to search in Elasticsearch +* `IndexOperations` define the functions to operate on indexes, like index creation or mappings creation. + +`ElasticsearchOperations` now extends `DocumentOperations` and `SearchOperations` and has methods get access to an `IndexOperations` instance. + +NOTE: All the functions from the `ElasticsearchOperations` interface in version 3.2 that are now moved to the `IndexOperations` interface are still available, they are marked as deprecated and have default implementations that delegate to the new implementation: + +[code,java] +---- +/** + * Create an index for given indexName . + * + * @param indexName the name of the index + * @return {@literal true} if the index was created + * @deprecated since 4.0, use {@link IndexOperations#create()} + */ +@Deprecated +default boolean createIndex(String indexName) { + return indexOps(IndexCoordinates.of(indexName)).create(); +} +---- + + +=== Deprecations + +==== Methods and classes + +Many functions and classes have been deprecated. These functions still work, but the Javadocs show with what they should be replaced. + +.Example from ElasticsearchOperations +[code,java] +---- +/** + * Retrieves an object from an index. + * + * @param query the query defining the id of the object to get + * @param clazz the type of the object to be returned + * @return the found object + * @deprecated since 4.0, use {@link #get(String, Class, IndexCoordinates)} + */ +@Deprecated +@Nullable + T queryForObject(GetQuery query, Class clazz); +---- + +==== Elasticsearch deprecations + +Since version 7 the Elasticsearch `TransportClient` is deprecated, it will be removed with Elasticsearch version 8. Spring Data Elasticsearch deprecates the `ElasticsearchTemplate` class which uses the `TransportClient` in version 4.0. + +Mapping types were removed from Elasticsearch 7, they still exist as deprecated values in the Spring Data `@Document` annotation and the `IndexCoordinates` class but they are not used anymore internally. + +=== Removals + +* As already described, the `ElasticsearchEntityMapper` interface has been removed. + +* The `SearchQuery` interface has been merged into it's base interface `Query`, so it's occurrences can just be replaced with `Query`. + +* The method `org.springframework.data.elasticsearch.core.ElasticsearchOperations.query(SearchQuery query, ResultsExtractor resultsExtractor);` and the `org.springframework.data.elasticsearch.core.ResultsExtractor` interface have been removed. These could be used to parse the result from Elasticsearch for cases in which the response mapping done with the Jackson based mapper was not enough. Since version 4.0, there are the new <> to return the information from an Elasticsearch response, so there is no need to expose this low level functionality. + +* The low level methods `startScroll`, `continueScroll` and `clearScroll` have been removed from the `ElasticsearchOperations` interface. For low level scroll API access, there now are `searchScrollStart`, `searchScrollContinue` and `searchScrollClear` methods on the `ElasticsearchRestTemplate` class. + diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index cf1915b92..27f0faeb9 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -11,8 +11,12 @@ * Removal of the Jackson `ObjectMapper`, now using the <> * Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules. * Introduction of `SearchHit` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_). -* Introduction of the `SearchHits` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_). +* Introduction of the `SearchHits` class to represent a whole search result together with the +metadata for the complete search result (i.e. _max_score_). +* Introduction of `SearchPage` class to represent a paged result containing a `SearchHits` instance. * Introduction of the `GeoDistanceOrder` class to be able to create sorting by geographical distance +* Implementation of Auditing Support +* Implementation of lifecycle entity callbacks [[new-features.3-2-0]] == New in Spring Data Elasticsearch 3.2 diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index c2fb1c4f4..b150cde1d 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -9,7 +9,7 @@ The main reasons for the removal of the Jackson based mapper are: * Custom mappings of fields needed to be done with annotations like `@JsonFormat` or `@JsonInclude`. This often caused problems when the same object was used in different JSON based datastores or sent over a JSON based API. * Custom field types and formats also need to be stored into the Elasticsearch index mappings. The Jackson based annotations did not fully provide all the information that is necessary to represent the types of Elasticsearch. -* Fields must be mapped not only when converting fromand to entities, but also an query argument, returned data and on other places. +* Fields must be mapped not only when converting from and to entities, but also in query argument, returned data and on other places. Using the `MappingElasticsearchConverter` now covers all these cases. @@ -29,23 +29,23 @@ The following annotations are available: * `@Document`: Applied at the class level to indicate this class is a candidate for mapping to the database. The most important attributes are: ** `indexName`: the name of the index to store this entity in -** `type`: the mapping type. If not set, the lowercased simple name of the class is used. +** `type`: [line-through]#the mapping type. If not set, the lowercased simple name of the class is used.# (deprecated since version 4.0) ** `shards`: the number of shards for the index. ** `replicas`: the number of replicas for the index. ** `refreshIntervall`: Refresh interval for the index. Used for index creation. Default value is _"1s"_. ** `indexStoreType`: Index storage type for the index. Used for index creation. Default value is _"fs"_. ** `createIndex`: Configuration whether to create an index on repository bootstrapping. Default value is _true_. ** `versionType`: Configuration of version management. Default value is _EXTERNAL_. + * `@Id`: Applied at the field level to mark the field used for identity purpose. -* `@Transient`: By default all private fields are mapped to the document, this annotation excludes the field where it is applied from being stored in the database +* `@Transient`: By default all fields are mapped to the document when it is stored or retrieved, this annotation excludes the field. * `@PersistenceConstructor`: Marks a given constructor - even a package protected one - to use when instantiating the object from the database. Constructor arguments are mapped by name to the key values in the retrieved Document. -* `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions: +* `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions (the following list is not complete, check the annotation Javadoc for a complete reference): ** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used. -** `type`: the field type, can be one of _Text, Integer, Long, Date, Float, Double, Boolean, Object, Auto, Nested, Ip, Attachment, Keyword_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types] +** `type`: the field type, can be one of _Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types] ** `format` and `pattern` custom definitions for the _Date_ type. ** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_. ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. -** `copy_to`: the target field to copy multiple document fields to. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic. diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index 3c3a03095..b8a691938 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -125,7 +125,7 @@ include::reactive-elasticsearch-operations.adoc[leveloffset=+1] When a document is retrieved with the methods of the `DocumentOperations` interface, just the found entity will be returned. When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity. -In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information. These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search ike the _maxScore_ or requested aggregations. +In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information. These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations. The following classes and interfaces are now available: .SearchHit Contains the following information: @@ -133,7 +133,7 @@ Contains the following information: * Id * Score * Sort Values -* Highligth fields +* Highlight fields * The retrieved entity of type .SearchHits @@ -145,3 +145,12 @@ Contains the following information: * A list of `SearchHit` objects * Returned aggregations +.SearchPage +Defines a Spring Data `Page` that contains a `SearchHits` element and can be used for paging access using repository methods. + +.SearchScrollHits +Returned by the low level scroll API functions in `ElasticsearchRestTemplate`, it enriches a `SearchHits` with the Elasticsearch scroll id. + +.SearchHitsIterator +An Iterator returned by the streaming functions of the `SearchOperations` interface. + diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java index a2d7088b8..f2b0a3ba0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/FieldType.java @@ -24,32 +24,32 @@ * @author Aleksei Arsenev */ public enum FieldType { - Auto, - Text, - Keyword, - Long, - Integer, - Short, - Byte, - Double, - Float, - Half_Float, - Scaled_Float, - Date, - Date_Nanos, - Boolean, - Binary, - Integer_Range, - Float_Range, - Long_Range, - Double_Range, - Date_Range, - Ip_Range, - Object, - Nested, - Ip, - TokenCount, - Percolator, - Flattened, - Search_As_You_Type + Auto, // + Text, // + Keyword, // + Long, // + Integer, // + Short, // + Byte, // + Double, // + Float, // + Half_Float, // + Scaled_Float, // + Date, // + Date_Nanos, // + Boolean, // + Binary, // + Integer_Range, // + Float_Range, // + Long_Range, // + Double_Range, // + Date_Range, // + Ip_Range, // + Object, // + Nested, // + Ip, // + TokenCount, // + Percolator, // + Flattened, // + Search_As_You_Type // } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 16d85ad74..2cc8633e6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -198,6 +198,12 @@ public T get(GetQuery query, Class clazz, IndexCoordinates index) { return get(query.getId(), clazz, index); } + @Override + @Nullable + public T queryForObject(GetQuery query, Class clazz) { + return get(query.getId(), clazz, getIndexCoordinatesFor(clazz)); + } + @Override public boolean exists(String id, Class clazz) { return exists(id, getIndexCoordinatesFor(clazz)); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 279f2156e..159a0cc4a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -256,5 +256,16 @@ default void bulkUpdate(List queries, IndexCoordinates index) { @Nullable T get(GetQuery query, Class clazz, IndexCoordinates index); + /** + * Retrieves an object from an index. + * + * @param query the query defining the id of the object to get + * @param clazz the type of the object to be returned + * @return the found object + * @deprecated since 4.0, use {@link #get(String, Class, IndexCoordinates)} + */ + @Deprecated + @Nullable + T queryForObject(GetQuery query, Class clazz); // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 62c87e5ee..b9eea299a 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -60,17 +60,17 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera IndexCoordinates getIndexCoordinatesFor(Class clazz); // region IndexOperations - /** - * Create an index for given indexName if it does not already exist. - * - * @param indexName the name of the index - * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#create()} - */ - @Deprecated - default boolean createIndex(String indexName) { - return indexOps(IndexCoordinates.of(indexName)).create(); - } +/** + * Create an index for given indexName . + * + * @param indexName the name of the index + * @return {@literal true} if the index was created + * @deprecated since 4.0, use {@link IndexOperations#create()} + */ +@Deprecated +default boolean createIndex(String indexName) { + return indexOps(IndexCoordinates.of(indexName)).create(); +} /** * Create an index for given indexName and Settings. From e605cad688a0e49875cf2624e7674319eb2e8c57 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 2 May 2020 20:08:25 +0200 Subject: [PATCH 0149/1191] DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses. Original PR: #445 --- .../DefaultReactiveElasticsearchClient.java | 66 ++++++++++++++++++- .../ElasticsearchExceptionTranslator.java | 19 +++++- .../ReactiveElasticsearchClientTests.java | 33 +++++----- .../ReactiveElasticsearchClientUnitTests.java | 5 +- ...ElasticsearchExceptionTranslatorTests.java | 15 +++++ .../ReactiveElasticsearchTemplateTests.java | 40 +++++------ ...eReactiveElasticsearchRepositoryTests.java | 26 +++++--- 7 files changed, 156 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 266118d34..7e5aff6d4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -49,6 +49,7 @@ import javax.net.ssl.SSLContext; import org.apache.http.util.EntityUtils; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; @@ -115,6 +116,7 @@ import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; +import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.reactive.function.BodyExtractors; import org.springframework.web.reactive.function.client.ClientRequest; @@ -764,6 +766,12 @@ private Publisher readResponseBody(String logId, Request reques return handleServerError(request, response); } + if (response.statusCode().is4xxClientError()) { + + ClientLogger.logRawResponse(logId, response.statusCode()); + return handleClientError(logId, request, response, responseType); + } + return response.body(BodyExtractors.toMono(byte[].class)) // .map(it -> new String(it, StandardCharsets.UTF_8)) // .doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // @@ -800,13 +808,68 @@ private static XContentParser createParser(String mediaType, String content) thr DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); } - private static Publisher handleServerError(Request request, ClientResponse response) { + private Publisher handleServerError(Request request, ClientResponse response) { return Mono.error( new HttpServerErrorException(response.statusCode(), String.format("%s request to %s returned error code %s.", request.getMethod(), request.getEndpoint(), response.statusCode().value()))); } + private Publisher handleClientError(String logId, Request request, ClientResponse response, + Class responseType) { + + return response.body(BodyExtractors.toMono(byte[].class)) // + .map(bytes -> new String(bytes, StandardCharsets.UTF_8)) // + .flatMap(content -> { + String mediaType = response.headers().contentType().map(MediaType::toString) + .orElse(XContentType.JSON.mediaType()); + try { + ElasticsearchException exception = getElasticsearchException(response, content, mediaType); + if (exception != null) { + StringBuilder sb = new StringBuilder(); + buildExceptionMessages(sb, exception); + return Mono.error(new HttpClientErrorException(response.statusCode(), sb.toString())); + } + } catch (Exception e) { + return Mono + .error(new ElasticsearchStatusException(content, RestStatus.fromCode(response.statusCode().value()))); + } + return Mono.just(content); + }) + .doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // + .flatMap(content -> doDecode(response, responseType, content)); + } + + // region ElasticsearchException helper + @Nullable + private ElasticsearchException getElasticsearchException(ClientResponse response, String content, String mediaType) + throws IOException { + + XContentParser parser = createParser(mediaType, content); + // we have a JSON object with an error and a status field + XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT + + do { + token = parser.nextToken(); + + if (parser.currentName().equals("error")) { + return ElasticsearchException.failureFromXContent(parser); + } + } while (token == XContentParser.Token.FIELD_NAME); + return null; + } + + private static void buildExceptionMessages(StringBuilder sb, Throwable t) { + + sb.append(t.getMessage()); + for (Throwable throwable : t.getSuppressed()) { + sb.append(", "); + buildExceptionMessages(sb, throwable); + } + } + // endregion + + // region internal classes /** * Reactive client {@link ReactiveElasticsearchClient.Status} implementation. * @@ -867,4 +930,5 @@ void updateScrollId(String scrollId) { } } } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index bf4738c64..f038294ce 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -34,6 +34,7 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; +import org.springframework.web.client.HttpClientErrorException; /** * @author Christoph Strobl @@ -63,6 +64,15 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return new UncategorizedElasticsearchException(ex.getMessage(), ex); } + if (ex instanceof HttpClientErrorException) { + HttpClientErrorException httpClientErrorException = (HttpClientErrorException) ex; + + if (isSeqNoConflict(httpClientErrorException)) { + return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict", + httpClientErrorException); + } + } + if (ex instanceof ValidationException) { return new DataIntegrityViolationException(ex.getMessage(), ex); } @@ -75,7 +85,7 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return null; } - private boolean isSeqNoConflict(ElasticsearchException exception) { + private boolean isSeqNoConflict(Exception exception) { if (exception instanceof ElasticsearchStatusException) { ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception; @@ -90,6 +100,13 @@ private boolean isSeqNoConflict(ElasticsearchException exception) { && versionConflictEngineException.getMessage().contains("version conflict, required seqNo"); } + if (exception instanceof HttpClientErrorException) { + HttpClientErrorException httpClientErrorException = (HttpClientErrorException) exception; + + return httpClientErrorException.getMessage() != null + && httpClientErrorException.getMessage().contains("version conflict, required seqNo"); + + } return false; } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index c737ec6b9..db8c89083 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import lombok.SneakyThrows; +import org.springframework.web.client.HttpClientErrorException; import reactor.test.StepVerifier; import java.io.IOException; @@ -147,7 +148,7 @@ public void getOnNonExistingIndexShouldThrowException() { client.get(new GetRequest(INDEX_I, "nonono")) // .as(StepVerifier::create) // - .expectError(ElasticsearchStatusException.class) // + .expectError(HttpClientErrorException.class) // .verify(); } @@ -304,7 +305,7 @@ public void indexShouldErrorForExistingDocuments() { client.index(request) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-488 @@ -353,7 +354,7 @@ public void updateShouldErrorNonExistingDocumentWhenNotUpserted() { client.update(request) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-488 @@ -514,7 +515,7 @@ public void createExistingIndexErrors() throws IOException { client.indices().createIndex(request -> request.index(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -529,12 +530,12 @@ public void deleteExistingIndex() throws IOException { assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void deleteNonExistingIndexErrors() { client.indices().deleteIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -547,12 +548,12 @@ public void openExistingIndex() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void openNonExistingIndex() { client.indices().openIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -565,12 +566,12 @@ public void closeExistingIndex() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void closeNonExistingIndex() { client.indices().closeIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -583,12 +584,12 @@ public void refreshIndex() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void refreshNonExistingIndex() { client.indices().refreshIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -604,7 +605,7 @@ public void updateMapping() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void updateMappingNonExistingIndex() { Map jsonMap = Collections.singletonMap("properties", @@ -612,7 +613,7 @@ public void updateMappingNonExistingIndex() { client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-569 @@ -625,12 +626,12 @@ public void flushIndex() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-767 public void flushNonExistingIndex() { client.indices().flushIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(ElasticsearchStatusException.class); + .verifyError(HttpClientErrorException.class); } @Test // DATAES-684 diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index 25b0bdea4..6a1b0fef5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.*; import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*; +import org.springframework.web.client.HttpClientErrorException; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -459,7 +460,7 @@ public void updateShouldEmitResponseCorrectly() { .verifyComplete(); } - @Test // DATAES-488 + @Test // DATAES-488, DATAES-767 public void updateShouldEmitErrorWhenNotFound() { hostProvider.when(HOST) // @@ -467,7 +468,7 @@ public void updateShouldEmitErrorWhenNotFound() { client.update(new UpdateRequest("twitter", "doc", "1").doc(Collections.singletonMap("user", "cstrobl"))) .as(StepVerifier::create) // - .expectError(ElasticsearchStatusException.class) // + .expectError(HttpClientErrorException.class) // .verify(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java index c2ba997e7..88a3367f3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java @@ -24,9 +24,12 @@ import org.junit.jupiter.api.Test; import org.springframework.dao.DataAccessException; import org.springframework.dao.OptimisticLockingFailureException; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.HttpClientErrorException; /** * @author Roman Puchkovskiy + * @author Peter-Josef Meisch */ class ElasticsearchExceptionTranslatorTests { private final ElasticsearchExceptionTranslator translator = new ElasticsearchExceptionTranslator(); @@ -56,4 +59,16 @@ void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLoc assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); assertThat(translated.getCause()).isSameAs(ex); } + + @Test // DATAES-767 + void shouldConvertHttpClientErrorExceptionWithSeqNoConflictToOptimisticLockingFailureException() { + HttpClientErrorException ex = new HttpClientErrorException(HttpStatus.BAD_REQUEST, + "Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]"); + + DataAccessException translated = translator.translateExceptionIfPossible(ex); + + assertThat(translated).isInstanceOf(OptimisticLockingFailureException.class); + assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); + assertThat(translated.getCause()).isSameAs(ex); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index b75beb71b..d765206e9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -25,6 +25,7 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; +import org.springframework.web.client.HttpClientErrorException; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -213,12 +214,12 @@ public void insertShouldErrorOnNullEntity() { }).isInstanceOf(IllegalArgumentException.class); } - @Test // DATAES-519 - public void getByIdShouldCompleteWhenIndexDoesNotExist() { + @Test // DATAES-519, DATAES-767 + public void getByIdShouldErrorWhenIndexDoesNotExist() { template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // .as(StepVerifier::create) // - .verifyComplete(); + .expectError(HttpClientErrorException.class); } @Test // DATAES-504 @@ -326,14 +327,14 @@ public void existsShouldReturnFalseWhenNotFound() { .verifyComplete(); } - @Test // DATAES-519 + @Test // DATAES-519, DATAES-767 public void searchShouldCompleteWhenIndexDoesNotExist() { template .search(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // - .verifyComplete(); + .expectError(HttpClientErrorException.class); } @Test // DATAES-504 @@ -430,7 +431,7 @@ public void shouldReturnListUsingLocalPreferenceForGivenCriteria() { .verifyComplete(); } - @Test // DATAES-595 + @Test // DATAES-595, DATAES-767 public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGivenCriteria() { SampleEntity sampleEntity1 = randomEntity("test message"); @@ -445,7 +446,7 @@ public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGiven template.search(queryWithInvalidPreference, SampleEntity.class) // .as(StepVerifier::create) // - .expectError(UncategorizedElasticsearchException.class).verify(); + .expectError(HttpClientErrorException.class).verify(); } @Test // DATAES-504 @@ -520,22 +521,20 @@ public void aggregateShouldReturnAggregations() { }).verifyComplete(); } - @Test // DATAES-567 - public void aggregateShouldReturnEmptyWhenIndexDoesNotExist() { - template - .aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + @Test // DATAES-567, DATAES-767 + public void aggregateShouldErrorWhenIndexDoesNotExist() { + template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // - .verifyComplete(); + .expectError(HttpClientErrorException.class); } - @Test // DATAES-519 + @Test // DATAES-519, DATAES-767 public void countShouldReturnZeroWhenIndexDoesNotExist() { template.count(SampleEntity.class) // .as(StepVerifier::create) // - .expectNext(0L) // - .verifyComplete(); + .expectError(HttpClientErrorException.class); } @Test // DATAES-504 @@ -562,12 +561,12 @@ public void countShouldReturnCountMatchingDocuments() { .verifyComplete(); } - @Test // DATAES-519 - public void deleteShouldCompleteWhenIndexDoesNotExist() { + @Test // DATAES-519, DATAES-767 + public void deleteShouldErrorWhenIndexDoesNotExist() { template.delete("does-not-exists", IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create)// - .verifyComplete(); + .expectError(HttpClientErrorException.class); } @Test // DATAES-504 @@ -926,7 +925,10 @@ void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnEnt template.save(forEdit1).block(); forEdit2.setMessage("It'll be great"); - template.save(forEdit2).as(StepVerifier::create).expectError(OptimisticLockingFailureException.class).verify(); + template.save(forEdit2) // + .as(StepVerifier::create) // + .expectError(OptimisticLockingFailureException.class) // + .verify(); } @Test // DATAES-799 diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index ac9668faf..dddf330cd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -72,6 +72,7 @@ import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.test.context.ContextConfiguration; import org.springframework.util.StringUtils; +import org.springframework.web.client.HttpClientErrorException; /** * @author Christoph Strobl @@ -129,9 +130,11 @@ public void saveShouldComputeMultipleEntities() { .verifyComplete(); } - @Test // DATAES-519 - public void findByIdShouldCompleteIfIndexDoesNotExist() { - repository.findById("id-two").as(StepVerifier::create).verifyComplete(); + @Test // DATAES-519, DATAES-767 + public void findByIdShouldErrorIfIndexDoesNotExist() { + repository.findById("id-two") // + .as(StepVerifier::create) // + .expectError(HttpClientErrorException.class); } @Test // DATAES-519 @@ -264,9 +267,11 @@ void shouldReturnHighlightsOnAnnotatedStringQueryMethod() throws IOException { .verifyComplete(); } - @Test // DATAES-519 - public void countShouldReturnZeroWhenIndexDoesNotExist() { - repository.count().as(StepVerifier::create).expectNext(0L).verifyComplete(); + @Test // DATAES-519, DATAES-767 + public void countShouldErrorWhenIndexDoesNotExist() { + repository.count() // + .as(StepVerifier::create) // + .expectError(HttpClientErrorException.class); } @Test // DATAES-519 @@ -352,9 +357,12 @@ public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); } - @Test // DATAES-519 - public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { - repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); + @Test // DATAES-519, DATAES-767 + public void deleteByIdShouldErrorWhenIndexDoesNotExist() { + repository.deleteById("does-not-exist") // + .as(StepVerifier::create) // + .verifyError(HttpClientErrorException.class); + ; } @Test // DATAES-519 From 97cb075afeed7d3fc744a3a1f1d3f9ba475d377d Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Mon, 4 May 2020 15:20:28 -0500 Subject: [PATCH 0150/1191] DATAES-811 - Remove Travis CI. --- .travis.yml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c15c7007c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -dist: xenial - -language: java - -sudo: true - -script: "./mvnw -Pjava11 clean dependency:list test -Dsort -U -B" From 4deea9d6670d22277504bb5116ce4f74c6dd6620 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 5 May 2020 21:39:06 +0200 Subject: [PATCH 0151/1191] DATAES-812 - IndexOperations should use SpEL index name from entity. Original PR: #447 --- .../core/AbstractDefaultIndexOperations.java | 36 ++++++++++++------- .../dynamicindex/DynamicIndexEntityTests.java | 15 ++++++++ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index f6100e8ab..9199fc784 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -55,7 +55,7 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations { protected final RequestFactory requestFactory; @Nullable protected final Class boundClass; - protected final IndexCoordinates boundIndex; + private final IndexCoordinates boundIndex; public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter, Class boundClass) { this.elasticsearchConverter = elasticsearchConverter; @@ -87,7 +87,7 @@ public boolean create() { if (boundClass != null) { Class clazz = boundClass; - String indexName = boundIndex.getIndexName(); + String indexName = getIndexCoordinates().getIndexName(); if (clazz.isAnnotationPresent(Setting.class)) { String settingPath = clazz.getAnnotation(Setting.class).settingPath(); @@ -104,40 +104,40 @@ public boolean create() { } return doCreate(indexName, getDefaultSettings(getRequiredPersistentEntity(clazz))); } - return doCreate(boundIndex.getIndexName(), null); + return doCreate(getIndexCoordinates().getIndexName(), null); } @Override public boolean create(Document settings) { - return doCreate(boundIndex.getIndexName(), settings); + return doCreate(getIndexCoordinates().getIndexName(), settings); } protected abstract boolean doCreate(String indexName, @Nullable Document settings); @Override public boolean delete() { - return doDelete(boundIndex.getIndexName()); + return doDelete(getIndexCoordinates().getIndexName()); } protected abstract boolean doDelete(String indexName); @Override public boolean exists() { - return doExists(boundIndex.getIndexName()); + return doExists(getIndexCoordinates().getIndexName()); } protected abstract boolean doExists(String indexName); @Override public boolean putMapping(Document mapping) { - return doPutMapping(boundIndex, mapping); + return doPutMapping(getIndexCoordinates(), mapping); } protected abstract boolean doPutMapping(IndexCoordinates index, Document mapping); @Override public Map getMapping() { - return doGetMapping(boundIndex); + return doGetMapping(getIndexCoordinates()); } abstract protected Map doGetMapping(IndexCoordinates index); @@ -149,35 +149,35 @@ public Map getSettings() { @Override public Map getSettings(boolean includeDefaults) { - return doGetSettings(boundIndex.getIndexName(), includeDefaults); + return doGetSettings(getIndexCoordinates().getIndexName(), includeDefaults); } protected abstract Map doGetSettings(String indexName, boolean includeDefaults); @Override public void refresh() { - doRefresh(boundIndex); + doRefresh(getIndexCoordinates()); } protected abstract void doRefresh(IndexCoordinates indexCoordinates); @Override public boolean addAlias(AliasQuery query) { - return doAddAlias(query, boundIndex); + return doAddAlias(query, getIndexCoordinates()); } protected abstract boolean doAddAlias(AliasQuery query, IndexCoordinates index); @Override public List queryForAlias() { - return doQueryForAlias(boundIndex.getIndexName()); + return doQueryForAlias(getIndexCoordinates().getIndexName()); } protected abstract List doQueryForAlias(String indexName); @Override public boolean removeAlias(AliasQuery query) { - return doRemoveAlias(query, boundIndex); + return doRemoveAlias(query, getIndexCoordinates()); } protected abstract boolean doRemoveAlias(AliasQuery query, IndexCoordinates index); @@ -238,6 +238,16 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } + /** + * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed + * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. + * + * @return IndexCoordinates + */ + protected IndexCoordinates getIndexCoordinates() { + return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; + } + public IndexCoordinates getIndexCoordinatesFor(Class clazz) { return getRequiredPersistentEntity(clazz).getIndexCoordinates(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 1db09a7ff..3e37fb3df 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -96,6 +96,21 @@ public void indexNameIsDynamicallyProvided() { assertThat(repository.count()).isEqualTo(0L); } + @Test // DATAES-821 + void indexOpsShouldUseDynamicallyProvidedName() { + + indexNameProvider.setIndexName("test-dynamic"); + IndexOperations indexOps = operations.indexOps(DynamicIndexEntity.class); + + int initialCallsCount = indexNameProvider.callsCount; + indexOps.create(); + indexOps.refresh(); + indexOps.refresh(); + indexOps.delete(); + + assertThat(indexNameProvider.callsCount - initialCallsCount).isEqualTo(4); + } + static class IndexNameProvider { private String indexName; From 3c9b0a7b2f0b73a3aca865176406059649a86de9 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 6 May 2020 08:19:48 +0200 Subject: [PATCH 0152/1191] DATAES-814 - Fix documentation. Original PR: #448 --- .../asciidoc/reference/elasticsearch-repository-queries.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index 8cb90d08e..c17844fb3 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -273,7 +273,7 @@ Repository methods can be defined to have the following return types for returni * `List` * `Stream` * `SearchHits` -* `List>` +* `List>` * `Stream>` * `SearchPage` From ec7414c3566d3d3606f86a9cfa495222593c3769 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 7 May 2020 22:11:18 +0200 Subject: [PATCH 0153/1191] DATAES-817 - StreamQueries does only delete the last scrollid. (#449) Original PR: #449 --- .../DefaultReactiveElasticsearchClient.java | 46 +----------- .../client/util/ScrollState.java | 72 +++++++++++++++++++ .../core/AbstractElasticsearchTemplate.java | 10 ++- .../core/ElasticsearchRestTemplate.java | 4 +- .../core/ElasticsearchTemplate.java | 4 +- .../elasticsearch/core/StreamQueries.java | 19 ++--- .../client/util/ScrollStateTest.java | 52 ++++++++++++++ .../elasticsearch/core/StreamQueriesTest.java | 50 +++++++++---- 8 files changed, 186 insertions(+), 71 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/client/util/ScrollState.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/client/util/ScrollStateTest.java diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 7e5aff6d4..be5fd5c82 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -36,10 +36,7 @@ import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.time.Duration; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.List; import java.util.Map.Entry; import java.util.Optional; import java.util.concurrent.TimeUnit; @@ -93,7 +90,6 @@ import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.rest.BytesRestResponse; import org.elasticsearch.rest.RestStatus; -import org.elasticsearch.search.Scroll; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; @@ -105,6 +101,7 @@ import org.springframework.data.elasticsearch.client.reactive.HostProvider.Verification; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices; import org.springframework.data.elasticsearch.client.util.NamedXContents; +import org.springframework.data.elasticsearch.client.util.ScrollState; import org.springframework.data.util.Lazy; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -115,7 +112,6 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; -import org.springframework.util.StringUtils; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.reactive.function.BodyExtractors; @@ -835,8 +831,7 @@ private Publisher handleClientError(String logId, Request reque .error(new ElasticsearchStatusException(content, RestStatus.fromCode(response.statusCode().value()))); } return Mono.just(content); - }) - .doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // + }).doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // .flatMap(content -> doDecode(response, responseType, content)); } @@ -893,42 +888,5 @@ public Collection hosts() { } } - /** - * Mutable state object holding scrollId to be used for {@link SearchScrollRequest#scroll(Scroll)} - * - * @author Christoph Strobl - * @since 3.2 - */ - private static class ScrollState { - - private final Object lock = new Object(); - - private final List pastIds = new ArrayList<>(1); - @Nullable private String scrollId; - - @Nullable - String getScrollId() { - return scrollId; - } - - List getScrollIds() { - - synchronized (lock) { - return Collections.unmodifiableList(new ArrayList<>(pastIds)); - } - } - - void updateScrollId(String scrollId) { - - if (StringUtils.hasText(scrollId)) { - - synchronized (lock) { - - this.scrollId = scrollId; - pastIds.add(scrollId); - } - } - } - } // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/ScrollState.java b/src/main/java/org/springframework/data/elasticsearch/client/util/ScrollState.java new file mode 100644 index 000000000..1b3ad1b6e --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/ScrollState.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 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.client.util; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.elasticsearch.action.search.SearchScrollRequest; +import org.elasticsearch.search.Scroll; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; + +/** + * Mutable state object holding scrollId to be used for {@link SearchScrollRequest#scroll(Scroll)} + * + * @author Christoph Strobl + * @author Peter-Josef Meisch + * @since 3.2 + */ +public class ScrollState { + + private final Object lock = new Object(); + + private final Set pastIds = new LinkedHashSet<>(); + @Nullable private String scrollId; + + public ScrollState() {} + + public ScrollState(String scrollId) { + updateScrollId(scrollId); + } + + @Nullable + public String getScrollId() { + return scrollId; + } + + public List getScrollIds() { + + synchronized (lock) { + return Collections.unmodifiableList(new ArrayList<>(pastIds)); + } + } + + public void updateScrollId(String scrollId) { + + if (StringUtils.hasText(scrollId)) { + + synchronized (lock) { + + this.scrollId = scrollId; + pastIds.add(scrollId); + } + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 2cc8633e6..8f54e6c83 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -341,7 +342,14 @@ abstract protected SearchScrollHits searchScrollContinue(@Nullable String /* * internal use only, not for public API */ - abstract protected void searchScrollClear(String scrollId); + protected void searchScrollClear(String scrollId) { + searchScrollClear(Collections.singletonList(scrollId)); + } + + /* + * internal use only, not for public API + */ + abstract protected void searchScrollClear(List scrollIds); abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 3d6fc25c5..0e4347a42 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -299,9 +299,9 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l } @Override - public void searchScrollClear(String scrollId) { + public void searchScrollClear(List scrollIds) { ClearScrollRequest request = new ClearScrollRequest(); - request.addScrollId(scrollId); + request.scrollIds(scrollIds); execute(client -> client.clearScroll(request, RequestOptions.DEFAULT)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 066fc8bcf..1a58eed4b 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -321,8 +321,8 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l } @Override - public void searchScrollClear(String scrollId) { - client.prepareClearScroll().addScrollId(scrollId).execute().actionGet(); + public void searchScrollClear(List scrollIds) { + client.prepareClearScroll().setScrollIds(scrollIds).execute().actionGet(); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index 77573c8f1..866eefdc4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -16,11 +16,13 @@ package org.springframework.data.elasticsearch.core; import java.util.Iterator; +import java.util.List; import java.util.NoSuchElementException; import java.util.function.Consumer; import java.util.function.Function; import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.data.elasticsearch.client.util.ScrollState; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -38,12 +40,12 @@ abstract class StreamQueries { * * @param searchHits the initial hits * @param continueScrollFunction function to continue scrolling applies to the current scrollId. - * @param clearScrollConsumer consumer to clear the scroll context by accepting the current scrollId. + * @param clearScrollConsumer consumer to clear the scroll context by accepting the scrollIds to clear. * @param * @return the {@link SearchHitsIterator}. */ static SearchHitsIterator streamResults(SearchScrollHits searchHits, - Function> continueScrollFunction, Consumer clearScrollConsumer) { + Function> continueScrollFunction, Consumer> clearScrollConsumer) { Assert.notNull(searchHits, "searchHits must not be null."); Assert.notNull(searchHits.getScrollId(), "scrollId of searchHits must not be null."); @@ -59,17 +61,17 @@ static SearchHitsIterator streamResults(SearchScrollHits searchHits, // As we couldn't retrieve single result with scroll, store current hits. private volatile Iterator> scrollHits = searchHits.iterator(); - private volatile String scrollId = searchHits.getScrollId(); private volatile boolean continueScroll = scrollHits.hasNext(); + private volatile ScrollState scrollState = new ScrollState(searchHits.getScrollId()); @Override public void close() { try { - clearScrollConsumer.accept(scrollId); + clearScrollConsumer.accept(scrollState.getScrollIds()); } finally { scrollHits = null; - scrollId = null; + scrollState = null; } } @@ -102,9 +104,9 @@ public boolean hasNext() { } if (!scrollHits.hasNext()) { - SearchScrollHits nextPage = continueScrollFunction.apply(scrollId); + SearchScrollHits nextPage = continueScrollFunction.apply(scrollState.getScrollId()); scrollHits = nextPage.iterator(); - scrollId = nextPage.getScrollId(); + scrollState.updateScrollId(nextPage.getScrollId()); continueScroll = scrollHits.hasNext(); } @@ -127,6 +129,5 @@ public void remove() { } // utility constructor - private StreamQueries() { - } + private StreamQueries() {} } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/util/ScrollStateTest.java b/src/test/java/org/springframework/data/elasticsearch/client/util/ScrollStateTest.java new file mode 100644 index 000000000..d93d6e75a --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/client/util/ScrollStateTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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.client.util; + +import static org.assertj.core.api.Assertions.*; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +/** + * @author Peter-Josef Meisch + */ +class ScrollStateTest { + + @Test // DATAES-817 + void shouldReturnLastSetScrollId() { + ScrollState scrollState = new ScrollState(); + + scrollState.updateScrollId("id-1"); + scrollState.updateScrollId("id-2"); + + assertThat(scrollState.getScrollId()).isEqualTo("id-2"); + } + + @Test + void shouldReturnUniqueListOfUsedScrollIdsInCorrectOrder() { + + ScrollState scrollState = new ScrollState(); + + scrollState.updateScrollId("id-1"); + scrollState.updateScrollId("id-2"); + scrollState.updateScrollId("id-1"); + scrollState.updateScrollId("id-3"); + scrollState.updateScrollId("id-2"); + + assertThat(scrollState.getScrollIds()).isEqualTo(Arrays.asList("id-1", "id-2", "id-3")); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java index 5a481c510..f55c18309 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java @@ -18,19 +18,17 @@ import static org.assertj.core.api.Assertions.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; -import org.elasticsearch.search.aggregations.Aggregations; import org.junit.jupiter.api.Test; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.lang.Nullable; /** * @author Sascha Woo + * @author Peter-Josef Meisch */ public class StreamQueriesTest { @@ -41,15 +39,15 @@ public void shouldCallClearScrollOnIteratorClose() { List> hits = new ArrayList<>(); hits.add(new SearchHit(null, 0, null, null, "one")); - SearchScrollHits searchHits = newSearchScrollHits(hits); + SearchScrollHits searchHits = newSearchScrollHits(hits, "1234"); AtomicBoolean clearScrollCalled = new AtomicBoolean(false); // when SearchHitsIterator iterator = StreamQueries.streamResults( // searchHits, // - scrollId -> newSearchScrollHits(Collections.emptyList()), // - scrollId -> clearScrollCalled.set(true)); + scrollId -> newSearchScrollHits(Collections.emptyList(), scrollId), // + scrollIds -> clearScrollCalled.set(true)); while (iterator.hasNext()) { iterator.next(); @@ -68,21 +66,47 @@ public void shouldReturnTotalHits() { List> hits = new ArrayList<>(); hits.add(new SearchHit(null, 0, null, null, "one")); - SearchScrollHits searchHits = newSearchScrollHits(hits); + SearchScrollHits searchHits = newSearchScrollHits(hits, "1234"); // when SearchHitsIterator iterator = StreamQueries.streamResults( // searchHits, // - scrollId -> newSearchScrollHits(Collections.emptyList()), // - scrollId -> { - }); + scrollId -> newSearchScrollHits(Collections.emptyList(), scrollId), // + scrollId -> {}); // then assertThat(iterator.getTotalHits()).isEqualTo(1); } - private SearchScrollHits newSearchScrollHits(List> hits) { - return new SearchHitsImpl(hits.size(), TotalHitsRelation.EQUAL_TO, 0, "1234", hits, null); + @Test // DATAES-817 + void shouldClearAllScrollIds() { + + SearchScrollHits searchHits1 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + SearchScrollHits searchHits2 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits3 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); + + Iterator> searchScrollHitsIterator = Arrays.asList(searchHits1, searchHits2, searchHits3,searchHits4).iterator(); + + List clearedScrollIds = new ArrayList<>(); + SearchHitsIterator iterator = StreamQueries.streamResults( // + searchScrollHitsIterator.next(), // + scrollId -> searchScrollHitsIterator.next(), // + scrollIds -> clearedScrollIds.addAll(scrollIds)); + + while (iterator.hasNext()) { + iterator.next(); + } + iterator.close(); + + assertThat(clearedScrollIds).isEqualTo(Arrays.asList("s-1", "s-2", "s-3")); + } + + private SearchScrollHits newSearchScrollHits(List> hits, String scrollId) { + return new SearchHitsImpl(hits.size(), TotalHitsRelation.EQUAL_TO, 0, scrollId, hits, null); } } From a4fd008a241c11fe78f0e7c364a229a8cf4442d2 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 9 May 2020 19:48:26 +0200 Subject: [PATCH 0154/1191] DATAES-819 - Test refactorings. Original PR: #450 --- .../data/elasticsearch/NestedObjectTests.java | 5 ++--- ...EnableNestedElasticsearchRepositoriesTransportTests.java | 2 +- .../notnested/EnableElasticsearchRepositoriesTests.java | 6 +++--- .../data/elasticsearch/core/index/MappingBuilderTests.java | 4 ++-- .../core/index/SimpleDynamicTemplatesMappingTests.java | 5 ----- .../immutable/ImmutableElasticsearchRepositoryTests.java | 4 ++-- 6 files changed, 10 insertions(+), 16 deletions(-) diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index e57bb32fc..a359f3738 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -30,7 +30,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.index.query.BoolQueryBuilder; @@ -50,7 +49,7 @@ import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.utils.IndexInitializer; import org.springframework.test.context.ContextConfiguration; @@ -63,7 +62,7 @@ * @author Mark Paluch */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) public class NestedObjectTests { @Autowired private ElasticsearchOperations operations; diff --git a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java index ed2790f24..7f6bf3c30 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/nested/EnableNestedElasticsearchRepositoriesTransportTests.java @@ -25,7 +25,7 @@ * @author Peter-Josef Meisch */ @ContextConfiguration(classes = { EnableNestedElasticsearchRepositoriesTransportTests.Config.class }) -public class EnableNestedElasticsearchRepositoriesTransportTests { +public class EnableNestedElasticsearchRepositoriesTransportTests extends EnableNestedElasticsearchRepositoriesTests { @Configuration @Import({ ElasticsearchTemplateConfiguration.class }) @EnableElasticsearchRepositories(considerNestedRepositories = true) diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index 6b5855602..33f41c2fb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-15 the original author or authors. + * Copyright 2013-2020 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. @@ -42,7 +42,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; @@ -71,7 +71,7 @@ public void setApplicationContext(ApplicationContext applicationContext) throws } @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) + @Import({ ElasticsearchRestTemplateConfiguration.class }) @EnableElasticsearchRepositories static class Config {} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index a59904a64..7b4c89934 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -63,7 +63,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.geo.Box; import org.springframework.data.geo.Circle; @@ -85,7 +85,7 @@ * @author Roman Puchkovskiy */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) public class MappingBuilderTests extends MappingContextBaseTests { @Autowired private ElasticsearchOperations operations; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java index 8faff283f..be3f64714 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleDynamicTemplatesMappingTests.java @@ -26,10 +26,7 @@ import org.springframework.data.elasticsearch.annotations.DynamicTemplates; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; -import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.lang.Nullable; -import org.springframework.test.context.ContextConfiguration; /** * Dynamic templates tests @@ -37,8 +34,6 @@ * @author Petr Kukral * @author Peter-Josef Meisch */ -@SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) public class SimpleDynamicTemplatesMappingTests extends MappingContextBaseTests { @Test // DATAES-568 diff --git a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java index 319830044..5cd8d4af7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/immutable/ImmutableElasticsearchRepositoryTests.java @@ -31,7 +31,7 @@ import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.repository.CrudRepository; @@ -49,7 +49,7 @@ public class ImmutableElasticsearchRepositoryTests { @Configuration - @Import({ ElasticsearchTemplateConfiguration.class }) + @Import({ ElasticsearchRestTemplateConfiguration.class }) @EnableElasticsearchRepositories(basePackages = { "org.springframework.data.elasticsearch.immutable" }, considerNestedRepositories = true) static class Config {} From 5100fe04ccc78b5e136010b77c6a2a3717727f4d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 10 May 2020 19:45:15 +0200 Subject: [PATCH 0155/1191] DATES-821 - Fix code for adding an alias. Original PR: #451 --- .../elasticsearch/core/RequestFactory.java | 13 ++++++-- ...asticsearchRepositoriesTransportTests.java | 31 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTransportTests.java diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 4d1a5c3e6..a26c8b83b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -107,13 +107,20 @@ public IndicesAliasesRequest.AliasActions aliasAction(AliasQuery query, IndexCoo aliasAction.filter(query.getFilterBuilder()); } else if (query.getFilter() != null) { aliasAction.filter(query.getFilter()); - } else if (!StringUtils.isEmpty(query.getRouting())) { + } + + if (!StringUtils.isEmpty(query.getRouting())) { aliasAction.routing(query.getRouting()); - } else if (!StringUtils.isEmpty(query.getSearchRouting())) { + } + + if (!StringUtils.isEmpty(query.getSearchRouting())) { aliasAction.searchRouting(query.getSearchRouting()); - } else if (!StringUtils.isEmpty(query.getIndexRouting())) { + } + + if (!StringUtils.isEmpty(query.getIndexRouting())) { aliasAction.indexRouting(query.getIndexRouting()); } + return aliasAction; } diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTransportTests.java new file mode 100644 index 000000000..b74c2f58c --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTransportTests.java @@ -0,0 +1,31 @@ +/* + * Copyright 2020 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.config.notnested; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; + +/** + * @author Peter-Josef Meisch + */ +public class EnableElasticsearchRepositoriesTransportTests extends EnableElasticsearchRepositoriesTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + @EnableElasticsearchRepositories(considerNestedRepositories = true) + static class Config {} +} From cea8c9361621cec79698663305a1561a801a1d77 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Mon, 11 May 2020 17:56:19 +0200 Subject: [PATCH 0156/1191] DATAES-822 - Convert Reactive Client exceptions to ElasticsearchStatusException. We now use ElasticsearchStatusException instead of HttpClientErrorException to simplify exception translation so that ElasticsearchExceptionTranslator does no longer depend on spring-web. --- .../DefaultReactiveElasticsearchClient.java | 7 ++-- .../ElasticsearchExceptionTranslator.java | 37 +++++++------------ .../ReactiveElasticsearchClientTests.java | 23 ++++++------ .../ReactiveElasticsearchClientUnitTests.java | 5 +-- ...ElasticsearchExceptionTranslatorTests.java | 14 +------ .../ReactiveElasticsearchTemplateTests.java | 17 +++++---- ...eReactiveElasticsearchRepositoryTests.java | 17 +++++---- 7 files changed, 50 insertions(+), 70 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index be5fd5c82..b3863985a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -94,6 +94,7 @@ import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; import org.reactivestreams.Publisher; + import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; import org.springframework.data.elasticsearch.client.ElasticsearchHost; @@ -112,7 +113,6 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; -import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.reactive.function.BodyExtractors; import org.springframework.web.reactive.function.client.ClientRequest; @@ -819,16 +819,17 @@ private Publisher handleClientError(String logId, Request reque .flatMap(content -> { String mediaType = response.headers().contentType().map(MediaType::toString) .orElse(XContentType.JSON.mediaType()); + RestStatus status = RestStatus.fromCode(response.statusCode().value()); try { ElasticsearchException exception = getElasticsearchException(response, content, mediaType); if (exception != null) { StringBuilder sb = new StringBuilder(); buildExceptionMessages(sb, exception); - return Mono.error(new HttpClientErrorException(response.statusCode(), sb.toString())); + return Mono.error(new ElasticsearchStatusException(sb.toString(), status, exception)); } } catch (Exception e) { return Mono - .error(new ElasticsearchStatusException(content, RestStatus.fromCode(response.statusCode().value()))); + .error(new ElasticsearchStatusException(content, status)); } return Mono.just(content); }).doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index f038294ce..c8c532ad6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.springframework.data.elasticsearch.core; import java.io.IOException; @@ -24,6 +23,7 @@ import org.elasticsearch.common.ValidationException; import org.elasticsearch.index.engine.VersionConflictEngineException; import org.elasticsearch.rest.RestStatus; + import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; @@ -34,12 +34,16 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; -import org.springframework.web.client.HttpClientErrorException; /** + * Simple {@link PersistenceExceptionTranslator} for Elasticsearch. Convert the given runtime exception to an + * appropriate exception from the {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation is + * appropriate: any other exception may have resulted from user code, and should not be translated. + * * @author Christoph Strobl * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Mark Paluch * @since 3.2 */ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTranslator { @@ -47,6 +51,10 @@ public class ElasticsearchExceptionTranslator implements PersistenceExceptionTra @Override public DataAccessException translateExceptionIfPossible(RuntimeException ex) { + if (isSeqNoConflict(ex)) { + return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict", ex); + } + if (ex instanceof ElasticsearchException) { ElasticsearchException elasticsearchException = (ElasticsearchException) ex; @@ -56,23 +64,9 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { ex); } - if (isSeqNoConflict(elasticsearchException)) { - return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict", - elasticsearchException); - } - return new UncategorizedElasticsearchException(ex.getMessage(), ex); } - if (ex instanceof HttpClientErrorException) { - HttpClientErrorException httpClientErrorException = (HttpClientErrorException) ex; - - if (isSeqNoConflict(httpClientErrorException)) { - return new OptimisticLockingFailureException("Cannot index a document due to seq_no+primary_term conflict", - httpClientErrorException); - } - } - if (ex instanceof ValidationException) { return new DataIntegrityViolationException(ex.getMessage(), ex); } @@ -88,25 +82,22 @@ public DataAccessException translateExceptionIfPossible(RuntimeException ex) { private boolean isSeqNoConflict(Exception exception) { if (exception instanceof ElasticsearchStatusException) { + ElasticsearchStatusException statusException = (ElasticsearchStatusException) exception; + return statusException.status() == RestStatus.CONFLICT && statusException.getMessage() != null && statusException.getMessage().contains("type=version_conflict_engine_exception") && statusException.getMessage().contains("version conflict, required seqNo"); } if (exception instanceof VersionConflictEngineException) { + VersionConflictEngineException versionConflictEngineException = (VersionConflictEngineException) exception; + return versionConflictEngineException.getMessage() != null && versionConflictEngineException.getMessage().contains("version conflict, required seqNo"); } - if (exception instanceof HttpClientErrorException) { - HttpClientErrorException httpClientErrorException = (HttpClientErrorException) exception; - - return httpClientErrorException.getMessage() != null - && httpClientErrorException.getMessage().contains("version conflict, required seqNo"); - - } return false; } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index db8c89083..8146ae47d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -18,7 +18,6 @@ import static org.assertj.core.api.Assertions.*; import lombok.SneakyThrows; -import org.springframework.web.client.HttpClientErrorException; import reactor.test.StepVerifier; import java.io.IOException; @@ -143,12 +142,12 @@ public void infoShouldReturnClusterInformation() { .verifyComplete(); } - @Test // DATAES-519 + @Test // DATAES-519, DATAES-822 public void getOnNonExistingIndexShouldThrowException() { client.get(new GetRequest(INDEX_I, "nonono")) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class) // + .expectError(ElasticsearchStatusException.class) // .verify(); } @@ -305,7 +304,7 @@ public void indexShouldErrorForExistingDocuments() { client.index(request) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-488 @@ -354,7 +353,7 @@ public void updateShouldErrorNonExistingDocumentWhenNotUpserted() { client.update(request) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-488 @@ -515,7 +514,7 @@ public void createExistingIndexErrors() throws IOException { client.indices().createIndex(request -> request.index(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -535,7 +534,7 @@ public void deleteNonExistingIndexErrors() { client.indices().deleteIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -553,7 +552,7 @@ public void openNonExistingIndex() { client.indices().openIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -571,7 +570,7 @@ public void closeNonExistingIndex() { client.indices().closeIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -589,7 +588,7 @@ public void refreshNonExistingIndex() { client.indices().refreshIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -613,7 +612,7 @@ public void updateMappingNonExistingIndex() { client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 @@ -631,7 +630,7 @@ public void flushNonExistingIndex() { client.indices().flushIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); + .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-684 diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java index 6a1b0fef5..4b0b4e79d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientUnitTests.java @@ -19,7 +19,6 @@ import static org.mockito.Mockito.*; import static org.springframework.data.elasticsearch.client.reactive.ReactiveMockClientTestsUtils.MockWebClientProvider.Receive.*; -import org.springframework.web.client.HttpClientErrorException; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -460,7 +459,7 @@ public void updateShouldEmitResponseCorrectly() { .verifyComplete(); } - @Test // DATAES-488, DATAES-767 + @Test // DATAES-488, DATAES-767, DATAES-822 public void updateShouldEmitErrorWhenNotFound() { hostProvider.when(HOST) // @@ -468,7 +467,7 @@ public void updateShouldEmitErrorWhenNotFound() { client.update(new UpdateRequest("twitter", "doc", "1").doc(Collections.singletonMap("user", "cstrobl"))) .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class) // + .expectError(ElasticsearchStatusException.class) // .verify(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java index 88a3367f3..a805502e2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslatorTests.java @@ -22,10 +22,9 @@ import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.rest.RestStatus; import org.junit.jupiter.api.Test; + import org.springframework.dao.DataAccessException; import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpClientErrorException; /** * @author Roman Puchkovskiy @@ -60,15 +59,4 @@ void shouldConvertVersionConflictEngineExceptionWithSeqNoConflictToOptimisticLoc assertThat(translated.getCause()).isSameAs(ex); } - @Test // DATAES-767 - void shouldConvertHttpClientErrorExceptionWithSeqNoConflictToOptimisticLockingFailureException() { - HttpClientErrorException ex = new HttpClientErrorException(HttpStatus.BAD_REQUEST, - "Elasticsearch exception [type=version_conflict_engine_exception, reason=[WPUUsXEB6uuA6j8_A7AB]: version conflict, required seqNo [34], primary term [16]. current document has seqNo [35] and primary term [16]]"); - - DataAccessException translated = translator.translateExceptionIfPossible(ex); - - assertThat(translated).isInstanceOf(OptimisticLockingFailureException.class); - assertThat(translated.getMessage()).startsWith("Cannot index a document due to seq_no+primary_term conflict"); - assertThat(translated.getCause()).isSameAs(ex); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index d765206e9..ecbad86c9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -25,7 +25,6 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import org.springframework.web.client.HttpClientErrorException; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -41,6 +40,7 @@ import java.util.stream.Collectors; import java.util.stream.IntStream; +import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.index.query.IdsQueryBuilder; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms; @@ -49,6 +49,7 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; @@ -214,12 +215,12 @@ public void insertShouldErrorOnNullEntity() { }).isInstanceOf(IllegalArgumentException.class); } - @Test // DATAES-519, DATAES-767 + @Test // DATAES-519, DATAES-767, DATAES-822 public void getByIdShouldErrorWhenIndexDoesNotExist() { template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-504 @@ -334,7 +335,7 @@ public void searchShouldCompleteWhenIndexDoesNotExist() { .search(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-504 @@ -446,7 +447,7 @@ public void shouldThrowElasticsearchStatusExceptionWhenInvalidPreferenceForGiven template.search(queryWithInvalidPreference, SampleEntity.class) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class).verify(); + .expectError(UncategorizedElasticsearchException.class).verify(); } @Test // DATAES-504 @@ -526,7 +527,7 @@ public void aggregateShouldErrorWhenIndexDoesNotExist() { template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-519, DATAES-767 @@ -534,7 +535,7 @@ public void countShouldReturnZeroWhenIndexDoesNotExist() { template.count(SampleEntity.class) // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-504 @@ -566,7 +567,7 @@ public void deleteShouldErrorWhenIndexDoesNotExist() { template.delete("does-not-exists", IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create)// - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-504 diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index dddf330cd..d0c517305 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -38,6 +38,7 @@ import java.util.UUID; import java.util.stream.IntStream; +import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; @@ -47,6 +48,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -57,6 +59,7 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.TestUtils; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Highlight; @@ -72,7 +75,6 @@ import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.test.context.ContextConfiguration; import org.springframework.util.StringUtils; -import org.springframework.web.client.HttpClientErrorException; /** * @author Christoph Strobl @@ -130,11 +132,11 @@ public void saveShouldComputeMultipleEntities() { .verifyComplete(); } - @Test // DATAES-519, DATAES-767 + @Test // DATAES-519, DATAES-767, DATAES-822 public void findByIdShouldErrorIfIndexDoesNotExist() { repository.findById("id-two") // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-519 @@ -267,11 +269,11 @@ void shouldReturnHighlightsOnAnnotatedStringQueryMethod() throws IOException { .verifyComplete(); } - @Test // DATAES-519, DATAES-767 + @Test // DATAES-519, DATAES-767, DATAES-822 public void countShouldErrorWhenIndexDoesNotExist() { repository.count() // .as(StepVerifier::create) // - .expectError(HttpClientErrorException.class); + .expectError(ElasticsearchStatusException.class); } @Test // DATAES-519 @@ -357,12 +359,11 @@ public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); } - @Test // DATAES-519, DATAES-767 + @Test // DATAES-519, DATAES-767, DATAES-822 public void deleteByIdShouldErrorWhenIndexDoesNotExist() { repository.deleteById("does-not-exist") // .as(StepVerifier::create) // - .verifyError(HttpClientErrorException.class); - ; + .verifyError(UncategorizedElasticsearchException.class); } @Test // DATAES-519 From 8118713706fa8e52fc41969e0370d953908bb0db Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 12 May 2020 06:22:13 +0200 Subject: [PATCH 0157/1191] DATAES-822 - Convert Reactive Server Exceptions to ElasticsearchStatusException. --- .../reactive/DefaultReactiveElasticsearchClient.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index b3863985a..e1b87ab0e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -94,7 +94,6 @@ import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; import org.reactivestreams.Publisher; - import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; import org.springframework.data.elasticsearch.client.ElasticsearchHost; @@ -113,7 +112,6 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; -import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.reactive.function.BodyExtractors; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; @@ -806,9 +804,10 @@ private static XContentParser createParser(String mediaType, String content) thr private Publisher handleServerError(Request request, ClientResponse response) { - return Mono.error( - new HttpServerErrorException(response.statusCode(), String.format("%s request to %s returned error code %s.", - request.getMethod(), request.getEndpoint(), response.statusCode().value()))); + RestStatus status = RestStatus.fromCode(response.statusCode().value()); + + return Mono.error(new ElasticsearchStatusException(String.format("%s request to %s returned error code %s.", + request.getMethod(), request.getEndpoint(), response.statusCode().value()), status)); } private Publisher handleClientError(String logId, Request request, ClientResponse response, @@ -828,8 +827,7 @@ private Publisher handleClientError(String logId, Request reque return Mono.error(new ElasticsearchStatusException(sb.toString(), status, exception)); } } catch (Exception e) { - return Mono - .error(new ElasticsearchStatusException(content, status)); + return Mono.error(new ElasticsearchStatusException(content, status)); } return Mono.just(content); }).doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // From 5483176be433a5a07fb7802c681a916bfe8aa1ad Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 12 May 2020 12:27:58 +0200 Subject: [PATCH 0158/1191] DATAES-808 - Updated changelog. --- src/main/resources/changelog.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index cb5832ba4..ae6048696 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,25 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.0.RELEASE (2020-05-12) +--------------------------------------------- +* DATAES-822 - ElasticsearchRestTemplate should not use `spring-web`. +* DATAES-821 - Fix code for adding an alias. +* DATAES-819 - Test refactorings. +* DATAES-817 - StreamQueries does only delete the last scrollid. +* DATAES-814 - Fix documentation. +* DATAES-812 - IndexOperations should use SpEL index name from entity. +* DATAES-811 - Remove Travis CI. +* DATAES-809 - Creation of test data may lead to duplicate values. +* DATAES-808 - Release 4.0 GA (Neumann). +* DATAES-799 - Support optimistic locking for full update scenario using seq_no + primary_term. +* DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses. +* DATAES-750 - Migration guide and documentation update. +* DATAES-602 - add support for refreshAsync into ElasticsearchRestTemplate. +* DATAES-587 - Add lifecycle events. +* DATAES-267 - ElasticSearch should allow to create nested not analyzed fields. + + Changes in version 4.0.0.RC2 (2020-04-28) ----------------------------------------- * DATAES-803 - Move count request setup from reactive template to reactive client. @@ -1119,3 +1138,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From f86231353fc39d71d24aab21e5291fc8ae788a2e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 12 May 2020 12:27:59 +0200 Subject: [PATCH 0159/1191] DATAES-808 - Prepare 4.0 GA (Neumann). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 979515864..3cd4fbfae 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RELEASE Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.2 2.9.1 - 2.3.0.BUILD-SNAPSHOT + 2.3.0.RELEASE 4.1.39.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-release + https://repo.spring.io/libs-release diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 081bded18..47e942ed4 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 RC2 +Spring Data Elasticsearch 4.0 GA Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -14,3 +14,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From 2bbe88f49afa48493ac3b57b71dff45c61475e1b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 12 May 2020 12:28:23 +0200 Subject: [PATCH 0160/1191] DATAES-808 - Release version 4.0 GA (Neumann). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3cd4fbfae..d9f664313 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.BUILD-SNAPSHOT + 4.0.0.RELEASE org.springframework.data.build From 0dc0f40cbadd74cfe7608bf1618c348ca74f37a9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 12 May 2020 12:40:28 +0200 Subject: [PATCH 0161/1191] DATAES-808 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d9f664313..8ceb290f2 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.0.0.RELEASE + 4.1.0-SNAPSHOT org.springframework.data.build From 9ac18855fccf0ec6eb528119ba672569d51fa888 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 12 May 2020 12:40:30 +0200 Subject: [PATCH 0162/1191] DATAES-808 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8ceb290f2..1a722c913 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.3.0.RELEASE + 2.4.0-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.6.2 2.9.1 - 2.3.0.RELEASE + 2.4.0-SNAPSHOT 4.1.39.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-release - https://repo.spring.io/libs-release + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 6487d0ddd4f415a21643365999ec4cab5cbf6360 Mon Sep 17 00:00:00 2001 From: Kai Kewley Date: Wed, 13 May 2020 17:26:23 +0100 Subject: [PATCH 0163/1191] DATAES-825 - Update link to spring.io docs to track latest. Original PR: #454 --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 8a6ccee65..69a0d9524 100644 --- a/README.adoc +++ b/README.adoc @@ -123,7 +123,7 @@ Add the Maven dependency: // Always change both files! **Compatibility Matrix** -The compatibility between Spring Data Elasticsearch, Elasticsearch client drivers and Spring Boot versions can be found in the https://docs.spring.io/spring-data/elasticsearch/docs/3.2.0.RC3/reference/html/#preface.versions[reference documentation]. +The compatibility between Spring Data Elasticsearch, Elasticsearch client drivers and Spring Boot versions can be found in the https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#preface.versions[reference documentation]. To use the Release candidate versions of the upcoming major version, use our Maven milestone repository and declare the appropriate dependency version: From 7540a2a1a84059cc5cbbf95f0c6f9bc82db050e2 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 14 May 2020 07:58:07 +0200 Subject: [PATCH 0164/1191] DATAES-826 - Add method to IndexOperations to write an index mapping from an entity class. Original PR: #455 --- .../core/ElasticsearchOperations.java | 4 ++-- .../data/elasticsearch/core/IndexOperations.java | 10 ++++++++++ .../support/AbstractElasticsearchRepository.java | 2 +- .../core/ElasticsearchTemplateTests.java | 14 +++++++------- .../core/ReactiveElasticsearchTemplateTests.java | 2 +- .../ElasticsearchOperationsCallbackTest.java | 2 +- ...ctiveElasticsearchOperationsCallbackTest.java | 2 +- .../core/index/MappingBuilderTests.java | 16 ++++++++-------- .../core/query/CriteriaQueryTests.java | 2 +- 9 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index b9eea299a..87bb9d560 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -186,7 +186,7 @@ default boolean indexExists(Class clazz) { @Deprecated default boolean putMapping(Class clazz) { IndexOperations indexOps = indexOps(clazz); - return indexOps.putMapping(indexOps.createMapping(clazz)); + return indexOps.putMapping(clazz); } /** @@ -202,7 +202,7 @@ default boolean putMapping(Class clazz) { @Deprecated default boolean putMapping(IndexCoordinates index, Class clazz) { IndexOperations indexOps = indexOps(index); - return indexOps.putMapping(indexOps.createMapping(clazz)); + return indexOps.putMapping(clazz); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 1eeaeb52d..7781f65dd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -93,6 +93,16 @@ public interface IndexOperations { */ boolean putMapping(Document mapping); + /** + * Creates the index mapping for the given class and writes it to the index. + * @param clazz the clazz to create a mapping for + * @return {@literal true} if the mapping could be stored + * @since 4.1 + */ + default boolean putMapping(Class clazz) { + return putMapping(createMapping(clazz)); + } + /** * Get mapping for an index defined by a class. * diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 864e7c8c3..c8d48c3d1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -102,7 +102,7 @@ private void createIndex() { } private void putMapping() { - indexOperations.putMapping(indexOperations.createMapping(entityClass)); + indexOperations.putMapping(entityClass); } private boolean createIndexAndMapping() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index e5eed540e..1b38cf408 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -123,15 +123,15 @@ public void before() { deleteIndices(); indexOperations.create(); - indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.putMapping(SampleEntity.class); IndexOperations indexOpsSampleEntityUUIDKeyed = operations.indexOps(SampleEntityUUIDKeyed.class); indexOpsSampleEntityUUIDKeyed.create(); - indexOpsSampleEntityUUIDKeyed.putMapping(indexOpsSampleEntityUUIDKeyed.createMapping(SampleEntityUUIDKeyed.class)); + indexOpsSampleEntityUUIDKeyed.putMapping(SampleEntityUUIDKeyed.class); IndexOperations indexOpsSearchHitsEntity = operations.indexOps(SearchHitsEntity.class); indexOpsSearchHitsEntity.create(); - indexOpsSearchHitsEntity.putMapping(indexOpsSearchHitsEntity.createMapping(SearchHitsEntity.class)); + indexOpsSearchHitsEntity.putMapping(SearchHitsEntity.class); } @AfterEach @@ -1419,7 +1419,7 @@ public void shouldPutMappingForGivenEntity() { // when // then - assertThat(indexOperations.putMapping(indexOperations.createMapping(entityClass))).isTrue(); + assertThat(indexOperations.putMapping(entityClass)).isTrue(); } @Test // DATAES-305 @@ -1432,7 +1432,7 @@ public void shouldPutMappingWithCustomIndexName() { indexOperations1.create(); // when - indexOperations1.putMapping(indexOperations1.createMapping(entity)); + indexOperations1.putMapping(entity); // then Map mapping = indexOperations.getMapping(); @@ -1622,7 +1622,7 @@ public void shouldReturnDifferentEntityForMultiSearch() { IndexOperations bookIndexOperations = operations.indexOps(Book.class); bookIndexOperations.delete(); bookIndexOperations.create(); - indexOperations.putMapping(indexOperations.createMapping(clazz)); + indexOperations.putMapping(clazz); bookIndexOperations.refresh(); IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template").withTypes("book"); @@ -2263,7 +2263,7 @@ public void shouldCreateIndexWithGivenClassAndSettings() { // when indexOperations.delete(); indexOperations.create(parse(settings)); - indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.putMapping(SampleEntity.class); indexOperations.refresh(); // then diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index ecbad86c9..a959e4dd6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -108,7 +108,7 @@ public void setUp() { deleteIndices(); indexOperations.create(); - indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.putMapping(SampleEntity.class); indexOperations.refresh(); template = new ReactiveElasticsearchTemplate(TestUtils.reactiveClient(), restTemplate.getElasticsearchConverter()); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java index 0e3755ffb..f8da614bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ElasticsearchOperationsCallbackTest.java @@ -55,7 +55,7 @@ void setUp() { IndexOperations indexOps = operations.indexOps(SampleEntity.class); indexOps.delete(); indexOps.create(); - indexOps.putMapping(indexOps.createMapping(SampleEntity.class)); + indexOps.putMapping(SampleEntity.class); } @AfterEach diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java index 035d4f059..6fe0e257c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveElasticsearchOperationsCallbackTest.java @@ -67,7 +67,7 @@ public Mono onBeforeConvert(SampleEntity entity, IndexCoordinates void setUp() { IndexOperations indexOps = nonreactiveOperations.indexOps(SampleEntity.class); indexOps.create(); - indexOps.putMapping(indexOps.createMapping(SampleEntity.class)); + indexOps.putMapping(SampleEntity.class); } @AfterEach diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 7b4c89934..30412fa1a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -108,7 +108,7 @@ public void before() { public void shouldNotFailOnCircularReference() { operations.indexOps(SimpleRecursiveEntity.class).create(); - indexOperations.putMapping(indexOperations.createMapping(SimpleRecursiveEntity.class)); + indexOperations.putMapping(SimpleRecursiveEntity.class); indexOperations.refresh(); } @@ -144,7 +144,7 @@ public void shouldAddStockPriceDocumentToIndex() { // When indexOps.create(); - indexOps.putMapping(indexOps.createMapping(StockPrice.class)); + indexOps.putMapping(StockPrice.class); String symbol = "AU"; double price = 2.34; String id = "abc"; @@ -197,7 +197,7 @@ public void shouldAddSampleInheritedEntityDocumentToIndex() { // when indexOps.create(); - indexOps.putMapping(indexOps.createMapping(SampleInheritedEntity.class)); + indexOps.putMapping(SampleInheritedEntity.class); Date createdDate = new Date(); String message = "msg"; String id = "abc"; @@ -238,11 +238,11 @@ public void shouldHandleReverseRelationship() { // given IndexOperations indexOpsUser = operations.indexOps(User.class); indexOpsUser.create(); - indexOpsUser.putMapping(indexOpsUser.createMapping(User.class)); + indexOpsUser.putMapping(User.class); IndexOperations indexOpsGroup = operations.indexOps(Group.class); indexOpsGroup.create(); - indexOpsGroup.putMapping(indexOpsGroup.createMapping(Group.class)); + indexOpsGroup.putMapping(Group.class); // when @@ -255,7 +255,7 @@ public void shouldMapBooks() { // given IndexOperations indexOps = operations.indexOps(Book.class); indexOps.create(); - indexOps.putMapping(indexOps.createMapping(Book.class)); + indexOps.putMapping(Book.class); // when @@ -268,7 +268,7 @@ public void shouldUseBothAnalyzer() { // given IndexOperations indexOps = this.operations.indexOps(Book.class); indexOps.create(); - indexOps.putMapping(indexOps.createMapping(Book.class)); + indexOps.putMapping(Book.class); // when Map mapping = indexOps.getMapping(); @@ -310,7 +310,7 @@ public void shouldUseCopyTo() { // given IndexOperations indexOps = operations.indexOps(CopyToEntity.class); indexOps.create(); - indexOps.putMapping(indexOps.createMapping(CopyToEntity.class)); + indexOps.putMapping(CopyToEntity.class); // when Map mapping = indexOps.getMapping(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index c83367f1c..8007656b7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -74,7 +74,7 @@ public void before() { indexOperations = operations.indexOps(SampleEntity.class); indexOperations.delete(); indexOperations.create(); - indexOperations.putMapping(indexOperations.createMapping(SampleEntity.class)); + indexOperations.putMapping(SampleEntity.class); indexOperations.refresh(); } From c7339dc248370e5e726b6a808c74bb5bd4dc1db1 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 14 May 2020 18:05:03 +0200 Subject: [PATCH 0165/1191] DATAES-826 - Repositories should not try to create an index when it already exists. original PR: #456 --- .../repository/support/AbstractElasticsearchRepository.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index c8d48c3d1..4dcd4a255 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -88,7 +88,7 @@ public AbstractElasticsearchRepository(ElasticsearchEntityInformation met this.entityClass = this.entityInformation.getJavaType(); this.indexOperations = operations.indexOps(this.entityClass); try { - if (createIndexAndMapping()) { + if (createIndexAndMapping() && !indexOperations.exists()) { createIndex(); putMapping(); } From aaef626684c0ee8f669664647397bf2283d86c24 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 14 May 2020 20:26:54 +0200 Subject: [PATCH 0166/1191] DATAES-828 - Fields of type date need to have a format defined. Original PR: #457 --- .../elasticsearch-object-mapping.adoc | 2 +- ...SimpleElasticsearchPersistentProperty.java | 8 ++++++- .../elasticsearch/core/LogEntityTests.java | 3 ++- .../core/index/MappingBuilderTests.java | 2 +- .../SimpleElasticsearchDateMappingTests.java | 6 ++--- ...sticsearchPersistentPropertyUnitTests.java | 22 +++++++++++++++++++ 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index b150cde1d..7e7496e7f 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -43,7 +43,7 @@ The following annotations are available: * `@Field`: Applied at the field level and defines properties of the field, most of the attributes map to the respective https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html[Elasticsearch Mapping] definitions (the following list is not complete, check the annotation Javadoc for a complete reference): ** `name`: The name of the field as it will be represented in the Elasticsearch document, if not set, the Java field name is used. ** `type`: the field type, can be one of _Text, Keyword, Long, Integer, Short, Byte, Double, Float, Half_Float, Scaled_Float, Date, Date_Nanos, Boolean, Binary, Integer_Range, Float_Range, Long_Range, Double_Range, Date_Range, Ip_Range, Object, Nested, Ip, TokenCount, Percolator, Flattened, Search_As_You_Type_. See https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html[Elasticsearch Mapping Types] -** `format` and `pattern` custom definitions for the _Date_ type. +** `format` and `pattern` definitions for the _Date_ type. `format` must be defined for date types. ** `store`: Flag wether the original field value should be store in Elasticsearch, default value is _false_. ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index beab6b433..15771b084 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -117,9 +117,15 @@ private void initDateConverter() { boolean isTemporalAccessor = TemporalAccessor.class.isAssignableFrom(getType()); boolean isDate = Date.class.isAssignableFrom(getType()); - if (field != null && field.type() == FieldType.Date && (isTemporalAccessor || isDate)) { + if (field != null && (field.type() == FieldType.Date || field.type() == FieldType.Date_Nanos) + && (isTemporalAccessor || isDate)) { DateFormat dateFormat = field.format(); + if (dateFormat == DateFormat.none) { + throw new MappingException(String.format("property %s is annotated with FieldType.%s but has no DateFormat defined", + getName(), field.type().name())); + } + ElasticsearchDateConverter converter = null; if (dateFormat == DateFormat.custom) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index b2b468e8d..0a9a52cca 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -34,6 +34,7 @@ import org.springframework.context.annotation.Import; import org.springframework.dao.DataAccessException; import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -146,7 +147,7 @@ static class LogEntity { @Field(type = Ip) private String ip; - @Field(type = Date) private java.util.Date date; + @Field(type = Date, format = DateFormat.date_time) private java.util.Date date; private LogEntity() {} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 30412fa1a..9f1403e86 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -859,7 +859,7 @@ static class AbstractInheritedEntity { @Nullable @Id private String id; - @Nullable @Field(type = FieldType.Date, index = false) private Date createdDate; + @Nullable @Field(type = FieldType.Date, format = DateFormat.date_time, index = false) private Date createdDate; @Nullable public String getId() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java index eec5b4c5c..ff4a34fb9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/SimpleElasticsearchDateMappingTests.java @@ -41,10 +41,10 @@ public class SimpleElasticsearchDateMappingTests extends MappingContextBaseTests private static final String EXPECTED_MAPPING = "{\"properties\":{\"message\":{\"store\":true," + "\"type\":\"text\",\"index\":false,\"analyzer\":\"standard\"},\"customFormatDate\":{\"type\":\"date\",\"format\":\"dd.MM.uuuu hh:mm\"}," - + "\"defaultFormatDate\":{\"type\":\"date\"},\"basicFormatDate\":{\"" + + "\"basicFormatDate\":{\"" + "type\":\"date\",\"format\":\"basic_date\"}}}"; - @Test // DATAES-568 + @Test // DATAES-568, DATAES-828 public void testCorrectDateMappings() { String mapping = getMappingBuilder().buildPropertyMapping(SampleDateMappingEntity.class); @@ -67,8 +67,6 @@ static class SampleDateMappingEntity { @Field(type = Date, format = DateFormat.custom, pattern = "dd.MM.uuuu hh:mm") private LocalDateTime customFormatDate; - @Field(type = FieldType.Date) private LocalDateTime defaultFormatDate; - @Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDateTime basicFormatDate; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 182fb75cd..3d6dec9e0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -173,6 +173,20 @@ void seqNoPrimaryTermPropertyShouldNotBeReadable() { assertThat(seqNoProperty.isReadable()).isFalse(); } + @Test // DATAES-828 + void shouldRequireFormatForDateField() { + assertThatExceptionOfType(MappingException.class) // + .isThrownBy(() -> context.getRequiredPersistentEntity(DateFieldWithNoFormat.class)) // + .withMessageContaining("date"); + } + + @Test // DATAES-828 + void shouldRequireFormatForDateNanosField() { + assertThatExceptionOfType(MappingException.class) // + .isThrownBy(() -> context.getRequiredPersistentEntity(DateNanosFieldWithNoFormat.class)) // + .withMessageContaining("date"); + } + static class InvalidScoreProperty { @Nullable @Score String scoreProperty; } @@ -195,4 +209,12 @@ static class SeqNoPrimaryTermProperty { SeqNoPrimaryTerm seqNoPrimaryTerm; String string; } + + static class DateFieldWithNoFormat { + @Field(type = FieldType.Date) LocalDateTime datetime; + } + + static class DateNanosFieldWithNoFormat { + @Field(type = FieldType.Date_Nanos) LocalDateTime datetime; + } } From 391e240b49a73331e8d6faf75e17b5d437dbae6b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 15 May 2020 21:15:31 +0200 Subject: [PATCH 0167/1191] DATAES-829 - Deprecate AbstractElasticsearchRepository and cleanup SimpleElasticsearchRepository. Original PR: #458 --- .../AbstractElasticsearchRepository.java | 353 +----------------- .../SimpleElasticsearchRepository.java | 331 +++++++++++++++- 2 files changed, 333 insertions(+), 351 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java index 4dcd4a255..a570b138d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/AbstractElasticsearchRepository.java @@ -15,42 +15,7 @@ */ package org.springframework.data.elasticsearch.repository.support; -import static org.elasticsearch.index.query.QueryBuilders.*; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import org.elasticsearch.index.query.IdsQueryBuilder; -import org.elasticsearch.index.query.QueryBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.IndexOperations; -import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.core.SearchHitSupport; -import org.springframework.data.elasticsearch.core.SearchHits; -import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -import org.springframework.data.util.Streamable; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; /** * Elasticsearch specific repository implementation. Likely to be used as target within @@ -59,323 +24,15 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Ryan Henszey - * @author Kevin Leturc - * @author Mark Paluch - * @author Christoph Strobl - * @author Michael Wirth * @author Sascha Woo - * @author Murali Chevuri * @author Peter-Josef Meisch - * @author Aleksei Arsenev + * @deprecated since 4.1, derive from {@link SimpleElasticsearchRepository} instead */ -public abstract class AbstractElasticsearchRepository implements ElasticsearchRepository { - - static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchRepository.class); - - protected ElasticsearchOperations operations; - protected IndexOperations indexOperations; - - protected Class entityClass; - protected @Nullable ElasticsearchEntityInformation entityInformation; +@Deprecated +public abstract class AbstractElasticsearchRepository extends SimpleElasticsearchRepository { public AbstractElasticsearchRepository(ElasticsearchEntityInformation metadata, - ElasticsearchOperations operations) { - this.operations = operations; - - Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); - - this.entityInformation = metadata; - this.entityClass = this.entityInformation.getJavaType(); - this.indexOperations = operations.indexOps(this.entityClass); - try { - if (createIndexAndMapping() && !indexOperations.exists()) { - createIndex(); - putMapping(); - } - } catch (Exception exception) { - LOGGER.warn("Cannot create index: {}", exception.getMessage()); - } - } - - private void createIndex() { - indexOperations.create(); - } - - private void putMapping() { - indexOperations.putMapping(entityClass); - } - - private boolean createIndexAndMapping() { - - final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter().getMappingContext() - .getRequiredPersistentEntity(getEntityClass()); - return entity.isCreateIndexAndMapping(); - } - - @Override - public Optional findById(ID id) { - return Optional.ofNullable(operations.get(stringIdRepresentation(id), getEntityClass(), getIndexCoordinates())); - } - - @Override - public Iterable findAll() { - int itemCount = (int) this.count(); - - if (itemCount == 0) { - return new PageImpl<>(Collections.emptyList()); - } - return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); - } - - @SuppressWarnings("unchecked") - @Override - public Page findAll(Pageable pageable) { - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); - SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); - AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); - return (Page) SearchHitSupport.unwrapSearchHits(page); - } - - @SuppressWarnings("unchecked") - @Override - public Iterable findAll(Sort sort) { - int itemCount = (int) this.count(); - - if (itemCount == 0) { - return new PageImpl<>(Collections.emptyList()); - } - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) - .withPageable(PageRequest.of(0, itemCount, sort)).build(); - List> searchHitList = operations.search(query, getEntityClass(), getIndexCoordinates()) - .getSearchHits(); - return (List) SearchHitSupport.unwrapSearchHits(searchHitList); - } - - @Override - public Iterable findAllById(Iterable ids) { - Assert.notNull(ids, "ids can't be null."); - NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); - return operations.multiGet(query, getEntityClass(), getIndexCoordinates()); - } - - @Override - public long count() { - NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - return operations.count(query, getEntityClass(), getIndexCoordinates()); - } - - @Override - public S save(S entity) { - - Assert.notNull(entity, "Cannot save 'null' entity."); - - operations.save(entity, getIndexCoordinates()); - operations.indexOps(entity.getClass()).refresh(); - return entity; - } - - public List save(List entities) { - - Assert.notNull(entities, "Cannot insert 'null' as a List."); - - return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); - } - - @Override - @Deprecated - public S indexWithoutRefresh(S entity) { - Assert.notNull(entity, "Cannot save 'null' entity."); - operations.save(entity); - return entity; - } - - @Override - public Iterable saveAll(Iterable entities) { - - Assert.notNull(entities, "Cannot insert 'null' as a List."); - - IndexCoordinates indexCoordinates = getIndexCoordinates(); - operations.save(entities, indexCoordinates); - operations.indexOps(indexCoordinates).refresh(); - - return entities; - } - - @Override - public boolean existsById(ID id) { - return operations.exists(stringIdRepresentation(id), getIndexCoordinates()); - } - - @SuppressWarnings("unchecked") - @Override - public Iterable search(QueryBuilder query) { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); - int count = (int) operations.count(searchQuery, getEntityClass(), getIndexCoordinates()); - - if (count == 0) { - return new PageImpl<>(Collections.emptyList()); - } - searchQuery.setPageable(PageRequest.of(0, count)); - SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); - AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); - return (Page) SearchHitSupport.unwrapSearchHits(page); - } - - @SuppressWarnings("unchecked") - @Override - public Page search(QueryBuilder query, Pageable pageable) { - NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); - SearchHits searchHits = operations.search(searchQuery, getEntityClass(), getIndexCoordinates()); - AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); - return (Page) SearchHitSupport.unwrapSearchHits(page); - } - - @SuppressWarnings("unchecked") - @Override - public Page search(Query query) { - SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); - AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); - return (Page) SearchHitSupport.unwrapSearchHits(page); - } - - @SuppressWarnings("unchecked") - @Override - public Page searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) { - - Assert.notNull(entity, "Cannot search similar records for 'null'."); - Assert.notNull(pageable, "'pageable' cannot be 'null'"); - - MoreLikeThisQuery query = new MoreLikeThisQuery(); - query.setId(stringIdRepresentation(extractIdFromBean(entity))); - query.setPageable(pageable); - - if (fields != null) { - query.addFields(fields); - } - - SearchHits searchHits = operations.search(query, getEntityClass(), getIndexCoordinates()); - AggregatedPage> page = SearchHitSupport.page(searchHits, pageable); - return (Page) SearchHitSupport.unwrapSearchHits(page); - } - - @Override - public void deleteById(ID id) { - - Assert.notNull(id, "Cannot delete entity with id 'null'."); - - IndexCoordinates indexCoordinates = getIndexCoordinates(); - doDelete(id, indexCoordinates); - indexOperations.refresh(); - } - - @Override - public void delete(T entity) { - - Assert.notNull(entity, "Cannot delete 'null' entity."); - - IndexCoordinates indexCoordinates = getIndexCoordinates(); - doDelete(extractIdFromBean(entity), indexCoordinates); - indexOperations.refresh(); - } - - @Override - public void deleteAll(Iterable entities) { - - Assert.notNull(entities, "Cannot delete 'null' list."); - - IndexCoordinates indexCoordinates = getIndexCoordinates(); - IdsQueryBuilder idsQueryBuilder = idsQuery(); - for (T entity : entities) { - ID id = extractIdFromBean(entity); - if (id != null) { - idsQueryBuilder.addIds(stringIdRepresentation(id)); - } - } - - if (idsQueryBuilder.ids().isEmpty()) { - return; - } - - Query query = new NativeSearchQueryBuilder().withQuery(idsQueryBuilder).build(); - - operations.delete(query, getEntityClass(), indexCoordinates); - indexOperations.refresh(); - } - - private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { - if (id != null) { - operations.delete(stringIdRepresentation(id), indexCoordinates); - } - } - - @Override - public void deleteAll() { - IndexCoordinates indexCoordinates = getIndexCoordinates(); - Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); - - operations.delete(query, getEntityClass(), indexCoordinates); - indexOperations.refresh(); - } - - @Override - public void refresh() { - indexOperations.refresh(); - } - - @SuppressWarnings("unchecked") - private Class resolveReturnedClassFromGenericType() { - ParameterizedType parameterizedType = resolveReturnedClassFromGenericType(getClass()); - return (Class) parameterizedType.getActualTypeArguments()[0]; - } - - private ParameterizedType resolveReturnedClassFromGenericType(Class clazz) { - Object genericSuperclass = clazz.getGenericSuperclass(); - - if (genericSuperclass instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; - Type rawtype = parameterizedType.getRawType(); - if (SimpleElasticsearchRepository.class.equals(rawtype)) { - return parameterizedType; - } - } - - return resolveReturnedClassFromGenericType(clazz.getSuperclass()); - } - - protected Class getEntityClass() { - - if (!isEntityClassSet()) { - try { - this.entityClass = resolveReturnedClassFromGenericType(); - } catch (Exception e) { - throw new InvalidDataAccessApiUsageException("Unable to resolve EntityClass. Please use according setter!", e); - } - } - return entityClass; - } - - private boolean isEntityClassSet() { - return entityClass != null; - } - - @Nullable - protected ID extractIdFromBean(T entity) { - return entityInformation.getId(entity); - } - - private List stringIdsRepresentation(Iterable ids) { - Assert.notNull(ids, "ids can't be null."); - List stringIds = new ArrayList<>(); - for (ID id : ids) { - stringIds.add(stringIdRepresentation(id)); - } - - return stringIds; - } - - protected abstract @Nullable String stringIdRepresentation(@Nullable ID id); - - private IndexCoordinates getIndexCoordinates() { - return operations.getIndexCoordinatesFor(getEntityClass()); + ElasticsearchOperations elasticsearchOperations) { + super(metadata, elasticsearchOperations); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 006bbded0..5f56a30c9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -15,8 +15,39 @@ */ package org.springframework.data.elasticsearch.repository.support; +import static org.elasticsearch.index.query.QueryBuilders.*; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.elasticsearch.index.query.IdsQueryBuilder; +import org.elasticsearch.index.query.QueryBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.SearchHitSupport; +import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.core.query.Query; +import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; +import org.springframework.data.util.StreamUtils; +import org.springframework.data.util.Streamable; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Elasticsearch specific repository implementation. Likely to be used as target within @@ -25,18 +56,312 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Ryan Henszey + * @author Kevin Leturc + * @author Mark Paluch + * @author Christoph Strobl + * @author Michael Wirth * @author Sascha Woo + * @author Murali Chevuri * @author Peter-Josef Meisch + * @author Aleksei Arsenev */ -public class SimpleElasticsearchRepository extends AbstractElasticsearchRepository { +public class SimpleElasticsearchRepository implements ElasticsearchRepository { + + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleElasticsearchRepository.class); + + protected ElasticsearchOperations operations; + protected IndexOperations indexOperations; + + protected Class entityClass; + protected ElasticsearchEntityInformation entityInformation; public SimpleElasticsearchRepository(ElasticsearchEntityInformation metadata, - ElasticsearchOperations elasticsearchOperations) { - super(metadata, elasticsearchOperations); + ElasticsearchOperations operations) { + this.operations = operations; + + Assert.notNull(metadata, "ElasticsearchEntityInformation must not be null!"); + + this.entityInformation = metadata; + this.entityClass = this.entityInformation.getJavaType(); + this.indexOperations = operations.indexOps(this.entityClass); + try { + if (createIndexAndMapping() && !indexOperations.exists()) { + createIndex(); + putMapping(); + } + } catch (Exception exception) { + LOGGER.warn("Cannot create index: {}", exception.getMessage()); + } + } + + private void createIndex() { + indexOperations.create(); + } + + private void putMapping() { + indexOperations.putMapping(entityClass); + } + + private boolean createIndexAndMapping() { + + final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter().getMappingContext() + .getRequiredPersistentEntity(entityClass); + return entity.isCreateIndexAndMapping(); } @Override + public Optional findById(ID id) { + return Optional.ofNullable( + execute(operations -> operations.get(stringIdRepresentation(id), entityClass, getIndexCoordinates()))); + } + + @Override + public Iterable findAll() { + int itemCount = (int) this.count(); + + if (itemCount == 0) { + return new PageImpl<>(Collections.emptyList()); + } + return this.findAll(PageRequest.of(0, Math.max(1, itemCount))); + } + + @SuppressWarnings("unchecked") + @Override + public Page findAll(Pageable pageable) { + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withPageable(pageable).build(); + SearchHits searchHits = execute(operations -> operations.search(query, entityClass, getIndexCoordinates())); + AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); + } + + @SuppressWarnings("unchecked") + @Override + public Iterable findAll(Sort sort) { + int itemCount = (int) this.count(); + + if (itemCount == 0) { + return new PageImpl<>(Collections.emptyList()); + } + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) + .withPageable(PageRequest.of(0, itemCount, sort)).build(); + List> searchHitList = execute( + operations -> operations.search(query, entityClass, getIndexCoordinates()).getSearchHits()); + return (List) SearchHitSupport.unwrapSearchHits(searchHitList); + } + + @Override + public Iterable findAllById(Iterable ids) { + Assert.notNull(ids, "ids can't be null."); + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); + // noinspection ConstantConditions + return execute(operations -> operations.multiGet(query, entityClass, getIndexCoordinates())); + } + + @Override + public long count() { + NativeSearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + // noinspection ConstantConditions + return execute(operations -> operations.count(query, entityClass, getIndexCoordinates())); + } + + @Override + public S save(S entity) { + + Assert.notNull(entity, "Cannot save 'null' entity."); + + // noinspection ConstantConditions + return executeAndRefresh(operations -> operations.save(entity, getIndexCoordinates())); + } + + public List save(List entities) { + + Assert.notNull(entities, "Cannot insert 'null' as a List."); + + return Streamable.of(saveAll(entities)).stream().collect(Collectors.toList()); + } + + @Override + @Deprecated + public S indexWithoutRefresh(S entity) { + Assert.notNull(entity, "Cannot save 'null' entity."); + // noinspection ConstantConditions + return execute(operations -> operations.save(entity)); + } + + @Override + public Iterable saveAll(Iterable entities) { + + Assert.notNull(entities, "Cannot insert 'null' as a List."); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); + executeAndRefresh(operations -> operations.save(entities, indexCoordinates)); + + return entities; + } + + @Override + public boolean existsById(ID id) { + // noinspection ConstantConditions + return execute(operations -> operations.exists(stringIdRepresentation(id), getIndexCoordinates())); + } + + @SuppressWarnings("unchecked") + @Override + public Iterable search(QueryBuilder query) { + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).build(); + long count = execute(operations -> operations.count(searchQuery, entityClass, getIndexCoordinates())); + + if (count == 0) { + return new PageImpl<>(Collections.emptyList()); + } + searchQuery.setPageable(PageRequest.of(0, (int)count)); + SearchHits searchHits = execute( + operations -> operations.search(searchQuery, entityClass, getIndexCoordinates())); + AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); + } + + @SuppressWarnings("unchecked") + @Override + public Page search(QueryBuilder query, Pageable pageable) { + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(query).withPageable(pageable).build(); + SearchHits searchHits = execute( + operations -> operations.search(searchQuery, entityClass, getIndexCoordinates())); + AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); + } + + @SuppressWarnings("unchecked") + @Override + public Page search(Query query) { + SearchHits searchHits = execute(operations -> operations.search(query, entityClass, getIndexCoordinates())); + AggregatedPage> page = SearchHitSupport.page(searchHits, query.getPageable()); + return (Page) SearchHitSupport.unwrapSearchHits(page); + } + + @SuppressWarnings("unchecked") + @Override + public Page searchSimilar(T entity, @Nullable String[] fields, Pageable pageable) { + + Assert.notNull(entity, "Cannot search similar records for 'null'."); + Assert.notNull(pageable, "'pageable' cannot be 'null'"); + + MoreLikeThisQuery query = new MoreLikeThisQuery(); + query.setId(stringIdRepresentation(extractIdFromBean(entity))); + query.setPageable(pageable); + + if (fields != null) { + query.addFields(fields); + } + + SearchHits searchHits = execute(operations -> operations.search(query, entityClass, getIndexCoordinates())); + AggregatedPage> page = SearchHitSupport.page(searchHits, pageable); + return (Page) SearchHitSupport.unwrapSearchHits(page); + } + + @Override + public void deleteById(ID id) { + + Assert.notNull(id, "Cannot delete entity with id 'null'."); + + doDelete(id, getIndexCoordinates()); + } + + @Override + public void delete(T entity) { + + Assert.notNull(entity, "Cannot delete 'null' entity."); + + doDelete(extractIdFromBean(entity), getIndexCoordinates()); + } + + @Override + public void deleteAll(Iterable entities) { + + Assert.notNull(entities, "Cannot delete 'null' list."); + + IndexCoordinates indexCoordinates = getIndexCoordinates(); + IdsQueryBuilder idsQueryBuilder = idsQuery(); + for (T entity : entities) { + ID id = extractIdFromBean(entity); + if (id != null) { + idsQueryBuilder.addIds(stringIdRepresentation(id)); + } + } + + if (idsQueryBuilder.ids().isEmpty()) { + return; + } + + Query query = new NativeSearchQueryBuilder().withQuery(idsQueryBuilder).build(); + + executeAndRefresh((OperationsCallback) operations -> { + operations.delete(query, entityClass, indexCoordinates); + return null; + }); + } + + private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { + + if (id != null) { + executeAndRefresh(operations -> operations.delete(stringIdRepresentation(id), indexCoordinates)); + } + } + + @Override + public void deleteAll() { + IndexCoordinates indexCoordinates = getIndexCoordinates(); + Query query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); + + executeAndRefresh((OperationsCallback) operations -> { + operations.delete(query, entityClass, indexCoordinates); + return null; + }); + } + + @Override + public void refresh() { + indexOperations.refresh(); + } + + @Nullable + protected ID extractIdFromBean(T entity) { + return entityInformation.getId(entity); + } + + private List stringIdsRepresentation(Iterable ids) { + + Assert.notNull(ids, "ids can't be null."); + + return StreamUtils.createStreamFromIterator(ids.iterator()).map(id -> stringIdRepresentation(id)) + .collect(Collectors.toList()); + } + protected @Nullable String stringIdRepresentation(@Nullable ID id) { return operations.stringIdRepresentation(id); } + + private IndexCoordinates getIndexCoordinates() { + return operations.getIndexCoordinatesFor(entityClass); + } + + // region operations callback + @FunctionalInterface + public interface OperationsCallback { + @Nullable + R doWithOperations(ElasticsearchOperations operations); + } + + @Nullable + public R execute(OperationsCallback callback) { + return callback.doWithOperations(operations); + } + + @Nullable + public R executeAndRefresh(OperationsCallback callback) { + R result = callback.doWithOperations(operations); + refresh(); + return result; + } + // endregion } From 506f79a45aa93ad5787b25d807de5e5970bf0ea3 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 17 May 2020 10:49:50 +0200 Subject: [PATCH 0168/1191] DATAES-831 - SearchOperations.searchForStream does not use requested maxResults. Original PR: #459 --- .../core/AbstractElasticsearchTemplate.java | 4 ++ .../core/ElasticsearchRestTemplate.java | 14 ++++- .../core/ElasticsearchTemplate.java | 7 ++- .../elasticsearch/core/StreamQueries.java | 34 ++++++----- .../core/ElasticsearchTemplateTests.java | 48 +++++++++------- .../elasticsearch/core/StreamQueriesTest.java | 57 ++++++++++++++++++- 6 files changed, 119 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 8f54e6c83..3e809613b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -258,7 +258,11 @@ public SearchHitsIterator searchForStream(Query query, Class clazz, In long scrollTimeInMillis = TimeValue.timeValueMinutes(1).millis(); + // noinspection ConstantConditions + int maxCount = query.isLimiting() ? query.getMaxResults() : 0; + return StreamQueries.streamResults( // + maxCount, // searchScrollStart(scrollTimeInMillis, query, clazz, index), // scrollId -> searchScrollContinue(scrollId, scrollTimeInMillis, clazz, index), // this::searchScrollClear); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 0e4347a42..8a1eeaa71 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -40,6 +40,8 @@ import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.suggest.SuggestBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; @@ -88,6 +90,8 @@ */ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { + private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); + private RestHighLevelClient client; private ElasticsearchExceptionTranslator exceptionTranslator; @@ -300,9 +304,13 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l @Override public void searchScrollClear(List scrollIds) { - ClearScrollRequest request = new ClearScrollRequest(); - request.scrollIds(scrollIds); - execute(client -> client.clearScroll(request, RequestOptions.DEFAULT)); + try { + ClearScrollRequest request = new ClearScrollRequest(); + request.scrollIds(scrollIds); + execute(client -> client.clearScroll(request, RequestOptions.DEFAULT)); + } catch (Exception e) { + LOGGER.warn("Could not clear scroll: {}", e.getMessage()); + } } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 1a58eed4b..c09827f79 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -86,6 +86,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate { private static final Logger QUERY_LOGGER = LoggerFactory .getLogger("org.springframework.data.elasticsearch.core.QUERY"); + private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchTemplate.class); private Client client; @Nullable private String searchTimeout; @@ -322,7 +323,11 @@ public SearchScrollHits searchScrollContinue(@Nullable String scrollId, l @Override public void searchScrollClear(List scrollIds) { - client.prepareClearScroll().setScrollIds(scrollIds).execute().actionGet(); + try { + client.prepareClearScroll().setScrollIds(scrollIds).execute().actionGet(); + } catch (Exception e) { + LOGGER.warn("Could not clear scroll: {}", e.getMessage()); + } } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java index 866eefdc4..12f605755 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/StreamQueries.java @@ -18,6 +18,7 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Function; @@ -38,13 +39,15 @@ abstract class StreamQueries { /** * Stream query results using {@link SearchScrollHits}. * + * @param maxCount the maximum number of entities to return, a value of 0 means that all available entities are + * returned * @param searchHits the initial hits * @param continueScrollFunction function to continue scrolling applies to the current scrollId. * @param clearScrollConsumer consumer to clear the scroll context by accepting the scrollIds to clear. - * @param + * @param the entity type * @return the {@link SearchHitsIterator}. */ - static SearchHitsIterator streamResults(SearchScrollHits searchHits, + static SearchHitsIterator streamResults(int maxCount, SearchScrollHits searchHits, Function> continueScrollFunction, Consumer> clearScrollConsumer) { Assert.notNull(searchHits, "searchHits must not be null."); @@ -59,20 +62,14 @@ static SearchHitsIterator streamResults(SearchScrollHits searchHits, return new SearchHitsIterator() { - // As we couldn't retrieve single result with scroll, store current hits. - private volatile Iterator> scrollHits = searchHits.iterator(); - private volatile boolean continueScroll = scrollHits.hasNext(); + private volatile AtomicInteger currentCount = new AtomicInteger(); + private volatile Iterator> currentScrollHits = searchHits.iterator(); + private volatile boolean continueScroll = currentScrollHits.hasNext(); private volatile ScrollState scrollState = new ScrollState(searchHits.getScrollId()); @Override public void close() { - - try { - clearScrollConsumer.accept(scrollState.getScrollIds()); - } finally { - scrollHits = null; - scrollState = null; - } + clearScrollConsumer.accept(scrollState.getScrollIds()); } @Override @@ -99,24 +96,25 @@ public TotalHitsRelation getTotalHitsRelation() { @Override public boolean hasNext() { - if (!continueScroll) { + if (!continueScroll || (maxCount > 0 && currentCount.get() >= maxCount)) { return false; } - if (!scrollHits.hasNext()) { + if (!currentScrollHits.hasNext()) { SearchScrollHits nextPage = continueScrollFunction.apply(scrollState.getScrollId()); - scrollHits = nextPage.iterator(); + currentScrollHits = nextPage.iterator(); scrollState.updateScrollId(nextPage.getScrollId()); - continueScroll = scrollHits.hasNext(); + continueScroll = currentScrollHits.hasNext(); } - return scrollHits.hasNext(); + return currentScrollHits.hasNext(); } @Override public SearchHit next() { if (hasNext()) { - return scrollHits.next(); + currentCount.incrementAndGet(); + return currentScrollHits.next(); } throw new NoSuchElementException(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 1b38cf408..53154cc50 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -77,7 +77,7 @@ import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; -import org.springframework.data.util.CloseableIterator; +import org.springframework.data.util.StreamUtils; import org.springframework.lang.Nullable; /** @@ -1298,27 +1298,33 @@ public void shouldReturnResultsWithScanAndScrollForGivenSearchQueryAndClass() { assertThat(sampleEntities).hasSize(30); } - @Test // DATAES-167 - public void shouldReturnResultsWithStreamForGivenCriteriaQuery() { + @Test // DATAES-167, DATAES-831 + public void shouldReturnAllResultsWithStreamForGivenCriteriaQuery() { - // given - List entities = createSampleEntitiesWithMessage("Test message", 30); + operations.bulkIndex(createSampleEntitiesWithMessage("Test message", 30), index); + indexOperations.refresh(); + CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); + criteriaQuery.setPageable(PageRequest.of(0, 10)); - // when - operations.bulkIndex(entities, index); + long count = StreamUtils + .createStreamFromIterator(operations.searchForStream(criteriaQuery, SampleEntity.class, index)).count(); + + assertThat(count).isEqualTo(30); + } + + @Test // DATAES-831 + void shouldLimitStreamResultToRequestedSize() { + + operations.bulkIndex(createSampleEntitiesWithMessage("Test message", 30), index); indexOperations.refresh(); - // then CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); - criteriaQuery.setPageable(PageRequest.of(0, 10)); + criteriaQuery.setMaxResults(10); - CloseableIterator> stream = operations.searchForStream(criteriaQuery, SampleEntity.class, - index); - List> sampleEntities = new ArrayList<>(); - while (stream.hasNext()) { - sampleEntities.add(stream.next()); - } - assertThat(sampleEntities).hasSize(30); + long count = StreamUtils + .createStreamFromIterator(operations.searchForStream(criteriaQuery, SampleEntity.class, index)).count(); + + assertThat(count).isEqualTo(10); } private static List createSampleEntitiesWithMessage(String message, int numberOfEntities) { @@ -3128,8 +3134,8 @@ void multiSearchShouldReturnSeqNoPrimaryTerm() { operations.refresh(OptimisticEntity.class); List queries = singletonList(queryForOne(saved.getId())); - List> retrievedHits = operations.multiSearch(queries, - OptimisticEntity.class, operations.getIndexCoordinatesFor(OptimisticEntity.class)); + List> retrievedHits = operations.multiSearch(queries, OptimisticEntity.class, + operations.getIndexCoordinatesFor(OptimisticEntity.class)); OptimisticEntity retrieved = retrievedHits.get(0).getSearchHit(0).getContent(); assertThatSeqNoPrimaryTermIsFilled(retrieved); @@ -3162,8 +3168,7 @@ void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnEnt operations.save(forEdit1); forEdit2.setMessage("It'll be great"); - assertThatThrownBy(() -> operations.save(forEdit2)) - .isInstanceOf(OptimisticLockingFailureException.class); + assertThatThrownBy(() -> operations.save(forEdit2)).isInstanceOf(OptimisticLockingFailureException.class); } @Test // DATAES-799 @@ -3179,8 +3184,7 @@ void shouldThrowOptimisticLockingFailureExceptionWhenConcurrentUpdateOccursOnVer operations.save(forEdit1); forEdit2.setMessage("It'll be great"); - assertThatThrownBy(() -> operations.save(forEdit2)) - .isInstanceOf(OptimisticLockingFailureException.class); + assertThatThrownBy(() -> operations.save(forEdit2)).isInstanceOf(OptimisticLockingFailureException.class); } @Test // DATAES-799 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java index f55c18309..51cc2589f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java @@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.junit.jupiter.api.Test; +import org.springframework.data.util.StreamUtils; /** * @author Sascha Woo @@ -45,6 +46,7 @@ public void shouldCallClearScrollOnIteratorClose() { // when SearchHitsIterator iterator = StreamQueries.streamResults( // + 0, // searchHits, // scrollId -> newSearchScrollHits(Collections.emptyList(), scrollId), // scrollIds -> clearScrollCalled.set(true)); @@ -70,6 +72,7 @@ public void shouldReturnTotalHits() { // when SearchHitsIterator iterator = StreamQueries.streamResults( // + 0, // searchHits, // scrollId -> newSearchScrollHits(Collections.emptyList(), scrollId), // scrollId -> {}); @@ -90,10 +93,12 @@ void shouldClearAllScrollIds() { Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); - Iterator> searchScrollHitsIterator = Arrays.asList(searchHits1, searchHits2, searchHits3,searchHits4).iterator(); + Iterator> searchScrollHitsIterator = Arrays + .asList(searchHits1, searchHits2, searchHits3, searchHits4).iterator(); List clearedScrollIds = new ArrayList<>(); SearchHitsIterator iterator = StreamQueries.streamResults( // + 0, // searchScrollHitsIterator.next(), // scrollId -> searchScrollHitsIterator.next(), // scrollIds -> clearedScrollIds.addAll(scrollIds)); @@ -106,6 +111,56 @@ void shouldClearAllScrollIds() { assertThat(clearedScrollIds).isEqualTo(Arrays.asList("s-1", "s-2", "s-3")); } + @Test // DATAES-831 + void shouldReturnAllForRequestedSizeOf0() { + + SearchScrollHits searchHits1 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + SearchScrollHits searchHits2 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits3 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); + + Iterator> searchScrollHitsIterator = Arrays + .asList(searchHits1, searchHits2, searchHits3, searchHits4).iterator(); + + SearchHitsIterator iterator = StreamQueries.streamResults( // + 0, // + searchScrollHitsIterator.next(), // + scrollId -> searchScrollHitsIterator.next(), // + scrollIds -> {}); + + long count = StreamUtils.createStreamFromIterator(iterator).count(); + + assertThat(count).isEqualTo(3); + } + + @Test // DATAES-831 + void shouldOnlyReturnRequestedCount() { + + SearchScrollHits searchHits1 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + SearchScrollHits searchHits2 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits3 = newSearchScrollHits( + Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); + + Iterator> searchScrollHitsIterator = Arrays + .asList(searchHits1, searchHits2, searchHits3, searchHits4).iterator(); + + SearchHitsIterator iterator = StreamQueries.streamResults( // + 2, // + searchScrollHitsIterator.next(), // + scrollId -> searchScrollHitsIterator.next(), // + scrollIds -> {}); + + long count = StreamUtils.createStreamFromIterator(iterator).count(); + + assertThat(count).isEqualTo(2); + } + private SearchScrollHits newSearchScrollHits(List> hits, String scrollId) { return new SearchHitsImpl(hits.size(), TotalHitsRelation.EQUAL_TO, 0, scrollId, hits, null); } From b439acac16f4cc6f3fada29b8d7f91f2a8310818 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 17 May 2020 19:22:25 +0200 Subject: [PATCH 0169/1191] DATAES-832 - findAllById repository method returns iterable with null elements for not found ids. #Original PR: #460 --- .../SimpleElasticsearchRepository.java | 7 ++-- .../SimpleElasticsearchRepositoryTests.java | 37 +++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 5f56a30c9..9df48f143 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -153,8 +154,8 @@ public Iterable findAll(Sort sort) { public Iterable findAllById(Iterable ids) { Assert.notNull(ids, "ids can't be null."); NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); - // noinspection ConstantConditions - return execute(operations -> operations.multiGet(query, entityClass, getIndexCoordinates())); + return execute(operations1 -> operations1.multiGet(query, entityClass, getIndexCoordinates())).stream() + .filter(Objects::nonNull).collect(Collectors.toList()); } @Override @@ -214,7 +215,7 @@ public Iterable search(QueryBuilder query) { if (count == 0) { return new PageImpl<>(Collections.emptyList()); } - searchQuery.setPageable(PageRequest.of(0, (int)count)); + searchQuery.setPageable(PageRequest.of(0, (int) count)); SearchHits searchHits = execute( operations -> operations.search(searchQuery, entityClass, getIndexCoordinates())); AggregatedPage> page = SearchHitSupport.page(searchHits, searchQuery.getPageable()); diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 284fa8f66..7af26b0f3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -25,12 +25,14 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.io.IOException; import java.lang.Long; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -56,6 +58,7 @@ import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories; import org.springframework.data.elasticsearch.utils.IndexInitializer; +import org.springframework.data.util.StreamUtils; import org.springframework.test.context.ContextConfiguration; /** @@ -361,6 +364,14 @@ public void shouldReturnResultsForGivenSearchQuery() { @Test public void shouldDeleteAll() { + // given + String documentId = randomNumeric(5); + SampleEntity sampleEntity = new SampleEntity(); + sampleEntity.setId(documentId); + sampleEntity.setMessage("hello world."); + sampleEntity.setVersion(System.currentTimeMillis()); + repository.save(sampleEntity); + // when repository.deleteAll(); @@ -677,6 +688,32 @@ public void shouldNotFailOnIndexingEmptyList() { assertThat(savedEntities).hasSize(0); } + @Test // DATAES-832 + void shouldNotReturnNullValuesInFindAllById() throws IOException { + + // given + String documentId1 = "id-one"; + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId1); + repository.save(sampleEntity1); + String documentId2 = "id-two"; + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + repository.save(sampleEntity2); + String documentId3 = "id-three"; + SampleEntity sampleEntity3 = new SampleEntity(); + sampleEntity3.setId(documentId3); + repository.save(sampleEntity3); + + Iterable allById = repository + .findAllById(Arrays.asList("id-one", "does-not-exist", "id-two", "where-am-i", "id-three")); + List results = StreamUtils.createStreamFromIterator(allById.iterator()).collect(Collectors.toList()); + + assertThat(results).hasSize(3); + assertThat(results.stream().map(SampleEntity::getId).collect(Collectors.toList())) + .containsExactlyInAnyOrder("id-one", "id-two", "id-three"); + } + private static List createSampleEntitiesWithMessage(String message, int numberOfEntities) { List sampleEntities = new ArrayList<>(); From 49f1516b9eed49d5fcae2d1846eaf404bf4654c2 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 18 May 2020 17:52:34 +0200 Subject: [PATCH 0170/1191] DATAES-832 - findAllById repository method returns iterable with null elements for not found ids. --- .../SimpleElasticsearchRepository.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 9df48f143..9fd0e7e2d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -17,9 +17,9 @@ import static org.elasticsearch.index.query.QueryBuilders.*; +import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -152,10 +152,23 @@ public Iterable findAll(Sort sort) { @Override public Iterable findAllById(Iterable ids) { + Assert.notNull(ids, "ids can't be null."); + NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(stringIdsRepresentation(ids)).build(); - return execute(operations1 -> operations1.multiGet(query, entityClass, getIndexCoordinates())).stream() - .filter(Objects::nonNull).collect(Collectors.toList()); + List result = new ArrayList<>(); + List multiGetEntities = execute(operations -> operations.multiGet(query, entityClass, getIndexCoordinates())); + + if (multiGetEntities != null) { + multiGetEntities.forEach(entity -> { + + if (entity != null) { + result.add(entity); + } + }); + } + + return result; } @Override From 75a430d431d1e9ba4ff6b27aac4094acb03128f2 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 19 May 2020 19:36:35 +0200 Subject: [PATCH 0171/1191] DATAES-833 - Documentation fix for custom date formats. Original PR: #461 --- src/main/asciidoc/reference/elasticsearch-object-mapping.adoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index 7e7496e7f..fe1a90bd2 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -48,6 +48,8 @@ The following annotations are available: ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. +NOTE: If you are using a custom date format, you need to use _uuuu_ for the year instead of _yyyy_. This is due to a https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats[change in Elasticsearch 7]. + The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic. [[elasticsearch.mapping.meta-model.rules]] From 2875c62cfe4fee1cd61d6099c954326954b05c43 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 20 May 2020 08:41:59 +0200 Subject: [PATCH 0172/1191] DATAES-835 - Fix code sample in documentation for scroll API. Original PR: #462 --- src/main/asciidoc/reference/elasticsearch-misc.adoc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index 9df0d064f..112d750c5 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -35,8 +35,6 @@ IndexCoordinates index = IndexCoordinates.of("sample-index"); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) - .withIndices(INDEX_NAME) - .withTypes(TYPE_NAME) .withFields("message") .withPageable(PageRequest.of(0, 10)) .build(); @@ -62,8 +60,6 @@ IndexCoordinates index = IndexCoordinates.of("sample-index"); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) - .withIndices(INDEX_NAME) - .withTypes(TYPE_NAME) .withFields("message") .withPageable(PageRequest.of(0, 10)) .build(); From d8d3f9431be7ccb809100056d01a92da1967c068 Mon Sep 17 00:00:00 2001 From: jinwook han Date: Wed, 20 May 2020 23:39:08 +0900 Subject: [PATCH 0173/1191] DATAES-836 - Fix typo in Javadoc. Original PR: #463 --- .../data/elasticsearch/annotations/DynamicTemplates.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicTemplates.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicTemplates.java index aa831c787..d2cea3f39 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicTemplates.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DynamicTemplates.java @@ -12,7 +12,7 @@ * Elasticsearch dynamic templates mapping. * This annotation is handy if you prefer apply dynamic templates on fields with annotation e.g. {@link Field} * with type = FieldType.Object etc. instead of static mapping on Document via {@link Mapping} annotation. - * DynamicTemplates annotation is ommited if {@link Mapping} annotation is used. + * DynamicTemplates annotation is omitted if {@link Mapping} annotation is used. * * @author Petr Kukral */ From bcd7c2a1d88b79da5eb1c87c155b57e4548f9b4a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 21 May 2020 06:47:39 +0200 Subject: [PATCH 0174/1191] DATAES-838 - Update to Elasticsearch 7.7.0. Original PR: #465 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 5 +++-- ...on-7.6.2.jar => analysis-common-7.7.0.jar} | Bin 198567 -> 198660 bytes .../plugin-descriptor.properties | 4 ++-- ....2.jar => elasticsearch-dissect-7.7.0.jar} | Bin 24704 -> 24682 bytes ...7.6.2.jar => elasticsearch-grok-7.7.0.jar} | Bin 33793 -> 33951 bytes ...mmon-7.6.2.jar => ingest-common-7.7.0.jar} | Bin 115433 -> 115859 bytes .../plugin-descriptor.properties | 4 ++-- .../lang-expression/lang-expression-7.6.2.jar | Bin 66049 -> 0 bytes .../lang-expression/lang-expression-7.7.0.jar | Bin 0 -> 65739 bytes ...8.4.0.jar => lucene-expressions-8.5.1.jar} | Bin 73069 -> 73343 bytes .../plugin-descriptor.properties | 4 ++-- ...icsearch-scripting-painless-spi-7.7.0.jar} | Bin 27879 -> 27844 bytes ...less-7.6.2.jar => lang-painless-7.7.0.jar} | Bin 558853 -> 561382 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- ...url-7.6.2.jar => repository-url-7.7.0.jar} | Bin 14744 -> 14716 bytes 19 files changed, 18 insertions(+), 17 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.6.2.jar => analysis-common-7.7.0.jar} (79%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.6.2.jar => elasticsearch-dissect-7.7.0.jar} (86%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.6.2.jar => elasticsearch-grok-7.7.0.jar} (58%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.6.2.jar => ingest-common-7.7.0.jar} (67%) delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.2.jar create mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.7.0.jar rename src/test/resources/test-home-dir/modules/lang-expression/{lucene-expressions-8.4.0.jar => lucene-expressions-8.5.1.jar} (72%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.6.2.jar => elasticsearch-scripting-painless-spi-7.7.0.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.6.2.jar => lang-painless-7.7.0.jar} (62%) rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.6.2.jar => repository-url-7.7.0.jar} (81%) diff --git a/pom.xml b/pom.xml index 1a722c913..a9a71063e 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.6.2 + 7.7.0 2.9.1 2.4.0-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 565700526..877dcd679 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -36,8 +36,9 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Neumannfootnote:cdv[Currently in development] |4.0.xfootnote:cdv[]|7.6.2 |2.3.xfootnote:cdv[] -| Moore | 3.2.x |6.8.6 | 2.2.x +| Ockhamfootnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.7.0 |2.3.xfootnote:cdv[] +| Neumann | 4.0.x | 7.6.2 |2.3.x +| Moore | 3.2.x |6.8.9 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] | Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.2.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.0.jar similarity index 79% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.6.2.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.0.jar index 1c948e374783b48477c8797fc37a4dc2b7d6613e..1d640598f10586a4926c7ca164d7381c9c410105 100644 GIT binary patch delta 27856 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 tI|~qMRRJ!-B#fj0qfbd}klJv?3sj<$vxPFi8La delta 28029 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 CK#xHH diff --git a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties index 6f7a0f23f..73c64397a 100644 --- a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds "built in" analyzers to Elasticsearch. # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=analysis-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.6.2.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.7.0.jar similarity index 86% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.6.2.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.7.0.jar index 03d1fd85e8d0ffb249ae808c7654abd23f404cff..49829eaa381369a092d7f56adb4127671eb326a2 100644 GIT binary patch delta 1320 zcmZoT$oT32BX58=GYc030|y5~u)vy$ylT8aDxmoIhZ%v43=BaN9i;0^gHHP$HW1k3 ze#+kE5tEZy*)6q$F#*vn8f&XES_QVN-dr+G$a>RUu77fu*?k3NYCfEKbEfJEt48Fa z(kHCFQ=>XNg2mYUeWR0`Pc?p4i1ZF$+_7b)#sAP-?hFqHn$@MJ)dqcvVJ1hW=MRQd{nQQe?5C$*^CV@iZT_}8_vqO{OYe+ z`0*8zISa!ln@7G_^!c2(vi8e`Uc0L6&F)&CEmh{bduL9m%iaUa^BqF#-uEyckJd?0 zINXxnTqMGO$;A6nVvw3^pX(fkbdFSsJ(D`~qF!E>JE!$O_LZmk`=XG&>FFgdKmWUF zv#!0Hp}t5ctGo80luv8lnPuni?^k{utbKQ;Om&Dv4I?7ZBly>BKF>IZpE-S9dQs{ z_oAhlrilQh)F&&&NGX6^)9}Yd%pT~RPs|JqK##$}md4{UK!tibXvPOLT}dr^&c?tH z0}Ki+xN-)DEsX*4Kn-e>KM1i+=8lF~_z&oodNr_H_B#WGJw+!+#`AzJes|WeA_r*k z5};X@DCWd!f;IfJl9=ol3o%Cu=x_xcu<+bi&dJHqLf}x4NswkbstZ-kJ~<$Q9V0Ym z$4E2n&;u)3r^$mM9UCjn#NhxnSQYHB8;u7<-vc9NHxIhQ1f9SN_d82Wejf+%h4;_L zR~7(Em#;vdp!y=*9cn7qWd1lvSaVJ2W_<}%D8|mfV1eRgKToL1Jd@8#b5A}W4Kdw* ziOkN)oD2*HCD0?M*9WSBbuxPbBrxoOKFtaP3)jc+i?9O26=)R@<^rvI9s%M30N84$ A{r~^~ delta 1313 zcmaELfU)5qBX58=GYc030|y5~zDdxy(n28IO_9i;202A%dhY#^}5 z{gl1SBPOS^xmHV7?pz?&Qn9ifB7AG|l*vQ)R9nO%O*W^3blUzsyP z7k_>txHj0WTV<(EU*5FUeA8Fh{s>Uverhe!xsmrM-<yQg4ku6?WyksAfCRmLvUT;F_f!i1dv#vfgl zrR@wlc%Lb!dETA4d$l?HZnR(H|1G-9D&qI|qwjvbtM07Q|J9TxzyG!VqMdD1vwOuo zdFLLs=vrKkh>CvWs(>w99<}B2GcasE#5kFsxy`t0a)jV6W&@L|$)ZAvVA@hhA53Qp znS8PHsAXp|#^8gc=A?m;e zVWhZ!ff%z?=r@ER=j6-^R@0+)8=~flOdEtT%jXuSAke@7@zid;Wef}q?}1o<@pwB1gM@lmun%o_!4EFU#ATM$9*+`{8 zkm*1}8JIu>5U@ZfASuA`*HKQ0fg!&rT|dAZVGp_vpb{tm>2R9t5Tz)Ou0{%`1Z--_ zY2^c;;$8s; z24fTr2j##T!lUKD3K>uSiZuk9{EnG{K@UaYCpDttAK^pL;+Pg!c~5Yk^>7@0#!CRgM|Z}B>2%>J6Q`DuE#u}(rl9pVidu? zZ}{UPW)F1RC!p_jP~5h}8?1Oov^d!KweiwSx_(gotdmpXguud)vC>Rj5kO(X$sq{> KY=0v_W&i+SPN+cu diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.6.2.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.7.0.jar similarity index 58% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.6.2.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.7.0.jar index 3a6c09d133d3e089b43eced5de4146c723d64de4..2aa562f45caeaf5aa9760566ef0a4cd85b725cf0 100644 GIT binary patch delta 11649 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 delta 11491 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 delta 30169 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 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties index 775c286a5..8027c72e7 100644 --- a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=ingest-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.2.jar b/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.6.2.jar deleted file mode 100644 index 6e8acfc35cf50910fa47cd001ebbaaca634b3540..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66049 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
LA-qb&}zKnHhl`W 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 diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties index 615f4d45c..ea4de483a 100644 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Lucene expressions integration for Elasticsearch # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=lang-expression @@ -35,7 +35,7 @@ classname=org.elasticsearch.script.expression.ExpressionPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.7.0.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.6.2.jar rename to src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.7.0.jar index 6e4f6e6c79e1cb510949b79f65d6d5c120ff0d76..bfc3994b2b8151bef4c42704086d401852cc016a 100644 GIT binary patch delta 1425 zcmaEUlkvz+M&1B#W)?061`ZB}Ab~X#dDVDJ}oW1%ssAglIl0J z3b)JNYgryn`FYRzw&{&Un-XLta+c%<2;^#Y@qP(=X4`Z!`ea~mCug^))%(=l zmV0qiL0UScPqxZ&$)<>zb3b|1pS5GT*~C26*6Fp+gry;ef6Hk!u|{n7J>ev_A@jgt zUT)UMN?sXfoaSu`zrWi&z@(z9|K*YI&)Dv!Y&`v7^63+2{gT|yU1$5mb~0wR-}~)5 zE!=DmiMidim^@XF?fD+FOR;($s&Cg;fBoQAe7DQlHrzhDh-rFU^Qt@dG}-&EM>xcF z8Tv0Sl5+E$bnKyu-eaZXNHSNr^etGHLv9kSMwlAkS_hproc`cvvKYxnm zi(gUEj$Rp6GTi0~T3Zf2e)RIS_mX6-%grYXU4GtEM+A8U|C-IW80YXahw-nOTq(GV zSxI2cWHTW}FdZeN52kyBEWq?}AsZ0ASuS`rE11D1yaLRayg=CQTHM< zn8Bm23SrnAXRv@pUMb5%L|P5ELlm269f2@bnNNeL>5bE6<%T5-kdJld$YwSTLwLXSSv9f;<8{lFIGN~`rFquw#AAvFt8d=78KUo zTw{|h%FDj#VqnNGO4kqYM%a$71E>TFKsvN03#KZ{ zqpOjIDFK@rGdVC-3*__3b*a*f(}6s>$q8C4llP?ZfOW1^Uv3`E%D^y{hk?Nsu9Jab zOXD@T+VfeQlYeDHV*GTfG*gSjWX2%H$sl2SVV=oyX*^&H{-jAW>QCO7rZoA2GB-b( zHzx1OkY=m|%Rb2DojgBXVDi!oA+SEJOlc;4g~^5KI+OFYL?-F+Ox~RiG4WKoG!wH5 zP)2X^+f0ecx)~B+4N_UsOxo&T4OPbSAk_+>KuEp%u3--_Y%c-57W@J@T8`f{~IuY&F5xdutahGOb@umJ880DtKI^g|I8OITw}u{ U7U0dw2GS-8f}FtgkqqJi0Ef`K4gdfE delta 1496 zcmX?dlkxdYM&1B#W)?061`ZB}Jd>)4ylT8aDxlKWH>Ze^fnm`^2kH8$K^yaK8wlKG zeId_Lk{K{znvd(Wn@c-{MSO)THUzTV^t!RllATW?@7lyySF&A^X>Wm?(Spj zd(Bs6+fLLk;J+1lv}oeeliLf8EEe?&tUU4EN-E^c&$tDR0;R$NHO3t$&+OeMe`tyQ zdKb-U@2%of;~%V!oPDCa<(#8oZoTrie+O(F!}p6+Gilwb(8?|Ex|?bJ-$pE|j(6f6 zoz1Doj89H~YNtI_XG%=x)m;(dpA3EXRb}w*>(y`dncVCCDu>^=NYiLyebnauX#QTu zZH0A3?)u`(9k+jANk2K^$lmPqOLuqPG=Gw4DEBTg@xZqlrrei8VpEQ5m%cW2T@q2h z{;{~#;h64Yy{}Y{ADv$*)R@Dk;`Zouz~NTC+3J)>1Q&o+Ps}{4nK37anN445XLeOFEC@Wjhs7JX0f(BGngTuq6%Tu8ysN-i?qpY zhA?atE<&V^>TQRJSg2>PfYrDeO@lB#`z{gXhNU5p-8URHA!;8Bt%lewZnF=O zt8SFp@74FIV(je|$l_AY^7beU*`GK~~y6m>(Sm$(bdEHWnGIN4$BzdiRm{oQUwH#)MHtY-W++xY4Fp@o z;Uqq}HX9O*E7g~q2Lpp}Dli$?q9_&&2HWsHRT1m~DY>#`1we&dd<+c6C<^yS02OLa t=Fb)bD?GU9YvpsGPvd|I0##u{9N5IQS-c{wY#<{fL6DPyVMj8E2LSbK$BqC1 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.0.jar similarity index 62% rename from src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.6.2.jar rename to src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.0.jar index 34e9474468b55533fb520697e8cd6aa168374e85..c75bafd082199a9b90bd3720cb58e7f1f9b21e1c 100644 GIT binary patch delta 197028 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 ral!?&YT;&6wUau72iWvmr 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

IL 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 xgz{ZoWf1= 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

sGckqQt^}G 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties index b5bb4c414..0d10e4fbf 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=An easy, safe and fast scripting language for Elasticsearch # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=lang-painless @@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties index 14a39cb7b..4a465f180 100644 --- a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds advanced field mappers # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=mapper-extras @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties index 2f51173a5..f6c396bb7 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=The Reindex module adds APIs to reindex from one index to another or update documents in place. # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=reindex @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties index cec2d76a4..c795e9bf2 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for URL repository # # 'version': plugin's version -version=7.6.2 +version=7.7.0 # # 'name': the plugin name name=repository-url @@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.6.2 +elasticsearch.version=7.7.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.2.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.0.jar similarity index 81% rename from src/test/resources/test-home-dir/modules/repository-url/repository-url-7.6.2.jar rename to src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.0.jar index 99a221f2a2bc80ce4ca801e7a34ebfb50c38591f..f0d3452c14cf8adb755e3c034fa01bb284654e5f 100644 GIT binary patch delta 1091 zcmbPH{HKUFz?+$ci-CcIgCSgC%|u=`ULX~~y+Ck(7$XBi&_oC6`qH4&euoVN_PC$2 zk9fr7WL9=b?O==mtD;vR|5|}Z+f-&>nUw9`*ZbmrvRtdeg9oS2ygBpkM0r9;ck}Y^ zFW6FhRhmAU?7aC+YI}yw4~|P)KS`->T$j8e@xv-PftbCCd->)XvGY}1YvkYUV_SaS zE9_t5r>P%2<5`y4#=4sEOwy=-ys`NGDcjPGlb=W`W&DwgTBj1JAslDd&=%L!-<@jn zc#8kZ6W44e$DG)c!g}82sQl$8w;UILwBDC6*<_|=&*Zb!Z8Kz^7nTJT6zwPp$W}3a zUG;n8*^72reCG{TY0kQHQ_bc1(%_9Oo>ouKKfc|f9(H@}pPW}u(vt%PE}JLp+L2nW z>hM6*EFe*F)tvQ5Tr|TC)petE~3#sr@Z`bwDxo|{U2yU_H6Aec zu9^#2or=05E12P-v!0zBDY7Rgswq$QS7e_os|eAdqv#0MS)k|&*04iy9t$rclL#|B zeN1LCF+oirlU+?rnSt(~Tx%lDxN-7K6J@X`_5*nVlW&_Sfee~tDs93m#K4eWl&&A( zjbdN`0}wEQ2p|9|fdT=BzmA4NlP8*q=-|^J4^z(o(vS?+F!_Ti@8k`p5FhO~m1bH5 z6P5*gPQXl>=_yP|aB`5DygVqygG_?CLlVWuU3kXJ=rj1A5mMZW9B;md1^0AVYx)WhS@l z@Z@?#chmAa3S0mu7ka6UH<;>h|H^UMvg@F1!p3 cjwo(2(1)6(CBn)Ek`V&JURDN%o5mm>0A&hV3IG5A delta 1245 zcmexUG^3a|z?+$ci-CcIgQ3)?L|)kFvB`l&&u^KKgm?BTv( zFYscitK%#q(a1D?*Ex$aW*uOccD!)gE6S5aBj|y0#=m_%vg&-7F$AmX8u)QIo8SET=RIr8TR(gU$r8> zdn~>jAGRjxbh(N?*ZB{rAy)MlVx1OGcbVDHY+W*M!D)9-IR#N)i>ceJJ@ck??(c8y zi*xiiHm&BQrg%x@+e%ee&7)mwuRYx*vj5YY-OYZFSJxbMnU^cG?Bu%zfgHyoKUVtM z<;iZ5I(cl@O}V`_R-Cbindh`l(a6gc7k+=v?YbI&_sfFs-P;rQe94{b73gWSqW**F zTtl-pTPN3?EBEA-63^hP~L zF#T1}6+~~g)t|@0jg&4XSLi8EzF@}A&&+^u8OR+1iVk3n!HOkPDwFfLu5^ zL7#oHzXcCCz~d~W8RaJ@nu`KOg)p450Vtacl@-%Qb7(-+?ZdylfT89BOc;)Ei$Jbf z4b`KM;RBE|Sb(ECE<_FNIAH3SJi!d&I8aFR!h~hP?)?B1x&RXrG$<{~!HA*YM#0Nx xfzGPqW?-;HahA9`)C$4L=M=>z&ozfwv&LMS$yx_4_0C*oa)u=z+gD?dW&lB1c^m)$ From dc6734db4391f236aeb11600204db28fe570fb34 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 21 May 2020 12:29:00 +0200 Subject: [PATCH 0175/1191] DATAES-839 - ReactiveElasticsearchTemplate should use RequestFactory. Original PR: #466 --- .../elasticsearch/BulkFailureException.java | 37 ++++ .../UncategorizedElasticsearchException.java | 1 + .../core/AbstractElasticsearchTemplate.java | 4 +- .../core/ElasticsearchRestTemplate.java | 2 +- .../core/ReactiveElasticsearchTemplate.java | 194 +++--------------- .../elasticsearch/core/RequestFactory.java | 7 + 6 files changed, 82 insertions(+), 163 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java diff --git a/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java b/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java new file mode 100644 index 000000000..7c07fe88c --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/BulkFailureException.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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; + +import org.springframework.dao.DataRetrievalFailureException; + +import java.util.Map; + +/** + * @author Peter-Josef Meisch + * @since 4.1 + */ +public class BulkFailureException extends DataRetrievalFailureException { + private final Map failedDocuments; + + public BulkFailureException(String msg, Map failedDocuments) { + super(msg); + this.failedDocuments = failedDocuments; + } + + public Map getFailedDocuments() { + return failedDocuments; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java index 70696b86f..bc241291a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java @@ -22,6 +22,7 @@ * @since 4.0 */ public class UncategorizedElasticsearchException extends UncategorizedDataAccessException { + public UncategorizedElasticsearchException(String msg, Throwable cause) { super(msg, cause); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 3e809613b..605275bdc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -36,7 +36,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.convert.EntityReader; -import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.BulkFailureException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; @@ -405,7 +405,7 @@ protected List checkForBulkOperationFailure(BulkResponse bulkResponse) { if (item.isFailed()) failedDocuments.put(item.getId(), item.getFailureMessage()); } - throw new ElasticsearchException( + throw new BulkFailureException( "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + failedDocuments + ']', failedDocuments); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 8a1eeaa71..072a475d9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -210,7 +210,7 @@ public String delete(String id, IndexCoordinates index) { Assert.notNull(id, "id must not be null"); Assert.notNull(index, "index must not be null"); - DeleteRequest request = new DeleteRequest(index.getIndexName(), elasticsearchConverter.convertId(id)); + DeleteRequest request = requestFactory.deleteRequest(elasticsearchConverter.convertId(id), index); return execute(client -> client.delete(request, RequestOptions.DEFAULT).getId()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 21f6b36fa..4b353439d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -15,15 +15,11 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.index.VersionType.*; - import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,19 +37,10 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; -import org.elasticsearch.client.Requests; -import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.index.get.GetResult; -import org.elasticsearch.index.query.QueryBuilder; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.index.query.WrapperQueryBuilder; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.aggregations.Aggregation; -import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.elasticsearch.search.sort.FieldSortBuilder; -import org.elasticsearch.search.sort.SortBuilders; -import org.elasticsearch.search.sort.SortOrder; import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,9 +48,9 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.data.convert.EntityReader; -import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.BulkFailureException; import org.springframework.data.elasticsearch.NoSuchIndexException; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity; import org.springframework.data.elasticsearch.core.EntityOperations.Entity; @@ -82,10 +69,8 @@ import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; -import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; @@ -194,6 +179,7 @@ public Mono save(T entity, IndexCoordinates index) { T savedEntity = it.getT1(); IndexResponse indexResponse = it.getT2(); AdaptibleEntity adaptableEntity = operations.forEntity(savedEntity, converter.getConversionService()); + // noinspection ReactiveStreamsNullableInLambdaInTransform return adaptableEntity.populateIdIfNecessary(indexResponse.getId()); }).flatMap(saved -> maybeCallAfterSave(saved, index)); } @@ -268,7 +254,8 @@ protected Mono doIndex(IndexRequest request) { protected Flux doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequest bulkRequest = prepareWriteRequest(requestFactory.bulkRequest(queries, bulkOptions, index)); return client.bulk(bulkRequest) // - .onErrorMap(e -> new ElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e)) // + .onErrorMap( + e -> new UncategorizedElasticsearchException("Error while bulk for request: " + bulkRequest.toString(), e)) // .flatMap(this::checkForBulkOperationFailure) // .flatMapMany(response -> Flux.fromArray(response.getItems())); } @@ -283,7 +270,7 @@ protected Mono checkForBulkOperationFailure(BulkResponse bulkRespo failedDocuments.put(item.getId(), item.getFailureMessage()); } } - ElasticsearchException exception = new ElasticsearchException( + BulkFailureException exception = new BulkFailureException( "Bulk operation has failures. Use ElasticsearchException.getFailedDocuments() for detailed messages [" + failedDocuments + ']', failedDocuments); @@ -315,9 +302,8 @@ public Mono exists(String id, Class entityType, IndexCoordinates ind return doExists(id, index); } - private Mono doExists(String id, @Nullable IndexCoordinates index) { - - return Mono.defer(() -> doExists(new GetRequest(index.getIndexName(), id))); + private Mono doExists(String id, IndexCoordinates index) { + return Mono.defer(() -> doExists(requestFactory.getRequest(id, index))); } /** @@ -334,27 +320,30 @@ protected Mono doExists(GetRequest request) { private Mono> doIndex(T entity, IndexCoordinates index) { - AdaptibleEntity adaptibleEntity = operations.forEntity(entity, converter.getConversionService()); - IndexRequest request = getIndexRequest(entity, adaptibleEntity, index); + IndexRequest request = requestFactory.indexRequest(getIndexQuery(entity), index); request = prepareIndexRequest(entity, request); return Mono.just(entity).zipWith(doIndex(request)); } - private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, IndexCoordinates index) { - Object id = entity.getId(); + private IndexQuery getIndexQuery(Object value) { + AdaptibleEntity entity = operations.forEntity(value, converter.getConversionService()); - IndexRequest request = id != null ? new IndexRequest(index.getIndexName()).id(converter.convertId(id)) - : new IndexRequest(index.getIndexName()); + Object id = entity.getId(); + IndexQuery query = new IndexQuery(); - request.source(converter.mapObject(value).toJson(), Requests.INDEX_CONTENT_TYPE); + if (id != null) { + query.setId(id.toString()); + } + query.setObject(value); boolean usingSeqNo = false; + if (entity.hasSeqNoPrimaryTerm()) { SeqNoPrimaryTerm seqNoPrimaryTerm = entity.getSeqNoPrimaryTerm(); if (seqNoPrimaryTerm != null) { - request.setIfSeqNo(seqNoPrimaryTerm.getSequenceNumber()); - request.setIfPrimaryTerm(seqNoPrimaryTerm.getPrimaryTerm()); + query.setSeqNo(seqNoPrimaryTerm.getSequenceNumber()); + query.setPrimaryTerm(seqNoPrimaryTerm.getPrimaryTerm()); usingSeqNo = true; } } @@ -364,32 +353,11 @@ private IndexRequest getIndexRequest(Object value, AdaptibleEntity entity, In Number version = entity.getVersion(); - if (version != null) { - request.version(version.longValue()); - request.versionType(EXTERNAL); - } - } - - return request; - } - - private IndexQuery getIndexQuery(Object value) { - AdaptibleEntity entity = operations.forEntity(value, converter.getConversionService()); - - Object id = entity.getId(); - IndexQuery query = new IndexQuery(); - if (id != null) { - query.setId(id.toString()); - } - query.setObject(value); - - if (entity.isVersionedEntity()) { - Number version = entity.getVersion(); - if (version != null) { query.setVersion(version.longValue()); } } + return query; } @@ -410,9 +378,7 @@ public Mono get(String id, Class entityType, IndexCoordinates index) { } private Mono doGet(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - return Mono.defer(() -> { - return doGet(new GetRequest(index.getIndexName(), id)); - }); + return Mono.defer(() -> doGet(requestFactory.getRequest(id, index))); } /** @@ -465,8 +431,8 @@ public Mono delete(String id, IndexCoordinates index) { private Mono doDeleteById(String id, IndexCoordinates index) { return Mono.defer(() -> { - - return doDelete(prepareDeleteRequest(new DeleteRequest(index.getIndexName(), id))); + DeleteRequest request = requestFactory.deleteRequest(id, index); + return doDelete(prepareDeleteRequest(request)); }); } @@ -479,8 +445,7 @@ public Mono delete(Query query, Class entityType, IndexCoordinates inde Assert.notNull(query, "Query must not be null!"); - return doDeleteBy(query, getPersistentEntityFor(entityType), index).map(BulkByScrollResponse::getDeleted) - .publishNext(); + return doDeleteBy(query, entityType, index).map(BulkByScrollResponse::getDeleted).publishNext(); } @Override @@ -488,13 +453,10 @@ public Mono delete(Query query, Class entityType) { return delete(query, entityType, getIndexCoordinatesFor(entityType)); } - private Flux doDeleteBy(Query query, ElasticsearchPersistentEntity entity, - IndexCoordinates index) { + private Flux doDeleteBy(Query query, Class entityType, IndexCoordinates index) { return Flux.defer(() -> { - DeleteByQueryRequest request = new DeleteByQueryRequest(index.getIndexNames()); - request.setQuery(mappedQuery(query, entity)); - + DeleteByQueryRequest request = requestFactory.deleteByQueryRequest(query, entityType, index); return doDeleteBy(prepareDeleteByRequest(request)); }); } @@ -552,8 +514,13 @@ protected DeleteRequest prepareDeleteRequest(DeleteRequest request) { */ protected DeleteByQueryRequest prepareDeleteByRequest(DeleteByQueryRequest request) { - if (refreshPolicy != null && !RefreshPolicy.NONE.equals(refreshPolicy)) { - request = request.setRefresh(true); + if (refreshPolicy != null) { + + if (RefreshPolicy.NONE.equals(refreshPolicy)) { + request = request.setRefresh(false); + } else { + request = request.setRefresh(true); + } } if (indicesOptions != null) { @@ -661,43 +628,6 @@ private Mono doCount(Query query, Class entityType, IndexCoordinates in }); } - private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity entity, IndexCoordinates index) { - - CountRequest request = new CountRequest(index.getIndexNames()); - SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); - searchSourceBuilder.query(mappedQuery(query, entity)); - searchSourceBuilder.trackScores(query.getTrackScores()); - - QueryBuilder postFilterQuery = mappedFilterQuery(query, entity); - if (postFilterQuery != null) { - searchSourceBuilder.postFilter(postFilterQuery); - } - - if (query.getSourceFilter() != null) { - searchSourceBuilder.fetchSource(query.getSourceFilter().getIncludes(), query.getSourceFilter().getExcludes()); - } - - if (query instanceof NativeSearchQuery && ((NativeSearchQuery) query).getCollapseBuilder() != null) { - searchSourceBuilder.collapse(((NativeSearchQuery) query).getCollapseBuilder()); - } - - sort(query, entity).forEach(searchSourceBuilder::sort); - - if (query.getMinScore() > 0) { - searchSourceBuilder.minScore(query.getMinScore()); - } - - if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); - } - - if (query.getPreference() != null) { - request.preference(query.getPreference()); - } - request.source(searchSourceBuilder); - return request; - } - /** * Customization hook on the actual execution result {@link Publisher}.
* @@ -762,61 +692,6 @@ protected Flux doScroll(SearchRequest request) { .map(DocumentAdapters::from).onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); } - @Nullable - private QueryBuilder mappedFilterQuery(Query query, ElasticsearchPersistentEntity entity) { - - if (query instanceof NativeSearchQuery) { - return ((NativeSearchQuery) query).getFilter(); - } - - return null; - } - - private QueryBuilder mappedQuery(Query query, ElasticsearchPersistentEntity entity) { - - QueryBuilder elasticsearchQuery = null; - - if (query instanceof CriteriaQuery) { - converter.updateQuery((CriteriaQuery) query, entity.getType()); - elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(((CriteriaQuery) query).getCriteria()); - } else if (query instanceof StringQuery) { - elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource()); - } else if (query instanceof NativeSearchQuery) { - elasticsearchQuery = ((NativeSearchQuery) query).getQuery(); - } else { - throw new IllegalArgumentException(String.format("Unknown query type '%s'.", query.getClass())); - } - - return elasticsearchQuery != null ? elasticsearchQuery : QueryBuilders.matchAllQuery(); - } - - private static List sort(Query query, ElasticsearchPersistentEntity entity) { - - if (query.getSort() == null || query.getSort().isUnsorted()) { - return Collections.emptyList(); - } - - List mappedSort = new ArrayList<>(); - for (Sort.Order order : query.getSort()) { - - ElasticsearchPersistentProperty property = entity.getPersistentProperty(order.getProperty()); - String fieldName = property != null ? property.getFieldName() : order.getProperty(); - - FieldSortBuilder sort = SortBuilders.fieldSort(fieldName) - .order(order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC); - - if (order.getNullHandling() == Sort.NullHandling.NULLS_FIRST) { - sort.missing("_first"); - } else if (order.getNullHandling() == Sort.NullHandling.NULLS_LAST) { - sort.missing("_last"); - } - - mappedSort.add(sort); - } - - return mappedSort; - } - /** * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. @@ -950,7 +825,6 @@ protected Mono maybeCallAfterConvert(T entity, Document document, IndexCo return Mono.just(entity); } - // endregion protected interface DocumentCallback { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index a26c8b83b..6171be9b4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -29,6 +29,7 @@ import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; +import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.MultiGetRequest; @@ -249,6 +250,10 @@ public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, In return deleteByQueryRequest; } + public DeleteRequest deleteRequest(String id, IndexCoordinates index) { + return new DeleteRequest(index.getIndexName(), id); + } + @Deprecated public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, DeleteQuery deleteQuery, IndexCoordinates index) { @@ -344,6 +349,7 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { throw new ElasticsearchException( "object or source is null, failed to index the document [id: " + query.getId() + ']'); } + if (query.getVersion() != null) { indexRequest.version(query.getVersion()); VersionType versionType = retrieveVersionTypeFromPersistentEntity(query.getObject().getClass()); @@ -353,6 +359,7 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { if (query.getSeqNo() != null) { indexRequest.setIfSeqNo(query.getSeqNo()); } + if (query.getPrimaryTerm() != null) { indexRequest.setIfPrimaryTerm(query.getPrimaryTerm()); } From 0f84158e1ed501f7debcd51a68b0c5b814646200 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 23 May 2020 16:56:13 +0200 Subject: [PATCH 0176/1191] DATAES-841 - Remove deprecated type mappings code. Original PR: #468 --- src/main/asciidoc/preface.adoc | 1 + ...elasticsearch-migration-guide-4.0-4.1.adoc | 9 +++ .../elasticsearch/annotations/Document.java | 11 ---- .../core/mapping/IndexCoordinates.java | 33 +---------- .../SimpleElasticsearchPersistentEntity.java | 17 +----- ...tReactiveElasticsearchRepositoryQuery.java | 3 +- .../data/elasticsearch/NestedObjectTests.java | 16 +++-- .../core/ElasticsearchTemplateTests.java | 58 +++++++++---------- .../core/IndexCoordinatesTest.java | 7 --- .../elasticsearch/core/LogEntityTests.java | 2 +- .../ReactiveElasticsearchTemplateTests.java | 16 ++--- ...eactiveElasticsearchTemplateUnitTests.java | 7 +-- ...ElasticsearchTemplateAggregationTests.java | 2 +- .../ElasticsearchTemplateCompletionTests.java | 12 ++-- ...chTemplateCompletionWithContextsTests.java | 9 ++- ...appingElasticsearchConverterUnitTests.java | 2 +- .../geo/ElasticsearchTemplateGeoTests.java | 6 +- .../core/index/MappingBuilderTests.java | 4 +- .../core/query/CriteriaQueryTests.java | 2 +- ...ettingAndMappingEntityRepositoryTests.java | 3 +- .../synonym/SynonymRepositoryTests.java | 2 +- 21 files changed, 80 insertions(+), 142 deletions(-) create mode 100644 src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 877dcd679..fcaa3e478 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -10,6 +10,7 @@ You will notice similarities to the Spring data solr and mongodb support in the include::reference/elasticsearch-new.adoc[leveloffset=+1] include::reference/elasticsearch-migration-guide-3.2-4.0.adoc[leveloffset=+1] +include::reference/elasticsearch-migration-guide-4.0-4.1.adoc[leveloffset=+1] [[preface.metadata]] == Project Metadata diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc new file mode 100644 index 000000000..bba17f4b1 --- /dev/null +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -0,0 +1,9 @@ +[[elasticsearch-migration-guide-4.0-4.1]] +== Upgrading from 4.0.x to 4.1.x + +This section describes breaking changes from version 4.0.x to 4.1.x and how removed features can be replaced by new introduced features. + +=== Removals + +The _type mappings_ parameters of the `@Document` annotation and the `IndexCoordinates` object were removed. They had been deprecated in Spring Data Elasticsearch 4.0 and their values weren't used anymore. + diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java index e72987ed4..0ae897bcc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Document.java @@ -53,17 +53,6 @@ */ String indexName(); - /** - * Mapping type name.
- * deprecated as Elasticsearch does not support this anymore - * (@see
Elastisearch removal of types documentation) and will remove it in - * Elasticsearch 8. - * - * @deprecated since 4.0 - */ - @Deprecated - String type() default ""; - /** * Use server-side settings when creating the index. */ diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java index 79fd063f1..d2061a7d2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/IndexCoordinates.java @@ -17,7 +17,6 @@ import java.util.Arrays; -import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -34,29 +33,15 @@ public class IndexCoordinates { public static final String TYPE = "_doc"; private final String[] indexNames; - private final String[] typeNames; public static IndexCoordinates of(String... indexNames) { Assert.notNull(indexNames, "indexNames must not be null"); - return new IndexCoordinates(indexNames, null); + return new IndexCoordinates(indexNames); } - private IndexCoordinates(String[] indexNames, @Nullable String[] typeNames) { + private IndexCoordinates(String[] indexNames) { Assert.notEmpty(indexNames, "indexNames may not be null or empty"); this.indexNames = indexNames; - this.typeNames = typeNames != null ? typeNames : new String[] {}; - } - - /** - * Using Index types is deprecated in Elasticsearch. - * - * @param typeNames - * @return - */ - @Deprecated - public IndexCoordinates withTypes(String... typeNames) { - Assert.notEmpty(typeNames, "typeNames must not be null"); - return new IndexCoordinates(this.indexNames, typeNames); } public String getIndexName() { @@ -67,20 +52,8 @@ public String[] getIndexNames() { return Arrays.copyOf(indexNames, indexNames.length); } - @Deprecated - @Nullable - public String getTypeName() { - return typeNames.length > 0 ? typeNames[0] : null; - } - - @Deprecated - public String[] getTypeNames() { - return Arrays.copyOf(typeNames, typeNames.length); - } - @Override public String toString() { - return "IndexCoordinates{" + "indexNames=" + Arrays.toString(indexNames) + ", typeNames=" - + Arrays.toString(typeNames) + '}'; + return "IndexCoordinates{" + "indexNames=" + Arrays.toString(indexNames) + '}'; } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 348ac676d..677f82215 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -15,9 +15,6 @@ */ package org.springframework.data.elasticsearch.core.mapping; -import static org.springframework.util.StringUtils.*; - -import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; @@ -66,7 +63,6 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private final SpelExpressionParser parser; private @Nullable String indexName; - private @Nullable String indexType; private boolean useServerConfiguration; private short shards; private short replicas; @@ -93,7 +89,6 @@ public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { Assert.hasText(document.indexName(), " Unknown indexName. Make sure the indexName is defined. e.g @Document(indexName=\"foo\")"); this.indexName = document.indexName(); - this.indexType = hasText(document.type()) ? document.type() : clazz.getSimpleName().toLowerCase(Locale.ENGLISH); this.useServerConfiguration = document.useServerConfiguration(); this.shards = document.shards(); this.replicas = document.replicas(); @@ -124,19 +119,9 @@ private String getIndexName() { return getTypeInformation().getType().getSimpleName(); } - private String getIndexType() { - - if (indexType != null) { - Expression expression = parser.parseExpression(indexType, ParserContext.TEMPLATE_EXPRESSION); - return expression.getValue(context, String.class); - } - - return ""; - } - @Override public IndexCoordinates getIndexCoordinates() { - return IndexCoordinates.of(getIndexName()).withTypes(getIndexType()); + return IndexCoordinates.of(getIndexName()); } @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java index dcfd49b1e..634a6cff2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractReactiveElasticsearchRepositoryQuery.java @@ -90,8 +90,7 @@ private Object execute(ElasticsearchParameterAccessor parameterAccessor) { Class targetType = processor.getReturnedType().getTypeToRead(); String indexName = queryMethod.getEntityInformation().getIndexName(); - String indexTypeName = queryMethod.getEntityInformation().getIndexTypeName(); - IndexCoordinates index = IndexCoordinates.of(indexName).withTypes(indexTypeName); + IndexCoordinates index = IndexCoordinates.of(indexName); ReactiveElasticsearchQueryExecution execution = getExecution(parameterAccessor, new ResultProcessingConverter(processor)); diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index a359f3738..05ac0838e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -121,7 +121,7 @@ public void shouldIndexInitialLevelNestedObject() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); + IndexCoordinates index = IndexCoordinates.of("test-index-person"); operations.bulkIndex(indexQueries, index); operations.indexOps(Person.class).refresh(); @@ -141,13 +141,12 @@ public void shouldIndexMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - operations.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-person-multiple-level-nested")); operations.indexOps(PersonMultipleLevelNested.class).refresh(); // then PersonMultipleLevelNested personIndexed = operations.get("1", PersonMultipleLevelNested.class, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); + IndexCoordinates.of("test-index-person-multiple-level-nested")); assertThat(personIndexed).isNotNull(); } @@ -158,8 +157,7 @@ public void shouldIndexMultipleLevelNestedObjectWithIncludeInParent() { List indexQueries = createPerson(); // when - operations.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user")); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-person-multiple-level-nested")); // then Map mapping = operations.indexOps(PersonMultipleLevelNested.class).getMapping(); @@ -178,7 +176,7 @@ public void shouldSearchUsingNestedQueryOnMultipleLevelNestedObject() { List indexQueries = createPerson(); // when - IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested").withTypes("user"); + IndexCoordinates index = IndexCoordinates.of("test-index-person-multiple-level-nested"); operations.bulkIndex(indexQueries, index); operations.indexOps(PersonMultipleLevelNested.class).refresh(); @@ -318,7 +316,7 @@ public void shouldSearchBooksForPersonInitialLevelNestedType() { indexQueries.add(indexQuery1); indexQueries.add(indexQuery2); - IndexCoordinates index = IndexCoordinates.of("test-index-person").withTypes("user"); + IndexCoordinates index = IndexCoordinates.of("test-index-person"); operations.bulkIndex(indexQueries, index); operations.indexOps(Person.class).refresh(); @@ -367,7 +365,7 @@ public void shouldIndexAndSearchMapAsNestedType() { indexQueries.add(indexQuery2); // when - IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects").withTypes("book"); + IndexCoordinates index = IndexCoordinates.of("test-index-book-nested-objects"); operations.bulkIndex(indexQueries, index); operations.indexOps(Book.class).refresh(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 53154cc50..f538b29b3 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -110,9 +110,8 @@ public abstract class ElasticsearchTemplateTests { private static final String INDEX_1_NAME = "test-index-1"; private static final String INDEX_2_NAME = "test-index-2"; private static final String INDEX_3_NAME = "test-index-3"; - private static final String TYPE_NAME = "test-type"; - protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME); + protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); @Autowired protected ElasticsearchOperations operations; private IndexOperations indexOperations; @@ -383,7 +382,7 @@ public void shouldPassIndicesOptionsForGivenSearchQuery() { IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); - operations.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(idxQuery, IndexCoordinates.of(INDEX_1_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) @@ -541,17 +540,17 @@ public void shouldDeleteAcrossIndex() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // when Query query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "foo")).build(); - operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*")); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -573,18 +572,18 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); + operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); - operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); // when Query query = new NativeSearchQueryBuilder().withQuery(termQuery("message", "negative")).build(); - operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*").withTypes(TYPE_NAME)); + operations.delete(query, SampleEntity.class, IndexCoordinates.of("test-index-*")); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -1568,7 +1567,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { IndexQuery idxQuery = new IndexQueryBuilder().withId(sampleEntity.getId()).withObject(sampleEntity).build(); - IndexCoordinates index = IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type"); + IndexCoordinates index = IndexCoordinates.of(INDEX_1_NAME); operations.index(idxQuery, index); operations.indexOps(index).refresh(); @@ -1631,7 +1630,7 @@ public void shouldReturnDifferentEntityForMultiSearch() { indexOperations.putMapping(clazz); bookIndexOperations.refresh(); - IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template").withTypes("book"); + IndexCoordinates bookIndex = IndexCoordinates.of("test-index-book-core-template"); operations.index(buildIndex(SampleEntity.builder().id("1").message("ab").build()), index); operations.index(buildIndex(Book.builder().id("2").description("bc").build()), bookIndex); @@ -1691,7 +1690,7 @@ public void shouldIndexDocumentForSpecifiedSource() { indexQuery.setSource(documentSource); // when - operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); + operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", indexQuery.getId())) .build(); @@ -1711,9 +1710,8 @@ public void shouldThrowElasticsearchExceptionWhenNoDocumentSpecified() { indexQuery.setId("2333343434"); // when - assertThatThrownBy( - () -> operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME))) - .isInstanceOf(ElasticsearchException.class); + assertThatThrownBy(() -> operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY))) + .isInstanceOf(ElasticsearchException.class); } @Test @@ -1920,7 +1918,7 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { IndexQuery indexQuery = new IndexQueryBuilder().withId(documentId).withObject(sampleEntity).build(); - operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY).withTypes(TYPE_NAME)); + operations.index(indexQuery, IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)); operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); @@ -2030,8 +2028,8 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2061,8 +2059,8 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2131,8 +2129,8 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2162,8 +2160,8 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2297,8 +2295,8 @@ public void shouldTestResultsAcrossMultipleIndices() { IndexQuery indexQuery2 = new IndexQueryBuilder().withId(sampleEntity2.getId()).withObject(sampleEntity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("test-type")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("test-type")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2325,8 +2323,8 @@ public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { IndexQuery indexQuery1 = new IndexQueryBuilder().withId(entity1.getId()).withObject(entity1).build(); IndexQuery indexQuery2 = new IndexQueryBuilder().withId(entity2.getId()).withObject(entity2).build(); - operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME).withTypes("hetro")); - operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME).withTypes("hetro")); + operations.index(indexQuery1, IndexCoordinates.of(INDEX_1_NAME)); + operations.index(indexQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -2756,7 +2754,7 @@ public void shouldAddAliasForVariousRoutingValues() { .withObject(entity) // .build(); - operations.index(indexQuery, IndexCoordinates.of(alias1).withTypes(TYPE_NAME)); + operations.index(indexQuery, IndexCoordinates.of(alias1)); // then List aliasMetaData = indexOperations.queryForAlias(); @@ -2804,7 +2802,7 @@ public void shouldAddAliasWithGivenRoutingValue() { .withObject(sampleEntity) // .build(); - operations.index(indexQuery, IndexCoordinates.of(alias).withTypes(TYPE_NAME)); + operations.index(indexQuery, IndexCoordinates.of(alias)); operations.indexOps(IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY)).refresh(); NativeSearchQuery query = new NativeSearchQueryBuilder() // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java index ee33e4b4f..132aaf774 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/IndexCoordinatesTest.java @@ -39,11 +39,4 @@ void cannotBeInitializedWithNullIndexNames() { void cannotBeInitializedWithEmptyIndexNames() { assertThatThrownBy(() -> IndexCoordinates.of(new String[] {})).isInstanceOf(IllegalArgumentException.class); } - - @Test - void shouldHaveEmptyTypesWhenNotSet() { - IndexCoordinates indexCoordinates = IndexCoordinates.of("test"); - - assertThat(indexCoordinates.getTypeNames()).isEmpty(); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java index 0a9a52cca..559417bbf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/LogEntityTests.java @@ -61,7 +61,7 @@ public class LogEntityTests { @Import({ ElasticsearchRestTemplateConfiguration.class }) static class Config {} - private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core").withTypes("test-log-type"); + private final IndexCoordinates index = IndexCoordinates.of("test-index-log-core"); @Autowired private ElasticsearchOperations operations; private IndexOperations indexOperations; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index a959e4dd6..4bd1be854 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -49,7 +49,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; @@ -201,7 +200,7 @@ public void insertShouldAcceptPlainMapStructureAsSource() { Map map = new LinkedHashMap<>(Collections.singletonMap("foo", "bar")); - template.save(map, IndexCoordinates.of(ALTERNATE_INDEX).withTypes("singleton-map")) // + template.save(map, IndexCoordinates.of(ALTERNATE_INDEX)) // .as(StepVerifier::create) // .consumeNextWith(actual -> { assertThat(map).containsKey("id"); @@ -218,7 +217,7 @@ public void insertShouldErrorOnNullEntity() { @Test // DATAES-519, DATAES-767, DATAES-822 public void getByIdShouldErrorWhenIndexDoesNotExist() { - template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index").withTypes("test-type")) // + template.get("foo", SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .expectError(ElasticsearchStatusException.class); } @@ -276,8 +275,8 @@ public void getByIdWithExplicitIndexNameShouldOverwriteMetadata() { IndexQuery indexQuery = getIndexQuery(sampleEntity); - IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type"); - IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX).withTypes("test-type"); + IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX); + IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX); restTemplate.index(indexQuery, alternateIndex); indexOperations.refresh(); @@ -524,7 +523,8 @@ public void aggregateShouldReturnAggregations() { @Test // DATAES-567, DATAES-767 public void aggregateShouldErrorWhenIndexDoesNotExist() { - template.aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, + template + .aggregate(new CriteriaQuery(Criteria.where("message").is("some message")), SampleEntity.class, IndexCoordinates.of("no-such-index")) // .as(StepVerifier::create) // .expectError(ElasticsearchStatusException.class); @@ -588,7 +588,7 @@ public void deleteShouldRemoveExistingDocumentByIdUsingIndexName() { SampleEntity sampleEntity = randomEntity("test message"); index(sampleEntity); - template.delete(sampleEntity.getId(), IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type")) // + template.delete(sampleEntity.getId(), IndexCoordinates.of(DEFAULT_INDEX)) // .as(StepVerifier::create)// .expectNext(sampleEntity.getId()) // .verifyComplete(); @@ -1001,7 +1001,7 @@ private List getIndexQueries(SampleEntity... sampleEntities) { private void index(SampleEntity... entities) { - IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX).withTypes("test-type"); + IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX); if (entities.length == 1) { restTemplate.index(getIndexQuery(entities[0]), indexCoordinates); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java index a1a412790..62e9d05d7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateUnitTests.java @@ -24,7 +24,6 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -56,6 +55,7 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +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; @@ -71,7 +71,7 @@ public class ReactiveElasticsearchTemplateUnitTests { @Mock ReactiveElasticsearchClient client; ReactiveElasticsearchTemplate template; - private IndexCoordinates index = IndexCoordinates.of("index").withTypes("type"); + private IndexCoordinates index = IndexCoordinates.of("index"); @BeforeEach public void setUp() { @@ -258,8 +258,7 @@ public void deleteByShouldApplyIndicesOptionsIfSet() { @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-core-reactive-template-Unit", replicas = 0, - refreshInterval = "-1") + @Document(indexName = "test-index-sample-core-reactive-template-Unit", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java index 911fb6e12..a13174cb7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java @@ -97,7 +97,7 @@ public void before() { .addAuthor(RIZWAN_IDREES).addPublishedYear(YEAR_2002).addPublishedYear(YEAR_2001).addPublishedYear(YEAR_2000) .score(40).buildIndex(); - IndexCoordinates index = IndexCoordinates.of(INDEX_NAME).withTypes("article"); + IndexCoordinates index = IndexCoordinates.of(INDEX_NAME); operations.index(article1, index); operations.index(article2, index); operations.index(article3, index); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java index 316e707ce..02663060b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java @@ -108,8 +108,7 @@ private void loadAnnotatedCompletionObjectEntities() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }).buildIndex()); - operations.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-annotated-completion")); operations.indexOps(AnnotatedCompletionEntity.class).refresh(); } @@ -125,8 +124,7 @@ private void loadAnnotatedCompletionObjectEntitiesWithWeights() { indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Mewes Kochheim4") .suggest(new String[] { "Mewes Kochheim4" }, Integer.MAX_VALUE).buildIndex()); - operations.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-annotated-completion")); operations.indexOps(AnnotatedCompletionEntity.class).refresh(); } @@ -142,7 +140,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionEntity() { // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-core-completion").withTypes("completion-type")); + IndexCoordinates.of("test-index-core-completion")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -170,7 +168,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingAnnotatedCompletionEn // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + IndexCoordinates.of("test-index-annotated-completion")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -191,7 +189,7 @@ public void shouldFindSuggestionsWithWeightsForGivenCriteriaQueryUsingAnnotatedC // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-annotated-completion").withTypes("annotated-completion-type")); + IndexCoordinates.of("test-index-annotated-completion")); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java index 77bdc2d9b..ed7989f01 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionWithContextsTests.java @@ -110,8 +110,7 @@ private void loadContextCompletionObjectEntities() { indexQueries.add(new ContextCompletionEntityBuilder("4").name("Artur Konczak") .suggest(new String[] { "Artur", "Konczak" }, context4).buildIndex()); - operations.bulkIndex(indexQueries, - IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); + operations.bulkIndex(indexQueries, IndexCoordinates.of("test-index-context-completion")); operations.indexOps(ContextCompletionEntity.class).refresh(); } @@ -137,7 +136,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); + IndexCoordinates.of("test-index-context-completion")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -169,7 +168,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); + IndexCoordinates.of("test-index-context-completion")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); @@ -201,7 +200,7 @@ public void shouldFindSuggestionsForGivenCriteriaQueryUsingContextCompletionEnti // when SearchResponse suggestResponse = ((AbstractElasticsearchTemplate) operations).suggest( new SuggestBuilder().addSuggestion("test-suggest", completionSuggestionFuzzyBuilder), - IndexCoordinates.of("test-index-context-completion").withTypes("context-completion-type")); + IndexCoordinates.of("test-index-context-completion")); assertThat(suggestResponse.getSuggest()).isNotNull(); CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest"); List options = completionSuggestion.getEntries().get(0).getOptions(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 486f3b417..adfc67203 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -897,7 +897,7 @@ static class Car { @AllArgsConstructor @Builder @org.springframework.data.elasticsearch.annotations.Document(indexName = "test-index-geo-core-entity-mapper", - type = "geo-test-index", replicas = 0, refreshInterval = "-1") + replicas = 0, refreshInterval = "-1") static class GeoEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java index 0d5bf827a..ccb73589b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/geo/ElasticsearchTemplateGeoTests.java @@ -71,10 +71,8 @@ public class ElasticsearchTemplateGeoTests { @Import({ ElasticsearchRestTemplateConfiguration.class }) static class Config {} - private final IndexCoordinates locationMarkerIndex = IndexCoordinates.of("test-index-location-marker-core-geo") - .withTypes("geo-annotation-point-type"); - private final IndexCoordinates authorMarkerIndex = IndexCoordinates.of("test-index-author-marker-core-geo") - .withTypes("geo-class-point-type"); + private final IndexCoordinates locationMarkerIndex = IndexCoordinates.of("test-index-location-marker-core-geo"); + private final IndexCoordinates authorMarkerIndex = IndexCoordinates.of("test-index-author-marker-core-geo"); @Autowired private ElasticsearchOperations operations; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 9f1403e86..b0f702c53 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -149,7 +149,7 @@ public void shouldAddStockPriceDocumentToIndex() { double price = 2.34; String id = "abc"; - IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder").withTypes("price"); + IndexCoordinates index = IndexCoordinates.of("test-index-stock-mapping-builder"); operations.index(buildIndex(StockPrice.builder() // .id(id) // .symbol(symbol) // @@ -192,7 +192,7 @@ public void shouldBuildMappingWithSuperclass() throws JSONException { @Test // DATAES-76 public void shouldAddSampleInheritedEntityDocumentToIndex() { // given - IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder").withTypes("mapping"); + IndexCoordinates index = IndexCoordinates.of("test-index-sample-inherited-mapping-builder"); IndexOperations indexOps = operations.indexOps(index); // when diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 8007656b7..2cd1a1d63 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -64,7 +64,7 @@ public class CriteriaQueryTests { @Import({ ElasticsearchRestTemplateConfiguration.class }) static class Config {} - private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query").withTypes("test-type"); + private final IndexCoordinates index = IndexCoordinates.of("test-index-sample-core-query"); @Autowired private ElasticsearchOperations operations; private IndexOperations indexOperations; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index b19050ad9..d500148d9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -116,8 +116,7 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.termQuery("email", dynamicSettingAndMappingEntity1.getEmail())).build(); - IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping") - .withTypes("test-setting-type"); + IndexCoordinates index = IndexCoordinates.of("test-index-dynamic-setting-and-mapping"); long count = operations.count(searchQuery, DynamicSettingAndMappingEntity.class, index); SearchHits entityList = operations.search(searchQuery, DynamicSettingAndMappingEntity.class, index); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java index 22ffaa154..8635a94f5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/synonym/SynonymRepositoryTests.java @@ -91,7 +91,7 @@ public void shouldDo() { SearchHits synonymEntities = operations.search( new NativeSearchQueryBuilder().withQuery(QueryBuilders.termQuery("text", "british")).build(), - SynonymEntity.class, IndexCoordinates.of("test-index-synonym").withTypes("synonym-type")); + SynonymEntity.class, IndexCoordinates.of("test-index-synonym")); assertThat(synonymEntities).hasSize(1); } From cb750e03a9e24c206c413e729b3672e59241bf36 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 26 May 2020 16:20:45 +0200 Subject: [PATCH 0177/1191] DATAES-844 - Improve TOC formatting for migration guides. --- src/main/asciidoc/index.adoc | 1 + src/main/asciidoc/preface.adoc | 2 - ...elasticsearch-migration-guide-3.2-4.0.adoc | 50 +++++++++---------- ...elasticsearch-migration-guide-4.0-4.1.adoc | 5 +- .../asciidoc/reference/migration-guides.adoc | 9 ++++ 5 files changed, 38 insertions(+), 29 deletions(-) create mode 100644 src/main/asciidoc/reference/migration-guides.adoc diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 20d119585..bdc2b90a2 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -44,4 +44,5 @@ include::{spring-data-commons-docs}/repository-namespace-reference.adoc[] include::{spring-data-commons-docs}/repository-populator-namespace-reference.adoc[] include::{spring-data-commons-docs}/repository-query-keywords-reference.adoc[] include::{spring-data-commons-docs}/repository-query-return-types-reference.adoc[] +include::reference/migration-guides.adoc[] :leveloffset: -1 diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index fcaa3e478..3dbbe82af 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -9,8 +9,6 @@ The Spring Data Elasticsearch project applies core Spring concepts to the develo You will notice similarities to the Spring data solr and mongodb support in the Spring Framework. include::reference/elasticsearch-new.adoc[leveloffset=+1] -include::reference/elasticsearch-migration-guide-3.2-4.0.adoc[leveloffset=+1] -include::reference/elasticsearch-migration-guide-4.0-4.1.adoc[leveloffset=+1] [[preface.metadata]] == Project Metadata diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc index 47fe3b408..3e66b0086 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-3.2-4.0.adoc @@ -1,25 +1,25 @@ [[elasticsearch-migration-guide-3.2-4.0]] -== Upgrading from 3.2.x to 4.0.x += Upgrading from 3.2.x to 4.0.x This section describes breaking changes from version 3.2.x to 4.0.x and how removed features can be replaced by new introduced features. - -=== Removal of the used Jackson Mapper. +[[elasticsearch-migration-guide-3.2-4.0.jackson-removal]] +== Removal of the used Jackson Mapper One of the changes in version 4.0.x is that Spring Data Elasticsearch does not use the Jackson Mapper anymore to map an entity to the JSON representation needed for Elasticsearch (see <>). In version 3.2.x the Jackson Mapper was the default that was used. It was possible to switch to the meta-model based converter (named `ElasticsearchEntityMapper`) by explicitly configuring it (<>). In version 4.0.x the meta-model based converter is the only one that is available and does not need to be configured explicitly. If you had a custom configuration to enable the meta-model converter by providing a bean like this: -[code,java] +[source,java] ---- @Bean @Override -public EntityMapper entityMapper() { +public EntityMapper entityMapper() { ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper( - elasticsearchMappingContext(), new DefaultConversionService() + elasticsearchMappingContext(), new DefaultConversionService() ); - entityMapper.setConversions(elasticsearchCustomConversions()); + entityMapper.setConversions(elasticsearchCustomConversions()); return entityMapper; } @@ -30,15 +30,15 @@ You now have to remove this bean, the `ElasticsearchEntityMapper` interface has .Entity configuration Some users had custom Jackson annotations on the entity class, for example in order to define a custom name for the mapped document in Elasticsearch or to configure date conversions. These are not taken into account anymore. The needed functionality is now provided with Spring Data Elasticsearch's `@Field` annotation. Please see <> for detailed information. - -=== Removal of implicit index name from query objects +[[elasticsearch-migration-guide-3.2-4.0.implicit-index-name]] +== Removal of implicit index name from query objects In 3.2.x the different query classes like `IndexQuery` or `SearchQuery` had properties that were taking the index name or index names that they were operating upon. If these were not set, the passed in entity was inspected to retrieve the index name that was set in the `@Document` annotation. + In 4.0.x the index name(s) must now be provided in an additional parameter of type `IndexCoordinates`. By separating this, it now is possible to use one query object against different indices. So for example the following code: -[code,java] +[source,java] ---- IndexQuery indexQuery = new IndexQueryBuilder() .withId(person.getId().toString()) @@ -50,7 +50,7 @@ String documentId = elasticsearchOperations.index(indexQuery); must be changed to: -[code,java] +[source,java] ---- IndexCoordinates indexCoordinates = elasticsearchOperations.getIndexCoordinatesFor(person.getClass()); @@ -58,14 +58,14 @@ IndexQuery indexQuery = new IndexQueryBuilder() .withId(person.getId().toString()) .withObject(person) .build(); - + String documentId = elasticsearchOperations.index(indexQuery, indexCoordinates); ---- To make it easier to work with entities and use the index name that is contained in the entitie's `@Document` annotation, new methods have been added like `DocumentOperations.save(T entity)`; - -=== The new Operations interfaces +[[elasticsearch-migration-guide-3.2-4.0.new-operations]] +== The new Operations interfaces In version 3.2 there was the `ElasticsearchOperations` interface that defined all the methods for the `ElasticsearchTemplate` class. In version 4 the functions have been split into different interfaces, aligning these interfaces with the Elasticsearch API: @@ -77,10 +77,10 @@ In version 3.2 there was the `ElasticsearchOperations` interface that defined al NOTE: All the functions from the `ElasticsearchOperations` interface in version 3.2 that are now moved to the `IndexOperations` interface are still available, they are marked as deprecated and have default implementations that delegate to the new implementation: -[code,java] +[source,java] ---- /** - * Create an index for given indexName . + * Create an index for given indexName. * * @param indexName the name of the index * @return {@literal true} if the index was created @@ -92,17 +92,17 @@ default boolean createIndex(String indexName) { } ---- +[[elasticsearch-migration-guide-3.2-4.0.deprecations]] +== Deprecations -=== Deprecations - -==== Methods and classes +=== Methods and classes Many functions and classes have been deprecated. These functions still work, but the Javadocs show with what they should be replaced. .Example from ElasticsearchOperations -[code,java] +[source,java] ---- -/** +/* * Retrieves an object from an index. * * @param query the query defining the id of the object to get @@ -113,15 +113,16 @@ Many functions and classes have been deprecated. These functions still work, but @Deprecated @Nullable T queryForObject(GetQuery query, Class clazz); ----- +---- -==== Elasticsearch deprecations +=== Elasticsearch deprecations Since version 7 the Elasticsearch `TransportClient` is deprecated, it will be removed with Elasticsearch version 8. Spring Data Elasticsearch deprecates the `ElasticsearchTemplate` class which uses the `TransportClient` in version 4.0. Mapping types were removed from Elasticsearch 7, they still exist as deprecated values in the Spring Data `@Document` annotation and the `IndexCoordinates` class but they are not used anymore internally. -=== Removals +[[elasticsearch-migration-guide-3.2-4.0.removal]] +== Removals * As already described, the `ElasticsearchEntityMapper` interface has been removed. @@ -130,4 +131,3 @@ Mapping types were removed from Elasticsearch 7, they still exist as deprecated * The method `org.springframework.data.elasticsearch.core.ElasticsearchOperations.query(SearchQuery query, ResultsExtractor resultsExtractor);` and the `org.springframework.data.elasticsearch.core.ResultsExtractor` interface have been removed. These could be used to parse the result from Elasticsearch for cases in which the response mapping done with the Jackson based mapper was not enough. Since version 4.0, there are the new <> to return the information from an Elasticsearch response, so there is no need to expose this low level functionality. * The low level methods `startScroll`, `continueScroll` and `clearScroll` have been removed from the `ElasticsearchOperations` interface. For low level scroll API access, there now are `searchScrollStart`, `searchScrollContinue` and `searchScrollClear` methods on the `ElasticsearchRestTemplate` class. - diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index bba17f4b1..a220252bc 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -1,9 +1,10 @@ [[elasticsearch-migration-guide-4.0-4.1]] -== Upgrading from 4.0.x to 4.1.x += Upgrading from 4.0.x to 4.1.x This section describes breaking changes from version 4.0.x to 4.1.x and how removed features can be replaced by new introduced features. -=== Removals +[[elasticsearch-migration-guide-4.0-4.1.removal]] +== Removals The _type mappings_ parameters of the `@Document` annotation and the `IndexCoordinates` object were removed. They had been deprecated in Spring Data Elasticsearch 4.0 and their values weren't used anymore. diff --git a/src/main/asciidoc/reference/migration-guides.adoc b/src/main/asciidoc/reference/migration-guides.adoc new file mode 100644 index 000000000..eaf6630cb --- /dev/null +++ b/src/main/asciidoc/reference/migration-guides.adoc @@ -0,0 +1,9 @@ +[[elasticsearch.migration]] += Appendix E: Migration Guides + +// line breaks required otherwise the TOC breaks due to joining of first/last lines. +:leveloffset: +1 +include::elasticsearch-migration-guide-3.2-4.0.adoc[] + +include::elasticsearch-migration-guide-4.0-4.1.adoc[] +:leveloffset: -1 From fa317014a7c73545a63fcdcad8bc0528a11c656d Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Fri, 29 May 2020 18:52:54 +0200 Subject: [PATCH 0178/1191] DATAES-847 - Add missing DateFormat values. Original PR: #469 --- .../elasticsearch/annotations/DateFormat.java | 9 ++++---- .../ElasticsearchDateConverterTests.java | 22 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java index 990abfd25..75c903649 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java @@ -17,6 +17,7 @@ /** * @author Jakub Vavrik + * @author Tim te Beek * Values based on reference doc - https://www.elastic.co/guide/reference/mapping/date-format/ */ public enum DateFormat { @@ -24,8 +25,8 @@ public enum DateFormat { basic_ordinal_date_time_no_millis, basic_time, basic_time_no_millis, basic_t_time, basic_t_time_no_millis, basic_week_date, basic_week_date_time, basic_week_date_time_no_millis, date, date_hour, date_hour_minute, date_hour_minute_second, date_hour_minute_second_fraction, date_hour_minute_second_millis, date_optional_time, - date_time, date_time_no_millis, hour, hour_minute, hour_minute_second, hour_minute_second_fraction, - hour_minute_second_millis, ordinal_date, ordinal_date_time, ordinal_date_time_no_millis, time, time_no_millis, - t_time, t_time_no_millis, week_date, week_date_time, weekDateTimeNoMillis, week_year, weekyearWeek, - weekyearWeekDay, year, year_month, year_month_day + date_time, date_time_no_millis, epoch_millis, epoch_second, hour, hour_minute, hour_minute_second, + hour_minute_second_fraction, hour_minute_second_millis, ordinal_date, ordinal_date_time, + ordinal_date_time_no_millis, time, time_no_millis, t_time, t_time_no_millis, week_date, week_date_time, + week_date_time_no_millis, weekyear, weekyear_week, weekyear_week_day, year, year_month, year_month_day } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index 58890750e..c1f6b352a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.*; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneId; @@ -16,6 +17,7 @@ /** * @author Peter-Josef Meisch + * @author Tim te Beek */ class ElasticsearchDateConverterTests { @@ -76,4 +78,24 @@ void shouldParseLegacyDateFromString() { assertThat(parsed).isEqualTo(legacyDate); } + + @Test + void shouldParseEpochMillisString() { + Instant instant = Instant.ofEpochMilli(1234568901234L); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.epoch_millis); + + Date parsed = converter.parse("1234568901234"); + + assertThat(parsed.toInstant()).isEqualTo(instant); + } + + @Test + void shouldConvertInstantToString() { + Instant instant = Instant.ofEpochMilli(1234568901234L); + ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.epoch_millis); + + String formatted = converter.format(instant); + + assertThat(formatted).isEqualTo("1234568901234"); + } } From d26dfbba708def67e956c32c3b4adb9b01c779e6 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 29 May 2020 19:01:27 +0200 Subject: [PATCH 0179/1191] DATAES-847 - Polishing. --- .../elasticsearch/annotations/DateFormat.java | 59 ++++++++++++++++--- .../ElasticsearchDateConverterTests.java | 4 +- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java index 75c903649..54a7775bc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/DateFormat.java @@ -16,17 +16,58 @@ package org.springframework.data.elasticsearch.annotations; /** + * Values based on reference doc - https://www.elastic.co/guide/reference/mapping/date-format/ + * * @author Jakub Vavrik * @author Tim te Beek - * Values based on reference doc - https://www.elastic.co/guide/reference/mapping/date-format/ + * @author Peter-Josef Meisch */ public enum DateFormat { - none, custom, basic_date, basic_date_time, basic_date_time_no_millis, basic_ordinal_date, basic_ordinal_date_time, - basic_ordinal_date_time_no_millis, basic_time, basic_time_no_millis, basic_t_time, basic_t_time_no_millis, - basic_week_date, basic_week_date_time, basic_week_date_time_no_millis, date, date_hour, date_hour_minute, - date_hour_minute_second, date_hour_minute_second_fraction, date_hour_minute_second_millis, date_optional_time, - date_time, date_time_no_millis, epoch_millis, epoch_second, hour, hour_minute, hour_minute_second, - hour_minute_second_fraction, hour_minute_second_millis, ordinal_date, ordinal_date_time, - ordinal_date_time_no_millis, time, time_no_millis, t_time, t_time_no_millis, week_date, week_date_time, - week_date_time_no_millis, weekyear, weekyear_week, weekyear_week_day, year, year_month, year_month_day + none, // + custom, // + basic_date, // + basic_date_time, // + basic_date_time_no_millis, // + basic_ordinal_date, // + basic_ordinal_date_time, // + basic_ordinal_date_time_no_millis, // + basic_time, // + basic_time_no_millis, // + basic_t_time, // + basic_t_time_no_millis, // + basic_week_date, // + basic_week_date_time, // + basic_week_date_time_no_millis, // + date, // + date_hour, // + date_hour_minute, // + date_hour_minute_second, // + date_hour_minute_second_fraction, // + date_hour_minute_second_millis, // + date_optional_time, // + date_time, // + date_time_no_millis, // + epoch_millis, // + epoch_second, // + hour, // + hour_minute, // + hour_minute_second, // + hour_minute_second_fraction, // + hour_minute_second_millis, // + ordinal_date, // + ordinal_date_time, // + ordinal_date_time_no_millis, // + time, // + time_no_millis, // + t_time, // + t_time_no_millis, // + week_date, // + week_date_time, // + week_date_time_no_millis, // + weekyear, // + weekyear_week, // + weekyear_week_day, // + year, // + year_month, // + year_month_day // } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index c1f6b352a..a99f9ec2c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -79,7 +79,7 @@ void shouldParseLegacyDateFromString() { assertThat(parsed).isEqualTo(legacyDate); } - @Test + @Test // DATAES-847 void shouldParseEpochMillisString() { Instant instant = Instant.ofEpochMilli(1234568901234L); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.epoch_millis); @@ -89,7 +89,7 @@ void shouldParseEpochMillisString() { assertThat(parsed.toInstant()).isEqualTo(instant); } - @Test + @Test // DATAES-847 void shouldConvertInstantToString() { Instant instant = Instant.ofEpochMilli(1234568901234L); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.epoch_millis); From 852273eff5c06dbd9e1ef4bcd28d2736c482bdf9 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 29 May 2020 19:09:08 +0200 Subject: [PATCH 0180/1191] DATAES-845 - MappingElasticsearchConverter handles lists with null values. Original PR: #470 --- .../MappingElasticsearchConverter.java | 14 ++++++----- ...appingElasticsearchConverterUnitTests.java | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 034fca418..b33a8d272 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -595,8 +595,14 @@ private Object writeCollectionValue(Object value, ElasticsearchPersistentPropert : Streamable.of(ObjectUtils.toObjectArray(value)); List target = new ArrayList<>(); - if (!typeHint.getActualType().getType().equals(Object.class) && isSimpleType(typeHint.getActualType().getType())) { - collectionSource.map(this::getWriteSimpleValue).forEach(target::add); + TypeInformation actualType = typeHint.getActualType(); + Class type = actualType != null ? actualType.getType() : null; + + if (type != null && !type.equals(Object.class) && isSimpleType(type)) { + // noinspection ReturnOfNull + collectionSource // + .map(element -> element != null ? getWriteSimpleValue(element) : null) // + .forEach(target::add); } else { collectionSource.map(it -> { @@ -670,10 +676,6 @@ private boolean requiresTypeHint(TypeInformation type, Class actualType, /** * Compute the type to use by checking the given entity against the store type; - * - * @param entity - * @param source - * @return */ private ElasticsearchPersistentEntity computeClosestEntity(ElasticsearchPersistentEntity entity, Map source) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index adfc67203..5e8b5f909 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -718,6 +718,23 @@ void shouldNotReadSeqNoPrimaryTermProperty() { assertThat(entity.seqNoPrimaryTerm).isNull(); } + @Test // DATAES-845 + void shouldWriteCollectionsWithNullValues() throws JSONException { + EntityWithListProperty entity = new EntityWithListProperty(); + entity.setId("42"); + entity.setValues(Arrays.asList(null, "two", null, "four")); + + String expected = '{' + // + " \"id\": \"42\"," + // + " \"values\": [null, \"two\", null, \"four\"]" + // + '}'; + Document document = Document.create(); + mappingElasticsearchConverter.write(entity, document); + String json = document.toJson(); + + assertEquals(expected, json, false); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -932,4 +949,11 @@ static class EntityWithSeqNoPrimaryTerm { @Nullable private SeqNoPrimaryTerm seqNoPrimaryTerm; } + + @Data + static class EntityWithListProperty { + @Id private String id; + + private List values; + } } From 79dae4ee030b8ebe6301a5d19ac1eee1d3a9071b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 29 May 2020 23:44:32 +0200 Subject: [PATCH 0181/1191] DATAES-848 - Add the name of the index to SearchHit. Original PR: #471 --- .../data/elasticsearch/core/SearchHit.java | 15 +- .../elasticsearch/core/SearchHitMapping.java | 3 +- .../elasticsearch/core/document/Document.java | 22 ++ .../core/document/DocumentAdapters.java | 270 ++---------------- .../core/document/MapDocument.java | 12 + .../core/DocumentAdaptersUnitTests.java | 27 +- .../core/ElasticsearchTemplateTests.java | 17 ++ .../core/SearchHitSupportTest.java | 2 +- .../elasticsearch/core/StreamQueriesTest.java | 22 +- 9 files changed, 124 insertions(+), 266 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index 83b9d3c77..a33c737e9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -35,14 +35,16 @@ */ public class SearchHit { - private final String id; + @Nullable private final String index; + @Nullable private final String id; private final float score; private final List sortValues; private final T content; private final Map> highlightFields = new LinkedHashMap<>(); - public SearchHit(@Nullable String id, float score, @Nullable Object[] sortValues, + public SearchHit(@Nullable String index, @Nullable String id, float score, @Nullable Object[] sortValues, @Nullable Map> highlightFields, T content) { + this.index = index; this.id = id; this.score = score; this.sortValues = (sortValues != null) ? Arrays.asList(sortValues) : new ArrayList<>(); @@ -53,6 +55,15 @@ public SearchHit(@Nullable String id, float score, @Nullable Object[] sortValues this.content = content; } + /** + * @return the index name where the hit's document was found + * @since 4.1 + */ + @Nullable + public String getIndex() { + return index; + } + @Nullable public String getId() { return id; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index 2a9a2973b..f0a65adb8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -62,12 +62,13 @@ SearchHit mapHit(SearchDocument searchDocument, T content) { Assert.notNull(searchDocument, "searchDocument is null"); Assert.notNull(content, "content is null"); + String index = searchDocument.getIndex(); String id = searchDocument.hasId() ? searchDocument.getId() : null; float score = searchDocument.getScore(); Object[] sortValues = searchDocument.getSortValues(); Map> highlightFields = getHighlightsAndRemapFieldNames(searchDocument); - return new SearchHit<>(id, score, sortValues, highlightFields, content); + return new SearchHit<>(index, id, score, sortValues, highlightFields, content); } SearchHits mapHits(SearchDocumentResponse searchDocumentResponse, List contents) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java index 59af552de..444db1b89 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/Document.java @@ -111,6 +111,27 @@ default boolean hasId() { return false; } + /** + * @return the index if this document was retrieved from an index + * @since 4.1 + */ + @Nullable + default String getIndex() { + return null; + } + + /** + * Sets the index name for this document + * + * @param index index name + *

+ * The default implementation throws {@link UnsupportedOperationException}. + * @since 4.1 + */ + default void setIndex(@Nullable String index) { + throw new UnsupportedOperationException(); + } + /** * Retrieve the identifier associated with this {@link Document}. *

@@ -461,4 +482,5 @@ default R transform(Function transformer) { * @return a JSON representation of this document. */ String toJson(); + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 95cf06c37..34c5129ad 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -77,11 +77,12 @@ public static Document from(GetResponse source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), + return fromDocumentFields(source, source.getIndex(), source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm()); } Document document = Document.from(source.getSourceAsMap()); + document.setIndex(source.getIndex()); document.setId(source.getId()); document.setVersion(source.getVersion()); document.setSeqNo(source.getSeqNo()); @@ -108,11 +109,12 @@ public static Document from(GetResult source) { } if (source.isSourceEmpty()) { - return fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), + return fromDocumentFields(source, source.getIndex(), source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm()); } Document document = Document.from(source.getSource()); + document.setIndex(source.getIndex()); document.setId(source.getId()); document.setVersion(source.getVersion()); document.setSeqNo(source.getSeqNo()); @@ -157,10 +159,12 @@ public static SearchDocument from(SearchHit source) { if (sourceRef == null || sourceRef.length() == 0) { return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, - fromDocumentFields(source, source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm())); + fromDocumentFields(source, source.getIndex(), source.getId(), source.getVersion(), source.getSeqNo(), + source.getPrimaryTerm())); } Document document = Document.from(source.getSourceAsMap()); + document.setIndex(source.getIndex()); document.setId(source.getId()); if (source.getVersion() >= 0) { @@ -177,13 +181,15 @@ public static SearchDocument from(SearchHit source) { * Create an unmodifiable {@link Document} from {@link Iterable} of {@link DocumentField}s. * * @param documentFields the {@link DocumentField}s backing the {@link Document}. + * @param index * @return the adapted {@link Document}. */ - public static Document fromDocumentFields(Iterable documentFields, String id, long version, long seqNo, - long primaryTerm) { + public static Document fromDocumentFields(Iterable documentFields, String index, String id, + long version, long seqNo, long primaryTerm) { if (documentFields instanceof Collection) { - return new DocumentFieldAdapter((Collection) documentFields, id, version, seqNo, primaryTerm); + return new DocumentFieldAdapter((Collection) documentFields, index, id, version, seqNo, + primaryTerm); } List fields = new ArrayList<>(); @@ -191,58 +197,49 @@ public static Document fromDocumentFields(Iterable documentFields fields.add(documentField); } - return new DocumentFieldAdapter(fields, id, version, seqNo, primaryTerm); + return new DocumentFieldAdapter(fields, index, id, version, seqNo, primaryTerm); } // TODO: Performance regarding keys/values/entry-set static class DocumentFieldAdapter implements Document { private final Collection documentFields; + private final String index; private final String id; private final long version; private final long seqNo; private final long primaryTerm; - DocumentFieldAdapter(Collection documentFields, String id, long version, long seqNo, + DocumentFieldAdapter(Collection documentFields, String index, String id, long version, long seqNo, long primaryTerm) { this.documentFields = documentFields; + this.index = index; this.id = id; this.version = version; this.seqNo = seqNo; this.primaryTerm = primaryTerm; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasId() - */ + @Override + public String getIndex() { + return index; + } + @Override public boolean hasId() { return StringUtils.hasLength(id); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getId() - */ @Override public String getId() { return this.id; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasVersion() - */ @Override public boolean hasVersion() { return this.version >= 0; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getVersion() - */ @Override public long getVersion() { @@ -253,19 +250,11 @@ public long getVersion() { return this.version; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() - */ @Override public boolean hasSeqNo() { return true; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getSeqNo() - */ @Override public long getSeqNo() { @@ -276,19 +265,11 @@ public long getSeqNo() { return this.seqNo; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() - */ @Override public boolean hasPrimaryTerm() { return true; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getPrimaryTerm() - */ @Override public long getPrimaryTerm() { @@ -299,28 +280,16 @@ public long getPrimaryTerm() { return this.primaryTerm; } - /* - * (non-Javadoc) - * @see java.util.Map#size() - */ @Override public int size() { return documentFields.size(); } - /* - * (non-Javadoc) - * @see java.util.Map#isEmpty() - */ @Override public boolean isEmpty() { return documentFields.isEmpty(); } - /* - * (non-Javadoc) - * @see java.util.Map#containsKey(java.lang.Object) - */ @Override public boolean containsKey(Object key) { @@ -333,10 +302,6 @@ public boolean containsKey(Object key) { return false; } - /* - * (non-Javadoc) - * @see java.util.Map#containsValue(java.lang.Object) - */ @Override public boolean containsValue(Object value) { @@ -351,10 +316,6 @@ public boolean containsValue(Object value) { return false; } - /* - * (non-Javadoc) - * @see java.util.Map#get(java.lang.Object) - */ @Override @Nullable public Object get(Object key) { @@ -365,74 +326,42 @@ public Object get(Object key) { } - /* - * (non-Javadoc) - * @see java.util.Map#put(java.lang.Object, java.lang.Object) - */ @Override public Object put(String key, Object value) { throw new UnsupportedOperationException(); } - /* - * (non-Javadoc) - * @see java.util.Map#remove(java.lang.Object) - */ @Override public Object remove(Object key) { throw new UnsupportedOperationException(); } - /* - * (non-Javadoc) - * @see java.util.Map#putAll(Map) - */ @Override public void putAll(Map m) { throw new UnsupportedOperationException(); } - /* - * (non-Javadoc) - * @see java.util.Map#clear() - */ @Override public void clear() { throw new UnsupportedOperationException(); } - /* - * (non-Javadoc) - * @see java.util.Map#keySet() - */ @Override public Set keySet() { return documentFields.stream().map(DocumentField::getName).collect(Collectors.toCollection(LinkedHashSet::new)); } - /* - * (non-Javadoc) - * @see java.util.Map#values() - */ @Override public Collection values() { return documentFields.stream().map(DocumentFieldAdapter::getValue).collect(Collectors.toList()); } - /* - * (non-Javadoc) - * @see java.util.Map#entrySet() - */ @Override public Set> entrySet() { return documentFields.stream().collect(Collectors.toMap(DocumentField::getName, DocumentFieldAdapter::getValue)) .entrySet(); } - /* - * (non-Javadoc) - * @see java.util.Map#forEach(java.util.function.BiConsumer) - */ @Override public void forEach(BiConsumer action) { @@ -441,10 +370,6 @@ public void forEach(BiConsumer action) { documentFields.forEach(field -> action.accept(field.getName(), getValue(field))); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#toJson() - */ @Override public String toJson() { @@ -472,10 +397,6 @@ public String toJson() { } } - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ @Override public String toString() { return getClass().getSimpleName() + '@' + this.id + '#' + this.version + ' ' + toJson(); @@ -517,10 +438,6 @@ static class SearchDocumentAdapter implements SearchDocument { this.highlightFields.putAll(highlightFields); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#append(java.lang.String, java.lang.Object) - */ @Override public SearchDocument append(String key, Object value) { delegate.append(key, value); @@ -528,281 +445,162 @@ public SearchDocument append(String key, Object value) { return this; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getScore() - */ @Override public float getScore() { return score; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getFields() - */ @Override public Map> getFields() { return fields; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getSortValues() - */ @Override public Object[] getSortValues() { return sortValues; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.SearchDocument#getHighlightFields() - */ @Override public Map> getHighlightFields() { return highlightFields; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasId() - */ + @Override + public String getIndex() { + return delegate.getIndex(); + } + @Override public boolean hasId() { return delegate.hasId(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getId() - */ @Override public String getId() { return delegate.getId(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#setId(java.lang.String) - */ @Override public void setId(String id) { delegate.setId(id); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasVersion() - */ @Override public boolean hasVersion() { return delegate.hasVersion(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getVersion() - */ @Override public long getVersion() { return delegate.getVersion(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#setVersion(long) - */ @Override public void setVersion(long version) { delegate.setVersion(version); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasSeqNo() - */ @Override public boolean hasSeqNo() { return delegate.hasSeqNo(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getSeqNo() - */ @Override public long getSeqNo() { return delegate.getSeqNo(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#setSeqNo(long) - */ @Override public void setSeqNo(long seqNo) { delegate.setSeqNo(seqNo); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#hasPrimaryTerm() - */ @Override public boolean hasPrimaryTerm() { return delegate.hasPrimaryTerm(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#getPrimaryTerm() - */ @Override public long getPrimaryTerm() { return delegate.getPrimaryTerm(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#setPrimaryTerm(long) - */ @Override public void setPrimaryTerm(long primaryTerm) { delegate.setPrimaryTerm(primaryTerm); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#get(java.lang.Object, java.lang.Class) - */ @Override @Nullable public T get(Object key, Class type) { return delegate.get(key, type); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.document.Document#toJson() - */ @Override public String toJson() { return delegate.toJson(); } - /* - * (non-Javadoc) - * @see java.util.Map#size() - */ @Override public int size() { return delegate.size(); } - /* - * (non-Javadoc) - * @see java.util.Map#isEmpty() - */ @Override public boolean isEmpty() { return delegate.isEmpty(); } - /* - * (non-Javadoc) - * @see java.util.Map#containsKey(java.lang.Object) - */ @Override public boolean containsKey(Object key) { return delegate.containsKey(key); } - /* - * (non-Javadoc) - * @see java.util.Map#containsValue(java.lang.Object) - */ @Override public boolean containsValue(Object value) { return delegate.containsValue(value); } - /* - * (non-Javadoc) - * @see java.util.Map#get(java.lang.Object) - */ @Override public Object get(Object key) { return delegate.get(key); } - /* - * (non-Javadoc) - * @see java.util.Map#put(java.lang.Object, java.lang.Object) - */ @Override public Object put(String key, Object value) { return delegate.put(key, value); } - /* - * (non-Javadoc) - * @see java.util.Map#remove(java.lang.Object) - */ @Override public Object remove(Object key) { return delegate.remove(key); } - /* - * (non-Javadoc) - * @see java.util.Map#putAll(Map) - */ @Override public void putAll(Map m) { delegate.putAll(m); } - /* - * (non-Javadoc) - * @see java.util.Map#clear() - */ @Override public void clear() { delegate.clear(); } - /* - * (non-Javadoc) - * @see java.util.Map#keySet() - */ @Override public Set keySet() { return delegate.keySet(); } - /* - * (non-Javadoc) - * @see java.util.Map#values() - */ @Override public Collection values() { return delegate.values(); } - /* - * (non-Javadoc) - * @see java.util.Map#entrySet() - */ @Override public Set> entrySet() { return delegate.entrySet(); } - /* - * (non-Javadoc) - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(Object o) { if (this == o) { @@ -815,37 +613,21 @@ public boolean equals(Object o) { return Float.compare(that.score, score) == 0 && delegate.equals(that.delegate); } - /* - * (non-Javadoc) - * @see java.lang.Object#hashCode() - */ @Override public int hashCode() { return delegate.hashCode(); } - /* - * (non-Javadoc) - * @see java.util.Map#forEach(java.util.function.BiConsumer) - */ @Override public void forEach(BiConsumer action) { delegate.forEach(action); } - /* - * (non-Javadoc) - * @see java.util.Map#remove(java.lang.Object, java.lang.Object) - */ @Override public boolean remove(Object key, Object value) { return delegate.remove(key, value); } - /* - * (non-Javadoc) - * @see java.lang.Object#toString() - */ @Override public String toString() { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java index fb80c35e1..693e55c18 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/MapDocument.java @@ -40,6 +40,7 @@ class MapDocument implements Document { private final LinkedHashMap documentAsMap; + private @Nullable String index; private @Nullable String id; private @Nullable Long version; private @Nullable Long seqNo; @@ -53,6 +54,17 @@ class MapDocument implements Document { this.documentAsMap = new LinkedHashMap<>(documentAsMap); } + @Override + public void setIndex(@Nullable String index) { + this.index = index; + } + + @Nullable + @Override + public String getIndex() { + return index; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.document.Document#hasId() diff --git a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java index 8568e6d46..37dca2fd5 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java @@ -17,6 +17,7 @@ import static org.assertj.core.api.Assertions.*; +import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; @@ -27,7 +28,9 @@ import org.elasticsearch.common.document.DocumentField; import org.elasticsearch.common.text.Text; import org.elasticsearch.index.get.GetResult; +import org.elasticsearch.index.shard.ShardId; import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchShardTarget; import org.junit.jupiter.api.Test; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.DocumentAdapters; @@ -42,7 +45,7 @@ */ public class DocumentAdaptersUnitTests { - @Test // DATAES-628 + @Test // DATAES-628, DATAES-848 public void shouldAdaptGetResponse() { Map fields = Collections.singletonMap("field", @@ -53,6 +56,7 @@ public void shouldAdaptGetResponse() { Document document = DocumentAdapters.from(response); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isTrue(); @@ -64,7 +68,7 @@ public void shouldAdaptGetResponse() { assertThat(document.getPrimaryTerm()).isEqualTo(2); } - @Test // DATAES-628 + @Test // DATAES-628, DATAES-848 public void shouldAdaptGetResponseSource() { BytesArray source = new BytesArray("{\"field\":\"value\"}"); @@ -74,6 +78,7 @@ public void shouldAdaptGetResponseSource() { Document document = DocumentAdapters.from(response); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isTrue(); @@ -85,7 +90,7 @@ public void shouldAdaptGetResponseSource() { assertThat(document.getPrimaryTerm()).isEqualTo(2); } - @Test // DATAES-799 + @Test // DATAES-799, DATAES-848 public void shouldAdaptGetResult() { Map fields = Collections.singletonMap("field", @@ -95,6 +100,7 @@ public void shouldAdaptGetResult() { Document document = DocumentAdapters.from(getResult); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isTrue(); @@ -106,7 +112,7 @@ public void shouldAdaptGetResult() { assertThat(document.getPrimaryTerm()).isEqualTo(2); } - @Test // DATAES-799 + @Test // DATAES-799, DATAES-848 public void shouldAdaptGetResultSource() { BytesArray source = new BytesArray("{\"field\":\"value\"}"); @@ -115,6 +121,7 @@ public void shouldAdaptGetResultSource() { Document document = DocumentAdapters.from(getResult); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isTrue(); @@ -126,19 +133,22 @@ public void shouldAdaptGetResultSource() { assertThat(document.getPrimaryTerm()).isEqualTo(2); } - @Test // DATAES-628 - public void shouldAdaptSearchResponse() { + @Test // DATAES-628, DATAES-848 + public void shouldAdaptSearchResponse() throws IOException { Map fields = Collections.singletonMap("field", new DocumentField("field", Collections.singletonList("value"))); + SearchShardTarget shard = new SearchShardTarget("node", new ShardId("index", "uuid", 42), null, null); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + searchHit.shard(shard); searchHit.setSeqNo(1); searchHit.setPrimaryTerm(2); searchHit.score(42); SearchDocument document = DocumentAdapters.from(searchHit); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isFalse(); @@ -199,12 +209,14 @@ public void shouldRenderToJson() { assertThat(document.toJson()).isEqualTo("{\"string\":\"value\",\"bool\":[true,true,false]}"); } - @Test // DATAES-628 + @Test // DATAES-628, DATAES-848 public void shouldAdaptSearchResponseSource() { BytesArray source = new BytesArray("{\"field\":\"value\"}"); + SearchShardTarget shard = new SearchShardTarget("node", new ShardId("index", "uuid", 42), null, null); SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), Collections.emptyMap()); + searchHit.shard(shard); searchHit.sourceRef(source).score(42); searchHit.version(22); searchHit.setSeqNo(1); @@ -212,6 +224,7 @@ public void shouldAdaptSearchResponseSource() { SearchDocument document = DocumentAdapters.from(searchHit); + assertThat(document.getIndex()).isEqualTo("index"); assertThat(document.hasId()).isTrue(); assertThat(document.getId()).isEqualTo("my-id"); assertThat(document.hasVersion()).isTrue(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index f538b29b3..a21057f8d 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -1728,6 +1728,23 @@ public void shouldReturnIds() { assertThat(ids).hasSize(30); } + @Test // DATAES-848 + public void shouldReturnIndexName() { + // given + List entities = createSampleEntitiesWithMessage("Test message", 3); + // when + operations.bulkIndex(entities, index); + indexOperations.refresh(); + NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("message", "message")) + .withPageable(PageRequest.of(0, 100)).build(); + // then + SearchHits searchHits = operations.search(searchQuery, SampleEntity.class); + + searchHits.forEach(searchHit -> { + assertThat(searchHit.getIndex()).isEqualTo(INDEX_NAME_SAMPLE_ENTITY); + }); + } + @Test public void shouldReturnDocumentAboveMinimalScoreGivenQuery() { // given diff --git a/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java index 6ef6f8cc4..9bd5bc4af 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/SearchHitSupportTest.java @@ -84,7 +84,7 @@ public boolean hasNext() { @Override public SearchHit next() { String nextString = iterator.next(); - return new SearchHit<>("id", 1.0f, new Object[0], emptyMap(), nextString); + return new SearchHit<>("index", "id", 1.0f, new Object[0], emptyMap(), nextString); } } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java index 51cc2589f..0d53e30ac 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/StreamQueriesTest.java @@ -38,7 +38,7 @@ public void shouldCallClearScrollOnIteratorClose() { // given List> hits = new ArrayList<>(); - hits.add(new SearchHit(null, 0, null, null, "one")); + hits.add(new SearchHit(null, null, 0, null, null, "one")); SearchScrollHits searchHits = newSearchScrollHits(hits, "1234"); @@ -66,7 +66,7 @@ public void shouldReturnTotalHits() { // given List> hits = new ArrayList<>(); - hits.add(new SearchHit(null, 0, null, null, "one")); + hits.add(new SearchHit(null, null, 0, null, null, "one")); SearchScrollHits searchHits = newSearchScrollHits(hits, "1234"); @@ -86,11 +86,11 @@ public void shouldReturnTotalHits() { void shouldClearAllScrollIds() { SearchScrollHits searchHits1 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-1"); SearchScrollHits searchHits2 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits3 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); Iterator> searchScrollHitsIterator = Arrays @@ -115,11 +115,11 @@ void shouldClearAllScrollIds() { void shouldReturnAllForRequestedSizeOf0() { SearchScrollHits searchHits1 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-1"); SearchScrollHits searchHits2 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits3 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); Iterator> searchScrollHitsIterator = Arrays @@ -140,11 +140,11 @@ void shouldReturnAllForRequestedSizeOf0() { void shouldOnlyReturnRequestedCount() { SearchScrollHits searchHits1 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-1"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-1"); SearchScrollHits searchHits2 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits3 = newSearchScrollHits( - Collections.singletonList(new SearchHit(null, 0, null, null, "one")), "s-2"); + Collections.singletonList(new SearchHit(null, null, 0, null, null, "one")), "s-2"); SearchScrollHits searchHits4 = newSearchScrollHits(Collections.emptyList(), "s-3"); Iterator> searchScrollHitsIterator = Arrays From 859b22db8e396dc533d479dcf49a590c07b8dc24 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 31 May 2020 22:59:32 +0200 Subject: [PATCH 0182/1191] DATAES-850 - Add warning and docs for missing TemporalAccessor configuration. Original PR: #472 --- .../elasticsearch-object-mapping.adoc | 3 +- .../MappingElasticsearchConverter.java | 39 ++++++++++++++++++- ...SimpleElasticsearchPersistentProperty.java | 5 ++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index fe1a90bd2..b1023af3f 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -48,7 +48,8 @@ The following annotations are available: ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. -NOTE: If you are using a custom date format, you need to use _uuuu_ for the year instead of _yyyy_. This is due to a https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats[change in Elasticsearch 7]. +NOTE: Properties that derive from `TemporalAccessor` must either have a `@Field` annotation of type `FieldType.Date` or a custom converter must be registerd for this type. + +If you are using a custom date format, you need to use _uuuu_ for the year instead of _yyyy_. This is due to a https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats[change in Elasticsearch 7]. The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index b33a8d272..a4605285a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core.convert; +import java.time.temporal.TemporalAccessor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -26,7 +27,10 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; @@ -77,6 +81,8 @@ public class MappingElasticsearchConverter implements ElasticsearchConverter, ApplicationContextAware, InitializingBean { + private static final Logger LOGGER = LoggerFactory.getLogger(MappingElasticsearchConverter.class); + private final MappingContext, ElasticsearchPersistentProperty> mappingContext; private final GenericConversionService conversionService; @@ -85,6 +91,8 @@ public class MappingElasticsearchConverter private ElasticsearchTypeMapper typeMapper; + private ConcurrentHashMap propertyWarnings = new ConcurrentHashMap<>(); + public MappingElasticsearchConverter( MappingContext, ElasticsearchPersistentProperty> mappingContext) { this(mappingContext, null); @@ -267,11 +275,26 @@ protected R readValue(@Nullable Object source, ElasticsearchPersistentProper return null; } + Class rawType = targetType.getType(); + if (property.hasPropertyConverter() && String.class.isAssignableFrom(source.getClass())) { source = property.getPropertyConverter().read((String) source); + } else if (TemporalAccessor.class.isAssignableFrom(property.getType()) + && !conversions.hasCustomReadTarget(source.getClass(), rawType)) { + + // log at most 5 times + String propertyName = property.getOwner().getType().getSimpleName() + '.' + property.getName(); + String key = propertyName + "-read"; + int count = propertyWarnings.computeIfAbsent(key, k -> 0); + if (count < 5) { + LOGGER.warn( + "Type {} of property {} is a TemporalAccessor class but has neither a @Field annotation defining the date type nor a registered converter for reading!" + + " It cannot be mapped from a complex object in Elasticsearch!", + property.getType().getSimpleName(), propertyName); + propertyWarnings.put(key, count + 1); + } } - Class rawType = targetType.getType(); if (conversions.hasCustomReadTarget(source.getClass(), rawType)) { return rawType.cast(conversionService.convert(source, rawType)); } else if (source instanceof List) { @@ -473,6 +496,20 @@ protected void writeProperties(ElasticsearchPersistentEntity entity, Persiste if (property.hasPropertyConverter()) { ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); value = propertyConverter.write(value); + } else if (TemporalAccessor.class.isAssignableFrom(property.getType()) + && !conversions.hasCustomWriteTarget(value.getClass())) { + + // log at most 5 times + String propertyName = entity.getType().getSimpleName() + '.' + property.getName(); + String key = propertyName + "-write"; + int count = propertyWarnings.computeIfAbsent(key, k -> 0); + if (count < 5) { + LOGGER.warn( + "Type {} of property {} is a TemporalAccessor class but has neither a @Field annotation defining the date type nor a registered converter for writing!" + + " It will be mapped to a complex object in Elasticsearch!", + property.getType().getSimpleName(), propertyName); + propertyWarnings.put(key, count + 1); + } } if (!isSimpleType(value)) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index 15771b084..b834a46e1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -122,8 +122,9 @@ private void initDateConverter() { DateFormat dateFormat = field.format(); if (dateFormat == DateFormat.none) { - throw new MappingException(String.format("property %s is annotated with FieldType.%s but has no DateFormat defined", - getName(), field.type().name())); + throw new MappingException( + String.format("Property %s is annotated with FieldType.%s but has no DateFormat defined", + getOwner().getType().getSimpleName() + "." + getName(), field.type().name())); } ElasticsearchDateConverter converter = null; From caebe08cf2592351336e94ae475f31db3314b44a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 3 Jun 2020 14:25:48 +0200 Subject: [PATCH 0183/1191] DATAES-263 - Inner Hits support. (#473) original PR: #473 --- .../reference/elasticsearch-operations.adoc | 1 + .../core/AbstractElasticsearchTemplate.java | 5 +- .../core/ReactiveElasticsearchTemplate.java | 2 +- .../data/elasticsearch/core/SearchHit.java | 52 +++++ .../elasticsearch/core/SearchHitMapping.java | 181 +++++++++++++++--- .../core/document/DocumentAdapters.java | 55 +++++- .../core/document/NestedMetaData.java | 53 +++++ .../core/document/SearchDocument.java | 21 +- .../core/document/SearchDocumentResponse.java | 38 +++- .../elasticsearch/core/InnerHitsTests.java | 170 ++++++++++++++++ .../core/InnerHitsTransportTests.java | 31 +++ 11 files changed, 568 insertions(+), 41 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/document/NestedMetaData.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTransportTests.java diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index b8a691938..69850323f 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -134,6 +134,7 @@ Contains the following information: * Score * Sort Values * Highlight fields +* Inner hits (this is an embedded `SearchHits` object containing eventually returned inner hits) * The retrieved entity of type .SearchHits diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 605275bdc..98f3d2ccd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -624,7 +624,7 @@ public ReadSearchDocumentResponseCallback(Class type, IndexCoordinates index) @Override public SearchHits doWith(SearchDocumentResponse response) { List entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList()); - return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()).mapHits(response, entities); + return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapHits(response, entities); } } @@ -644,8 +644,7 @@ public ReadSearchScrollDocumentResponseCallback(Class type, IndexCoordinates @Override public SearchScrollHits doWith(SearchDocumentResponse response) { List entities = response.getSearchDocuments().stream().map(delegate::doWith).collect(Collectors.toList()); - return SearchHitMapping.mappingFor(type, elasticsearchConverter.getMappingContext()).mapScrollHits(response, - entities); + return SearchHitMapping.mappingFor(type, elasticsearchConverter).mapScrollHits(response, entities); } } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 4b353439d..8a0e3dae4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -878,7 +878,7 @@ public ReadSearchDocumentCallback(Class type, IndexCoordinates index) { @Override public Mono> doWith(SearchDocument response) { return delegate.doWith(response) - .map(entity -> SearchHitMapping.mappingFor(type, converter.getMappingContext()).mapHit(response, entity)); + .map(entity -> SearchHitMapping.mappingFor(type, converter).mapHit(response, entity)); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java index a33c737e9..1c4a59bf3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHit.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.springframework.data.elasticsearch.core.document.NestedMetaData; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -41,17 +42,32 @@ public class SearchHit { private final List sortValues; private final T content; private final Map> highlightFields = new LinkedHashMap<>(); + private final Map> innerHits = new LinkedHashMap<>(); + @Nullable private final NestedMetaData nestedMetaData; public SearchHit(@Nullable String index, @Nullable String id, float score, @Nullable Object[] sortValues, @Nullable Map> highlightFields, T content) { + this(index, id, score, sortValues, highlightFields, null, null, content); + } + + public SearchHit(@Nullable String index, @Nullable String id, float score, @Nullable Object[] sortValues, + @Nullable Map> highlightFields, @Nullable Map> innerHits, + @Nullable NestedMetaData nestedMetaData, T content) { this.index = index; this.id = id; this.score = score; this.sortValues = (sortValues != null) ? Arrays.asList(sortValues) : new ArrayList<>(); + if (highlightFields != null) { this.highlightFields.putAll(highlightFields); } + if (innerHits != null) { + this.innerHits.putAll(innerHits); + } + + this.nestedMetaData = nestedMetaData; + this.content = content; } @@ -90,6 +106,9 @@ public List getSortValues() { return Collections.unmodifiableList(sortValues); } + /** + * @return the map from field names to highlight values, never {@literal null} + */ public Map> getHighlightFields() { return Collections.unmodifiableMap(highlightFields.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, entry -> Collections.unmodifiableList(entry.getValue())))); @@ -108,6 +127,39 @@ public List getHighlightField(String field) { return Collections.unmodifiableList(highlightFields.getOrDefault(field, Collections.emptyList())); } + /** + * returns the {@link SearchHits} for the inner hits with the given name. If the inner hits could be mapped to a + * nested entity class, the returned data will be of this type, otherwise + * {{@link org.springframework.data.elasticsearch.core.document.SearchDocument}} instances are returned in this + * {@link SearchHits} object. + * + * @param name the inner hits name + * @return {@link SearchHits} if available, otherwise {@literal null} + */ + @Nullable + public SearchHits getInnerHits(String name) { + return innerHits.get(name); + } + + /** + * @return the map from inner_hits names to inner hits, in a {@link SearchHits} object, never {@literal null} + * @since 4.1 + */ + public Map> getInnerHits() { + return innerHits; + } + + /** + * If this is a nested inner hit, return the nested metadata information + * + * @return {{@link NestedMetaData} + * @since 4.1 + */ + @Nullable + public NestedMetaData getNestedMetaData() { + return nestedMetaData; + } + @Override public String toString() { return "SearchHit{" + "id='" + id + '\'' + ", score=" + score + ", sortValues=" + sortValues + ", content=" diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index f0a65adb8..d6a0b3933 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -16,11 +16,18 @@ package org.springframework.data.elasticsearch.core; import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.elasticsearch.search.aggregations.Aggregations; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.document.NestedMetaData; import org.springframework.data.elasticsearch.core.document.SearchDocument; import org.springframework.data.elasticsearch.core.document.SearchDocumentResponse; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; @@ -39,36 +46,24 @@ * @since 4.0 */ class SearchHitMapping { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchHitMapping.class); + private final Class type; + private final ElasticsearchConverter converter; private final MappingContext, ElasticsearchPersistentProperty> mappingContext; - private SearchHitMapping(Class type, - MappingContext, ElasticsearchPersistentProperty> context) { - + private SearchHitMapping(Class type, ElasticsearchConverter converter) { Assert.notNull(type, "type is null"); - Assert.notNull(context, "context is null"); + Assert.notNull(converter, "converter is null"); this.type = type; - this.mappingContext = context; + this.converter = converter; + this.mappingContext = converter.getMappingContext(); } - static SearchHitMapping mappingFor(Class entityClass, - MappingContext, ElasticsearchPersistentProperty> context) { - return new SearchHitMapping<>(entityClass, context); - } - - SearchHit mapHit(SearchDocument searchDocument, T content) { - - Assert.notNull(searchDocument, "searchDocument is null"); - Assert.notNull(content, "content is null"); - - String index = searchDocument.getIndex(); - String id = searchDocument.hasId() ? searchDocument.getId() : null; - float score = searchDocument.getScore(); - Object[] sortValues = searchDocument.getSortValues(); - Map> highlightFields = getHighlightsAndRemapFieldNames(searchDocument); - - return new SearchHit<>(index, id, score, sortValues, highlightFields, content); + static SearchHitMapping mappingFor(Class entityClass, ElasticsearchConverter converter) { + return new SearchHitMapping<>(entityClass, converter); } SearchHits mapHits(SearchDocumentResponse searchDocumentResponse, List contents) { @@ -105,6 +100,21 @@ private SearchHitsImpl mapHitsFromResponse(SearchDocumentResponse searchDocum return new SearchHitsImpl<>(totalHits, totalHitsRelation, maxScore, scrollId, searchHits, aggregations); } + SearchHit mapHit(SearchDocument searchDocument, T content) { + + Assert.notNull(searchDocument, "searchDocument is null"); + Assert.notNull(content, "content is null"); + + return new SearchHit(searchDocument.getIndex(), // + searchDocument.hasId() ? searchDocument.getId() : null, // + searchDocument.getScore(), // + searchDocument.getSortValues(), // + getHighlightsAndRemapFieldNames(searchDocument), // + mapInnerHits(searchDocument), // + searchDocument.getNestedMetaData(), // + content); // + } + @Nullable private Map> getHighlightsAndRemapFieldNames(SearchDocument searchDocument) { Map> highlightFields = searchDocument.getHighlightFields(); @@ -123,4 +133,131 @@ private Map> getHighlightsAndRemapFieldNames(SearchDocument return property != null ? property.getName() : entry.getKey(); }, Map.Entry::getValue)); } + + private Map> mapInnerHits(SearchDocument searchDocument) { + + Map> innerHits = new LinkedHashMap<>(); + Map documentInnerHits = searchDocument.getInnerHits(); + + if (documentInnerHits != null && documentInnerHits.size() > 0) { + + SearchHitMapping searchDocumentSearchHitMapping = SearchHitMapping + .mappingFor(SearchDocument.class, converter); + + for (Map.Entry entry : documentInnerHits.entrySet()) { + SearchDocumentResponse searchDocumentResponse = entry.getValue(); + + SearchHits searchHits = searchDocumentSearchHitMapping + .mapHitsFromResponse(searchDocumentResponse, searchDocumentResponse.getSearchDocuments()); + + // map Documents to real objects + SearchHits mappedSearchHits = mapInnerDocuments(searchHits, type); + + innerHits.put(entry.getKey(), mappedSearchHits); + } + + } + return innerHits; + } + + /** + * try to convert the SearchDocument instances to instances of the inner property class. + * + * @param searchHits {@link SearchHits} containing {@link Document} instances + * @param type the class of the containing class + * @return a new {@link SearchHits} instance containing the mapped objects or the original inout if any error occurs + */ + private SearchHits mapInnerDocuments(SearchHits searchHits, Class type) { + + if (searchHits.getTotalHits() == 0) { + return searchHits; + } + + try { + NestedMetaData nestedMetaData = searchHits.getSearchHit(0).getContent().getNestedMetaData(); + ElasticsearchPersistentEntityWithNestedMetaData persistentEntityWithNestedMetaData = getPersistentEntity( + mappingContext.getPersistentEntity(type), nestedMetaData); + + List> convertedSearchHits = new ArrayList<>(); + + if (persistentEntityWithNestedMetaData.entity != null) { + Class targetType = persistentEntityWithNestedMetaData.entity.getType(); + // convert the list of SearchHit to list of SearchHit + searchHits.getSearchHits().forEach(searchHit -> { + SearchDocument searchDocument = searchHit.getContent(); + + Object targetObject = converter.read(targetType, searchDocument); + convertedSearchHits.add(new SearchHit(searchDocument.getIndex(), // + searchDocument.getId(), // + searchDocument.getScore(), // + searchDocument.getSortValues(), // + searchDocument.getHighlightFields(), // + mapInnerHits(searchDocument), // + persistentEntityWithNestedMetaData.nestedMetaData, // + targetObject)); + }); + + String scrollId = null; + if (searchHits instanceof SearchHitsImpl) { + scrollId = ((SearchHitsImpl) searchHits).getScrollId(); + } + + return new SearchHitsImpl<>(searchHits.getTotalHits(), // + searchHits.getTotalHitsRelation(), // + searchHits.getMaxScore(), // + scrollId, // + convertedSearchHits, // + searchHits.getAggregations()); + } + } catch (Exception e) { + LOGGER.warn("Could not map inner_hits", e); + } + + return searchHits; + } + + /** + * find a {@link ElasticsearchPersistentEntity} following the property chain defined by the nested metadata + * + * @param persistentEntity base entity + * @param nestedMetaData nested metadata + * @return The found entity or null + */ + @Nullable + private ElasticsearchPersistentEntityWithNestedMetaData getPersistentEntity( + @Nullable ElasticsearchPersistentEntity persistentEntity, @Nullable NestedMetaData nestedMetaData) { + + NestedMetaData currentMetaData = nestedMetaData; + List mappedNestedMetaDatas = new LinkedList<>(); + + while (persistentEntity != null && currentMetaData != null) { + ElasticsearchPersistentProperty persistentProperty = persistentEntity + .getPersistentPropertyWithFieldName(currentMetaData.getField()); + + if (persistentProperty == null) { + persistentEntity = null; + } else { + persistentEntity = mappingContext.getPersistentEntity(persistentProperty.getActualType()); + mappedNestedMetaDatas.add(0, + NestedMetaData.of(persistentProperty.getName(), currentMetaData.getOffset(), null)); + currentMetaData = currentMetaData.getChild(); + } + } + + NestedMetaData mappedNestedMetaData = mappedNestedMetaDatas.stream().reduce(null, + (result, nmd) -> NestedMetaData.of(nmd.getField(), nmd.getOffset(), result)); + + return new ElasticsearchPersistentEntityWithNestedMetaData(persistentEntity, mappedNestedMetaData); + } + + private static class ElasticsearchPersistentEntityWithNestedMetaData { + @Nullable private ElasticsearchPersistentEntity entity; + private NestedMetaData nestedMetaData; + + public ElasticsearchPersistentEntityWithNestedMetaData(@Nullable ElasticsearchPersistentEntity entity, + NestedMetaData nestedMetaData) { + this.entity = entity; + this.nestedMetaData = nestedMetaData; + } + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java index 34c5129ad..7f2d9b5ea 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/DocumentAdapters.java @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -37,6 +38,7 @@ import org.elasticsearch.common.text.Text; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.search.SearchHit; +import org.elasticsearch.search.SearchHits; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -155,12 +157,28 @@ public static SearchDocument from(SearchHit source) { .collect(Collectors.toMap(Map.Entry::getKey, entry -> Arrays.stream(entry.getValue().getFragments()).map(Text::string).collect(Collectors.toList())))); + Map innerHits = new LinkedHashMap<>(); + Map sourceInnerHits = source.getInnerHits(); + + if (sourceInnerHits != null) { + sourceInnerHits.forEach((name, searchHits) -> { + innerHits.put(name, SearchDocumentResponse.from(searchHits, null, null)); + }); + } + + NestedMetaData nestedMetaData = null; + + if (source.getNestedIdentity() != null) { + nestedMetaData = from(source.getNestedIdentity()); + } + BytesReference sourceRef = source.getSourceRef(); if (sourceRef == null || sourceRef.length() == 0) { - return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, - fromDocumentFields(source, source.getIndex(), source.getId(), source.getVersion(), source.getSeqNo(), - source.getPrimaryTerm())); + return new SearchDocumentAdapter( + source.getScore(), source.getSortValues(), source.getFields(), highlightFields, fromDocumentFields(source, + source.getIndex(), source.getId(), source.getVersion(), source.getSeqNo(), source.getPrimaryTerm()), + innerHits, nestedMetaData); } Document document = Document.from(source.getSourceAsMap()); @@ -174,7 +192,18 @@ public static SearchDocument from(SearchHit source) { document.setPrimaryTerm(source.getPrimaryTerm()); return new SearchDocumentAdapter(source.getScore(), source.getSortValues(), source.getFields(), highlightFields, - document); + document, innerHits, nestedMetaData); + } + + private static NestedMetaData from(SearchHit.NestedIdentity nestedIdentity) { + + NestedMetaData child = null; + + if (nestedIdentity.getChild() != null) { + child = from(nestedIdentity.getChild()); + } + + return NestedMetaData.of(nestedIdentity.getField().string(), nestedIdentity.getOffset(), child); } /** @@ -427,15 +456,20 @@ static class SearchDocumentAdapter implements SearchDocument { private final Map> fields = new HashMap<>(); private final Document delegate; private final Map> highlightFields = new HashMap<>(); + private final Map innerHits = new HashMap<>(); + @Nullable private final NestedMetaData nestedMetaData; SearchDocumentAdapter(float score, Object[] sortValues, Map fields, - Map> highlightFields, Document delegate) { + Map> highlightFields, Document delegate, Map innerHits, + @Nullable NestedMetaData nestedMetaData) { this.score = score; this.sortValues = sortValues; this.delegate = delegate; fields.forEach((name, documentField) -> this.fields.put(name, documentField.getValues())); this.highlightFields.putAll(highlightFields); + this.innerHits.putAll(innerHits); + this.nestedMetaData = nestedMetaData; } @Override @@ -530,6 +564,17 @@ public void setPrimaryTerm(long primaryTerm) { delegate.setPrimaryTerm(primaryTerm); } + @Override + public Map getInnerHits() { + return innerHits; + } + + @Override + @Nullable + public NestedMetaData getNestedMetaData() { + return nestedMetaData; + } + @Override @Nullable public T get(Object key, Class type) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/NestedMetaData.java b/src/main/java/org/springframework/data/elasticsearch/core/document/NestedMetaData.java new file mode 100644 index 000000000..ea1405368 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/NestedMetaData.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020 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.document; + +import org.springframework.lang.Nullable; + +/** + * meta data returned for nested inner hits. + * + * @author Peter-Josef Meisch + */ +public class NestedMetaData { + + private final String field; + private final int offset; + @Nullable private final NestedMetaData child; + + public static NestedMetaData of(String field, int offset, @Nullable NestedMetaData nested) { + return new NestedMetaData(field, offset, nested); + } + + private NestedMetaData(String field, int offset, @Nullable NestedMetaData child) { + this.field = field; + this.offset = offset; + this.child = child; + } + + public String getField() { + return field; + } + + public int getOffset() { + return offset; + } + + @Nullable + public NestedMetaData getChild() { + return child; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java index 3caafc554..ab46c4026 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocument.java @@ -69,5 +69,24 @@ default Object[] getSortValues() { */ @Nullable default Map> getHighlightFields() { - return null;} + return null; + } + + /** + * @return the innerHits for the SearchHit + * @since 4.1 + */ + @Nullable + default Map getInnerHits() { + return null; + } + + /** + * @return the nested metadata in case this is a nested inner hit. + * @since 4.1 + */ + @Nullable + default NestedMetaData getNestedMetaData() { + return null; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java index 489c5cd43..cadbbef45 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/document/SearchDocumentResponse.java @@ -22,7 +22,9 @@ import org.apache.lucene.search.TotalHits; import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregations; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -42,7 +44,7 @@ public class SearchDocumentResponse { private final Aggregations aggregations; private SearchDocumentResponse(long totalHits, String totalHitsRelation, float maxScore, String scrollId, - List searchDocuments, Aggregations aggregations) { + List searchDocuments, Aggregations aggregations) { this.totalHits = totalHits; this.totalHitsRelation = totalHitsRelation; this.maxScore = maxScore; @@ -78,27 +80,45 @@ public Aggregations getAggregations() { /** * creates a SearchDocumentResponse from the {@link SearchResponse} * - * @param searchResponse - * must not be {@literal null} + * @param searchResponse must not be {@literal null} * @return the SearchDocumentResponse */ public static SearchDocumentResponse from(SearchResponse searchResponse) { + Assert.notNull(searchResponse, "searchResponse must not be null"); - TotalHits responseTotalHits = searchResponse.getHits().getTotalHits(); + Aggregations aggregations = searchResponse.getAggregations(); + String scrollId = searchResponse.getScrollId(); + + SearchHits searchHits = searchResponse.getHits(); + + SearchDocumentResponse searchDocumentResponse = from(searchHits, scrollId, aggregations); + return searchDocumentResponse; + } + + /** + * creates a {@link SearchDocumentResponse} from {@link SearchHits} with the given scrollId and aggregations + * + * @param searchHits the {@link SearchHits} to process + * @param scrollId scrollId + * @param aggregations aggregations + * @return the {@link SearchDocumentResponse} + * @since 4.1 + */ + public static SearchDocumentResponse from(SearchHits searchHits, @Nullable String scrollId, + @Nullable Aggregations aggregations) { + TotalHits responseTotalHits = searchHits.getTotalHits(); long totalHits = responseTotalHits.value; String totalHitsRelation = responseTotalHits.relation.name(); - float maxScore = searchResponse.getHits().getMaxScore(); - String scrollId = searchResponse.getScrollId(); + float maxScore = searchHits.getMaxScore(); - List searchDocuments = StreamSupport.stream(searchResponse.getHits().spliterator(), false) // + List searchDocuments = StreamSupport.stream(searchHits.spliterator(), false) // .filter(Objects::nonNull) // .map(DocumentAdapters::from) // .collect(Collectors.toList()); - Aggregations aggregations = searchResponse.getAggregations(); - return new SearchDocumentResponse(totalHits, totalHitsRelation, maxScore, scrollId, searchDocuments, aggregations); } + } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTests.java b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTests.java new file mode 100644 index 000000000..a7a6f4b5d --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTests.java @@ -0,0 +1,170 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.elasticsearch.index.query.QueryBuilders.*; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.RequiredArgsConstructor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.apache.lucene.search.join.ScoreMode; +import org.assertj.core.api.SoftAssertions; +import org.elasticsearch.index.query.InnerHitBuilder; +import org.elasticsearch.index.query.NestedQueryBuilder; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.annotation.Id; +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.core.document.NestedMetaData; +import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.lang.Nullable; +import org.springframework.test.context.ContextConfiguration; + +/** + * Testing the querying and parsing of inner_hits. + * + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { InnerHitsTests.Config.class }) +public class InnerHitsTests { + + public static final String INDEX_NAME = "tests-inner-hits"; + + @Configuration + @Import({ ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + @Autowired ElasticsearchOperations operations; + @Nullable IndexOperations indexOps; + + @BeforeEach + void setUp() { + indexOps = operations.indexOps(City.class); + indexOps.create(); + indexOps.putMapping(City.class); + + Inhabitant john = new Inhabitant("John", "Smith"); + Inhabitant carla = new Inhabitant("Carla", "Miller"); + House cornerHouse = new House("Round the corner", "7", Arrays.asList(john, carla)); + City metropole = new City("Metropole", Arrays.asList(cornerHouse)); + + Inhabitant jack = new Inhabitant("Jack", "Wayne"); + Inhabitant emmy = new Inhabitant("Emmy", "Stone"); + House mainStreet = new House("Main Street", "42", Arrays.asList(jack, emmy)); + City village = new City("Village", Arrays.asList(mainStreet)); + + operations.save(Arrays.asList(metropole, village)); + indexOps.refresh(); + } + + @AfterEach + void tearDown() { + indexOps.delete(); + } + + @Test + void shouldReturnInnerHits() { + String innerHitName = "inner_hit_name"; + + NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder(); + + NestedQueryBuilder nestedQueryBuilder = nestedQuery("hou-ses.in-habi-tants", + matchQuery("hou-ses.in-habi-tants.first-name", "Carla"), ScoreMode.Avg); + nestedQueryBuilder.innerHit(new InnerHitBuilder(innerHitName)); + queryBuilder.withQuery(nestedQueryBuilder); + + NativeSearchQuery query = queryBuilder.build(); + + SoftAssertions softly = new SoftAssertions(); + SearchHits searchHits = operations.search(query, City.class); + + softly.assertThat(searchHits.getTotalHits()).isEqualTo(1); + + SearchHit searchHit = searchHits.getSearchHit(0); + softly.assertThat(searchHit.getInnerHits()).hasSize(1); + + SearchHits innerHits = searchHit.getInnerHits(innerHitName); + softly.assertThat(innerHits).hasSize(1); + + SearchHit innerHit = innerHits.getSearchHit(0); + Object content = innerHit.getContent(); + assertThat(content).isInstanceOf(Inhabitant.class); + Inhabitant inhabitant = (Inhabitant) content; + softly.assertThat(inhabitant.getFirstName()).isEqualTo("Carla"); + softly.assertThat(inhabitant.getLastName()).isEqualTo("Miller"); + + NestedMetaData nestedMetaData = innerHit.getNestedMetaData(); + softly.assertThat(nestedMetaData.getField()).isEqualTo("houses"); + softly.assertThat(nestedMetaData.getOffset()).isEqualTo(0); + softly.assertThat(nestedMetaData.getChild().getField()).isEqualTo("inhabitants"); + softly.assertThat(nestedMetaData.getChild().getOffset()).isEqualTo(1); + + softly.assertAll(); + } + + @Data + @AllArgsConstructor + @RequiredArgsConstructor + @Document(indexName = INDEX_NAME) + static class City { + + @Id private String name; + + // NOTE: using a custom names here to cover property name matching + @Field(name = "hou-ses", type = FieldType.Nested) private Collection houses = new ArrayList<>(); + } + + @Data + @AllArgsConstructor + @RequiredArgsConstructor + static class House { + + @Field(type = FieldType.Text) private String street; + + @Field(type = FieldType.Text) private String streetNumber; + + // NOTE: using a custom names here to cover property name matching + @Field(name = "in-habi-tants", type = FieldType.Nested) private List inhabitants = new ArrayList<>(); + } + + @Data + @AllArgsConstructor + @RequiredArgsConstructor + static class Inhabitant { + // NOTE: using a custom names here to cover property name matching + + @Field(name = "first-name", type = FieldType.Text) private String firstName; + + @Field(name = "last-name", type = FieldType.Text) private String lastName; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTransportTests.java new file mode 100644 index 000000000..8ff213ded --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/InnerHitsTransportTests.java @@ -0,0 +1,31 @@ +/* + * Copyright 2020 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; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { InnerHitsTransportTests.Config.class }) +public class InnerHitsTransportTests extends InnerHitsTests { + @Configuration + @Import({ ElasticsearchTemplateConfiguration.class }) + static class Config {} +} From 8fea655854699fdad0b4f74438b4974eed79fa97 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 5 Jun 2020 14:47:19 +0200 Subject: [PATCH 0184/1191] DATAES-852 - Upgrade to Elasticsearch 7.7.1. Original PR: #475 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 4 ++-- ...on-7.7.0.jar => analysis-common-7.7.1.jar} | Bin 198660 -> 198666 bytes .../plugin-descriptor.properties | 4 ++-- ....0.jar => elasticsearch-dissect-7.7.1.jar} | Bin 24682 -> 24687 bytes ...7.7.0.jar => elasticsearch-grok-7.7.1.jar} | Bin 33951 -> 33956 bytes ...mmon-7.7.0.jar => ingest-common-7.7.1.jar} | Bin 115859 -> 115865 bytes .../plugin-descriptor.properties | 4 ++-- ...on-7.7.0.jar => lang-expression-7.7.1.jar} | Bin 65739 -> 65744 bytes .../plugin-descriptor.properties | 4 ++-- ...icsearch-scripting-painless-spi-7.7.1.jar} | Bin 27844 -> 27849 bytes ...less-7.7.0.jar => lang-painless-7.7.1.jar} | Bin 561382 -> 561388 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- ...url-7.7.0.jar => repository-url-7.7.1.jar} | Bin 14716 -> 14721 bytes 17 files changed, 17 insertions(+), 17 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.7.0.jar => analysis-common-7.7.1.jar} (88%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.7.0.jar => elasticsearch-dissect-7.7.1.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.7.0.jar => elasticsearch-grok-7.7.1.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.7.0.jar => ingest-common-7.7.1.jar} (89%) rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.7.0.jar => lang-expression-7.7.1.jar} (88%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.7.0.jar => elasticsearch-scripting-painless-spi-7.7.1.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.7.0.jar => lang-painless-7.7.1.jar} (93%) rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.7.0.jar => repository-url-7.7.1.jar} (82%) diff --git a/pom.xml b/pom.xml index a9a71063e..c5bb3b77f 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.7.0 + 7.7.1 2.9.1 2.4.0-SNAPSHOT 4.1.39.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 3dbbe82af..ab746ec20 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,9 +35,9 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| Ockhamfootnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.7.0 |2.3.xfootnote:cdv[] +| 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.7.1 |2.3.xfootnote:cdv[] | Neumann | 4.0.x | 7.6.2 |2.3.x -| Moore | 3.2.x |6.8.9 | 2.2.x +| Moore | 3.2.x |6.8.10 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] | Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.0.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.1.jar similarity index 88% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.0.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.1.jar index 1d640598f10586a4926c7ca164d7381c9c410105..1ebf4a14cebefc8fe4241095e394c18d7b09ce34 100644 GIT binary patch delta 8249 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 delta 8119 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 delta 1244 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 iO^~dx6R5bSaWGgLnWN5*F(K diff --git a/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.0.jar b/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.1.jar similarity index 89% rename from src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.0.jar rename to src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.1.jar index 99239ebe693b628b152b49a5087cda726ff670b2..8cb83e99573a18100362acf22ac3c79ac6186f07 100644 GIT binary patch delta 4830 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 C!NzR> delta 4638 zcmZWtdtA&}8$V~7rc^W4R7j-~3DFR3kxQuDRU$&(qL(CLu`caau4~^Uh7Lld5-OD$ z4V5mk>y}Gdt;?d8k5*Q)J~o$K-sgADFVk<9KYr(Pp6B^K_vbv*fgJ|Q9R|{X$$DZV zgbWQ)uvz|Ysk0P50hfPzw0|Z>C~)@}oA@+kb*kkwrm8^P^Rm_Wuy)9!;u4>->{8(Mfpv)`wJs)HL4fWUVOQJ9R zb=V;&eva$)u=Pis(>E=vPP}>~<4$PG*5H3G;mez?XKO+(kL_BtvZ_XEtp6lp@2&k? zy(42Q+Lt&KzP7c$eYyRZ_i6W&Dpu=O)eAb zJ(GUxb;G^3rn~1jm$+BM_O~3{H|S;flJ>lxRmc6jW+dE}dPC%d5NhiN7TdtZHvwSk{)njfH6|F$j06rnIzge(z4Q++m+JNHZxC&thOEr)5;7>XSi&*8{uzov52;Gw?V>6sddLWjOqEal= z#Jgj{q`!R@D53uK%Wq^M>;5o;8QH_>5arP%_UkZha>{IGn)&hz><}K=$PTG#*Qgm; zVc}w`e1e}%>mxmc(v6f&D_w|NIkwR_`QYCvyCx;1!+x*SQ0CI|K-`aEogHDtY+00X zow29Q$6qtpXQh?4DltNtM#^HPv(nx|s#=&^!)PDd8qD7T?SL^yBMG_KLX{dIVp#s4 z`ZBJCYSX2wASw-FFwB`NA~RAMiY1!$@pv=y*xCcD*-7S$1L>(`JFYaKIW~{L9?Ysq z2H1cSRsXH|Y|0U{9xB*Hmi=nRQ?wU0?WDp;qbu*D86uWA% zn=Ub~23w2&@lnW?;Q^MeI@ACdUkEZo|5@{2gv`)CJ`tRN4SA7?O*pT~2hM;r?y?v0 zI*LskxXv3H_b{psD)9#RLmz`6tK4pBtG%jQ)xQMfSf4jbz)BE=D`$bOfl|D&C4u;%cUOlvatyFq`(&2 zJ-h;;W-gf{F_2Ph?$QWO2NJi%Ijwe@hAmb>AViUH~`Z=f!DA5x-;El<;GHgM0 z)SEOvT>`$^!8_nD&`~voG!V~&=IpwUCV>>Oz=Tm?Y{taA?2WO3J6N~gCH8$3!{K*H@T?00~utLaN;Mn4Aox>m}Nkv#r-Ein5 zzA+Y>;4uW-T_Cb<7Zqufficyg}2s%hQBjCZENFC~iz_k!3aD z)h|4KHK53lD;42{FL>`>RJ*gqBS#X(JPYs6@ z8IiBD`TYA%?Q0wdVbFs-35UwCJIroq<}PH#IoypJ|FJPF#R!u10m3G%7xCRM^U8!w z>!_Ii+|*m}fNG99$xo1dN9Lp_0EiSandW}kEOiO^|7Qx_A2t*8? zP;eMeMkL`B?^fFH>atwW;0hXqEq?ySum<;1*3OiX2lCFtsk8!+R){H?)XwJ{f~t<;isYFglY}Ko ztKKIU-q#kQ(7<4U4a%NrZ<9`_1MShEeS{#y?iLLG{%IIbUuGi}(k@!M%{#vv6Z*1y zk#*JBf*N+c6b$R%gVALr9B9WYIR{oqQIjpRx$2#m94g1wROmJLj1049LW&D~Wjk=w zu-%#6f-6!oJ)(1XytoOg=+CQy^@f;1r;yzxxEn=X$~}9-T^apEG3*;$)(f)X*4vxi zY8?>e@FT1IeRHZKgh~xv;3){z=uu2)R3V1x0bbE4y*7F|`V@586W|wiS&0whzj6+$ zu5B-tXnTALXM|=vrNaZ(DM&X}KzT5oNy5(7mnzY2n!2g*p2b+Tp1|_S9@=x&d7$!WxLOG zu5v?`2u+icyb6Aj#hwBB>S#uX_BJL3B5Xja&hU?Z-iULW0x($&e*h3Bp?SF$RC&GK zknB?Pm;>_xvn5tbroRfvrhGme>J7pDv*878ffrP`(q| zAPg5oZhahMg?VS9l)dbTf47GOUOFDUx;x*PW@~Zegt4UQS>y?^GT3+(_S% zOzFxtTN~}8ag&Q%%x+$?1iMfr&C5fMD4_)Z`qz7Rdk_7#|xeJm`?$uyFOMNgMq51HCYHxT2G9d5h|G?+4iN+J|eO+qTA#L~+vTW8C9G_*?5$fWdGOSxv-!eV>u z(qhF)Ii!s}iB4OpEpMHcmdRUE8! zcAILAa?{%!Mw_&2)6R9CofL}aM(x))cA+t=QT$zwo2cNk_7J~ZEzWj#p&)PA(|Cuj zx7tbZ-P^Z(4m8_5v0pc%K&!F-{XWf&TTgg)#63~-J~o@ z{FI|??anpcrk8Zm%ttE?7C$>+lGz+r)oTC9oOj}vBL8Sziwd=d$jF5^BTBbEDiz=0 zn>*k5J1+ZxN%7h*e=Co@uDP|mrYZepuk*KWT1Gexo7^JXb;3FEMX&iWfqkz$mm68_ zSaBoluwnY|4LtGO(4l*Y`i@?W>{7qsU?bnMRgBPO7eoi{8|!(ys+ewA8eY4*E-&uV z@dmqzx0M{`tv6P?b<9+xc`n;B3<9?g@i?j;Np^<;8 z*8!h-To>6{q8A&?#D;(61Opr6{9y_k9T$9=vt+|G31fvGq5$wwhO0_lN{*(UCILBx zgT%;+JKVgf2O2_y-TEy=`CPc|V%KmY2U3PvB>(?a3Ji#jVfdjw&n!XJtk!d9tv zNpExt!QqwjNtXDS4>9&`*C1C@9a+R^c0EJtmRO1iS7+ci#NhCD5aVFBG7FQ28FC0t z{FO80Dn8}{!LdAFOpNqmIkH7rKk-OT7?AYV`E0^vpxaBXmS*vZ(aW_aF#_8pf}H(o z1&jTkhgOo4Fhu4h6dIB$#_V^I>>QsOk`(I~LaqWG)0Na2)EwsYLxr!q?G#@sH1Dxz ziqOgg_t1+;{rI^o+5&I)7<~$X3g88HR*jqSBQ|{W3;cNq?lRDV7VF0;w;N#wv@bbWH;`%^SPBd~k zL92_Zu;2rMl#bDqcpi>CnyLZ=-V=BHI88+uVfTyi*@m*RU(DSTc^RqUrUJmK>9PSR z6@6if$%EhOs?Hk8RXhU#cZI-R^HHEH49Hi7f^k9=_MWEREks0%;l?ygnHyv1 zH!rH{LPO1@0kBiR(6L1rX3#K64Gs))ace;nH08y|#U_-hz^Vy?(diJr*aFqzg>Y6X zV60sQi=!7n-iR?KYuQqCv5W`6-W>oqD+JcBMyPx!m?A{wNY;*E#P1Fb1_?>qOZq)P zByFf!SB2dByHTzeCRiHPIBbi8B2XoY1Pel7?vy9);xwAX&2X$_p{)k&8sp;JoLe2W zhmqv{8~~Om5VQ&8N+>~%P&Vh2RfH}hH1%@~YSaRr8kvtN65i6($ynragPSLa{!VCl zb_=m~-%pZFDR@UyKPF)8fp-gVV*C(IjU~!!iy8InO)v=ZvdpZ3L0f-Zf_ zVaCWDoWE$0rmmfWqW;w|MLx8%eKh5mg6HsO-&_orY_3)&Tb#E@OBaP!E7CA`M-&@Y z4HL+RZ)j@6d0eIb2W@yKn*{|!q$evWO<< zV*}u!5Hzz@PC~;0pPAFTi0YHaRG9!IqP1V6knrRs)ExG~6*c#x-?L6MC)s+>M&nZz Nmoa9sTDxTl{{UIZFp#Mshz}6Ohz$kBC9b$=n1qs|DYBKf2Qw}znj*@M zbP>UbOwl=AL+qhUO_R8oB~N8}2`^YOxer8<(fQBWgZDP^w%FZ2V^lzG~~Jzh7~%43h6*?N(#P&Xb-@?TLgE9j1Y zrq|pVXZPR!=YrxukIQ~TXz^X=b8nxx=yLC#fAg1K(t4%+fw*ZW^~P_q5(Zvd*X>YM zQP8mIXkqKOt0&j^##cRFvcBx*meShNx01_;b%BDIM**SYf!rXzKvwVI&^#lg`e1|q zr5%Cs#+Q%G)@hyiGY{SV=fj_}u2%0}8&x}$+^#t3IXkq<=or4_R&G^kzW%TI!STYn zdV^Z1SIq6wcSfI{8S-VyTJ?nDLlKX_lg`f<=~Oi}w+gdF0Hg&1;0^$o6Pu)%5}yzk zY`o4Z5ZR=Nba1h2oeer2D51yWbvhl4*EMuFUiGwsU5#bugYB@f@^lArx!NT-mmVFaFP%sDiev`R*eMfFpMBW`@F8 z>3NU1H3)zB))fF3Fsu;L z0A#iOO7mq|V0UEz zyf#F14fQaT+7G8o?j;Plh~a0c6*&e54LHKoK^ik<_Vo>iq8=0?rfD3e8-X|=r`Y+K zB4oo1wKxQAPlZlRo-nP;3Fp#pd@I6&9^!E*Upyz5DGY-pw_IWJh?rGhn#yA+RRpHU zYx9QbgCxh3%L+gYCr6hI*Ytb`X_4ud@SH8^5F_jWh~og;qA{6XO2bzc*}?lgq%W!g zhWaUHREK`R9e43s7eg(Wg>}gL9pI#H8oO7GFceILAr=K}9`VGkmHiBrIv*!+YNBCN zzdNovzo}?YfX-@@Jpi#BAz7(bwy~@T3@)1Ja55ORrysRj!2w@ch`~qw9pT0YM4G;v zp_VSj(sot5u}6k===vDSv=qDZ+Q!1aas<%XOlnl3t;Xee%U3Oe<$c7xy_2E#Xsr2N zM?2zeW~kED7@cmOjP;!ny$~IZy4sF3MsxIO)?whTYKCRQV9uk(0Sj{wSTS04W!xgy z^K4ezr>jtA$KQ=bX8seuUeA#&iY;*YYWzXKjZE zu4n;z7$%ov9&|-;MUtWep+`{u4CkjSTD~7wMB3&GJ06hB9JM*~GCN%h(TghQkZBI! zfONAM${*6Wf~)7KMiy*9qd1ELwm{88Da>OWpkDeMTk#mS;#yry`ySXcaD;fD#K6ao z$TPMR9lEFvyZ$y4SNeU1N;rjBroyB5$u;#t?_a`cgp$E`t;f0oop#1Gs}?*2xW8M= zOg%A(Scrsk+tu5O+tppkK9&-EKF86Ur@f8cJ1)^;mC_c;Mb8iVyDkRc%02eizv@@~ZIyseqmfK?_0{85le#I!M>Y2A$42Y#^{l z`VW6wTvS)g$^Ii@`l_CqzQRQw8cVnL?%l@Pm6Bq)r9R%2|Irf#7URvcZpP|5c5+#J z+g&Vi(w5sW;n%&O>3dx^87&gyTise)xcuez#D(QDswH6}{>yhe8@LKvHNN+i4lw=1 zaH=FkY{t_yCp4Q?`nN^5NjxvCKe}kss#Pg6&O%4`eRo|}b)D<^H>;X=LK!lB&SqD1 ze=&*1u|&>@<6b8prJb?cEm|%_!TQVI@3Gp2?WdYbzosa!De2t0^6=}nsGGarz26mP zGvDY=$UV0?U!0;gmF3+3=%CTP)l%d9l_%5Ls|yxvO3&E(?4Z+%f6qClq_ACE+L@8; z!s+WdCHF?h@hQREr?*_v`TcFLIrCB(o&*uK|KEa}*KM=evEhlKAE&pQ$&PqQ4HdTF z+^E_!p9{=pAC_ZV?cWxBr(xyANk88_{vVv;oVB((_(8*`z4nN3Z*1PPc{}4Ae&*Wd zJ(I%(cQJ1S(!xTDVA@7FrEq+;G%n1S@87o(~q8Y$N9m77$QTWd<`AYs*6zNARqgow1sZH9={ z8ysN-+hC!d!2;HG-^>(Z`DfpCqRhaQGkHm}32F+O{508=8R*5yvMJJx>nB^LD1-eO z59Ikxu1-+``))ysv^Z7as$IF^V}kNjD)jPUdhDpIn;_@qSOXG!wf%*djY;K@``4f&!!+7VcVbvp~VP z(gbXlg9`WLeQA(za}xgEunVaAFVK}>olp&18b8An8%~~`0kL>hhBTA31=I}Q$q%$; z;8F^i(oDA2P$|{P8tFpdn6gcmX8LXew{@3+$mDJX9=NWvY0^xm9gqwZ0Ohl0$OJmh1?~$_gf==MnI|<_FP%pLl-zba^3z}erhtFI6zGYf!NUcvp(aCH9u!6g z7k#aK4pbZmOfIM~xOuVwFapJ}oW1%ssAglIl0J z3b)JNYgryn`FYRzw&{&Un-XLta+c%<2;^#Y@qP(=X4`Z!`ea~mCug^))%(=l zmV0qiL0UScPqxZ&$)<>zb3b|1pS5GT*~C26*6Fp+gry;ef6Hk!u|{n7J>ev_A@jgt zUT)UMN?sXfoaSu`zrWi&z@(z9|K*YI&)Dv!Y&`v7^63+2{gT|yU1$5mb~0wR-}~)5 zE!=DmiMidim^@XF?fD+FOR;($s&Cg;fBoQAe7DQlHrzhDh-rFU^Qt@dG}-&EM>xcF z8Tv0Sl5+E$bnKyu-eaZXNHSNr^etGHLv9kSMwlAkS_hproc`cvvKYxnm zi(gUEj$Rp6GTi0~T3Zf2e)RIS_mX6-%grYXU4GtEM+A8U|C-Hv80YXahw-nO94)wu zSxI2cWC#DPyv@WNEO5hNGb5P6VtbJp z#Mor23Z^%Qx@53`Wi%}0AtGMZ+aYTEoQ^;k4`io7)Ew|Ig;-Fjv=72~p{of|BceYa zDk9_sVf^r2C&~;=Gm}>)o1mth$*+=4<$*p7*s|qOTP{BXL!1r+g9rlxENNUd*)By{ z9_aZ1KE@5XJwT}^KrD<K<87tM7n+LNp zFihoPV6cUo!N9Pk@ft{>*5s;mMX<}Oj8xu50u>$xDl|b+*fQB5%^4Ikle03Une^qr z<{OxD>!4X5@FY~?Q5Y~wN&rK^3B`y?m?qxI-I)TDC9{OU=ILbt%~ODxH`(4+Ve*G; zh~J%rzc=gxn)4UvBygxg&D+w*tOC+7Dbp4lMmrw)X|Mo8`X4Y9JW=e_R)-rr!9^Zq zFxXCqOlhWR+E6Kwb2Px_Y(IP2CzNG>+ zWCAs~plB#EfLk1&tp+x|{a;w4FVL0ufv(g;QEX`hRID|5ZyF>-{%1=wT`~g;{q(>L zVJW$?Wd*YW0NU@H{8 u-<`mEef5PVM`u7nX)Q1%&GY~Ze@T@E8<~(J&GgI{EVMjFhHYvx$P56xKd=x0 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.0.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.1.jar similarity index 93% rename from src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.0.jar rename to src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.7.1.jar index c75bafd082199a9b90bd3720cb58e7f1f9b21e1c..69c18c8279da5f2b5a3bd97598cf82cbe51d25fc 100644 GIT binary patch delta 14279 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 delta 14216 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties index 0d10e4fbf..f821931b2 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=An easy, safe and fast scripting language for Elasticsearch # # 'version': plugin's version -version=7.7.0 +version=7.7.1 # # 'name': the plugin name name=lang-painless @@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.0 +elasticsearch.version=7.7.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties index 4a465f180..6c32f77ab 100644 --- a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds advanced field mappers # # 'version': plugin's version -version=7.7.0 +version=7.7.1 # # 'name': the plugin name name=mapper-extras @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.0 +elasticsearch.version=7.7.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties index f6c396bb7..73cf92448 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=The Reindex module adds APIs to reindex from one index to another or update documents in place. # # 'version': plugin's version -version=7.7.0 +version=7.7.1 # # 'name': the plugin name name=reindex @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.0 +elasticsearch.version=7.7.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties index c795e9bf2..e7117d26a 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for URL repository # # 'version': plugin's version -version=7.7.0 +version=7.7.1 # # 'name': the plugin name name=repository-url @@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.0 +elasticsearch.version=7.7.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.0.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.1.jar similarity index 82% rename from src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.0.jar rename to src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.1.jar index f0d3452c14cf8adb755e3c034fa01bb284654e5f..c3b47b7aea36b2c013ae4c38b843fba95a2ede6c 100644 GIT binary patch delta 1178 zcmexU)L6_L;LXg!#lXP9!SJYg&qQ7|ULY0lE+*(^G$R8;$V3O}`q-e@>_Y}3wfbM| zMZRq^yri0Yb=F><(jLpB?5RC_V{hM<>hSawp83D-Bll{4#e#D?zt5?jY^f2Ln0?ZG zR#?VSWwFZ!GhScvRN+?6dbly_hIzeNo~(G)=|HD!*N;W}qFI7-lJq&6KeC1N+B9vt zuFrj@eT_sA+f9SW^^!?eKK0turi6y3Hj8Xh;cb>Tx^~;GV*B^J-PsEqZ8{>u&5K#J z_HcdLQLeoscT32HEz-G_A&ohPJa*fAkLYS~U%Nhe>V`||*Ov9=vu7>&eA!+ir$l>= zS@oly8r$PLvy0}JJ!#pJ@-p)JCl8J8t(IE)S2E5omaPc5$-O1wQ-<1<-`0#-sxuqD z9u%4t;8d-0GJMVX;8QE>7xi4S`On+T&%E@_n?>^J?7ufU#z)J=Mtqy|jpOt$ld2dA z4HdWKT&dbqpGyp9AL6sxukc#0gmsyl_p-_B5C1>0`$~{?a6&s*b3G#X8=LoR-p4qH zpSiYq&*WIaUCh9Um@Flv2&V0X^uct2kPVm?P*k4WZpu6PzL0<*D8jVAp46Ji%fRqj zk%7T%a-yOrNOrT5@Frfc@(MlW$rsGn`I#9I_JNESP;>yx2P?XO=*_bf6v+83N_H-W-%~qX?!(V zz|2(v-Aj^iH6RC`R{%K>6fKh{nDKza5@;7A$K*tFH4ImL0Lpj+WwbCH5!@(v`7AK7 z>bMygEa4V_95D%~-UDpz8gpr;ZE8^K1Sh{US0muI0zI(e1bz0&{uU6o#aT!*t%L~+ tVK{IDQ2H%QS_~uDqi!Gm?FDqD3owm3qPWsjA8M8U`Ov-le>wR%QS*}&#!GqIh-kf=NqC6p_yLtKd z7i_7$Dor0vcHaCZwLQb;2gjwYpQKbbu1j8#_+gctK+N96y?k?x*!ilhHS+KFu`NIE z74|Rj)6@^1@hnSiV_nU7CTY|^-dOzplx^w8$xkGeGXBU#ty78A5RS8JXp3v=?@qOO zJjH+IiEB2KV@~WzVLk71RQ~dlTaJrATJKAkY%_xjQzVimFG-utpspj&0Y4AoCPphZrAKz|K54*kgPtL0+>B)ftm(3G)?WiwT zb$Fm@7Lcg8YR}xX%E&NRGtFCzR&G4WB_OlVcQU)x=G$>cx2)cHcYV zY6}0CUd!|4@Ube-s0++}t=R>#RaX1=)c%&eIwR`lgDjcA%uig1kdNSB6R>5=qqbar z28K8t1_luZ1_oc(5Jz24KR5l&cNv@bnZx+kOimKq#SDy{$?`&qVA@$oA551D*??(L zMdisoro5A%2nm4ro4*S^;ss08>M2kDuOJLnBw|;4z+g zvY@#dUiIoI&T#{(heU~&xin)hkf$|yg1H>n0UOPwnKr5c9iTe7$DDieKXYlAyBM=4 wU$l_HYmEwuHA{f%)$yv=KvDk!sNNiG8@Hu2lYu@kyqza!TMDq Date: Fri, 5 Jun 2020 21:25:01 +0200 Subject: [PATCH 0185/1191] DATAES-853 - Cleanup tests that do not delete test indices. Original PR: #476 --- .../data/elasticsearch/NestedObjectTests.java | 12 +++++++++--- .../EnableElasticsearchRepositoriesTests.java | 8 ++++++++ .../core/ElasticsearchTemplateTests.java | 2 ++ .../core/ReactiveElasticsearchTemplateTests.java | 4 +++- .../core/index/MappingBuilderTests.java | 4 +++- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 05ac0838e..64686a1a4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -34,6 +34,7 @@ import org.apache.lucene.search.join.ScoreMode; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -67,11 +68,16 @@ public class NestedObjectTests { @Autowired private ElasticsearchOperations operations; + private final List> entityClasses = Arrays.asList(Book.class, Person.class, PersonMultipleLevelNested.class); + @BeforeEach public void before() { - IndexInitializer.init(operations.indexOps(Book.class)); - IndexInitializer.init(operations.indexOps(Person.class)); - IndexInitializer.init(operations.indexOps(PersonMultipleLevelNested.class)); + entityClasses.stream().map(operations::indexOps).forEach(IndexInitializer::init); + } + + @AfterEach + void tearDown() { + entityClasses.forEach(clazz -> operations.indexOps(clazz).delete()); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java index 33f41c2fb..38d656f90 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/notnested/EnableElasticsearchRepositoriesTests.java @@ -24,6 +24,7 @@ import java.lang.Long; import java.util.UUID; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.BeansException; @@ -42,6 +43,7 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.IndexOperations; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; @@ -90,6 +92,12 @@ public void before() { IndexInitializer.init(indexOperations); } + @AfterEach + void tearDown() { + operations.indexOps(IndexCoordinates.of("test-index-sample-config-not-nested")).delete(); + operations.indexOps(IndexCoordinates.of("test-index-uuid-keyed-config-not-nested")).delete(); + } + @Test public void bootstrapsRepository() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index a21057f8d..89d96a021 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -151,6 +151,8 @@ private void deleteIndices() { operations.indexOps(IndexCoordinates.of(INDEX_3_NAME)).delete(); operations.indexOps(SearchHitsEntity.class).delete(); operations.indexOps(HighlightEntity.class).delete(); + operations.indexOps(OptimisticEntity.class).delete(); + operations.indexOps(OptimisticAndVersionedEntity.class).delete(); } @Test // DATAES-106 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 4bd1be854..ed6403719 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -119,7 +119,9 @@ public void after() { } private void deleteIndices() { - TestUtils.deleteIndex(DEFAULT_INDEX, ALTERNATE_INDEX, "rx-template-test-index-this", "rx-template-test-index-that"); + TestUtils.deleteIndex(DEFAULT_INDEX, ALTERNATE_INDEX, "rx-template-test-index-this", "rx-template-test-index-that", + "test-index-reactive-optimistic-entity-template", + "test-index-reactive-optimistic-and-versioned-entity-template"); } @Test // DATAES-504 diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index b0f702c53..a8101bef3 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -47,6 +47,7 @@ import org.assertj.core.data.Percentage; import org.elasticsearch.search.suggest.completion.context.ContextMapping; import org.json.JSONException; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -91,8 +92,9 @@ public class MappingBuilderTests extends MappingContextBaseTests { @Autowired private ElasticsearchOperations operations; private IndexOperations indexOperations; + @AfterEach @BeforeEach - public void before() { + public void deleteIndices() { indexOperations = operations.indexOps(SimpleRecursiveEntity.class); indexOperations.delete(); operations.indexOps(StockPrice.class).delete(); From 846dbea2b80eaf07be7660299038bcf4e509e9db Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 8 Jun 2020 10:13:28 +0200 Subject: [PATCH 0186/1191] DATAES-263 - Inner Hits support. Original PR: #473 minor fix --- .../data/elasticsearch/core/SearchHitMapping.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java index d6a0b3933..7a128ae11 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitMapping.java @@ -178,10 +178,10 @@ private SearchHits mapInnerDocuments(SearchHits searchHits, C ElasticsearchPersistentEntityWithNestedMetaData persistentEntityWithNestedMetaData = getPersistentEntity( mappingContext.getPersistentEntity(type), nestedMetaData); - List> convertedSearchHits = new ArrayList<>(); - if (persistentEntityWithNestedMetaData.entity != null) { + List> convertedSearchHits = new ArrayList<>(); Class targetType = persistentEntityWithNestedMetaData.entity.getType(); + // convert the list of SearchHit to list of SearchHit searchHits.getSearchHits().forEach(searchHit -> { SearchDocument searchDocument = searchHit.getContent(); @@ -192,7 +192,7 @@ private SearchHits mapInnerDocuments(SearchHits searchHits, C searchDocument.getScore(), // searchDocument.getSortValues(), // searchDocument.getHighlightFields(), // - mapInnerHits(searchDocument), // + searchHit.getInnerHits(), // persistentEntityWithNestedMetaData.nestedMetaData, // targetObject)); }); @@ -221,9 +221,9 @@ private SearchHits mapInnerDocuments(SearchHits searchHits, C * * @param persistentEntity base entity * @param nestedMetaData nested metadata - * @return The found entity or null + * @return A {@link ElasticsearchPersistentEntityWithNestedMetaData} containing the found entity or null together with + * the {@link NestedMetaData} that has mapped field names. */ - @Nullable private ElasticsearchPersistentEntityWithNestedMetaData getPersistentEntity( @Nullable ElasticsearchPersistentEntity persistentEntity, @Nullable NestedMetaData nestedMetaData) { From 407da040ab165d521c9005d7d046f08afaef1dd1 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 9 Jun 2020 16:08:02 +0200 Subject: [PATCH 0187/1191] DATAES-858 - Use standard Spring code of conduct. Using https://github.com/spring-projects/.github/blob/master/CODE_OF_CONDUCT.md. --- CODE_OF_CONDUCT.adoc | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 CODE_OF_CONDUCT.adoc diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc deleted file mode 100644 index 33ae7bc9f..000000000 --- a/CODE_OF_CONDUCT.adoc +++ /dev/null @@ -1,27 +0,0 @@ -= Contributor Code of Conduct - -As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, such as physical or electronic addresses, - without explicit permission -* Other unethical or unprofessional conduct - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io. -All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. -Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. - -This Code of Conduct is adapted from the https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]. \ No newline at end of file From 407c8c6c17cf13dffcf0c577fe7ea47bd6f96200 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 9 Jun 2020 16:27:39 +0200 Subject: [PATCH 0188/1191] DATAES-857 - Registered simple types are not read from list. Original PR: #478 --- .../MappingElasticsearchConverter.java | 7 ++- .../data/elasticsearch/core/geo/GeoPoint.java | 16 +++++ ...appingElasticsearchConverterUnitTests.java | 60 +++++++++++++++++++ 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index a4605285a..d4a7fb8f5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -316,14 +316,17 @@ private R readCollectionValue(@Nullable List source, ElasticsearchPersist } Collection target = createCollectionForValue(targetType, source.size()); + TypeInformation componentType = targetType.getComponentType(); for (Object value : source) { if (value == null) { target.add(null); + } else if (componentType != null && !ClassTypeInformation.OBJECT.equals(componentType) + && isSimpleType(componentType.getType())) { + target.add(readSimpleValue(value, componentType)); } else if (isSimpleType(value)) { - target.add( - readSimpleValue(value, targetType.getComponentType() != null ? targetType.getComponentType() : targetType)); + target.add(readSimpleValue(value, componentType != null ? componentType : targetType)); } else { if (value instanceof List) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java index 5d2c33a70..7bd21956f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/geo/GeoPoint.java @@ -17,6 +17,8 @@ import org.springframework.data.geo.Point; +import java.util.Objects; + /** * geo-location used for #{@link org.springframework.data.elasticsearch.core.query.Criteria}. * @@ -60,6 +62,20 @@ public static Point toPoint(GeoPoint point) { return new Point(point.getLat(), point.getLon()); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + GeoPoint geoPoint = (GeoPoint) o; + return Double.compare(geoPoint.lat, lat) == 0 && + Double.compare(geoPoint.lon, lon) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(lat, lon); + } + @Override public String toString() { return "GeoPoint{" + diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 5e8b5f909..2ae0e2304 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -735,6 +735,60 @@ void shouldWriteCollectionsWithNullValues() throws JSONException { assertEquals(expected, json, false); } + @Test // DATAES-857 + void shouldWriteEntityWithListOfGeoPoints() throws JSONException { + + GeoPointListEntity entity = new GeoPointListEntity(); + entity.setId("42"); + List locations = Arrays.asList(new GeoPoint(12.34, 23.45), new GeoPoint(34.56, 45.67)); + entity.setLocations(locations); + + String expected = "{\n" + // + " \"id\": \"42\",\n" + // + " \"locations\": [\n" + // + " {\n" + // + " \"lat\": 12.34,\n" + // + " \"lon\": 23.45\n" + // + " },\n" + // + " {\n" + // + " \"lat\": 34.56,\n" + // + " \"lon\": 45.67\n" + // + " }\n" + // + " ]\n" + // + "}"; // + Document document = Document.create(); + + mappingElasticsearchConverter.write(entity, document); + String json = document.toJson(); + + assertEquals(expected, json, false); + } + + @Test // DATAES-857 + void shouldReadEntityWithListOfGeoPoints() { + + String json = "{\n" + // + " \"id\": \"42\",\n" + // + " \"locations\": [\n" + // + " {\n" + // + " \"lat\": 12.34,\n" + // + " \"lon\": 23.45\n" + // + " },\n" + // + " {\n" + // + " \"lat\": 34.56,\n" + // + " \"lon\": 45.67\n" + // + " }\n" + // + " ]\n" + // + "}"; // + + Document document = Document.parse(json); + + GeoPointListEntity entity = mappingElasticsearchConverter.read(GeoPointListEntity.class, document); + + assertThat(entity.id).isEqualTo("42"); + assertThat(entity.locations).containsExactly(new GeoPoint(12.34, 23.45), new GeoPoint(34.56, 45.67)); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -956,4 +1010,10 @@ static class EntityWithListProperty { private List values; } + + @Data + static class GeoPointListEntity { + @Id String id; + List locations; + } } From bbf4c2419506afee34d3208e620ba550cb412a82 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 9 Jun 2020 19:21:00 +0200 Subject: [PATCH 0189/1191] DATAES-859 - No randomnumeric in tests. Original PR: #479 --- .../data/elasticsearch/NestedObjectTests.java | 6 +- .../core/ElasticsearchRestTemplateTests.java | 4 +- .../core/ElasticsearchTemplateTests.java | 180 +++++++++--------- .../ElasticsearchTransportTemplateTests.java | 4 +- .../core/query/CriteriaQueryTests.java | 68 +++---- .../CustomMethodRepositoryBaseTests.java | 166 ++++++++-------- .../doubleid/DoubleIDRepositoryTests.java | 8 +- .../integer/IntegerIDRepositoryTests.java | 8 +- .../nestedobject/InnerObjectTests.java | 4 +- ...ettingAndMappingEntityRepositoryTests.java | 6 +- .../SimpleElasticsearchRepositoryTests.java | 76 ++++---- .../data/elasticsearch/utils/IdGenerator.java | 41 ++++ 12 files changed, 306 insertions(+), 265 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java diff --git a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java index 64686a1a4..9a8a7fe04 100644 --- a/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/NestedObjectTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.Data; import lombok.Getter; @@ -343,10 +343,10 @@ public void shouldIndexAndSearchMapAsNestedType() { Book book1 = new Book(); Book book2 = new Book(); - book1.setId(randomNumeric(5)); + book1.setId(nextIdAsString()); book1.setName("testBook1"); - book2.setId(randomNumeric(5)); + book2.setId(nextIdAsString()); book2.setName("testBook2"); Map> map1 = new HashMap<>(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 367cf8c42..0abaf7599 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch.core; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.Builder; import lombok.Data; @@ -67,7 +67,7 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() // when org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document .create(); - UpdateQuery updateQuery = UpdateQuery.builder(randomNumeric(5)).withDocument(document).build(); + UpdateQuery updateQuery = UpdateQuery.builder(nextIdAsString()).withDocument(document).build(); assertThatThrownBy(() -> operations.update(updateQuery, index)) .isInstanceOf(UncategorizedElasticsearchException.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 89d96a021..07b5e4aa9 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -16,11 +16,11 @@ package org.springframework.data.elasticsearch.core; import static java.util.Collections.*; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.core.document.Document.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; import lombok.AllArgsConstructor; @@ -159,7 +159,7 @@ private void deleteIndices() { public void shouldReturnCountForGivenCriteriaQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -181,7 +181,7 @@ public void shouldReturnCountForGivenCriteriaQuery() { public void shouldReturnCountForGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -202,7 +202,7 @@ public void shouldReturnCountForGivenSearchQuery() { public void shouldReturnObjectForGivenId() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); @@ -220,12 +220,12 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGet() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") .version(System.currentTimeMillis()).build(); @@ -249,12 +249,12 @@ public void shouldReturnNullObjectForNotExistingIdUsingMultiGet() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") .version(System.currentTimeMillis()).build(); @@ -264,7 +264,7 @@ public void shouldReturnNullObjectForNotExistingIdUsingMultiGet() { indexOperations.refresh(); // when - List idsToSearch = Arrays.asList(documentId, randomNumeric(5), documentId2); + List idsToSearch = Arrays.asList(documentId, nextIdAsString(), documentId2); assertThat(idsToSearch).hasSize(3); NativeSearchQuery query = new NativeSearchQueryBuilder().withIds(idsToSearch).build(); @@ -282,12 +282,12 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message").type("type1") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message").type("type2") .version(System.currentTimeMillis()).build(); @@ -309,7 +309,7 @@ public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { public void shouldReturnSearchHitsForGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -333,7 +333,7 @@ public void shouldReturnSearchHitsForGivenSearchQuery() { public void shouldReturnSearchHitsUsingLocalPreferenceForGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -357,7 +357,7 @@ public void shouldReturnSearchHitsUsingLocalPreferenceForGivenSearchQuery() { public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -378,7 +378,7 @@ public void shouldThrowExceptionWhenInvalidPreferenceForSearchQuery() { public void shouldPassIndicesOptionsForGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -406,12 +406,12 @@ public void shouldDoBulkIndex() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") .version(System.currentTimeMillis()).build(); @@ -432,7 +432,7 @@ public void shouldDoBulkIndex() { public void shouldDoBulkUpdate() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); String messageBeforeUpdate = "some test message"; String messageAfterUpdate = "test message"; @@ -466,7 +466,7 @@ public void shouldDoBulkUpdate() { public void shouldDeleteDocumentForGivenId() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -489,7 +489,7 @@ public void shouldDeleteDocumentForGivenId() { public void shouldDeleteEntityForGivenId() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -511,7 +511,7 @@ public void shouldDeleteEntityForGivenId() { public void shouldDeleteDocumentForGivenQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -540,12 +540,12 @@ public void shouldDeleteAcrossIndex() { .version(System.currentTimeMillis()) // .build(); - IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); + IndexQuery idxQuery1 = new IndexQueryBuilder().withId(nextIdAsString()).withObject(sampleEntity).build(); operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); - IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); + IndexQuery idxQuery2 = new IndexQueryBuilder().withId(nextIdAsString()).withObject(sampleEntity).build(); operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -572,12 +572,12 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .version(System.currentTimeMillis()) // .build(); - IndexQuery idxQuery1 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); + IndexQuery idxQuery1 = new IndexQueryBuilder().withId(nextIdAsString()).withObject(sampleEntity).build(); operations.index(idxQuery1, IndexCoordinates.of(INDEX_1_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_1_NAME)).refresh(); - IndexQuery idxQuery2 = new IndexQueryBuilder().withId(randomNumeric(5)).withObject(sampleEntity).build(); + IndexQuery idxQuery2 = new IndexQueryBuilder().withId(nextIdAsString()).withObject(sampleEntity).build(); operations.index(idxQuery2, IndexCoordinates.of(INDEX_2_NAME)); operations.indexOps(IndexCoordinates.of(INDEX_2_NAME)).refresh(); @@ -600,7 +600,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { public void shouldFilterSearchResultsForGivenFilter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -624,17 +624,17 @@ public void shouldSortResultsGivenSortCriteria() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(15) .version(System.currentTimeMillis()).build(); @@ -660,17 +660,17 @@ public void shouldSortResultsGivenMultipleSortCriteria() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(15) .version(System.currentTimeMillis()).build(); @@ -699,17 +699,17 @@ public void shouldSortResultsGivenNullFirstSortCriteria() { List indexQueries; // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(15) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).rate(10).version(System.currentTimeMillis()) .build(); @@ -737,17 +737,17 @@ public void shouldSortResultsGivenNullLastSortCriteria() { List indexQueries; // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(15) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).rate(10).version(System.currentTimeMillis()) .build(); @@ -798,7 +798,7 @@ public void shouldSortResultsByScore() { public void shouldExecuteStringQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -820,7 +820,7 @@ public void shouldExecuteStringQuery() { public void shouldUseScriptedFields() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setRate(2); @@ -852,7 +852,7 @@ public void shouldUseScriptedFields() { public void shouldReturnPageableResultsGivenStringQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -874,7 +874,7 @@ public void shouldReturnPageableResultsGivenStringQuery() { public void shouldReturnSortedResultsGivenStringQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -901,7 +901,7 @@ public void shouldReturnSortedResultsGivenStringQuery() { public void shouldReturnObjectMatchingGivenStringQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -936,7 +936,7 @@ public void shouldCreateIndexGivenEntityClass() { public void shouldExecuteGivenCriteriaQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("test message") .version(System.currentTimeMillis()).build(); @@ -957,7 +957,7 @@ public void shouldExecuteGivenCriteriaQuery() { public void shouldDeleteGivenCriteriaQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("test message") .version(System.currentTimeMillis()).build(); @@ -982,7 +982,7 @@ public void shouldDeleteGivenCriteriaQuery() { public void shouldReturnSpecifiedFields() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); String message = "some test message"; String type = "some type"; SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(message).type(type) @@ -1011,7 +1011,7 @@ public void shouldReturnSpecifiedFields() { public void shouldReturnFieldsBasedOnSourceFilter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); String message = "some test message"; SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message(message) .version(System.currentTimeMillis()).build(); @@ -1046,7 +1046,7 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { + "we want our search server to be always available, we want to be able to start with one machine and scale to hundreds, " + "we want real-time search, we want simple multi-tenancy, and we want a solution that is built for the cloud."; - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId1).message(sampleMessage) .version(System.currentTimeMillis()).build(); @@ -1054,7 +1054,7 @@ public void shouldReturnSimilarResultsGivenMoreLikeThisQuery() { operations.index(indexQuery, index); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); operations.index( getIndexQuery( @@ -1351,17 +1351,17 @@ public void shouldReturnListForGivenCriteria() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("test message") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("test test").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("some message").rate(15) .version(System.currentTimeMillis()).build(); @@ -1388,17 +1388,17 @@ public void shouldReturnListForGivenStringQuery() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("test message") .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("test test").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("some message").rate(15) .version(System.currentTimeMillis()).build(); @@ -1463,7 +1463,7 @@ public void shouldDeleteIndexForGivenEntity() { public void shouldDoPartialUpdateForExistingDocument() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); String messageBeforeUpdate = "some test message"; String messageAfterUpdate = "test message"; @@ -1541,7 +1541,7 @@ public void shouldReturnSourceWhenRequested() { public void shouldDoUpsertIfDocumentDoesNotExist() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document .create(); document.put("message", "test message"); @@ -1563,7 +1563,7 @@ public void shouldPassIndicesOptionsForGivenSearchScrollQuery() { // given long scrollTimeInMillis = 3000; - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -1662,7 +1662,7 @@ public void shouldReturnDifferentEntityForMultiSearch() { public void shouldDeleteDocumentBySpecifiedTypeUsingDeleteQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -1901,7 +1901,7 @@ public void shouldIndexMapWithIndexNameAndTypeAtRuntime() { public void shouldIndexGteEntityWithVersionType() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); GTEVersionEntity entity = GTEVersionEntity.builder().id(documentId).name("FooBar") .version(System.currentTimeMillis()).build(); @@ -1931,7 +1931,7 @@ public void shouldIndexGteEntityWithVersionType() { public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -1954,7 +1954,7 @@ public void shouldIndexSampleEntityWithIndexAndTypeAtRuntime() { public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -1974,7 +1974,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexUsingCriteriaQue public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -1994,7 +1994,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexUsingSearchQuery() public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCriteriaQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -2014,7 +2014,7 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexAndTypeUsingCrit public void shouldReturnCountForGivenSearchQueryWithGivenIndexAndTypeUsingSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -2035,13 +2035,13 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenMultiIndices() { // given cleanUpIndices(); - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); @@ -2066,13 +2066,13 @@ public void shouldReturnCountForGivenSearchQueryWithGivenMultiIndices() { // given cleanUpIndices(); - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); @@ -2136,13 +2136,13 @@ public void shouldReturnCountForGivenCriteriaQueryWithGivenIndexNameForSpecificI // given cleanUpIndices(); - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); @@ -2167,13 +2167,13 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd // given cleanUpIndices(); - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); @@ -2197,7 +2197,7 @@ public void shouldReturnCountForGivenSearchQueryWithGivenIndexNameForSpecificInd public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCountQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -2215,7 +2215,7 @@ public void shouldThrowAnExceptionForGivenCriteriaQueryWhenNoIndexSpecifiedForCo public void shouldThrowAnExceptionForGivenSearchQueryWhenNoIndexSpecifiedForCountQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); @@ -2302,13 +2302,13 @@ public void shouldCreateIndexWithGivenClassAndSettings() { public void shouldTestResultsAcrossMultipleIndices() { // given - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId1).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(sampleEntity1.getId()).withObject(sampleEntity1).build(); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some test message") .version(System.currentTimeMillis()).build(); @@ -2336,8 +2336,8 @@ public void shouldTestResultsAcrossMultipleIndices() { public void shouldComposeObjectsReturnedFromHeterogeneousIndexes() { // given - HetroEntity1 entity1 = new HetroEntity1(randomNumeric(3), "aFirstName"); - HetroEntity2 entity2 = new HetroEntity2(randomNumeric(4), "aLastName"); + HetroEntity1 entity1 = new HetroEntity1(nextIdAsString(), "aFirstName"); + HetroEntity2 entity2 = new HetroEntity2(nextIdAsString(), "aLastName"); IndexQuery indexQuery1 = new IndexQueryBuilder().withId(entity1.getId()).withObject(entity1).build(); IndexQuery indexQuery2 = new IndexQueryBuilder().withId(entity2.getId()).withObject(entity2).build(); @@ -2588,17 +2588,17 @@ public void shouldSortResultsGivenSortCriteriaWithScanAndScroll() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(10) .version(System.currentTimeMillis()).build(); @@ -2635,17 +2635,17 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { // given // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("abc").rate(10) .version(System.currentTimeMillis()).build(); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("xyz").rate(5) .version(System.currentTimeMillis()).build(); // third document - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3).message("xyz").rate(10) .version(System.currentTimeMillis()).build(); @@ -2682,11 +2682,11 @@ public void shouldSortResultsGivenSortCriteriaFromPageableWithScanAndScroll() { public void shouldReturnDocumentWithCollapsedField() { // given - SampleEntity sampleEntity = SampleEntity.builder().id(randomNumeric(5)).message("message 1").rate(1) + SampleEntity sampleEntity = SampleEntity.builder().id(nextIdAsString()).message("message 1").rate(1) .version(System.currentTimeMillis()).build(); - SampleEntity sampleEntity2 = SampleEntity.builder().id(randomNumeric(5)).message("message 2").rate(2) + SampleEntity sampleEntity2 = SampleEntity.builder().id(nextIdAsString()).message("message 2").rate(2) .version(System.currentTimeMillis()).build(); - SampleEntity sampleEntity3 = SampleEntity.builder().id(randomNumeric(5)).message("message 1").rate(1) + SampleEntity sampleEntity3 = SampleEntity.builder().id(nextIdAsString()).message("message 1").rate(1) .version(System.currentTimeMillis()).build(); List indexQueries = getIndexQueries(Arrays.asList(sampleEntity, sampleEntity2, sampleEntity3)); @@ -2761,7 +2761,7 @@ public void shouldAddAliasForVariousRoutingValues() { indexOperations.addAlias(aliasQuery1); indexOperations.addAlias(aliasQuery2); - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity entity = SampleEntity.builder() // .id(documentId) // .message("some message") // @@ -2809,7 +2809,7 @@ public void shouldAddAliasWithGivenRoutingValue() { // when indexOperations.addAlias(aliasQuery); - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = SampleEntity.builder() // .id(documentId) // .message("some message") // diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java index 401b3f19c..d2379cafe 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTransportTemplateTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch.core; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.Data; import lombok.val; @@ -65,7 +65,7 @@ public void shouldThrowExceptionIfDocumentDoesNotExistWhileDoingPartialUpdate() // when org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document .create(); - UpdateQuery updateQuery = UpdateQuery.builder(randomNumeric(5)).withDocument(document).build(); + UpdateQuery updateQuery = UpdateQuery.builder(nextIdAsString()).withDocument(document).build(); assertThatThrownBy(() -> operations.update(updateQuery, index)).isInstanceOf(DocumentMissingException.class); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 2cd1a1d63..516c64b5f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch.core.query; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import static org.springframework.data.elasticsearch.utils.IndexBuilder.*; import lombok.AllArgsConstructor; @@ -87,7 +87,7 @@ void after() { public void shouldPerformAndOperation() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some test message"); @@ -116,7 +116,7 @@ public void shouldPerformOrOperation() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("some message"); @@ -128,7 +128,7 @@ public void shouldPerformOrOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); @@ -159,7 +159,7 @@ public void shouldPerformAndOperationWithinCriteria() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -190,7 +190,7 @@ public void shouldPerformOrOperationWithinCriteria() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -219,7 +219,7 @@ public void shouldPerformIsOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -249,7 +249,7 @@ public void shouldPerformMultipleIsOperations() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("some message"); @@ -261,7 +261,7 @@ public void shouldPerformMultipleIsOperations() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); @@ -291,7 +291,7 @@ public void shouldPerformEndsWithOperation() { List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("some message"); @@ -303,7 +303,7 @@ public void shouldPerformEndsWithOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message end"); @@ -333,7 +333,7 @@ public void shouldPerformStartsWithOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("start some message"); @@ -345,7 +345,7 @@ public void shouldPerformStartsWithOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); @@ -375,7 +375,7 @@ public void shouldPerformContainsOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("contains some message"); @@ -387,7 +387,7 @@ public void shouldPerformContainsOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); @@ -416,7 +416,7 @@ public void shouldExecuteExpression() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("elasticsearch search"); @@ -428,7 +428,7 @@ public void shouldExecuteExpression() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test message"); @@ -457,7 +457,7 @@ public void shouldExecuteCriteriaChain() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("some message search"); @@ -469,7 +469,7 @@ public void shouldExecuteCriteriaChain() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("test test message"); @@ -499,7 +499,7 @@ public void shouldPerformIsNotOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("bar"); @@ -511,7 +511,7 @@ public void shouldPerformIsNotOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("foo"); @@ -541,7 +541,7 @@ public void shouldPerformBetweenOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(100); @@ -554,7 +554,7 @@ public void shouldPerformBetweenOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(200); @@ -583,7 +583,7 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(300); @@ -596,7 +596,7 @@ public void shouldPerformBetweenOperationWithoutUpperBound() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(400); @@ -626,7 +626,7 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(500); @@ -639,7 +639,7 @@ public void shouldPerformBetweenOperationWithoutLowerBound() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(600); @@ -669,7 +669,7 @@ public void shouldPerformLessThanEqualOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(700); @@ -682,7 +682,7 @@ public void shouldPerformLessThanEqualOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(800); @@ -712,7 +712,7 @@ public void shouldPerformGreaterThanEquals() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(900); @@ -725,7 +725,7 @@ public void shouldPerformGreaterThanEquals() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(1000); @@ -755,7 +755,7 @@ public void shouldPerformBoostOperation() { // given List indexQueries = new ArrayList<>(); // first document - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setRate(700); @@ -768,7 +768,7 @@ public void shouldPerformBoostOperation() { indexQueries.add(indexQuery1); // second document - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setRate(800); @@ -819,7 +819,7 @@ public void shouldReturnDocumentAboveMinimalScoreGivenCriteria() { public void shouldEscapeValue() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("Hello World!"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index f815d0bf0..9bffc6c0d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -15,9 +15,9 @@ */ package org.springframework.data.elasticsearch.repositories.custommethod; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -100,7 +100,7 @@ void after() { public void shouldExecuteCustomMethod() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -119,7 +119,7 @@ public void shouldExecuteCustomMethod() { public void shouldExecuteCustomMethodForNot() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("some"); @@ -137,7 +137,7 @@ public void shouldExecuteCustomMethodForNot() { public void shouldExecuteCustomMethodWithQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -157,7 +157,7 @@ public void shouldExecuteCustomMethodWithQuery() { public void shouldExecuteCustomMethodWithLessThan() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -165,7 +165,7 @@ public void shouldExecuteCustomMethodWithLessThan() { sampleEntity.setMessage("some message"); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -185,7 +185,7 @@ public void shouldExecuteCustomMethodWithLessThan() { public void shouldExecuteCustomMethodWithBefore() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -205,7 +205,7 @@ public void shouldExecuteCustomMethodWithBefore() { public void shouldExecuteCustomMethodWithAfter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -225,7 +225,7 @@ public void shouldExecuteCustomMethodWithAfter() { public void shouldExecuteCustomMethodWithLike() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -245,7 +245,7 @@ public void shouldExecuteCustomMethodWithLike() { public void shouldExecuteCustomMethodForStartingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -265,7 +265,7 @@ public void shouldExecuteCustomMethodForStartingWith() { public void shouldExecuteCustomMethodForEndingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -285,7 +285,7 @@ public void shouldExecuteCustomMethodForEndingWith() { public void shouldExecuteCustomMethodForContains() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -305,7 +305,7 @@ public void shouldExecuteCustomMethodForContains() { public void shouldExecuteCustomMethodForIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -313,7 +313,7 @@ public void shouldExecuteCustomMethodForIn() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -334,7 +334,7 @@ public void shouldExecuteCustomMethodForIn() { public void shouldExecuteCustomMethodForNotIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -342,7 +342,7 @@ public void shouldExecuteCustomMethodForNotIn() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -363,13 +363,13 @@ public void shouldExecuteCustomMethodForNotIn() { public void shouldHandleManyValuesQueryingIn() { // given - String documentId1 = randomNumeric(32); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setKeyword("foo"); repository.save(sampleEntity1); - String documentId2 = randomNumeric(32); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setKeyword("bar"); @@ -379,7 +379,7 @@ public void shouldHandleManyValuesQueryingIn() { keywords.add("foo"); for (int i = 0; i < 1025; i++) { - keywords.add(randomNumeric(32)); + keywords.add(nextIdAsString()); } // when @@ -394,13 +394,13 @@ public void shouldHandleManyValuesQueryingIn() { public void shouldHandleManyValuesQueryingNotIn() { // given - String documentId1 = randomNumeric(32); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setKeyword("foo"); repository.save(sampleEntity1); - String documentId2 = randomNumeric(32); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setKeyword("bar"); @@ -410,7 +410,7 @@ public void shouldHandleManyValuesQueryingNotIn() { keywords.add("foo"); for (int i = 0; i < 1025; i++) { - keywords.add(randomNumeric(32)); + keywords.add(nextIdAsString()); } // when @@ -425,7 +425,7 @@ public void shouldHandleManyValuesQueryingNotIn() { public void shouldExecuteCustomMethodForTrue() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -434,7 +434,7 @@ public void shouldExecuteCustomMethodForTrue() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -453,7 +453,7 @@ public void shouldExecuteCustomMethodForTrue() { public void shouldExecuteCustomMethodForFalse() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -462,7 +462,7 @@ public void shouldExecuteCustomMethodForFalse() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -482,7 +482,7 @@ public void shouldExecuteCustomMethodForFalse() { public void shouldExecuteCustomMethodForOrderBy() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("abc"); @@ -491,7 +491,7 @@ public void shouldExecuteCustomMethodForOrderBy() { repository.save(sampleEntity); // document 2 - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("xyz"); @@ -500,7 +500,7 @@ public void shouldExecuteCustomMethodForOrderBy() { repository.save(sampleEntity2); // document 3 - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setType("def"); @@ -520,7 +520,7 @@ public void shouldExecuteCustomMethodForOrderBy() { public void shouldExecuteCustomMethodWithBooleanParameter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -529,7 +529,7 @@ public void shouldExecuteCustomMethodWithBooleanParameter() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -549,7 +549,7 @@ public void shouldExecuteCustomMethodWithBooleanParameter() { public void shouldReturnPageableInUnwrappedPageResult() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -558,7 +558,7 @@ public void shouldReturnPageableInUnwrappedPageResult() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -601,21 +601,21 @@ public void shouldReturnPageableResultsWithQueryAnnotationExpectedPageSize() { public void shouldReturnPageableResultsWithGivenSortingOrder() { // given - String documentId = random(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("abc"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("abd"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity2); - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setMessage("abe"); @@ -635,21 +635,21 @@ public void shouldReturnPageableResultsWithGivenSortingOrder() { public void shouldReturnListForMessage() { // given - String documentId = random(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("abc"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("abd"); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity2); - String documentId3 = randomNumeric(5); + String documentId3 = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId3); sampleEntity3.setMessage("abe"); @@ -667,7 +667,7 @@ public void shouldReturnListForMessage() { public void shouldExecuteCustomMethodWithGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -689,7 +689,7 @@ public void shouldExecuteCustomMethodWithGeoPoint() { public void shouldExecuteCustomMethodWithGeoPointAndString() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -699,7 +699,7 @@ public void shouldExecuteCustomMethodWithGeoPointAndString() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -722,7 +722,7 @@ public void shouldExecuteCustomMethodWithGeoPointAndString() { public void shouldExecuteCustomMethodWithWithinGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -745,7 +745,7 @@ public void shouldExecuteCustomMethodWithWithinGeoPoint() { public void shouldExecuteCustomMethodWithWithinPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -768,7 +768,7 @@ public void shouldExecuteCustomMethodWithWithinPoint() { public void shouldExecuteCustomMethodWithNearBox() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -778,7 +778,7 @@ public void shouldExecuteCustomMethodWithNearBox() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -808,7 +808,7 @@ public void shouldExecuteCustomMethodWithNearBox() { public void shouldExecuteCustomMethodWithNearPointAndDistance() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -846,7 +846,7 @@ public void shouldAllowReturningJava8StreamInCustomQuery() { public void shouldCountCustomMethod() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -854,7 +854,7 @@ public void shouldCountCustomMethod() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -873,7 +873,7 @@ public void shouldCountCustomMethod() { public void shouldCountCustomMethodForNot() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("some"); @@ -881,7 +881,7 @@ public void shouldCountCustomMethodForNot() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -900,7 +900,7 @@ public void shouldCountCustomMethodForNot() { public void shouldCountCustomMethodWithBooleanParameter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -909,7 +909,7 @@ public void shouldCountCustomMethodWithBooleanParameter() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -928,7 +928,7 @@ public void shouldCountCustomMethodWithBooleanParameter() { public void shouldCountCustomMethodWithLessThan() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -936,7 +936,7 @@ public void shouldCountCustomMethodWithLessThan() { sampleEntity.setMessage("some message"); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -955,7 +955,7 @@ public void shouldCountCustomMethodWithLessThan() { public void shouldCountCustomMethodWithBefore() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -964,7 +964,7 @@ public void shouldCountCustomMethodWithBefore() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -984,7 +984,7 @@ public void shouldCountCustomMethodWithBefore() { public void shouldCountCustomMethodWithAfter() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -993,7 +993,7 @@ public void shouldCountCustomMethodWithAfter() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1013,7 +1013,7 @@ public void shouldCountCustomMethodWithAfter() { public void shouldCountCustomMethodWithLike() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1022,7 +1022,7 @@ public void shouldCountCustomMethodWithLike() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1042,7 +1042,7 @@ public void shouldCountCustomMethodWithLike() { public void shouldCountCustomMethodForStartingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1051,7 +1051,7 @@ public void shouldCountCustomMethodForStartingWith() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1071,7 +1071,7 @@ public void shouldCountCustomMethodForStartingWith() { public void shouldCountCustomMethodForEndingWith() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1080,7 +1080,7 @@ public void shouldCountCustomMethodForEndingWith() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1100,7 +1100,7 @@ public void shouldCountCustomMethodForEndingWith() { public void shouldCountCustomMethodForContains() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1109,7 +1109,7 @@ public void shouldCountCustomMethodForContains() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1129,7 +1129,7 @@ public void shouldCountCustomMethodForContains() { public void shouldCountCustomMethodForIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1137,7 +1137,7 @@ public void shouldCountCustomMethodForIn() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1157,7 +1157,7 @@ public void shouldCountCustomMethodForIn() { public void shouldCountCustomMethodForNotIn() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1165,7 +1165,7 @@ public void shouldCountCustomMethodForNotIn() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1185,7 +1185,7 @@ public void shouldCountCustomMethodForNotIn() { public void shouldCountCustomMethodForTrue() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1194,7 +1194,7 @@ public void shouldCountCustomMethodForTrue() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1212,7 +1212,7 @@ public void shouldCountCustomMethodForTrue() { public void shouldCountCustomMethodForFalse() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1221,7 +1221,7 @@ public void shouldCountCustomMethodForFalse() { repository.save(sampleEntity); // given - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setType("test"); @@ -1240,7 +1240,7 @@ public void shouldCountCustomMethodForFalse() { public void shouldCountCustomMethodWithWithinGeoPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1250,7 +1250,7 @@ public void shouldCountCustomMethodWithWithinGeoPoint() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1271,7 +1271,7 @@ public void shouldCountCustomMethodWithWithinGeoPoint() { public void shouldCountCustomMethodWithWithinPoint() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1281,7 +1281,7 @@ public void shouldCountCustomMethodWithWithinPoint() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); @@ -1302,7 +1302,7 @@ public void shouldCountCustomMethodWithWithinPoint() { public void shouldCountCustomMethodWithNearBox() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1312,7 +1312,7 @@ public void shouldCountCustomMethodWithNearBox() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test2"); @@ -1333,7 +1333,7 @@ public void shouldCountCustomMethodWithNearBox() { public void shouldCountCustomMethodWithNearPointAndDistance() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setType("test"); @@ -1343,7 +1343,7 @@ public void shouldCountCustomMethodWithNearPointAndDistance() { repository.save(sampleEntity); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("test"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java index ea69d7f33..41c199168 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/doubleid/DoubleIDRepositoryTests.java @@ -16,11 +16,11 @@ package org.springframework.data.elasticsearch.repositories.doubleid; import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import java.util.Arrays; import java.util.Optional; -import org.apache.commons.lang.math.RandomUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -75,13 +75,13 @@ public void after() { public void shouldDoBulkIndexDocument() { // given - Double documentId1 = RandomUtils.nextDouble(); + Double documentId1 = nextIdAsDouble(); DoubleIDEntity sampleEntity1 = new DoubleIDEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setMessage("some message"); sampleEntity1.setVersion(System.currentTimeMillis()); - Double documentId2 = RandomUtils.nextDouble(); + Double documentId2 = nextIdAsDouble(); DoubleIDEntity sampleEntity2 = new DoubleIDEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("some message"); @@ -102,7 +102,7 @@ public void shouldDoBulkIndexDocument() { public void shouldSaveDocument() { // given - Double documentId = RandomUtils.nextDouble(); + Double documentId = nextIdAsDouble(); DoubleIDEntity sampleEntity = new DoubleIDEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java index 03f889152..8d0799304 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/integer/IntegerIDRepositoryTests.java @@ -16,11 +16,11 @@ package org.springframework.data.elasticsearch.repositories.integer; import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import java.util.Arrays; import java.util.Optional; -import org.apache.commons.lang.math.RandomUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -76,13 +76,13 @@ void after() { public void shouldDoBulkIndexDocument() { // given - Integer documentId1 = RandomUtils.nextInt(); + Integer documentId1 = nextIdAsInt(); IntegerIDEntity sampleEntity1 = new IntegerIDEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setMessage("some message"); sampleEntity1.setVersion(System.currentTimeMillis()); - Integer documentId2 = RandomUtils.nextInt(); + Integer documentId2 = nextIdAsInt(); IntegerIDEntity sampleEntity2 = new IntegerIDEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("some message"); @@ -103,7 +103,7 @@ public void shouldDoBulkIndexDocument() { public void shouldSaveDocument() { // given - Integer documentId = RandomUtils.nextInt(); + Integer documentId = nextIdAsInt(); IntegerIDEntity sampleEntity = new IntegerIDEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java index 1e6c6e564..2377dff3e 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/nestedobject/InnerObjectTests.java @@ -16,8 +16,8 @@ package org.springframework.data.elasticsearch.repositories.nestedobject; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -85,7 +85,7 @@ void after() { public void shouldIndexInnerObject() { // given - String id = randomAlphanumeric(5); + String id = nextIdAsString(); Book book = new Book(); book.setId(id); book.setName("xyz"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java index d500148d9..442b77835 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/setting/dynamic/DynamicSettingAndMappingEntityRepositoryTests.java @@ -17,10 +17,10 @@ import static org.assertj.core.api.Assertions.*; import static org.springframework.data.elasticsearch.core.document.Document.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import java.util.Map; -import org.apache.commons.lang.RandomStringUtils; import org.elasticsearch.index.query.QueryBuilders; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; @@ -99,14 +99,14 @@ public void shouldSearchOnGivenTokenizerUsingGivenDynamicSettingsForGivenIndex() // given DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity1 = new DynamicSettingAndMappingEntity(); - dynamicSettingAndMappingEntity1.setId(RandomStringUtils.randomNumeric(5)); + dynamicSettingAndMappingEntity1.setId(nextIdAsString()); dynamicSettingAndMappingEntity1.setName("test-setting1"); dynamicSettingAndMappingEntity1.setEmail("test_setting1@Test.com"); repository.save(dynamicSettingAndMappingEntity1); DynamicSettingAndMappingEntity dynamicSettingAndMappingEntity2 = new DynamicSettingAndMappingEntity(); - dynamicSettingAndMappingEntity2.setId(RandomStringUtils.randomNumeric(5)); + dynamicSettingAndMappingEntity2.setId(nextIdAsString()); dynamicSettingAndMappingEntity2.setName("test-setting2"); dynamicSettingAndMappingEntity2.setEmail("test_setting2@Test.com"); diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java index 7af26b0f3..cc1ef13c2 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/simple/SimpleElasticsearchRepositoryTests.java @@ -15,10 +15,10 @@ */ package org.springframework.data.elasticsearch.repository.support.simple; -import static org.apache.commons.lang.RandomStringUtils.*; import static org.assertj.core.api.Assertions.*; import static org.elasticsearch.index.query.QueryBuilders.*; import static org.springframework.data.elasticsearch.annotations.FieldType.*; +import static org.springframework.data.elasticsearch.utils.IdGenerator.*; import lombok.AllArgsConstructor; import lombok.Builder; @@ -101,13 +101,13 @@ void after() { public void shouldDoBulkIndexDocument() { // given - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setMessage("some message"); sampleEntity1.setVersion(System.currentTimeMillis()); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("some message"); @@ -128,7 +128,7 @@ public void shouldDoBulkIndexDocument() { public void shouldSaveDocument() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -158,7 +158,7 @@ public void throwExceptionWhenTryingToInsertWithVersionButWithoutId() { public void shouldFindDocumentById() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -177,7 +177,7 @@ public void shouldFindDocumentById() { public void shouldReturnCountOfDocuments() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -205,7 +205,7 @@ public void shouldFindAllDocuments() { public void shouldDeleteDocument() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); @@ -224,7 +224,7 @@ public void shouldDeleteDocument() { public void shouldSearchDocumentsGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some test message"); @@ -245,7 +245,7 @@ public void shouldSearchDocumentsGivenSearchQuery() { public void shouldSearchDocumentsGivenElasticsearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -264,14 +264,14 @@ public void shouldSearchDocumentsGivenElasticsearchQuery() { public void shouldFindAllByIdQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); sampleEntity.setVersion(System.currentTimeMillis()); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello world."); @@ -289,13 +289,13 @@ public void shouldFindAllByIdQuery() { public void shouldSaveIterableEntities() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("hello world."); sampleEntity1.setVersion(System.currentTimeMillis()); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello world."); @@ -315,7 +315,7 @@ public void shouldSaveIterableEntities() { public void shouldReturnTrueGivenDocumentWithIdExists() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -333,7 +333,7 @@ public void shouldReturnTrueGivenDocumentWithIdExists() { public void shouldReturnFalseGivenDocumentWithIdDoesNotExist() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); // when boolean exist = repository.existsById(documentId); @@ -346,7 +346,7 @@ public void shouldReturnFalseGivenDocumentWithIdDoesNotExist() { public void shouldReturnResultsForGivenSearchQuery() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -365,7 +365,7 @@ public void shouldReturnResultsForGivenSearchQuery() { public void shouldDeleteAll() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -385,7 +385,7 @@ public void shouldDeleteAll() { public void shouldDeleteById() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -406,21 +406,21 @@ public void shouldDeleteById() { public void shouldDeleteByMessageAndReturnList() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("hello world 1"); sampleEntity1.setAvailable(true); sampleEntity1.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setMessage("hello world 2"); sampleEntity2.setAvailable(true); sampleEntity2.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId); sampleEntity3.setMessage("hello world 3"); @@ -442,19 +442,19 @@ public void shouldDeleteByMessageAndReturnList() { public void shouldDeleteByListForMessage() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("hello world 1"); sampleEntity1.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setMessage("hello world 2"); sampleEntity2.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId); sampleEntity3.setMessage("hello world 3"); @@ -475,19 +475,19 @@ public void shouldDeleteByListForMessage() { public void shouldDeleteByType() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setType("book"); sampleEntity1.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId); sampleEntity2.setType("article"); sampleEntity2.setVersion(System.currentTimeMillis()); - documentId = randomNumeric(5); + documentId = nextIdAsString(); SampleEntity sampleEntity3 = new SampleEntity(); sampleEntity3.setId(documentId); sampleEntity3.setType("image"); @@ -507,7 +507,7 @@ public void shouldDeleteByType() { public void shouldDeleteEntity() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("hello world."); @@ -527,14 +527,14 @@ public void shouldDeleteEntity() { public void shouldReturnIterableEntities() { // given - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setMessage("hello world."); sampleEntity1.setVersion(System.currentTimeMillis()); repository.save(sampleEntity1); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello world."); @@ -552,13 +552,13 @@ public void shouldReturnIterableEntities() { public void shouldDeleteIterableEntities() { // given - String documentId1 = randomNumeric(5); + String documentId1 = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId1); sampleEntity1.setMessage("hello world."); sampleEntity1.setVersion(System.currentTimeMillis()); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello world."); @@ -579,7 +579,7 @@ public void shouldDeleteIterableEntities() { public void shouldIndexEntity() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setVersion(System.currentTimeMillis()); @@ -597,7 +597,7 @@ public void shouldIndexEntity() { public void shouldIndexWithoutRefreshEntity() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setVersion(System.currentTimeMillis()); @@ -620,13 +620,13 @@ public void shouldIndexWithoutRefreshEntity() { public void shouldSortByGivenField() { // given - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("world"); repository.save(sampleEntity); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello"); @@ -664,13 +664,13 @@ public void shouldReturnSimilarEntities() { public void shouldIndexNotEmptyList() { // given List list = new ArrayList<>(); - String documentId = randomNumeric(5); + String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); sampleEntity1.setId(documentId); sampleEntity1.setMessage("world"); list.add(sampleEntity1); - String documentId2 = randomNumeric(5); + String documentId2 = nextIdAsString(); SampleEntity sampleEntity2 = new SampleEntity(); sampleEntity2.setId(documentId2); sampleEntity2.setMessage("hello"); diff --git a/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java b/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java new file mode 100644 index 000000000..9ea7770f2 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/utils/IdGenerator.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 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.utils; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Class to provide sequential IDs. Uses an integer, 2^31 -1 values should be enough for the test runs. + * + * @author Peter-Josef Meisch + */ +public final class IdGenerator { + + private static final AtomicInteger NEXT = new AtomicInteger(); + + private IdGenerator() {} + + public static int nextIdAsInt() { + return NEXT.incrementAndGet(); + } + + public static double nextIdAsDouble() { + return NEXT.incrementAndGet(); + } + public static String nextIdAsString() { + return "" + nextIdAsInt(); + } +} From 282214f8bc2e0e054d7cb6a5111a1bf6c364aad5 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 10 Jun 2020 10:53:10 +0200 Subject: [PATCH 0190/1191] DATAES-806 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index ae6048696..833ea41a4 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,12 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.18.RELEASE (2020-06-10) +---------------------------------------------- +* DATAES-811 - Remove Travis CI. +* DATAES-806 - Release 3.1.18 (Lovelace SR18). + + Changes in version 4.0.0.RELEASE (2020-05-12) --------------------------------------------- * DATAES-822 - ElasticsearchRestTemplate should not use `spring-web`. From 7b24ea95755379ae7fe6cc54614cd2270e8b42b9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 10 Jun 2020 12:10:58 +0200 Subject: [PATCH 0191/1191] DATAES-807 - Updated changelog. --- src/main/resources/changelog.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 833ea41a4..de131709c 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,17 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.8.RELEASE (2020-06-10) +--------------------------------------------- +* DATAES-851 - Upgrade to Elasticsearch 6.8.10. +* DATAES-837 - Update to Elasticsearch 6.8.9. +* DATAES-821 - Fix code for adding an alias. +* DATAES-811 - Remove Travis CI. +* DATAES-807 - Release 3.2.8 (Moore SR8). +* DATAES-776 - Adapt RestClients class to change in InetSocketAddress class in JDK14. +* DATAES-767 - Fix ReactiveElasticsearch handling of 4xx HTTP responses. + + Changes in version 3.1.18.RELEASE (2020-06-10) ---------------------------------------------- * DATAES-811 - Remove Travis CI. @@ -1145,3 +1156,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 384e52b2c39e6a9c6241658023c0efd2e9aaa10a Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 10 Jun 2020 14:01:56 +0200 Subject: [PATCH 0192/1191] DATAES-823 - Updated changelog. --- src/main/resources/changelog.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index de131709c..5eac8b3bd 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,21 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.1.RELEASE (2020-06-10) +--------------------------------------------- +* DATAES-857 - Registered simple types are not read from list. +* DATAES-850 - Add warning and documentation for missing TemporalAccessor configuration. +* DATAES-845 - MappingElasticsearchConverter crashes when writing lists containing null values. +* DATAES-844 - Improve TOC formatting for migration guides. +* DATAES-839 - ReactiveElasticsearchTemplate should use RequestFactory. +* DATAES-835 - Fix code sample in documentation for scroll API. +* DATAES-832 - findAllById repository method returns iterable with null elements for not found ids. +* DATAES-831 - SearchOperations.searchForStream does not use requested maxResults. +* DATAES-828 - Fields of type date need to have a format defined. +* DATAES-827 - Repositories should not try to create an index when it already exists. +* DATAES-823 - Release 4.0.1 (Neumann SR1). + + Changes in version 3.2.8.RELEASE (2020-06-10) --------------------------------------------- * DATAES-851 - Upgrade to Elasticsearch 6.8.10. @@ -1157,3 +1172,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 3c44a1c96996ff2af496500505a8194e22b3de02 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 11 Jun 2020 19:13:59 +0200 Subject: [PATCH 0193/1191] DATAES-863 - Improve server error response handling. Original PR: #480 --- .../DefaultReactiveElasticsearchClient.java | 91 ++++++++++++------- 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index e1b87ab0e..4f687c36e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -804,53 +804,82 @@ private static XContentParser createParser(String mediaType, String content) thr private Publisher handleServerError(Request request, ClientResponse response) { - RestStatus status = RestStatus.fromCode(response.statusCode().value()); + int statusCode = response.statusCode().value(); + RestStatus status = RestStatus.fromCode(statusCode); + String mediaType = response.headers().contentType().map(MediaType::toString).orElse(XContentType.JSON.mediaType()); - return Mono.error(new ElasticsearchStatusException(String.format("%s request to %s returned error code %s.", - request.getMethod(), request.getEndpoint(), response.statusCode().value()), status)); + return response.body(BodyExtractors.toMono(byte[].class)) // + .map(bytes -> new String(bytes, StandardCharsets.UTF_8)) // + .flatMap(content -> contentOrError(content, mediaType, status)) + .flatMap(unused -> Mono + .error(new ElasticsearchStatusException(String.format("%s request to %s returned error code %s.", + request.getMethod(), request.getEndpoint(), statusCode), status))); } private Publisher handleClientError(String logId, Request request, ClientResponse response, Class responseType) { + int statusCode = response.statusCode().value(); + RestStatus status = RestStatus.fromCode(statusCode); + String mediaType = response.headers().contentType().map(MediaType::toString).orElse(XContentType.JSON.mediaType()); + return response.body(BodyExtractors.toMono(byte[].class)) // .map(bytes -> new String(bytes, StandardCharsets.UTF_8)) // - .flatMap(content -> { - String mediaType = response.headers().contentType().map(MediaType::toString) - .orElse(XContentType.JSON.mediaType()); - RestStatus status = RestStatus.fromCode(response.statusCode().value()); - try { - ElasticsearchException exception = getElasticsearchException(response, content, mediaType); - if (exception != null) { - StringBuilder sb = new StringBuilder(); - buildExceptionMessages(sb, exception); - return Mono.error(new ElasticsearchStatusException(sb.toString(), status, exception)); - } - } catch (Exception e) { - return Mono.error(new ElasticsearchStatusException(content, status)); - } - return Mono.just(content); - }).doOnNext(it -> ClientLogger.logResponse(logId, response.statusCode(), it)) // + .flatMap(content -> contentOrError(content, mediaType, status)) // + .doOnNext(content -> ClientLogger.logResponse(logId, response.statusCode(), content)) // .flatMap(content -> doDecode(response, responseType, content)); } // region ElasticsearchException helper + /** + * checks if the given content body contains an {@link ElasticsearchException}, if yes it is returned in a Mono.error. + * Otherwise the content is returned in the Mono + * + * @param content the content to analyze + * @param mediaType the returned media type + * @param status the response status + * @return a Mono with the content or an Mono.error + */ + private static Mono contentOrError(String content, String mediaType, RestStatus status) { + + ElasticsearchException exception = getElasticsearchException(content, mediaType, status); + + if (exception != null) { + StringBuilder sb = new StringBuilder(); + buildExceptionMessages(sb, exception); + return Mono.error(new ElasticsearchStatusException(sb.toString(), status, exception)); + } + + return Mono.just(content); + } + + /** + * tries to parse an {@link ElasticsearchException} from the given body content + * + * @param content the content to analyse + * @param mediaType the type of the body content + * @return an {@link ElasticsearchException} or {@literal null}. + */ @Nullable - private ElasticsearchException getElasticsearchException(ClientResponse response, String content, String mediaType) - throws IOException { + private static ElasticsearchException getElasticsearchException(String content, String mediaType, RestStatus status) { - XContentParser parser = createParser(mediaType, content); - // we have a JSON object with an error and a status field - XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT + try { + XContentParser parser = createParser(mediaType, content); + // we have a JSON object with an error and a status field + XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT - do { - token = parser.nextToken(); + do { + token = parser.nextToken(); - if (parser.currentName().equals("error")) { - return ElasticsearchException.failureFromXContent(parser); - } - } while (token == XContentParser.Token.FIELD_NAME); - return null; + if (parser.currentName().equals("error")) { + return ElasticsearchException.failureFromXContent(parser); + } + } while (token == XContentParser.Token.FIELD_NAME); + + return null; + } catch (IOException e) { + return new ElasticsearchStatusException(content, status); + } } private static void buildExceptionMessages(StringBuilder sb, Throwable t) { From aeaa27cb9981b857198e9c76f211b1cbbfa56c6c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 12 Jun 2020 08:23:41 +0200 Subject: [PATCH 0194/1191] DATAES-840 - Introduce IndexCoordinateResolver. Original PR: #467 --- ...elasticsearch-migration-guide-4.0-4.1.adoc | 8 + .../core/AbstractDefaultIndexOperations.java | 71 +- .../core/AbstractElasticsearchTemplate.java | 77 ++ .../core/DefaultIndexOperations.java | 143 +--- .../core/DefaultTransportIndexOperations.java | 67 +- .../core/DocumentOperations.java | 51 ++ .../core/ElasticsearchOperations.java | 22 +- .../core/ElasticsearchRestTemplate.java | 6 +- .../core/ElasticsearchTemplate.java | 12 +- .../elasticsearch/core/EntityOperations.java | 45 +- .../core/ReactiveDocumentOperations.java | 70 +- .../core/ReactiveElasticsearchTemplate.java | 10 + .../elasticsearch/core/RequestFactory.java | 785 ++++++++++-------- .../elasticsearch/core/SearchOperations.java | 31 + .../core/convert/ElasticsearchConverter.java | 6 +- .../MappingElasticsearchConverter.java | 4 +- .../ElasticsearchPersistentEntity.java | 1 + .../SimpleElasticsearchMappingContext.java | 22 +- .../SimpleElasticsearchPersistentEntity.java | 77 +- ...SimpleElasticsearchPersistentProperty.java | 14 + .../ElasticsearchEntityInformation.java | 1 + ...MappingElasticsearchEntityInformation.java | 36 +- ...eactiveElasticsearchRepositoryFactory.java | 3 +- .../core/ElasticsearchPartQueryTests.java | 1 + .../core/ElasticsearchTemplateTests.java | 18 +- .../dynamicindex/DynamicIndexEntityTests.java | 22 +- 26 files changed, 975 insertions(+), 628 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index a220252bc..1697205c7 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -3,8 +3,16 @@ This section describes breaking changes from version 4.0.x to 4.1.x and how removed features can be replaced by new introduced features. +== Deprecations + +.Definition of the id property +It is possible to define a property of en entity as the id property by naming it either `id` or `document`. This behaviour is now deprecated and will produce a warning. PLease us the `@Id` annotation to mark a property as being the id property. + [[elasticsearch-migration-guide-4.0-4.1.removal]] == Removals +.Type mappings The _type mappings_ parameters of the `@Document` annotation and the `IndexCoordinates` object were removed. They had been deprecated in Spring Data Elasticsearch 4.0 and their values weren't used anymore. +=== Breaking changes + diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 9199fc784..4008e11bf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -38,6 +38,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -55,20 +56,24 @@ abstract class AbstractDefaultIndexOperations implements IndexOperations { protected final RequestFactory requestFactory; @Nullable protected final Class boundClass; - private final IndexCoordinates boundIndex; + @Nullable private final IndexCoordinates boundIndex; public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter, Class boundClass) { + + Assert.notNull(boundClass, "boundClass may not be null"); + this.elasticsearchConverter = elasticsearchConverter; requestFactory = new RequestFactory(elasticsearchConverter); - this.boundClass = boundClass; - this.boundIndex = getIndexCoordinatesFor(boundClass); + this.boundIndex = null; } public AbstractDefaultIndexOperations(ElasticsearchConverter elasticsearchConverter, IndexCoordinates boundIndex) { + + Assert.notNull(boundIndex, "boundIndex may not be null"); + this.elasticsearchConverter = elasticsearchConverter; requestFactory = new RequestFactory(elasticsearchConverter); - this.boundClass = null; this.boundIndex = boundIndex; } @@ -85,48 +90,59 @@ protected Class checkForBoundClass() { @Override public boolean create() { + IndexCoordinates index; + Document settings = null; + if (boundClass != null) { Class clazz = boundClass; - String indexName = getIndexCoordinates().getIndexName(); + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(clazz); + index = persistentEntity.getIndexCoordinates(); if (clazz.isAnnotationPresent(Setting.class)) { String settingPath = clazz.getAnnotation(Setting.class).settingPath(); if (hasText(settingPath)) { - String settings = ResourceUtil.readFileFromClasspath(settingPath); + String fileSettings = ResourceUtil.readFileFromClasspath(settingPath); - if (hasText(settings)) { - return doCreate(indexName, Document.parse(settings)); + if (hasText(fileSettings)) { + settings = Document.parse(fileSettings); } } else { LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); } } - return doCreate(indexName, getDefaultSettings(getRequiredPersistentEntity(clazz))); + + if (settings == null) { + settings = getDefaultSettings(persistentEntity); + } + } else { + index = boundIndex; } - return doCreate(getIndexCoordinates().getIndexName(), null); + + // noinspection ConstantConditions + return doCreate(index, settings); } @Override public boolean create(Document settings) { - return doCreate(getIndexCoordinates().getIndexName(), settings); + return doCreate(getIndexCoordinates(), settings); } - protected abstract boolean doCreate(String indexName, @Nullable Document settings); + protected abstract boolean doCreate(IndexCoordinates index, @Nullable Document settings); @Override public boolean delete() { - return doDelete(getIndexCoordinates().getIndexName()); + return doDelete(getIndexCoordinates()); } - protected abstract boolean doDelete(String indexName); + protected abstract boolean doDelete(IndexCoordinates index); @Override public boolean exists() { - return doExists(getIndexCoordinates().getIndexName()); + return doExists(getIndexCoordinates()); } - protected abstract boolean doExists(String indexName); + protected abstract boolean doExists(IndexCoordinates index); @Override public boolean putMapping(Document mapping) { @@ -149,10 +165,10 @@ public Map getSettings() { @Override public Map getSettings(boolean includeDefaults) { - return doGetSettings(getIndexCoordinates().getIndexName(), includeDefaults); + return doGetSettings(getIndexCoordinates(), includeDefaults); } - protected abstract Map doGetSettings(String indexName, boolean includeDefaults); + protected abstract Map doGetSettings(IndexCoordinates index, boolean includeDefaults); @Override public void refresh() { @@ -170,10 +186,10 @@ public boolean addAlias(AliasQuery query) { @Override public List queryForAlias() { - return doQueryForAlias(getIndexCoordinates().getIndexName()); + return doQueryForAlias(getIndexCoordinates()); } - protected abstract List doQueryForAlias(String indexName); + protected abstract List doQueryForAlias(IndexCoordinates index); @Override public boolean removeAlias(AliasQuery query) { @@ -238,14 +254,15 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } - /** - * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed - * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. - * - * @return IndexCoordinates - */ protected IndexCoordinates getIndexCoordinates() { - return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; + + if (boundClass != null) { + return getIndexCoordinatesFor(boundClass); + } + + Assert.notNull(boundIndex, "boundIndex may not be null"); + + return boundIndex; } public IndexCoordinates getIndexCoordinatesFor(Class clazz) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 98f3d2ccd..e20b231bc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -32,6 +32,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.query.MoreLikeThisQueryBuilder; +import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -48,6 +49,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; +import org.springframework.data.elasticsearch.core.query.BulkOptions; import org.springframework.data.elasticsearch.core.query.GetQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; @@ -55,6 +57,7 @@ import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; +import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.util.CloseableIterator; @@ -199,6 +202,11 @@ public T get(GetQuery query, Class clazz, IndexCoordinates index) { return get(query.getId(), clazz, index); } + @Override + public List multiGet(Query query, Class clazz) { + return multiGet(query, clazz, getIndexCoordinatesFor(clazz)); + } + @Override @Nullable public T queryForObject(GetQuery query, Class clazz) { @@ -226,6 +234,11 @@ public String delete(String id, Class entityType) { return this.delete(id, getIndexCoordinatesFor(entityType)); } + @Override + public void delete(Query query, Class clazz) { + delete(query, getIndexCoordinatesFor(clazz)); + } + @Override public String delete(Object entity) { return delete(entity, getIndexCoordinatesFor(entity.getClass())); @@ -235,6 +248,22 @@ public String delete(Object entity) { public String delete(Object entity, IndexCoordinates index) { return this.delete(getEntityId(entity), index); } + + @Override + public List bulkIndex(List queries, Class clazz) { + return bulkIndex(queries, getIndexCoordinatesFor(clazz)); + } + + @Override + public List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz) { + return bulkIndex(queries, bulkOptions, getIndexCoordinatesFor(clazz)); + } + + @Override + public void bulkUpdate(List queries, Class clazz) { + bulkUpdate(queries, getIndexCoordinatesFor(clazz)); + } + // endregion // region SearchOperations @@ -282,6 +311,11 @@ public SearchHits search(MoreLikeThisQuery query, Class clazz, IndexCo return search(new NativeSearchQueryBuilder().withQuery(moreLikeThisQueryBuilder).build(), clazz, index); } + @Override + public List> multiSearch(List queries, Class clazz) { + return multiSearch(queries, clazz, getIndexCoordinatesFor(clazz)); + } + @Override public List> multiSearch(List queries, Class clazz, IndexCoordinates index) { MultiSearchRequest request = new MultiSearchRequest(); @@ -300,9 +334,46 @@ public List> multiSearch(List queries, Class< return res; } + @Override + public List> multiSearch(List queries, List> classes) { + + Assert.notNull(queries, "queries must not be null"); + Assert.notNull(classes, "classes must not be null"); + Assert.isTrue(queries.size() == classes.size(), "queries and classes must have the same size"); + + MultiSearchRequest request = new MultiSearchRequest(); + Iterator> it = classes.iterator(); + for (Query query : queries) { + Class clazz = it.next(); + request.add(requestFactory.searchRequest(query, clazz, getIndexCoordinatesFor(clazz))); + } + + MultiSearchResponse.Item[] items = getMultiSearchResult(request); + + List> res = new ArrayList<>(queries.size()); + int c = 0; + Iterator> it1 = classes.iterator(); + for (Query query : queries) { + Class entityClass = it1.next(); + + SearchDocumentResponseCallback> callback = new ReadSearchDocumentResponseCallback<>(entityClass, + getIndexCoordinatesFor(entityClass)); + + SearchResponse response = items[c++].getResponse(); + res.add(callback.doWith(SearchDocumentResponse.from(response))); + } + return res; + } + @Override public List> multiSearch(List queries, List> classes, IndexCoordinates index) { + + Assert.notNull(queries, "queries must not be null"); + Assert.notNull(classes, "classes must not be null"); + Assert.notNull(index, "index must not be null"); + Assert.isTrue(queries.size() == classes.size(), "queries and classes must have the same size"); + MultiSearchRequest request = new MultiSearchRequest(); Iterator> it = classes.iterator(); for (Query query : queries) { @@ -356,6 +427,12 @@ protected void searchScrollClear(String scrollId) { abstract protected void searchScrollClear(List scrollIds); abstract protected MultiSearchResponse.Item[] getMultiSearchResult(MultiSearchRequest request); + + @Override + public SearchResponse suggest(SuggestBuilder suggestion, Class clazz) { + return suggest(suggestion, getIndexCoordinatesFor(clazz)); + } + // endregion // region Helper methods diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index a3ca8c694..ca121aaad 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -15,40 +15,31 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.client.Requests.*; - -import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.apache.http.util.EntityUtils; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; -import org.elasticsearch.client.Request; +import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.Response; -import org.elasticsearch.client.RestClient; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; +import org.elasticsearch.client.indices.GetMappingsResponse; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; -import org.springframework.data.elasticsearch.core.client.support.AliasData; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - /** * {@link IndexOperations} implementation using the RestClient. * @@ -58,7 +49,7 @@ */ class DefaultIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { - private ElasticsearchRestTemplate restTemplate; + private final ElasticsearchRestTemplate restTemplate; public DefaultIndexOperations(ElasticsearchRestTemplate restTemplate, Class boundClass) { super(restTemplate.getElasticsearchConverter(), boundClass); @@ -71,27 +62,29 @@ public DefaultIndexOperations(ElasticsearchRestTemplate restTemplate, IndexCoord } @Override - protected boolean doCreate(String indexName, @Nullable Document settings) { - CreateIndexRequest request = requestFactory.createIndexRequest(indexName, settings); + protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) { + CreateIndexRequest request = requestFactory.createIndexRequest(index, settings); return restTemplate.execute(client -> client.indices().create(request, RequestOptions.DEFAULT).isAcknowledged()); } @Override - protected boolean doDelete(String indexName) { + protected boolean doDelete(IndexCoordinates index) { - Assert.notNull(indexName, "No index defined for delete operation"); + Assert.notNull(index, "index must not be null"); - if (doExists(indexName)) { - DeleteIndexRequest request = new DeleteIndexRequest(indexName); - return restTemplate.execute(client -> client.indices().delete(request, RequestOptions.DEFAULT).isAcknowledged()); + if (doExists(index)) { + DeleteIndexRequest deleteIndexRequest = requestFactory.deleteIndexRequest(index); + return restTemplate + .execute(client -> client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT).isAcknowledged()); } return false; } @Override - protected boolean doExists(String indexName) { - GetIndexRequest request = new GetIndexRequest(indexName); - return restTemplate.execute(client -> client.indices().exists(request, RequestOptions.DEFAULT)); + protected boolean doExists(IndexCoordinates index) { + + GetIndexRequest getIndexRequest = requestFactory.getIndexRequest(index); + return restTemplate.execute(client -> client.indices().exists(getIndexRequest, RequestOptions.DEFAULT)); } @Override @@ -109,16 +102,20 @@ protected Map doGetMapping(IndexCoordinates index) { Assert.notNull(index, "No index defined for getMapping()"); + GetMappingsRequest mappingsRequest = requestFactory.getMappingsRequest(index); + return restTemplate.execute(client -> { - RestClient restClient = client.getLowLevelClient(); - Request request = new Request("GET", '/' + index.getIndexName() + "/_mapping"); - Response response = restClient.performRequest(request); - return convertMappingResponse(EntityUtils.toString(response.getEntity())); + GetMappingsResponse mapping = client.indices().getMapping(mappingsRequest, RequestOptions.DEFAULT); + // we only return data for the first index name that was requested (always have done so) + String index1 = mappingsRequest.indices()[0]; + Map result = new LinkedHashMap<>(); + return mapping.mappings().get(index1).getSourceAsMap(); }); } @Override protected boolean doAddAlias(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest request = requestFactory.indicesAddAliasesRequest(query, index); return restTemplate .execute(client -> client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged()); @@ -136,34 +133,28 @@ protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { } @Override - protected List doQueryForAlias(String indexName) { - List aliases = null; - return restTemplate.execute(client -> { - RestClient restClient = client.getLowLevelClient(); - Response response; - String aliasResponse; + protected List doQueryForAlias(IndexCoordinates index) { - response = restClient.performRequest(new Request("GET", '/' + indexName + "/_alias/*")); - aliasResponse = EntityUtils.toString(response.getEntity()); + GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(index); - return convertAliasResponse(aliasResponse); + return restTemplate.execute(client -> { + GetAliasesResponse alias = client.indices().getAlias(getAliasesRequest, RequestOptions.DEFAULT); + // we only return data for the first index name that was requested (always have done so) + String index1 = getAliasesRequest.indices()[0]; + return new ArrayList<>(alias.getAliases().get(index1)); }); } @Override - protected Map doGetSettings(String indexName, boolean includeDefaults) { - - Assert.notNull(indexName, "No index defined for getSettings"); + protected Map doGetSettings(IndexCoordinates index, boolean includeDefaults) { - GetSettingsRequest request = new GetSettingsRequest() // - .indices(indexName) // - .includeDefaults(includeDefaults); + Assert.notNull(index, "index must not be null"); - // + GetSettingsRequest getSettingsRequest = requestFactory.getSettingsRequest(index, includeDefaults); GetSettingsResponse response = restTemplate.execute(client -> client.indices() // - .getSettings(request, RequestOptions.DEFAULT)); + .getSettings(getSettingsRequest, RequestOptions.DEFAULT)); - return convertSettingsResponseToMap(response, indexName); + return convertSettingsResponseToMap(response, getSettingsRequest.indices()[0]); } @Override @@ -171,61 +162,9 @@ protected void doRefresh(IndexCoordinates index) { Assert.notNull(index, "No index defined for refresh()"); - restTemplate - .execute(client -> client.indices().refresh(refreshRequest(index.getIndexNames()), RequestOptions.DEFAULT)); + RefreshRequest refreshRequest = requestFactory.refreshRequest(index); + restTemplate.execute(client -> client.indices().refresh(refreshRequest, RequestOptions.DEFAULT)); } - // region Helper methods - private Map convertMappingResponse(String mappingResponse) { - ObjectMapper mapper = new ObjectMapper(); - - try { - Map result = null; - JsonNode node = mapper.readTree(mappingResponse); - - node = node.findValue("mappings"); - result = mapper.readValue(mapper.writeValueAsString(node), HashMap.class); - - return result; - } catch (IOException e) { - throw new UncategorizedElasticsearchException("Could not map alias response : " + mappingResponse, e); - } - } - - /** - * It takes two steps to create a List from the elasticsearch http response because the aliases field - * is actually a Map by alias name, but the alias name is on the AliasMetadata. - * - * @param aliasResponse - * @return - */ - private List convertAliasResponse(String aliasResponse) { - ObjectMapper mapper = new ObjectMapper(); - - try { - JsonNode node = mapper.readTree(aliasResponse); - node = node.findValue("aliases"); - - if (node == null) { - return Collections.emptyList(); - } - - Map aliasData = mapper.readValue(mapper.writeValueAsString(node), - new TypeReference>() {}); - - Iterable> aliasIter = aliasData.entrySet(); - List aliasMetaDataList = new ArrayList<>(); - - for (Map.Entry aliasentry : aliasIter) { - AliasData data = aliasentry.getValue(); - aliasMetaDataList.add(AliasMetaData.newAliasMetaDataBuilder(aliasentry.getKey()).filter(data.getFilter()) - .routing(data.getRouting()).searchRouting(data.getSearch_routing()).indexRouting(data.getIndex_routing()) - .build()); - } - return aliasMetaDataList; - } catch (IOException e) { - throw new UncategorizedElasticsearchException("Could not map alias response : " + aliasResponse, e); - } - } // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index c185d06ae..0618ff4c8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -21,16 +21,18 @@ import java.util.Map; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; +import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -62,26 +64,29 @@ public DefaultTransportIndexOperations(Client client, ElasticsearchConverter ela } @Override - protected boolean doCreate(String indexName, @Nullable Document settings) { - CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, indexName, + protected boolean doCreate(IndexCoordinates index, @Nullable Document settings) { + CreateIndexRequestBuilder createIndexRequestBuilder = requestFactory.createIndexRequestBuilder(client, index, settings); return createIndexRequestBuilder.execute().actionGet().isAcknowledged(); } @Override - protected boolean doDelete(String indexName) { + protected boolean doDelete(IndexCoordinates index) { - Assert.notNull(indexName, "No index defined for delete operation"); + Assert.notNull(index, "No index defined for delete operation"); - if (doExists(indexName)) { - return client.admin().indices().delete(new DeleteIndexRequest(indexName)).actionGet().isAcknowledged(); + if (doExists(index)) { + DeleteIndexRequest deleteIndexRequest = requestFactory.deleteIndexRequest(index); + return client.admin().indices().delete(deleteIndexRequest).actionGet().isAcknowledged(); } return false; } @Override - protected boolean doExists(String indexName) { - return client.admin().indices().exists(indicesExistsRequest(indexName)).actionGet().isExists(); + protected boolean doExists(IndexCoordinates index) { + + IndicesExistsRequest indicesExistsRequest = requestFactory.indicesExistsRequest(index); + return client.admin().indices().exists(indicesExistsRequest).actionGet().isExists(); } @Override @@ -98,14 +103,12 @@ protected Map doGetMapping(IndexCoordinates index) { Assert.notNull(index, "No index defined for getMapping()"); - try { - return client.admin().indices().getMappings( // - new GetMappingsRequest().indices(index.getIndexNames())).actionGet() // - .getMappings().get(index.getIndexName()).get(IndexCoordinates.TYPE) // - .getSourceAsMap(); - } catch (Exception e) { - throw new ElasticsearchException("Error while getting mapping for indexName : " + index.getIndexName(), e); - } + GetMappingsRequest mappingsRequest = requestFactory.getMappingsRequest(client, index); + + return client.admin().indices().getMappings( // + mappingsRequest).actionGet() // + .getMappings().get(mappingsRequest.indices()[0]).get(IndexCoordinates.TYPE) // + .getSourceAsMap(); } @Override @@ -120,39 +123,39 @@ protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); - return client.admin().indices().prepareAliases().removeAlias(index.getIndexName(), query.getAliasName()).execute() - .actionGet().isAcknowledged(); + IndicesAliasesRequestBuilder indicesAliasesRequestBuilder = requestFactory + .indicesRemoveAliasesRequestBuilder(client, query, index); + return indicesAliasesRequestBuilder.execute().actionGet().isAcknowledged(); } @Override - protected List doQueryForAlias(String indexName) { - return client.admin().indices().getAliases(new GetAliasesRequest().indices(indexName)).actionGet().getAliases() - .get(indexName); + protected List doQueryForAlias(IndexCoordinates index) { + + GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(index); + return client.admin().indices().getAliases(getAliasesRequest).actionGet().getAliases().get(index.getIndexName()); } @Override - protected Map doGetSettings(String indexName, boolean includeDefaults) { - - Assert.notNull(indexName, "No index defined for getSettings"); + protected Map doGetSettings(IndexCoordinates index, boolean includeDefaults) { - GetSettingsRequest request = new GetSettingsRequest() // - .indices(indexName) // - .includeDefaults(includeDefaults); + Assert.notNull(index, "index must not be null"); + GetSettingsRequest getSettingsRequest = requestFactory.getSettingsRequest(index, includeDefaults); GetSettingsResponse response = client.admin() // .indices() // - .getSettings(request) // + .getSettings(getSettingsRequest) // .actionGet(); - return convertSettingsResponseToMap(response, indexName); + return convertSettingsResponseToMap(response, getSettingsRequest.indices()[0]); } @Override protected void doRefresh(IndexCoordinates index) { - Assert.notNull(index, "No index defined for refresh()"); + Assert.notNull(index, "index must not be null"); - client.admin().indices().refresh(refreshRequest(index.getIndexNames())).actionGet(); + RefreshRequest request = requestFactory.refreshRequest(index); + client.admin().indices().refresh(request).actionGet(); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 159a0cc4a..005aff73c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -114,6 +114,16 @@ public interface DocumentOperations { @Nullable T get(String id, Class clazz, IndexCoordinates index); + /** + * Execute a multiGet against elasticsearch for the given ids. + * + * @param query the query defining the ids of the objects to get + * @param clazz the type of the object to be returned + * @return list of objects, contains null values for ids that are not found + * @since 4.1 + */ + List multiGet(Query query, Class clazz); + /** * Execute a multiGet against elasticsearch for the given ids. * @@ -142,6 +152,18 @@ public interface DocumentOperations { */ boolean exists(String id, IndexCoordinates index); + /** + * Bulk index all objects. Will do save or update. + * + * @param queries the queries to execute in bulk + * @param clazz the entity class + * @return the ids of the indexed objects + * @since 4.1 + */ + default List bulkIndex(List queries, Class clazz) { + return bulkIndex(queries, BulkOptions.defaultOptions(), clazz); + } + /** * Bulk index all objects. Will do save or update. * @@ -152,6 +174,17 @@ default List bulkIndex(List queries, IndexCoordinates index) return bulkIndex(queries, BulkOptions.defaultOptions(), index); } + /** + * Bulk index all objects. Will do save or update. + * + * @param queries the queries to execute in bulk + * @param bulkOptions options to be added to the bulk request + * @param clazz the entity class + * @return the ids of the indexed objects + * @since 4.1 + */ + List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz); + /** * Bulk index all objects. Will do save or update. * @@ -170,6 +203,14 @@ default void bulkUpdate(List queries, IndexCoordinates index) { bulkUpdate(queries, BulkOptions.defaultOptions(), index); } + /** + * Bulk update all objects. Will do update. + * @param clazz the entity class + * @param queries the queries to execute in bulk + * @since 4.1 + */ + void bulkUpdate(List queries, Class clazz); + /** * Bulk update all objects. Will do update. * @@ -213,6 +254,16 @@ default void bulkUpdate(List queries, IndexCoordinates index) { */ String delete(Object entity, IndexCoordinates index); + /** + * Delete all records matching the query. + * + * @param query query defining the objects + * @param clazz The entity class, must be annotated with + * {@link org.springframework.data.elasticsearch.annotations.Document} + * @since 4.1 + */ + void delete(Query query, Class clazz); + /** * Delete all records matching the query. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 87bb9d560..a086dab1f 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -60,17 +60,17 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera IndexCoordinates getIndexCoordinatesFor(Class clazz); // region IndexOperations -/** - * Create an index for given indexName . - * - * @param indexName the name of the index - * @return {@literal true} if the index was created - * @deprecated since 4.0, use {@link IndexOperations#create()} - */ -@Deprecated -default boolean createIndex(String indexName) { - return indexOps(IndexCoordinates.of(indexName)).create(); -} + /** + * Create an index for given indexName . + * + * @param indexName the name of the index + * @return {@literal true} if the index was created + * @deprecated since 4.0, use {@link IndexOperations#create()} + */ + @Deprecated + default boolean createIndex(String indexName) { + return indexOps(IndexCoordinates.of(indexName)).create(); + } /** * Create an index for given indexName and Settings. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 072a475d9..cc82a7eba 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -37,7 +37,6 @@ import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.reindex.DeleteByQueryRequest; -import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; import org.elasticsearch.search.suggest.SuggestBuilder; import org.slf4j.Logger; @@ -315,10 +314,7 @@ public void searchScrollClear(List scrollIds) { @Override public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { - SearchRequest searchRequest = new SearchRequest(index.getIndexNames()); - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.suggest(suggestion); - searchRequest.source(sourceBuilder); + SearchRequest searchRequest = requestFactory.searchRequest(suggestion, index); return execute(client -> client.search(searchRequest, RequestOptions.DEFAULT)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index c09827f79..0892a1fa0 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -23,6 +23,7 @@ import org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequestBuilder; import org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse; import org.elasticsearch.action.bulk.BulkRequestBuilder; +import org.elasticsearch.action.delete.DeleteRequestBuilder; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.MultiGetRequestBuilder; @@ -227,8 +228,9 @@ public String delete(String id, IndexCoordinates index) { Assert.notNull(id, "id must not be null"); Assert.notNull(index, "index must not be null"); - return client.prepareDelete(index.getIndexName(), IndexCoordinates.TYPE, elasticsearchConverter.convertId(id)) - .execute().actionGet().getId(); + DeleteRequestBuilder deleteRequestBuilder = requestFactory.deleteRequestBuilder(client, + elasticsearchConverter.convertId(id), index); + return deleteRequestBuilder.execute().actionGet().getId(); } @Override @@ -293,8 +295,7 @@ public SearchScrollHits searchScrollStart(long scrollTimeInMillis, Query Assert.notNull(query.getPageable(), "pageable of query must not be null."); - ActionFuture action = requestFactory // - .searchRequestBuilder(client, query, clazz, index) // + ActionFuture action = requestFactory.searchRequestBuilder(client, query, clazz, index) // .setScroll(TimeValue.timeValueMillis(scrollTimeInMillis)) // .execute(); @@ -332,7 +333,8 @@ public void searchScrollClear(List scrollIds) { @Override public SearchResponse suggest(SuggestBuilder suggestion, IndexCoordinates index) { - return client.prepareSearch(index.getIndexNames()).suggest(suggestion).get(); + SearchRequestBuilder searchRequestBuilder = requestFactory.searchRequestBuilder(client, suggestion, index); + return searchRequestBuilder.get(); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index 4f8b45102..c6e7ea75b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -28,7 +28,6 @@ import org.springframework.data.mapping.model.ConvertingPropertyAccessor; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; /** * Common operations performed on an entity in the context of it's mapping metadata. @@ -43,6 +42,8 @@ class EntityOperations { private static final String ID_FIELD = "id"; + private final MappingContext, ElasticsearchPersistentProperty> context; + public EntityOperations( MappingContext, ElasticsearchPersistentProperty> context) { @@ -51,8 +52,6 @@ public EntityOperations( this.context = context; } - private final MappingContext, ElasticsearchPersistentProperty> context; - /** * Creates a new {@link Entity} for the given bean. * @@ -100,11 +99,26 @@ AdaptibleEntity forEntity(T entity, ConversionService conversionService) * @param index index name override can be {@literal null}. * @param type index type override can be {@literal null}. * @return the {@link IndexCoordinates} containing index name and index type. + * @deprecated since 4.1, use {@link EntityOperations#determineIndex(Entity, String)} */ + @Deprecated IndexCoordinates determineIndex(Entity entity, @Nullable String index, @Nullable String type) { return determineIndex(entity.getPersistentEntity(), index, type); } + /** + * Determine index name and type name from {@link Entity} with {@code index} and {@code type} overrides. Allows using + * preferred values for index and type if provided, otherwise fall back to index and type defined on entity level. + * + * @param entity the entity to determine the index name. Can be {@literal null} if {@code index} and {@literal type} + * are provided. + * @param index index name override can be {@literal null}. + * @return the {@link IndexCoordinates} containing index name and index type. + */ + IndexCoordinates determineIndex(Entity entity, @Nullable String index) { + return determineIndex(entity.getPersistentEntity(), index); + } + /** * Determine index name and type name from {@link ElasticsearchPersistentEntity} with {@code index} and {@code type} * overrides. Allows using preferred values for index and type if provided, otherwise fall back to index and type @@ -115,20 +129,27 @@ IndexCoordinates determineIndex(Entity entity, @Nullable String index, @Nulla * @param index index name override can be {@literal null}. * @param type index type override can be {@literal null}. * @return the {@link IndexCoordinates} containing index name and index type. + * @deprecated since 4.1, use {@link EntityOperations#determineIndex(ElasticsearchPersistentEntity, String)} */ + @Deprecated IndexCoordinates determineIndex(ElasticsearchPersistentEntity persistentEntity, @Nullable String index, @Nullable String type) { - return persistentEntity.getIndexCoordinates(); + return determineIndex(persistentEntity, index); } - private static String indexName(@Nullable ElasticsearchPersistentEntity entity, @Nullable String index) { - - if (StringUtils.isEmpty(index)) { - Assert.notNull(entity, "Cannot determine index name"); - return entity.getIndexCoordinates().getIndexName(); - } - - return index; + /** + * Determine index name and type name from {@link ElasticsearchPersistentEntity} with {@code index} and {@code type} + * overrides. Allows using preferred values for index and type if provided, otherwise fall back to index and type + * defined on entity level. + * + * @param persistentEntity the entity to determine the index name. Can be {@literal null} if {@code index} and + * {@literal type} are provided. + * @param index index name override can be {@literal null}. + * @return the {@link IndexCoordinates} containing index name and index type. + * @since 4.1 + */ + IndexCoordinates determineIndex(ElasticsearchPersistentEntity persistentEntity, @Nullable String index) { + return index != null ? IndexCoordinates.of(index) : persistentEntity.getIndexCoordinates(); } /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 66f1eebee..37109773b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -38,7 +38,7 @@ */ public interface ReactiveDocumentOperations { /** - * Index the given entity, once available, extracting index and type from entity metadata. + * Index the given entity, once available, extracting index from entity metadata. * * @param entityPublisher must not be {@literal null}. * @param @@ -50,15 +50,6 @@ default Mono save(Mono entityPublisher) { return entityPublisher.flatMap(this::save); } - /** - * Index the given entity extracting index and type from entity metadata. - * - * @param entity must not be {@literal null}. - * @param - * @return a {@link Mono} emitting the saved entity. - */ - Mono save(T entity); - /** * Index the entity, once available, under the given {@literal type} in the given {@literal index}. If the * {@literal index} is {@literal null} or empty the index name provided via entity metadata is used. Same for the @@ -75,6 +66,15 @@ default Mono save(Mono entityPublisher, IndexCoordinates ind return entityPublisher.flatMap(it -> save(it, index)); } + /** + * Index the given entity extracting index from entity metadata. + * + * @param entity must not be {@literal null}. + * @param + * @return a {@link Mono} emitting the saved entity. + */ + Mono save(T entity); + /** * Index the entity under the given {@literal type} in the given {@literal index}. If the {@literal index} is * {@literal null} or empty the index name provided via entity metadata is used. Same for the {@literal type}. @@ -87,7 +87,21 @@ default Mono save(Mono entityPublisher, IndexCoordinates ind Mono save(T entity, IndexCoordinates index); /** - * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is + * Index entities the index extracted from entity metadata. + * + * @param entities must not be {@literal null}. + * @param clazz the entity class, used to determine the index + * @return a {@link Flux} emitting saved entities. + * @since 4.1 + */ + default Flux saveAll(Iterable entities, Class clazz) { + List entityList = new ArrayList<>(); + entities.forEach(entityList::add); + return saveAll(Mono.just(entityList), clazz); + } + + /** + * Index entities in the given {@literal index}. If the {@literal index} is * {@literal null} or empty the index name provided via entity metadata is used. * * @param entities must not be {@literal null}. @@ -103,7 +117,17 @@ default Flux saveAll(Iterable entities, IndexCoordinates index) { } /** - * Index entities under the given {@literal type} in the given {@literal index}. If the {@literal index} is + * Index entities in the index extracted from entity metadata. + * + * @param entities must not be {@literal null}. + * @param clazz the entity class, used to determine the index + * @return a {@link Flux} emitting saved entities. + * @since 4.1 + */ + Flux saveAll(Mono> entities, Class clazz); + + /** + * Index entities in the given {@literal index}. If the {@literal index} is * {@literal null} or empty the index name provided via entity metadata is used. * * @param entities must not be {@literal null}. @@ -114,6 +138,16 @@ default Flux saveAll(Iterable entities, IndexCoordinates index) { */ Flux saveAll(Mono> entities, IndexCoordinates index); + /** + * Execute a multiGet against elasticsearch for the given ids. + * + * @param query the query defining the ids of the objects to get + * @param clazz the type of the object to be returned, used to determine the index + * @return flux with list of nullable objects + * @since 4.1 + */ + Flux multiGet(Query query, Class clazz); + /** * Execute a multiGet against elasticsearch for the given ids. * @@ -223,7 +257,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in Mono exists(String id, Class entityType, IndexCoordinates index); /** - * Delete the given entity extracting index and type from entity metadata. + * Delete the given entity extracting index from entity metadata. * * @param entity must not be {@literal null}. * @return a {@link Mono} emitting the {@literal id} of the removed document. @@ -231,7 +265,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in Mono delete(Object entity); /** - * Delete the given entity extracting index and type from entity metadata. + * Delete the given entity extracting index from entity metadata. * * @param entity must not be {@literal null}. * @param index the target index, must not be {@literal null} @@ -249,7 +283,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in Mono delete(String id, IndexCoordinates index); /** - * Delete the entity with given {@literal id} extracting index and type from entity metadata. + * Delete the entity with given {@literal id} extracting index from entity metadata. * * @param id must not be {@literal null}. * @param entityType must not be {@literal null}. @@ -259,7 +293,7 @@ default Mono findById(String id, Class entityType, IndexCoordinates in Mono delete(String id, Class entityType); /** - * Delete the entity with given {@literal id} extracting index and type from entity metadata. + * Delete the entity with given {@literal id} extracting index from entity metadata. * * @param id must not be {@literal null}. * @param entityType must not be {@literal null}. @@ -273,7 +307,7 @@ default Mono delete(String id, Class entityType, IndexCoordinates ind } /** - * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. + * Delete the documents matching the given {@link Query} extracting index from entity metadata. * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. @@ -282,7 +316,7 @@ default Mono delete(String id, Class entityType, IndexCoordinates ind Mono delete(Query query, Class entityType); /** - * Delete the documents matching the given {@link Query} extracting index and type from entity metadata. + * Delete the documents matching the given {@link Query} extracting index from entity metadata. * * @param query must not be {@literal null}. * @param entityType must not be {@literal null}. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 8a0e3dae4..1d10f9743 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -189,6 +189,11 @@ public Mono save(T entity) { return save(entity, getIndexCoordinatesFor(entity.getClass())); } + @Override + public Flux saveAll(Mono> entities, Class clazz) { + return saveAll(entities, getIndexCoordinatesFor(clazz)); + } + @Override public Flux saveAll(Mono> entitiesPublisher, IndexCoordinates index) { @@ -215,6 +220,11 @@ public Flux saveAll(Mono> entitiesPubli }); } + @Override + public Flux multiGet(Query query, Class clazz) { + return multiGet(query, clazz, getIndexCoordinatesFor(clazz)); + } + @Override public Flux multiGet(Query query, Class clazz, IndexCoordinates index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 6171be9b4..79c92a446 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -25,11 +25,18 @@ import java.util.Map; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; +import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.delete.DeleteRequestBuilder; import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequestBuilder; import org.elasticsearch.action.get.MultiGetRequest; @@ -44,6 +51,8 @@ import org.elasticsearch.client.Client; import org.elasticsearch.client.Requests; import org.elasticsearch.client.indices.CreateIndexRequest; +import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.unit.DistanceUnit; @@ -67,6 +76,7 @@ import org.elasticsearch.search.sort.SortBuilders; import org.elasticsearch.search.sort.SortMode; import org.elasticsearch.search.sort.SortOrder; +import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -98,11 +108,15 @@ public RequestFactory(ElasticsearchConverter elasticsearchConverter) { this.elasticsearchConverter = elasticsearchConverter; } + // region alias public IndicesAliasesRequest.AliasActions aliasAction(AliasQuery query, IndexCoordinates index) { + Assert.notNull(index, "No index defined for Alias"); Assert.notNull(query.getAliasName(), "No alias defined"); + + String[] indexNames = index.getIndexNames(); IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.add() - .alias(query.getAliasName()).index(index.getIndexName()); + .alias(query.getAliasName()).indices(indexNames); if (query.getFilterBuilder() != null) { aliasAction.filter(query.getFilterBuilder()); @@ -125,6 +139,40 @@ public IndicesAliasesRequest.AliasActions aliasAction(AliasQuery query, IndexCoo return aliasAction; } + public GetAliasesRequest getAliasesRequest(IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new GetAliasesRequest().indices(indexNames); + } + + public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { + IndicesAliasesRequest.AliasActions aliasAction = aliasAction(query, index); + IndicesAliasesRequest request = new IndicesAliasesRequest(); + request.addAliasAction(aliasAction); + return request; + } + + public IndicesAliasesRequest indicesRemoveAliasesRequest(AliasQuery query, IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() // + .indices(indexNames) // + .alias(query.getAliasName()); + + return Requests.indexAliasesRequest() // + .addAliasAction(aliasAction); + } + + IndicesAliasesRequestBuilder indicesRemoveAliasesRequestBuilder(Client client, AliasQuery query, + IndexCoordinates index) { + + String indexName = index.getIndexName(); + return client.admin().indices().prepareAliases().removeAlias(indexName, query.getAliasName()); + } + + // endregion + + // region bulk public BulkRequest bulkRequest(List queries, BulkOptions bulkOptions, IndexCoordinates index) { BulkRequest bulkRequest = new BulkRequest(); @@ -195,9 +243,12 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, Bul return bulkRequestBuilder; } - @SuppressWarnings("unchecked") - public CreateIndexRequest createIndexRequest(String indexName, @Nullable Document settings) { - CreateIndexRequest request = new CreateIndexRequest(indexName); + // endregion + + // region index management + public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) { + + CreateIndexRequest request = new CreateIndexRequest(index.getIndexName()); if (settings != null) { request.settings(settings); @@ -205,9 +256,10 @@ public CreateIndexRequest createIndexRequest(String indexName, @Nullable Documen return request; } - @SuppressWarnings("unchecked") - public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String indexName, + public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, IndexCoordinates index, @Nullable Document settings) { + + String indexName = index.getIndexName(); CreateIndexRequestBuilder createIndexRequestBuilder = client.admin().indices().prepareCreate(indexName); if (settings != null) { @@ -216,9 +268,71 @@ public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, String return createIndexRequestBuilder; } + public GetIndexRequest getIndexRequest(IndexCoordinates index) { + return new GetIndexRequest(index.getIndexNames()); + } + + public IndicesExistsRequest indicesExistsRequest(IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new IndicesExistsRequest(indexNames); + } + + public DeleteIndexRequest deleteIndexRequest(IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new DeleteIndexRequest(indexNames); + } + + public RefreshRequest refreshRequest(IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new RefreshRequest(indexNames); + } + + public GetSettingsRequest getSettingsRequest(IndexCoordinates index, boolean includeDefaults) { + + String[] indexNames = index.getIndexNames(); + return new GetSettingsRequest().indices(indexNames).includeDefaults(includeDefaults); + } + + public PutMappingRequest putMappingRequest(IndexCoordinates index, Document mapping) { + + PutMappingRequest request = new PutMappingRequest(index.getIndexNames()); + request.source(mapping); + return request; + } + + public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Document mapping) { + + String[] indexNames = index.getIndexNames(); + PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(indexNames) + .setType(IndexCoordinates.TYPE); + requestBuilder.setSource(mapping); + return requestBuilder; + } + + public GetMappingsRequest getMappingsRequest(IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new GetMappingsRequest().indices(indexNames); + } + + public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest(Client client, + IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + return new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest().indices(indexNames); + } + + // endregion + + // region delete @Deprecated public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexCoordinates index) { - DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(index.getIndexNames()) // + + String[] indexNames = index.getIndexNames(); + DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(indexNames) // .setQuery(deleteQuery.getQuery()) // .setAbortOnVersionConflict(false) // .setRefresh(true); @@ -251,14 +365,23 @@ public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, In } public DeleteRequest deleteRequest(String id, IndexCoordinates index) { - return new DeleteRequest(index.getIndexName(), id); + String indexName = index.getIndexName(); + return new DeleteRequest(indexName, id); + } + + public DeleteRequestBuilder deleteRequestBuilder(Client client, String id, IndexCoordinates index) { + String indexName = index.getIndexName(); + return client.prepareDelete(indexName, IndexCoordinates.TYPE, id); } @Deprecated public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, DeleteQuery deleteQuery, IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + DeleteByQueryRequestBuilder requestBuilder = new DeleteByQueryRequestBuilder(client, DeleteByQueryAction.INSTANCE) // - .source(index.getIndexNames()) // + .source(indexNames) // .filter(deleteQuery.getQuery()) // .abortOnVersionConflict(false) // .refresh(true); @@ -283,16 +406,20 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, Qu SearchRequestBuilder source = requestBuilder.source(); if (query.isLimiting()) { + // noinspection ConstantConditions source.setSize(query.getMaxResults()); } if (query.hasScrollTime()) { + // noinspection ConstantConditions source.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); } return requestBuilder; } + // endregion + // region get public GetRequest getRequest(String id, IndexCoordinates index) { return new GetRequest(index.getIndexName(), id); } @@ -301,36 +428,45 @@ public GetRequestBuilder getRequestBuilder(Client client, String id, IndexCoordi return client.prepareGet(index.getIndexName(), null, id); } - @Nullable - public HighlightBuilder highlightBuilder(Query query) { - HighlightBuilder highlightBuilder = query.getHighlightQuery().map(HighlightQuery::getHighlightBuilder).orElse(null); + public MultiGetRequest multiGetRequest(Query query, IndexCoordinates index) { + MultiGetRequest multiGetRequest = new MultiGetRequest(); + getMultiRequestItems(query, index).forEach(multiGetRequest::add); + return multiGetRequest; + } - if (highlightBuilder == null) { + public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, IndexCoordinates index) { + MultiGetRequestBuilder multiGetRequestBuilder = client.prepareMultiGet(); + getMultiRequestItems(searchQuery, index).forEach(multiGetRequestBuilder::add); + return multiGetRequestBuilder; + } - if (query instanceof NativeSearchQuery) { - NativeSearchQuery searchQuery = (NativeSearchQuery) query; + private List getMultiRequestItems(Query searchQuery, IndexCoordinates index) { + List items = new ArrayList<>(); - if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { - highlightBuilder = searchQuery.getHighlightBuilder(); + if (!isEmpty(searchQuery.getFields())) { + searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null)); + } - if (highlightBuilder == null) { - highlightBuilder = new HighlightBuilder(); - } + if (!isEmpty(searchQuery.getIds())) { + String indexName = index.getIndexName(); + for (String id : searchQuery.getIds()) { + MultiGetRequest.Item item = new MultiGetRequest.Item(indexName, id); - if (searchQuery.getHighlightFields() != null) { - for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { - highlightBuilder.field(highlightField); - } - } + if (searchQuery.getRoute() != null) { + item = item.routing(searchQuery.getRoute()); } + items.add(item); } } - return highlightBuilder; + return items; } + // endregion + + // region indexing public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { - String indexName = index.getIndexName(); + String indexName = index.getIndexName(); IndexRequest indexRequest; if (query.getObject() != null) { @@ -405,9 +541,40 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, return indexRequestBuilder; } + // endregion + + // region search + @Nullable + public HighlightBuilder highlightBuilder(Query query) { + HighlightBuilder highlightBuilder = query.getHighlightQuery().map(HighlightQuery::getHighlightBuilder).orElse(null); + + if (highlightBuilder == null) { + + if (query instanceof NativeSearchQuery) { + NativeSearchQuery searchQuery = (NativeSearchQuery) query; + + if (searchQuery.getHighlightFields() != null || searchQuery.getHighlightBuilder() != null) { + highlightBuilder = searchQuery.getHighlightBuilder(); + + if (highlightBuilder == null) { + highlightBuilder = new HighlightBuilder(); + } + + if (searchQuery.getHighlightFields() != null) { + for (HighlightBuilder.Field highlightField : searchQuery.getHighlightFields()) { + highlightBuilder.field(highlightField); + } + } + } + } + } + return highlightBuilder; + } public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query, IndexCoordinates index) { - MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(index.getIndexName(), query.getId()); + + String indexName = index.getIndexName(); + MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(indexName, query.getId()); String[] fields = null; if (query.getFields() != null) { @@ -452,6 +619,21 @@ public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query return moreLikeThisQueryBuilder; } + public SearchRequest searchRequest(SuggestBuilder suggestion, IndexCoordinates index) { + + String[] indexNames = index.getIndexNames(); + SearchRequest searchRequest = new SearchRequest(indexNames); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.suggest(suggestion); + searchRequest.source(sourceBuilder); + return searchRequest; + } + + public SearchRequestBuilder searchRequestBuilder(Client client, SuggestBuilder suggestion, IndexCoordinates index) { + String[] indexNames = index.getIndexNames(); + return client.prepareSearch(indexNames).suggest(suggestion); + } + public SearchRequest searchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { SearchRequest searchRequest = prepareSearchRequest(query, clazz, index); @@ -492,283 +674,149 @@ public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nu return searchRequestBuilder; } - public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { - - UpdateRequest updateRequest = new UpdateRequest(index.getIndexName(), query.getId()); + private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz, IndexCoordinates indexCoordinates) { - if (query.getScript() != null) { - Map params = query.getParams(); + String[] indexNames = indexCoordinates.getIndexNames(); + Assert.notNull(indexNames, "No index defined for Query"); + Assert.notEmpty(indexNames, "No index defined for Query"); - if (params == null) { - params = new HashMap<>(); - } - Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); - updateRequest.script(script); + SearchRequest request = new SearchRequest(indexNames); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.version(true); + sourceBuilder.trackScores(query.getTrackScores()); + if (hasSeqNoPrimaryTermProperty(clazz)) { + sourceBuilder.seqNoAndPrimaryTerm(true); } - if (query.getDocument() != null) { - updateRequest.doc(query.getDocument()); + if (query.getSourceFilter() != null) { + SourceFilter sourceFilter = query.getSourceFilter(); + sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); } - if (query.getUpsert() != null) { - updateRequest.upsert(query.getUpsert()); + if (query.getPageable().isPaged()) { + sourceBuilder.from((int) query.getPageable().getOffset()); + sourceBuilder.size(query.getPageable().getPageSize()); + } else { + sourceBuilder.from(0); + sourceBuilder.size(INDEX_MAX_RESULT_WINDOW); } - if (query.getRouting() != null) { - updateRequest.routing(query.getRouting()); + if (!query.getFields().isEmpty()) { + sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); } - if (query.getScriptedUpsert() != null) { - updateRequest.scriptedUpsert(query.getScriptedUpsert()); + if (query.getIndicesOptions() != null) { + request.indicesOptions(query.getIndicesOptions()); } - if (query.getDocAsUpsert() != null) { - updateRequest.docAsUpsert(query.getDocAsUpsert()); + if (query.isLimiting()) { + sourceBuilder.size(query.getMaxResults()); } - if (query.getFetchSource() != null) { - updateRequest.fetchSource(query.getFetchSource()); + if (query.getMinScore() > 0) { + sourceBuilder.minScore(query.getMinScore()); } - if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { - List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() - : Collections.emptyList(); - List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() - : Collections.emptyList(); - updateRequest.fetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); + if (query.getPreference() != null) { + request.preference(query.getPreference()); } - if (query.getIfSeqNo() != null) { - updateRequest.setIfSeqNo(query.getIfSeqNo()); - } + request.searchType(query.getSearchType()); - if (query.getIfPrimaryTerm() != null) { - updateRequest.setIfPrimaryTerm(query.getIfPrimaryTerm()); - } + prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); - if (query.getRefresh() != null) { - updateRequest.setRefreshPolicy(query.getRefresh().name().toLowerCase()); + HighlightBuilder highlightBuilder = highlightBuilder(query); + + if (highlightBuilder != null) { + sourceBuilder.highlighter(highlightBuilder); } - if (query.getRetryOnConflict() != null) { - updateRequest.retryOnConflict(query.getRetryOnConflict()); + if (query instanceof NativeSearchQuery) { + prepareNativeSearch((NativeSearchQuery) query, sourceBuilder); + } - if (query.getTimeout() != null) { - updateRequest.timeout(query.getTimeout()); + if (query.getTrackTotalHits()) { + sourceBuilder.trackTotalHits(query.getTrackTotalHits()); } - if (query.getWaitForActiveShards() != null) { - updateRequest.waitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); + if (StringUtils.hasLength(query.getRoute())) { + request.routing(query.getRoute()); } - return updateRequest; + request.source(sourceBuilder); + return request; } - public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery query, IndexCoordinates index) { - - UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(index.getIndexName(), IndexCoordinates.TYPE, - query.getId()); + private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class clazz, + IndexCoordinates index) { - if (query.getScript() != null) { - Map params = query.getParams(); + String[] indexNames = index.getIndexNames(); + Assert.notNull(indexNames, "No index defined for Query"); + Assert.notEmpty(indexNames, "No index defined for Query"); - if (params == null) { - params = new HashMap<>(); - } - Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); - updateRequestBuilder.setScript(script); + SearchRequestBuilder searchRequestBuilder = client.prepareSearch(indexNames) // + .setSearchType(query.getSearchType()) // + .setVersion(true) // + .setTrackScores(query.getTrackScores()); + if (hasSeqNoPrimaryTermProperty(clazz)) { + searchRequestBuilder.seqNoAndPrimaryTerm(true); } - if (query.getDocument() != null) { - updateRequestBuilder.setDoc(query.getDocument()); + if (query.getSourceFilter() != null) { + SourceFilter sourceFilter = query.getSourceFilter(); + searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); } - if (query.getUpsert() != null) { - updateRequestBuilder.setUpsert(query.getUpsert()); - } - - if (query.getRouting() != null) { - updateRequestBuilder.setRouting(query.getRouting()); - } - - if (query.getScriptedUpsert() != null) { - updateRequestBuilder.setScriptedUpsert(query.getScriptedUpsert()); - } - - if (query.getDocAsUpsert() != null) { - updateRequestBuilder.setDocAsUpsert(query.getDocAsUpsert()); - } - - if (query.getFetchSource() != null) { - updateRequestBuilder.setFetchSource(query.getFetchSource()); - } - - if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { - List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() - : Collections.emptyList(); - List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() - : Collections.emptyList(); - updateRequestBuilder.setFetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); - } - - if (query.getIfSeqNo() != null) { - updateRequestBuilder.setIfSeqNo(query.getIfSeqNo()); - } - - if (query.getIfPrimaryTerm() != null) { - updateRequestBuilder.setIfPrimaryTerm(query.getIfPrimaryTerm()); - } - - if (query.getRefresh() != null) { - updateRequestBuilder.setRefreshPolicy(query.getRefresh().name().toLowerCase()); - } - - if (query.getRetryOnConflict() != null) { - updateRequestBuilder.setRetryOnConflict(query.getRetryOnConflict()); - } - - if (query.getTimeout() != null) { - updateRequestBuilder.setTimeout(query.getTimeout()); - } - - if (query.getWaitForActiveShards() != null) { - updateRequestBuilder.setWaitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); - } - - return updateRequestBuilder; - } - - private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { - Assert.notNull(index.getIndexNames(), "No index defined for Query"); - Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); - - SearchRequest request = new SearchRequest(index.getIndexNames()); - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.version(true); - sourceBuilder.trackScores(query.getTrackScores()); - if (hasSeqNoPrimaryTermProperty(clazz)) { - sourceBuilder.seqNoAndPrimaryTerm(true); - } - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - sourceBuilder.fetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (query.getPageable().isPaged()) { - sourceBuilder.from((int) query.getPageable().getOffset()); - sourceBuilder.size(query.getPageable().getPageSize()); - } else { - sourceBuilder.from(0); - sourceBuilder.size(INDEX_MAX_RESULT_WINDOW); + if (query.getPageable().isPaged()) { + searchRequestBuilder.setFrom((int) query.getPageable().getOffset()); + searchRequestBuilder.setSize(query.getPageable().getPageSize()); + } else { + searchRequestBuilder.setFrom(0); + searchRequestBuilder.setSize(INDEX_MAX_RESULT_WINDOW); } if (!query.getFields().isEmpty()) { - sourceBuilder.fetchSource(query.getFields().toArray(new String[0]), null); + searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null); } if (query.getIndicesOptions() != null) { - request.indicesOptions(query.getIndicesOptions()); + searchRequestBuilder.setIndicesOptions(query.getIndicesOptions()); } if (query.isLimiting()) { - sourceBuilder.size(query.getMaxResults()); + searchRequestBuilder.setSize(query.getMaxResults()); } if (query.getMinScore() > 0) { - sourceBuilder.minScore(query.getMinScore()); + searchRequestBuilder.setMinScore(query.getMinScore()); } if (query.getPreference() != null) { - request.preference(query.getPreference()); - } - - if (query.getSearchType() != null) { - request.searchType(query.getSearchType()); + searchRequestBuilder.setPreference(query.getPreference()); } - prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); + prepareSort(query, searchRequestBuilder, getPersistentEntity(clazz)); HighlightBuilder highlightBuilder = highlightBuilder(query); if (highlightBuilder != null) { - sourceBuilder.highlighter(highlightBuilder); + searchRequestBuilder.highlighter(highlightBuilder); } if (query instanceof NativeSearchQuery) { - prepareNativeSearch((NativeSearchQuery) query, sourceBuilder); - + prepareNativeSearch(searchRequestBuilder, (NativeSearchQuery) query); } if (query.getTrackTotalHits()) { - sourceBuilder.trackTotalHits(query.getTrackTotalHits()); + searchRequestBuilder.setTrackTotalHits(query.getTrackTotalHits()); } if (StringUtils.hasLength(query.getRoute())) { - request.routing(query.getRoute()); - } - - request.source(sourceBuilder); - return request; - } - - private boolean hasSeqNoPrimaryTermProperty(@Nullable Class entityClass) { - - if (entityClass == null) { - return false; - } - - if (!elasticsearchConverter.getMappingContext().hasPersistentEntityFor(entityClass)) { - return false; - } - - ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() - .getRequiredPersistentEntity(entityClass); - return entity.hasSeqNoPrimaryTermProperty(); - } - - public PutMappingRequest putMappingRequest(IndexCoordinates index, Document mapping) { - PutMappingRequest request = new PutMappingRequest(index.getIndexName()); - request.source(mapping); - return request; - } - - @SuppressWarnings("rawtypes") - public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Document mapping) { - PutMappingRequestBuilder requestBuilder = client.admin().indices().preparePutMapping(index.getIndexName()) - .setType(IndexCoordinates.TYPE); - requestBuilder.setSource(mapping); - return requestBuilder; - } - - public MultiGetRequest multiGetRequest(Query query, IndexCoordinates index) { - MultiGetRequest multiGetRequest = new MultiGetRequest(); - getMultiRequestItems(query, index).forEach(multiGetRequest::add); - return multiGetRequest; - } - - public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, IndexCoordinates index) { - MultiGetRequestBuilder multiGetRequestBuilder = client.prepareMultiGet(); - getMultiRequestItems(searchQuery, index).forEach(multiGetRequestBuilder::add); - return multiGetRequestBuilder; - } - - private List getMultiRequestItems(Query searchQuery, IndexCoordinates index) { - List items = new ArrayList<>(); - if (!isEmpty(searchQuery.getFields())) { - searchQuery.addSourceFilter(new FetchSourceFilter(toArray(searchQuery.getFields()), null)); + searchRequestBuilder.setRouting(query.getRoute()); } - for (String id : searchQuery.getIds()) { - MultiGetRequest.Item item = new MultiGetRequest.Item(index.getIndexName(), id); - - if (searchQuery.getRoute() != null) { - item = item.routing(searchQuery.getRoute()); - } - items.add(item); - } - return items; + return searchRequestBuilder; } private void prepareNativeSearch(NativeSearchQuery query, SearchSourceBuilder sourceBuilder) { @@ -821,75 +869,6 @@ private void prepareNativeSearch(SearchRequestBuilder searchRequestBuilder, Nati } } - private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client client, @Nullable Class clazz, - IndexCoordinates index) { - Assert.notNull(index.getIndexNames(), "No index defined for Query"); - Assert.notEmpty(index.getIndexNames(), "No index defined for Query"); - - SearchRequestBuilder searchRequestBuilder = client.prepareSearch(index.getIndexNames()) // - .setSearchType(query.getSearchType()) // - .setVersion(true) // - .setTrackScores(query.getTrackScores()); - if (hasSeqNoPrimaryTermProperty(clazz)) { - searchRequestBuilder.seqNoAndPrimaryTerm(true); - } - - if (query.getSourceFilter() != null) { - SourceFilter sourceFilter = query.getSourceFilter(); - searchRequestBuilder.setFetchSource(sourceFilter.getIncludes(), sourceFilter.getExcludes()); - } - - if (query.getPageable().isPaged()) { - searchRequestBuilder.setFrom((int) query.getPageable().getOffset()); - searchRequestBuilder.setSize(query.getPageable().getPageSize()); - } else { - searchRequestBuilder.setFrom(0); - searchRequestBuilder.setSize(INDEX_MAX_RESULT_WINDOW); - } - - if (!query.getFields().isEmpty()) { - searchRequestBuilder.setFetchSource(query.getFields().toArray(new String[0]), null); - } - - if (query.getIndicesOptions() != null) { - searchRequestBuilder.setIndicesOptions(query.getIndicesOptions()); - } - - if (query.isLimiting()) { - searchRequestBuilder.setSize(query.getMaxResults()); - } - - if (query.getMinScore() > 0) { - searchRequestBuilder.setMinScore(query.getMinScore()); - } - - if (query.getPreference() != null) { - searchRequestBuilder.setPreference(query.getPreference()); - } - - prepareSort(query, searchRequestBuilder, getPersistentEntity(clazz)); - - HighlightBuilder highlightBuilder = highlightBuilder(query); - - if (highlightBuilder != null) { - searchRequestBuilder.highlighter(highlightBuilder); - } - - if (query instanceof NativeSearchQuery) { - prepareNativeSearch(searchRequestBuilder, (NativeSearchQuery) query); - } - - if (query.getTrackTotalHits()) { - searchRequestBuilder.setTrackTotalHits(query.getTrackTotalHits()); - } - - if (StringUtils.hasLength(query.getRoute())) { - searchRequestBuilder.setRouting(query.getRoute()); - } - - return searchRequestBuilder; - } - @SuppressWarnings("rawtypes") private void prepareSort(Query query, SearchSourceBuilder sourceBuilder, @Nullable ElasticsearchPersistentEntity entity) { @@ -961,7 +940,159 @@ private SortBuilder getSortBuilder(Sort.Order order, @Nullable ElasticsearchP } } } + // endregion + + // region update + public UpdateRequest updateRequest(UpdateQuery query, IndexCoordinates index) { + + String indexName = index.getIndexName(); + UpdateRequest updateRequest = new UpdateRequest(indexName, query.getId()); + + if (query.getScript() != null) { + Map params = query.getParams(); + + if (params == null) { + params = new HashMap<>(); + } + Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); + updateRequest.script(script); + } + if (query.getDocument() != null) { + updateRequest.doc(query.getDocument()); + } + + if (query.getUpsert() != null) { + updateRequest.upsert(query.getUpsert()); + } + + if (query.getRouting() != null) { + updateRequest.routing(query.getRouting()); + } + + if (query.getScriptedUpsert() != null) { + updateRequest.scriptedUpsert(query.getScriptedUpsert()); + } + + if (query.getDocAsUpsert() != null) { + updateRequest.docAsUpsert(query.getDocAsUpsert()); + } + + if (query.getFetchSource() != null) { + updateRequest.fetchSource(query.getFetchSource()); + } + + if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { + List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() + : Collections.emptyList(); + List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() + : Collections.emptyList(); + updateRequest.fetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); + } + + if (query.getIfSeqNo() != null) { + updateRequest.setIfSeqNo(query.getIfSeqNo()); + } + + if (query.getIfPrimaryTerm() != null) { + updateRequest.setIfPrimaryTerm(query.getIfPrimaryTerm()); + } + + if (query.getRefresh() != null) { + updateRequest.setRefreshPolicy(query.getRefresh().name().toLowerCase()); + } + + if (query.getRetryOnConflict() != null) { + updateRequest.retryOnConflict(query.getRetryOnConflict()); + } + + if (query.getTimeout() != null) { + updateRequest.timeout(query.getTimeout()); + } + + if (query.getWaitForActiveShards() != null) { + updateRequest.waitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); + } + + return updateRequest; + } + + public UpdateRequestBuilder updateRequestBuilderFor(Client client, UpdateQuery query, IndexCoordinates index) { + + String indexName = index.getIndexName(); + UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, IndexCoordinates.TYPE, query.getId()); + + if (query.getScript() != null) { + Map params = query.getParams(); + + if (params == null) { + params = new HashMap<>(); + } + Script script = new Script(ScriptType.INLINE, query.getLang(), query.getScript(), params); + updateRequestBuilder.setScript(script); + } + + if (query.getDocument() != null) { + updateRequestBuilder.setDoc(query.getDocument()); + } + + if (query.getUpsert() != null) { + updateRequestBuilder.setUpsert(query.getUpsert()); + } + + if (query.getRouting() != null) { + updateRequestBuilder.setRouting(query.getRouting()); + } + + if (query.getScriptedUpsert() != null) { + updateRequestBuilder.setScriptedUpsert(query.getScriptedUpsert()); + } + + if (query.getDocAsUpsert() != null) { + updateRequestBuilder.setDocAsUpsert(query.getDocAsUpsert()); + } + + if (query.getFetchSource() != null) { + updateRequestBuilder.setFetchSource(query.getFetchSource()); + } + + if (query.getFetchSourceIncludes() != null || query.getFetchSourceExcludes() != null) { + List includes = query.getFetchSourceIncludes() != null ? query.getFetchSourceIncludes() + : Collections.emptyList(); + List excludes = query.getFetchSourceExcludes() != null ? query.getFetchSourceExcludes() + : Collections.emptyList(); + updateRequestBuilder.setFetchSource(includes.toArray(new String[0]), excludes.toArray(new String[0])); + } + + if (query.getIfSeqNo() != null) { + updateRequestBuilder.setIfSeqNo(query.getIfSeqNo()); + } + + if (query.getIfPrimaryTerm() != null) { + updateRequestBuilder.setIfPrimaryTerm(query.getIfPrimaryTerm()); + } + + if (query.getRefresh() != null) { + updateRequestBuilder.setRefreshPolicy(query.getRefresh().name().toLowerCase()); + } + + if (query.getRetryOnConflict() != null) { + updateRequestBuilder.setRetryOnConflict(query.getRetryOnConflict()); + } + + if (query.getTimeout() != null) { + updateRequestBuilder.setTimeout(query.getTimeout()); + } + + if (query.getWaitForActiveShards() != null) { + updateRequestBuilder.setWaitForActiveShards(ActiveShardCount.parseString(query.getWaitForActiveShards())); + } + + return updateRequestBuilder; + } + // endregion + + // region helper functions private QueryBuilder getQuery(Query query) { QueryBuilder elasticsearchQuery; @@ -981,22 +1112,7 @@ private QueryBuilder getQuery(Query query) { return elasticsearchQuery; } - public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { - IndicesAliasesRequest.AliasActions aliasAction = aliasAction(query, index); - IndicesAliasesRequest request = new IndicesAliasesRequest(); - request.addAliasAction(aliasAction); - return request; - } - - public IndicesAliasesRequest indicesRemoveAliasesRequest(AliasQuery query, IndexCoordinates index) { - IndicesAliasesRequest.AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() // - .index(index.getIndexName()) // - .alias(query.getAliasName()); - - return Requests.indexAliasesRequest() // - .addAliasAction(aliasAction); - } - + @Nullable private QueryBuilder getFilter(Query query) { QueryBuilder elasticsearchFilter; @@ -1036,10 +1152,10 @@ private String getPersistentEntityId(Object entity) { private VersionType retrieveVersionTypeFromPersistentEntity(Class clazz) { - if (clazz != null) { - return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz).getVersionType(); - } - return VersionType.EXTERNAL; + VersionType versionType = elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz) + .getVersionType(); + + return versionType != null ? versionType : VersionType.EXTERNAL; } private String[] toArray(List values) { @@ -1047,4 +1163,21 @@ private String[] toArray(List values) { return values.toArray(valuesAsArray); } + private boolean hasSeqNoPrimaryTermProperty(@Nullable Class entityClass) { + + if (entityClass == null) { + return false; + } + + if (!elasticsearchConverter.getMappingContext().hasPersistentEntityFor(entityClass)) { + return false; + } + + ElasticsearchPersistentEntity entity = elasticsearchConverter.getMappingContext() + .getRequiredPersistentEntity(entityClass); + return entity.hasSeqNoPrimaryTermProperty(); + } + + // endregion + } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java index 4f229be16..e404e5bfa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchOperations.java @@ -241,6 +241,16 @@ default AggregatedPage moreLikeThis(MoreLikeThisQuery query, Class cla // endregion + /** + * Does a suggest query + * + * @param suggestion the query + * @param the entity class + * @return the suggest response + * @since 4.1 + */ + SearchResponse suggest(SuggestBuilder suggestion, Class clazz); + /** * Does a suggest query * @@ -277,6 +287,17 @@ default SearchHit searchOne(Query query, Class clazz, IndexCoordinates return content.isEmpty() ? null : content.get(0); } + /** + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. + * + * @param queries the queries to execute + * @param clazz the entity clazz + * @param element return type + * @return list of SearchHits + * @since 4.1 + */ + List> multiSearch(List queries, Class clazz); + /** * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. * @@ -288,6 +309,16 @@ default SearchHit searchOne(Query query, Class clazz, IndexCoordinates */ List> multiSearch(List queries, Class clazz, IndexCoordinates index); + /** + * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. + * + * @param queries the queries to execute + * @param classes the entity classes + * @return list of SearchHits + * @since 4.1 + */ + List> multiSearch(List queries, List> classes); + /** * Execute the multi search query against elasticsearch and return result as {@link List} of {@link SearchHits}. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index 435763f82..8b34b1915 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -73,8 +73,12 @@ default String convertId(Object idValue) { * @return will not be {@literal null}. */ default Document mapObject(@Nullable Object source) { + Document target = Document.create(); - write(source, target); + + if (source != null) { + write(source, target); + } return target; } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index d4a7fb8f5..4d85bda96 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -87,9 +87,9 @@ public class MappingElasticsearchConverter private final GenericConversionService conversionService; private CustomConversions conversions = new ElasticsearchCustomConversions(Collections.emptyList()); - private EntityInstantiators instantiators = new EntityInstantiators(); + private final EntityInstantiators instantiators = new EntityInstantiators(); - private ElasticsearchTypeMapper typeMapper; + private final ElasticsearchTypeMapper typeMapper; private ConcurrentHashMap propertyWarnings = new ConcurrentHashMap<>(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index bc7fed013..8f99b528b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -58,6 +58,7 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity, ElasticsearchPersistentProperty> - implements ApplicationContextAware { - - private @Nullable ApplicationContext context; + extends AbstractMappingContext, ElasticsearchPersistentProperty> { @Override protected SimpleElasticsearchPersistentEntity createPersistentEntity(TypeInformation typeInformation) { - SimpleElasticsearchPersistentEntity persistentEntity = new SimpleElasticsearchPersistentEntity<>( - typeInformation); - if (context != null) { - persistentEntity.setApplicationContext(context); - } - return persistentEntity; + return new SimpleElasticsearchPersistentEntity<>(typeInformation); } @Override @@ -52,9 +41,4 @@ protected ElasticsearchPersistentProperty createPersistentProperty(Property prop SimpleElasticsearchPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) { return new SimpleElasticsearchPersistentProperty(property, owner, simpleTypeHolder); } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 677f82215..462e5a7aa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -22,11 +22,6 @@ import org.elasticsearch.index.VersionType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.BeansException; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.expression.BeanFactoryAccessor; -import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Setting; @@ -35,10 +30,11 @@ import org.springframework.data.mapping.model.BasicPersistentEntity; import org.springframework.data.mapping.model.PersistentPropertyAccessorFactory; import org.springframework.data.util.TypeInformation; +import org.springframework.expression.EvaluationContext; import org.springframework.expression.Expression; import org.springframework.expression.ParserContext; +import org.springframework.expression.common.LiteralExpression; import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -55,12 +51,10 @@ * @author Roman Puchkovskiy */ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntity - implements ElasticsearchPersistentEntity, ApplicationContextAware { + implements ElasticsearchPersistentEntity { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleElasticsearchPersistentEntity.class); - - private final StandardEvaluationContext context; - private final SpelExpressionParser parser; + private static final SpelExpressionParser PARSER = new SpelExpressionParser(); private @Nullable String indexName; private boolean useServerConfiguration; @@ -76,12 +70,11 @@ public class SimpleElasticsearchPersistentEntity extends BasicPersistentEntit private @Nullable VersionType versionType; private boolean createIndexAndMapping; private final Map fieldNamePropertyCache = new ConcurrentHashMap<>(); + private final ConcurrentHashMap indexNameExpressions = new ConcurrentHashMap<>(); public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { super(typeInformation); - this.context = new StandardEvaluationContext(); - this.parser = new SpelExpressionParser(); Class clazz = typeInformation.getType(); if (clazz.isAnnotationPresent(Document.class)) { @@ -102,26 +95,13 @@ public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { } } - @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { - context.addPropertyAccessor(new BeanFactoryAccessor()); - context.setBeanResolver(new BeanFactoryResolver(applicationContext)); - context.setRootObject(applicationContext); - } - private String getIndexName() { - - if (indexName != null) { - Expression expression = parser.parseExpression(indexName, ParserContext.TEMPLATE_EXPRESSION); - return expression.getValue(context, String.class); - } - - return getTypeInformation().getType().getSimpleName(); + return indexName != null ? indexName : getTypeInformation().getType().getSimpleName(); } @Override public IndexCoordinates getIndexCoordinates() { - return IndexCoordinates.of(getIndexName()); + return resolve(IndexCoordinates.of(getIndexName())); } @Nullable @@ -294,4 +274,47 @@ public boolean hasSeqNoPrimaryTermProperty() { public ElasticsearchPersistentProperty getSeqNoPrimaryTermProperty() { return seqNoPrimaryTermProperty; } + + // region SpEL handling + /** + * resolves all the names in the IndexCoordinates object. If a name cannot be resolved, the original name is returned. + * + * @param indexCoordinates IndexCoordinates with names to resolve + * @return IndexCoordinates with resolved names + */ + private IndexCoordinates resolve(IndexCoordinates indexCoordinates) { + + EvaluationContext context = getEvaluationContext(null); + + String[] indexNames = indexCoordinates.getIndexNames(); + String[] resolvedNames = new String[indexNames.length]; + + for (int i = 0; i < indexNames.length; i++) { + String indexName = indexNames[i]; + resolvedNames[i] = resolve(context, indexName); + } + + return IndexCoordinates.of(resolvedNames); + } + + /** + * tries to resolve the given name. If this is not successful, the original value is returned + * + * @param context SpEL evaluation context + * @param name name to resolve + * @return the resolved name or the input name if it cannot be resolved + */ + private String resolve(EvaluationContext context, String name) { + + Assert.notNull(name, "name must not be null"); + + Expression expression = indexNameExpressions.computeIfAbsent(name, s -> { + Expression expr = PARSER.parseExpression(name, ParserContext.TEMPLATE_EXPRESSION); + return expr instanceof LiteralExpression ? null : expr; + }); + + String resolvedName = expression != null ? expression.getValue(context, String.class) : null; + return resolvedName != null ? resolvedName : name; + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index b834a46e1..a15fa56c6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -20,6 +20,9 @@ import java.util.Date; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; @@ -50,6 +53,8 @@ public class SimpleElasticsearchPersistentProperty extends AnnotationBasedPersistentProperty implements ElasticsearchPersistentProperty { + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleElasticsearchPersistentProperty.class); + private static final List SUPPORTED_ID_PROPERTY_NAMES = Arrays.asList("id", "document"); private final boolean isScore; @@ -66,6 +71,15 @@ public SimpleElasticsearchPersistentProperty(Property property, this.annotatedFieldName = getAnnotatedFieldName(); this.isId = super.isIdProperty() || SUPPORTED_ID_PROPERTY_NAMES.contains(getFieldName()); + + // deprecated since 4.1 + @Deprecated + boolean isIdWithoutAnnotation = isId && !isAnnotationPresent(Id.class); + if (isIdWithoutAnnotation) { + LOGGER.warn("Using the property name of '{}' to identify the id property is deprecated." + + " Please annotate the id property with '@Id'", getName()); + } + this.isScore = isAnnotationPresent(Score.class); this.isParent = isAnnotationPresent(Parent.class); this.isSeqNoPrimaryTerm = SeqNoPrimaryTerm.class.isAssignableFrom(getRawType()); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java index e2f57275c..4f1be7414 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java @@ -39,6 +39,7 @@ public interface ElasticsearchEntityInformation extends EntityInformation @Nullable Long getVersion(T entity); + @Nullable VersionType getVersionType(); @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java index 83c55edb5..304f11954 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java @@ -16,9 +16,9 @@ package org.springframework.data.elasticsearch.repository.support; import org.elasticsearch.index.VersionType; -import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.repository.core.support.PersistentEntityInformation; /** @@ -35,44 +35,34 @@ * @author Christoph Strobl * @author Ivan Greene * @author Sylvain Laurent + * @author Peter-Josef Meisch */ public class MappingElasticsearchEntityInformation extends PersistentEntityInformation implements ElasticsearchEntityInformation { - private final ElasticsearchPersistentEntity entityMetadata; - private final IndexCoordinates indexCoordinates; - private final VersionType versionType; - - public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity entity) { - this(entity, entity.getIndexCoordinates(), entity.getVersionType()); - } - - public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity entity, - IndexCoordinates indexCoordinates, VersionType versionType) { - super(entity); + private final ElasticsearchPersistentEntity persistentEntity; - this.entityMetadata = entity; - this.indexCoordinates = indexCoordinates; - this.versionType = versionType; + public MappingElasticsearchEntityInformation(ElasticsearchPersistentEntity persistentEntity) { + super(persistentEntity); + this.persistentEntity = persistentEntity; } @Override public String getIdAttribute() { - return entityMetadata.getRequiredIdProperty().getFieldName(); + return persistentEntity.getRequiredIdProperty().getFieldName(); } - @Override public IndexCoordinates getIndexCoordinates() { - return indexCoordinates; + return persistentEntity.getIndexCoordinates(); } @Override public Long getVersion(T entity) { - ElasticsearchPersistentProperty versionProperty = entityMetadata.getVersionProperty(); + ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); try { - return versionProperty != null ? (Long) entityMetadata.getPropertyAccessor(entity).getProperty(versionProperty) + return versionProperty != null ? (Long) persistentEntity.getPropertyAccessor(entity).getProperty(versionProperty) : null; } catch (Exception e) { throw new IllegalStateException("failed to load version field", e); @@ -81,15 +71,15 @@ public Long getVersion(T entity) { @Override public VersionType getVersionType() { - return versionType; + return persistentEntity.getVersionType(); } @Override public String getParentId(T entity) { - ElasticsearchPersistentProperty parentProperty = entityMetadata.getParentIdProperty(); + ElasticsearchPersistentProperty parentProperty = persistentEntity.getParentIdProperty(); try { - return parentProperty != null ? (String) entityMetadata.getPropertyAccessor(entity).getProperty(parentProperty) + return parentProperty != null ? (String) persistentEntity.getPropertyAccessor(entity).getProperty(parentProperty) : null; } catch (Exception e) { throw new IllegalStateException("failed to load parent ID: " + e, e); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java index d7f2b9788..e4e249698 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ReactiveElasticsearchRepositoryFactory.java @@ -113,8 +113,7 @@ private ElasticsearchEntityInformation getEntityInformation(Class @Nullable RepositoryInformation information) { ElasticsearchPersistentEntity entity = mappingContext.getRequiredPersistentEntity(domainClass); - return new MappingElasticsearchEntityInformation<>((ElasticsearchPersistentEntity) entity, - entity.getIndexCoordinates(), entity.getVersionType()); + return new MappingElasticsearchEntityInformation<>((ElasticsearchPersistentEntity) entity); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java index 8382cdc20..70691f434 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -492,6 +492,7 @@ void findByAvailableTrueOrderByNameDesc() throws NoSuchMethodException, JSONExce private String getQueryBuilder(String methodName, Class[] parameterClasses, Object[] parameters) throws NoSuchMethodException { + Method method = SampleRepository.class.getMethod(methodName, parameterClasses); ElasticsearchQueryMethod queryMethod = new ElasticsearchQueryMethod(method, new DefaultRepositoryMetadata(SampleRepository.class), new SpelAwareProxyProjectionFactory(), diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 07b5e4aa9..e17f58d47 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -2781,13 +2781,23 @@ public void shouldAddAliasForVariousRoutingValues() { AliasMetaData aliasMetaData1 = aliasMetaData.get(0); assertThat(aliasMetaData1).isNotNull(); - assertThat(aliasMetaData1.alias()).isEqualTo(alias1); - assertThat(aliasMetaData1.indexRouting()).isEqualTo("0"); + if (aliasMetaData1.alias().equals(alias1)) { + assertThat(aliasMetaData1.indexRouting()).isEqualTo("0"); + } else if (aliasMetaData1.alias().equals(alias2)) { + assertThat(aliasMetaData1.searchRouting()).isEqualTo("1"); + } else { + fail("unknown alias"); + } AliasMetaData aliasMetaData2 = aliasMetaData.get(1); assertThat(aliasMetaData2).isNotNull(); - assertThat(aliasMetaData2.alias()).isEqualTo(alias2); - assertThat(aliasMetaData2.searchRouting()).isEqualTo("1"); + if (aliasMetaData2.alias().equals(alias1)) { + assertThat(aliasMetaData2.indexRouting()).isEqualTo("0"); + } else if (aliasMetaData2.alias().equals(alias2)) { + assertThat(aliasMetaData2.searchRouting()).isEqualTo("1"); + } else { + fail("unknown alias"); + } // cleanup indexOperations.removeAlias(aliasQuery1); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java index 3e37fb3df..d9e936648 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/dynamicindex/DynamicIndexEntityTests.java @@ -87,35 +87,37 @@ public void indexNameIsDynamicallyProvided() { int initialCallsCount = indexNameProvider.callsCount; - indexNameProvider.setIndexName("index1"); + indexNameProvider.indexName = "index1"; repository.save(new DynamicIndexEntity()); assertThat(indexNameProvider.callsCount > initialCallsCount).isTrue(); assertThat(repository.count()).isEqualTo(1L); - indexNameProvider.setIndexName("index2"); + indexNameProvider.indexName = "index2"; assertThat(repository.count()).isEqualTo(0L); } @Test // DATAES-821 void indexOpsShouldUseDynamicallyProvidedName() { - indexNameProvider.setIndexName("test-dynamic"); - IndexOperations indexOps = operations.indexOps(DynamicIndexEntity.class); + indexNameProvider.indexName = "index-dynamic"; + indexNameProvider.callsCount = 0; - int initialCallsCount = indexNameProvider.callsCount; + operations.indexOps(IndexCoordinates.of("index-dynamic")).delete(); + + IndexOperations indexOps = operations.indexOps(DynamicIndexEntity.class); indexOps.create(); indexOps.refresh(); indexOps.refresh(); - indexOps.delete(); + indexOps.delete(); // internally calls doExists - assertThat(indexNameProvider.callsCount - initialCallsCount).isEqualTo(4); + assertThat(indexNameProvider.callsCount).isGreaterThan(0); } static class IndexNameProvider { private String indexName; - int callsCount; + private int callsCount; public String getIndexName() { @@ -123,10 +125,6 @@ public String getIndexName() { return indexName; } - public void setIndexName(String indexName) { - this.indexName = indexName; - } - } @Document(indexName = "#{@indexNameProvider.getIndexName()}", createIndex = false) From b177dd168118476068461b361c0358bf717beeb9 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 13 Jun 2020 17:08:48 +0200 Subject: [PATCH 0195/1191] DATAES-678 - Introduce ReactiveIndexOperations. Original PR: #481 --- ...elasticsearch-migration-guide-4.0-4.1.adoc | 21 +- .../UncategorizedElasticsearchException.java | 4 + .../DefaultReactiveElasticsearchClient.java | 41 +- .../reactive/ReactiveElasticsearchClient.java | 177 ++++++++- .../client/reactive/RequestCreator.java | 20 +- .../client/util/RequestConverters.java | 34 +- .../core/AbstractDefaultIndexOperations.java | 70 ++-- .../core/DefaultReactiveIndexOperations.java | 238 ++++++++++++ .../core/DefaultTransportIndexOperations.java | 2 +- .../ElasticsearchExceptionTranslator.java | 8 +- .../core/ElasticsearchOperations.java | 2 +- .../elasticsearch/core/IndexOperations.java | 12 +- .../core/ReactiveElasticsearchOperations.java | 39 +- .../core/ReactiveElasticsearchTemplate.java | 118 +++--- .../core/ReactiveIndexOperations.java | 134 +++++++ .../core/ReactiveResourceUtil.java | 81 ++++ .../elasticsearch/core/RequestFactory.java | 123 +++++- .../ElasticsearchPersistentEntity.java | 9 + .../SimpleElasticsearchPersistentEntity.java | 23 +- .../SimpleElasticsearchRepository.java | 17 +- ...SimpleReactiveElasticsearchRepository.java | 115 ++++-- .../ReactiveElasticsearchClientTests.java | 7 +- .../ReactiveElasticsearchTemplateTests.java | 3 +- .../core/ReactiveIndexOperationsTest.java | 358 ++++++++++++++++++ .../core/ReactiveResourceUtilTest.java | 68 ++++ ...eReactiveElasticsearchRepositoryTests.java | 8 +- 26 files changed, 1524 insertions(+), 208 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtilTest.java diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index 1697205c7..fbe2009b8 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -3,16 +3,31 @@ This section describes breaking changes from version 4.0.x to 4.1.x and how removed features can be replaced by new introduced features. +[[elasticsearch-migration-guide-4.0-4.1.deprecations]] == Deprecations .Definition of the id property -It is possible to define a property of en entity as the id property by naming it either `id` or `document`. This behaviour is now deprecated and will produce a warning. PLease us the `@Id` annotation to mark a property as being the id property. +It is possible to define a property of en entity as the id property by naming it either `id` or `document`. +This behaviour is now deprecated and will produce a warning. +PLease us the `@Id` annotation to mark a property as being the id property. + +In the `ReactiveElasticsearchClient.Indices` interface the `updateMapping` methods are deprecated in favour of the `putMapping` methods. +They do the same, but `putMapping` is consistent with the naming in the Elasticsearch API: [[elasticsearch-migration-guide-4.0-4.1.removal]] == Removals .Type mappings -The _type mappings_ parameters of the `@Document` annotation and the `IndexCoordinates` object were removed. They had been deprecated in Spring Data Elasticsearch 4.0 and their values weren't used anymore. +The _type mappings_ parameters of the `@Document` annotation and the `IndexCoordinates` object were removed. +They had been deprecated in Spring Data Elasticsearch 4.0 and their values weren't used anymore. + +[[elasticsearch-migration-guide-4.0-4.1.breaking-changes]] +== Breaking Changes + +=== Return types of ReactiveElasticsearchClient.Indices methods -=== Breaking changes +The methods in the `ReactiveElasticsearchClient.Indices` were not used up to now. +With the introduction of the `ReactiveIndexOperations` it became necessary to change some of the return types: +* the `createIndex` variants now return a `Mono` instead of a `Mono` to signal successful index creation. +* the `updateMapping` variants now return a `Mono` instead of a `Mono` to signal successful mappings storage. diff --git a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java index bc241291a..f9a8414ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/UncategorizedElasticsearchException.java @@ -23,6 +23,10 @@ */ public class UncategorizedElasticsearchException extends UncategorizedDataAccessException { + public UncategorizedElasticsearchException(String msg) { + super(msg, null); + } + public UncategorizedElasticsearchException(String msg, Throwable cause) { super(msg, cause); } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 4f687c36e..5e8e688e8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -55,10 +55,14 @@ import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.flush.FlushResponse; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; @@ -551,26 +555,20 @@ public Mono existsIndex(HttpHeaders headers, GetIndexRequest request) { .next(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#deleteIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest) - */ @Override - public Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest request) { + public Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest request) { return sendRequest(request, requestCreator.indexDelete(), AcknowledgedResponse.class, headers) // - .then(); + .map(AcknowledgedResponse::isAcknowledged) // + .next(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#createIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.create.CreateIndexRequest) - */ @Override - public Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest) { + public Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest) { return sendRequest(createIndexRequest, requestCreator.indexCreate(), AcknowledgedResponse.class, headers) // - .then(); + .map(AcknowledgedResponse::isAcknowledged) // + .next(); } /* @@ -606,15 +604,12 @@ public Mono refreshIndex(HttpHeaders headers, RefreshRequest refreshReques .then(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#updateMapping(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest) - */ @Override - public Mono updateMapping(HttpHeaders headers, PutMappingRequest putMappingRequest) { + public Mono putMapping(HttpHeaders headers, PutMappingRequest putMappingRequest) { return sendRequest(putMappingRequest, requestCreator.putMapping(), AcknowledgedResponse.class, headers) // - .then(); + .map(AcknowledgedResponse::isAcknowledged) // + .next(); } /* @@ -628,6 +623,16 @@ public Mono flushIndex(HttpHeaders headers, FlushRequest flushRequest) { .then(); } + @Override + public Mono getMapping(HttpHeaders headers, GetMappingsRequest getMappingsRequest) { + return sendRequest(getMappingsRequest, requestCreator.getMapping(), GetMappingsResponse.class, headers).next(); + } + + @Override + public Mono getSettings(HttpHeaders headers, GetSettingsRequest getSettingsRequest) { + return sendRequest(getSettingsRequest, requestCreator.getSettings(), GetSettingsResponse.class, headers).next(); + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.ReactiveElasticsearchClientCallback) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 89602ef1f..193390733 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -27,9 +27,13 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; @@ -416,11 +420,10 @@ default Flux search(SearchRequest searchRequest) { /** * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. * - * @param consumer - * never {@literal null}. + * @param consumer never {@literal null}. * @return the {@link Flux} emitting {@link Aggregation} one by one. * @see Search API on - * elastic.co + * elastic.co * @since 4.0 */ default Flux aggregate(Consumer consumer) { @@ -674,7 +677,7 @@ default Mono existsIndex(GetIndexRequest getIndexRequest) { * @see Indices * Delete API on elastic.co */ - default Mono deleteIndex(Consumer consumer) { + default Mono deleteIndex(Consumer consumer) { DeleteIndexRequest request = new DeleteIndexRequest(); consumer.accept(request); @@ -690,7 +693,7 @@ default Mono deleteIndex(Consumer consumer) { * @see Indices * Delete API on elastic.co */ - default Mono deleteIndex(DeleteIndexRequest deleteIndexRequest) { + default Mono deleteIndex(DeleteIndexRequest deleteIndexRequest) { return deleteIndex(HttpHeaders.EMPTY, deleteIndexRequest); } @@ -704,18 +707,18 @@ default Mono deleteIndex(DeleteIndexRequest deleteIndexRequest) { * @see Indices * Delete API on elastic.co */ - Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest deleteIndexRequest); + Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest deleteIndexRequest); /** * Execute the given {@link CreateIndexRequest} against the {@literal indices} API. * * @param consumer never {@literal null}. - * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index - * already exist. + * @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if + * eg. the index already exist. * @see Indices * Create API on elastic.co */ - default Mono createIndex(Consumer consumer) { + default Mono createIndex(Consumer consumer) { CreateIndexRequest request = new CreateIndexRequest(); consumer.accept(request); @@ -726,12 +729,12 @@ default Mono createIndex(Consumer consumer) { * Execute the given {@link CreateIndexRequest} against the {@literal indices} API. * * @param createIndexRequest must not be {@literal null}. - * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index - * already exist. + * @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if + * eg. the index already exist. * @see Indices * Create API on elastic.co */ - default Mono createIndex(CreateIndexRequest createIndexRequest) { + default Mono createIndex(CreateIndexRequest createIndexRequest) { return createIndex(HttpHeaders.EMPTY, createIndexRequest); } @@ -740,12 +743,12 @@ default Mono createIndex(CreateIndexRequest createIndexRequest) { * * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. * @param createIndexRequest must not be {@literal null}. - * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index - * already exist. + * @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if + * eg. the index already exist. * @see Indices * Create API on elastic.co */ - Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest); + Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest); /** * Execute the given {@link OpenIndexRequest} against the {@literal indices} API. @@ -870,6 +873,52 @@ default Mono refreshIndex(RefreshRequest refreshRequest) { */ Mono refreshIndex(HttpHeaders headers, RefreshRequest refreshRequest); + /** + * Execute the given {@link PutMappingRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Put Mapping API on elastic.co + * @deprecated since 4.1, use {@link #putMapping(Consumer)} + */ + @Deprecated + default Mono updateMapping(Consumer consumer) { + return putMapping(consumer); + } + + /** + * Execute the given {@link PutMappingRequest} against the {@literal indices} API. + * + * @param putMappingRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Put Mapping API on elastic.co + * @deprecated since 4.1, use {@link #putMapping(PutMappingRequest)} + */ + @Deprecated + default Mono updateMapping(PutMappingRequest putMappingRequest) { + return putMapping(putMappingRequest); + } + + /** + * Execute the given {@link PutMappingRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param putMappingRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Put Mapping API on elastic.co + * @deprecated since 4.1, use {@link #putMapping(HttpHeaders, PutMappingRequest)} + */ + @Deprecated + default Mono updateMapping(HttpHeaders headers, PutMappingRequest putMappingRequest) { + return putMapping(headers, putMappingRequest); + } + /** * Execute the given {@link PutMappingRequest} against the {@literal indices} API. * @@ -879,11 +928,11 @@ default Mono refreshIndex(RefreshRequest refreshRequest) { * @see Indices * Put Mapping API on elastic.co */ - default Mono updateMapping(Consumer consumer) { + default Mono putMapping(Consumer consumer) { PutMappingRequest request = new PutMappingRequest(); consumer.accept(request); - return updateMapping(request); + return putMapping(request); } /** @@ -895,8 +944,8 @@ default Mono updateMapping(Consumer consumer) { * @see Indices * Put Mapping API on elastic.co */ - default Mono updateMapping(PutMappingRequest putMappingRequest) { - return updateMapping(HttpHeaders.EMPTY, putMappingRequest); + default Mono putMapping(PutMappingRequest putMappingRequest) { + return putMapping(HttpHeaders.EMPTY, putMappingRequest); } /** @@ -909,7 +958,7 @@ default Mono updateMapping(PutMappingRequest putMappingRequest) { * @see Indices * Put Mapping API on elastic.co */ - Mono updateMapping(HttpHeaders headers, PutMappingRequest putMappingRequest); + Mono putMapping(HttpHeaders headers, PutMappingRequest putMappingRequest); /** * Execute the given {@link FlushRequest} against the {@literal indices} API. @@ -951,5 +1000,93 @@ default Mono flushIndex(FlushRequest flushRequest) { * API on elastic.co */ Mono flushIndex(HttpHeaders headers, FlushRequest flushRequest); + + /** + * Execute the given {@link GetSettingsRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + default Mono getSettings(Consumer consumer) { + + GetSettingsRequest request = new GetSettingsRequest(); + consumer.accept(request); + return getSettings(request); + } + + /** + * Execute the given {@link GetSettingsRequest} against the {@literal indices} API. + * + * @param getSettingsRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + default Mono getSettings(GetSettingsRequest getSettingsRequest) { + return getSettings(HttpHeaders.EMPTY, getSettingsRequest); + } + + /** + * Execute the given {@link GetSettingsRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param getSettingsRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + Mono getSettings(HttpHeaders headers, GetSettingsRequest getSettingsRequest); + + /** + * Execute the given {@link GetMappingsRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + default Mono getMapping(Consumer consumer) { + + GetMappingsRequest request = new GetMappingsRequest(); + consumer.accept(request); + return getMapping(request); + } + + /** + * Execute the given {@link GetMappingsRequest} against the {@literal indices} API. + * + * @param getMappingsRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + default Mono getMapping(GetMappingsRequest getMappingsRequest) { + return getMapping(HttpHeaders.EMPTY, getMappingsRequest); + } + + /** + * Execute the given {@link GetMappingsRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param getMappingsRequest must not be {@literal null}. + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error} if eg. the index + * does not exist. + * @see Indices + * Flush API on elastic.co + * @since 4.1 + */ + Mono getMapping(HttpHeaders headers, GetMappingsRequest getMappingsRequest); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java index 0c5e13e28..44d05c8e2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java @@ -8,9 +8,11 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; @@ -24,7 +26,7 @@ import org.elasticsearch.client.Request; import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequest; -import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.client.util.RequestConverters; /** @@ -88,7 +90,7 @@ default Function bulk() { try { return RequestConverters.bulk(request); } catch (IOException e) { - throw new ElasticsearchException("Could not parse request", e); + throw new UncategorizedElasticsearchException("Could not parse request", e); } }; } @@ -131,4 +133,18 @@ default Function count() { return RequestConverters::count; } + /** + * @since 4.1 + */ + default Function getSettings() { + return RequestConverters::getSettings; + } + + /** + * @since 4.1 + */ + default Function getMapping() { + return RequestConverters::getMapping; + } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index 5abc0986c..796260a10 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -38,9 +38,11 @@ import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.flush.FlushRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.explain.ExplainRequest; @@ -751,12 +753,12 @@ public static Request putMapping(PutMappingRequest putMappingRequest) { } Request request = new Request(HttpMethod.PUT.name(), - RequestConverters.endpoint(putMappingRequest.indices(), "_mapping", putMappingRequest.type())); + RequestConverters.endpoint(putMappingRequest.indices(), "_mapping")); RequestConverters.Params parameters = new RequestConverters.Params(request) // .withTimeout(putMappingRequest.timeout()) // .withMasterTimeout(putMappingRequest.masterNodeTimeout()) // - .withIncludeTypeName(true); + .withIncludeTypeName(false); request.setEntity(RequestConverters.createEntity(putMappingRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE)); return request; } @@ -772,6 +774,34 @@ public static Request flushIndex(FlushRequest flushRequest) { return request; } + public static Request getMapping(GetMappingsRequest getMappingsRequest) { + String[] indices = getMappingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.indices(); + String[] types = getMappingsRequest.types() == null ? Strings.EMPTY_ARRAY : getMappingsRequest.types(); + + Request request = new Request(HttpMethod.GET.name(), RequestConverters.endpoint(indices, "_mapping", types)); + + RequestConverters.Params parameters = new RequestConverters.Params(request); + parameters.withMasterTimeout(getMappingsRequest.masterNodeTimeout()); + parameters.withIndicesOptions(getMappingsRequest.indicesOptions()); + parameters.withLocal(getMappingsRequest.local()); + parameters.withIncludeTypeName(false); + return request; + } + + public static Request getSettings(GetSettingsRequest getSettingsRequest) { + String[] indices = getSettingsRequest.indices() == null ? Strings.EMPTY_ARRAY : getSettingsRequest.indices(); + String[] names = getSettingsRequest.names() == null ? Strings.EMPTY_ARRAY : getSettingsRequest.names(); + + Request request = new Request(HttpMethod.GET.name(), RequestConverters.endpoint(indices, "_settings", names)); + + RequestConverters.Params parameters = new RequestConverters.Params(request); + parameters.withIndicesOptions(getSettingsRequest.indicesOptions()); + parameters.withLocal(getSettingsRequest.local()); + parameters.withIncludeDefaults(getSettingsRequest.includeDefaults()); + parameters.withMasterTimeout(getSettingsRequest.masterNodeTimeout()); + return request; + } + static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) { try { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 4008e11bf..8851fb91d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -17,13 +17,11 @@ import static org.springframework.util.StringUtils.*; -import java.util.HashMap; import java.util.List; import java.util.Map; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; -import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.settings.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,37 +88,22 @@ protected Class checkForBoundClass() { @Override public boolean create() { - IndexCoordinates index; Document settings = null; if (boundClass != null) { Class clazz = boundClass; - ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(clazz); - index = persistentEntity.getIndexCoordinates(); if (clazz.isAnnotationPresent(Setting.class)) { String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - - if (hasText(settingPath)) { - String fileSettings = ResourceUtil.readFileFromClasspath(settingPath); - - if (hasText(fileSettings)) { - settings = Document.parse(fileSettings); - } - } else { - LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); - } + settings = loadSettings(settingPath); } if (settings == null) { - settings = getDefaultSettings(persistentEntity); + settings = getRequiredPersistentEntity(clazz).getDefaultSettings(); } - } else { - index = boundIndex; } - // noinspection ConstantConditions - return doCreate(index, settings); + return doCreate(getIndexCoordinates(), settings); } @Override @@ -236,42 +219,41 @@ protected Document buildMapping(Class clazz) { // endregion // region Helper functions - private Document getDefaultSettings(ElasticsearchPersistentEntity persistentEntity) { - - if (persistentEntity.isUseServerConfiguration()) { - return Document.create(); - } - - Map map = new MapBuilder() - .put("index.number_of_shards", String.valueOf(persistentEntity.getShards())) - .put("index.number_of_replicas", String.valueOf(persistentEntity.getReplicas())) - .put("index.refresh_interval", persistentEntity.getRefreshInterval()) - .put("index.store.type", persistentEntity.getIndexStoreType()).map(); - return Document.from(map); - } - ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } + /** + * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed + * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. + * + * @return IndexCoordinates + */ protected IndexCoordinates getIndexCoordinates() { - - if (boundClass != null) { - return getIndexCoordinatesFor(boundClass); - } - - Assert.notNull(boundIndex, "boundIndex may not be null"); - - return boundIndex; + return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; } public IndexCoordinates getIndexCoordinatesFor(Class clazz) { return getRequiredPersistentEntity(clazz).getIndexCoordinates(); } - protected Map convertSettingsResponseToMap(GetSettingsResponse response, String indexName) { + @Nullable + private Document loadSettings(String settingPath) { + if (hasText(settingPath)) { + String settingsFile = ResourceUtil.readFileFromClasspath(settingPath); + + if (hasText(settingsFile)) { + return Document.parse(settingsFile); + } + } else { + LOGGER.info("settingPath in @Setting has to be defined. Using default instead."); + } + return null; + } + + protected Document convertSettingsResponseToMap(GetSettingsResponse response, String indexName) { - Map settings = new HashMap<>(); + Document settings = Document.create(); if (!response.getIndexToDefaultSettings().isEmpty()) { Settings defaultSettings = response.getIndexToDefaultSettings().get(indexName); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java new file mode 100644 index 000000000..94d30dcd1 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java @@ -0,0 +1,238 @@ +/* + * Copyright 2020 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; + +import static org.elasticsearch.client.Requests.*; +import static org.springframework.util.StringUtils.*; + +import reactor.core.publisher.Mono; + +import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.get.GetIndexRequest; +import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.InvalidDataAccessApiUsageException; +import org.springframework.data.elasticsearch.NoSuchIndexException; +import org.springframework.data.elasticsearch.annotations.Mapping; +import org.springframework.data.elasticsearch.annotations.Setting; +import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.index.MappingBuilder; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * @author Peter-Josef Meisch + * @since 4.1 + */ +class DefaultReactiveIndexOperations implements ReactiveIndexOperations { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultReactiveIndexOperations.class); + + @Nullable private final Class boundClass; + private final IndexCoordinates boundIndex; + private final RequestFactory requestFactory; + private final ReactiveElasticsearchOperations operations; + private final ElasticsearchConverter converter; + + public DefaultReactiveIndexOperations(ReactiveElasticsearchOperations operations, IndexCoordinates index) { + + Assert.notNull(operations, "operations must not be null"); + Assert.notNull(index, "index must not be null"); + + this.operations = operations; + this.converter = operations.getElasticsearchConverter(); + this.requestFactory = new RequestFactory(operations.getElasticsearchConverter()); + this.boundClass = null; + this.boundIndex = index; + } + + public DefaultReactiveIndexOperations(ReactiveElasticsearchOperations operations, Class clazz) { + + Assert.notNull(operations, "operations must not be null"); + Assert.notNull(clazz, "clazz must not be null"); + + this.operations = operations; + this.converter = operations.getElasticsearchConverter(); + this.requestFactory = new RequestFactory(operations.getElasticsearchConverter()); + this.boundClass = clazz; + this.boundIndex = getIndexCoordinatesFor(clazz); + } + + // region index management + @Override + public Mono create() { + + String indexName = getIndexCoordinates().getIndexName(); + Document settings = null; + + if (boundClass != null) { + Class clazz = boundClass; + + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + + return loadDocument(settingPath, "@Setting").flatMap(document -> doCreate(indexName, document)); + } + + settings = getRequiredPersistentEntity(clazz).getDefaultSettings(); + } + + return doCreate(indexName, settings); + } + + @Override + public Mono create(Document settings) { + return doCreate(getIndexCoordinates().getIndexName(), settings); + } + + private Mono doCreate(String indexName, @Nullable Document settings) { + CreateIndexRequest request = requestFactory.createIndexRequestReactive(getIndexCoordinates().getIndexName(), + settings); + return Mono.from(operations.executeWithIndicesClient(client -> client.createIndex(request))); + } + + @Override + public Mono delete() { + + return exists() // + .flatMap(exists -> { + + if (exists) { + DeleteIndexRequest request = requestFactory.deleteIndexRequest(getIndexCoordinates()); + return Mono.from(operations.executeWithIndicesClient(client -> client.deleteIndex(request))) + .onErrorResume(NoSuchIndexException.class, e -> Mono.just(false)); + } else { + return Mono.just(false); + } + }); + } + + @Override + public Mono exists() { + + GetIndexRequest request = requestFactory.getIndexRequestReactive(getIndexCoordinates().getIndexName()); + return Mono.from(operations.executeWithIndicesClient(client -> client.existsIndex(request))); + } + + @Override + public Mono refresh() { + return Mono.from(operations.executeWithIndicesClient( + client -> client.refreshIndex(refreshRequest(getIndexCoordinates().getIndexNames())))); + } + + @Override + public Mono createMapping() { + return createMapping(checkForBoundClass()); + } + + @Override + public Mono createMapping(Class clazz) { + + if (clazz.isAnnotationPresent(Mapping.class)) { + String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath(); + return loadDocument(mappingPath, "@Mapping"); + } + + String mapping = new MappingBuilder(converter).buildPropertyMapping(clazz); + return Mono.just(Document.parse(mapping)); + } + + @Override + public Mono putMapping(Mono mapping) { + return mapping.map(document -> requestFactory.putMappingRequestReactive(getIndexCoordinates(), document)) // + .flatMap(request -> Mono.from(operations.executeWithIndicesClient(client -> client.putMapping(request)))); + } + + @Override + public Mono getMapping() { + + IndexCoordinates indexCoordinates = getIndexCoordinates(); + GetMappingsRequest request = requestFactory.getMappingRequestReactive(indexCoordinates); + + return Mono.from(operations.executeWithIndicesClient(client -> client.getMapping(request))) + .flatMap(getMappingsResponse -> { + Document document = Document.create(); + document.put("properties", + getMappingsResponse.mappings().get(indexCoordinates.getIndexName()).get("properties").getSourceAsMap()); + return Mono.just(document); + }); + } + + @Override + public Mono getSettings(boolean includeDefaults) { + + String indexName = getIndexCoordinates().getIndexName(); + GetSettingsRequest request = requestFactory.getSettingsRequest(indexName, includeDefaults); + + return Mono.from(operations.executeWithIndicesClient(client -> client.getSettings(request))) + .map(getSettingsResponse -> requestFactory.fromSettingsResponse(getSettingsResponse, indexName)); + } + + // endregion + + // region helper functions + /** + * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed + * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. + * + * @return IndexCoordinates + */ + private IndexCoordinates getIndexCoordinates() { + return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; + } + + private IndexCoordinates getIndexCoordinatesFor(Class clazz) { + return operations.getElasticsearchConverter().getMappingContext().getRequiredPersistentEntity(clazz) + .getIndexCoordinates(); + } + + private ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { + return converter.getMappingContext().getRequiredPersistentEntity(clazz); + } + + private Mono loadDocument(String path, String annotation) { + + if (hasText(path)) { + return ReactiveResourceUtil.readFileFromClasspath(path).flatMap(s -> { + if (hasText(s)) { + return Mono.just(Document.parse(s)); + } else { + return Mono.just(Document.create()); + } + }); + } else { + LOGGER.info("path in {} has to be defined. Using default instead.", annotation); + } + + return Mono.just(Document.create()); + } + + private Class checkForBoundClass() { + if (boundClass == null) { + throw new InvalidDataAccessApiUsageException("IndexOperations are not bound"); + } + return boundClass; + } + + // endregion + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 0618ff4c8..3d15ebf11 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -146,7 +146,7 @@ protected Map doGetSettings(IndexCoordinates index, boolean incl .getSettings(getSettingsRequest) // .actionGet(); - return convertSettingsResponseToMap(response, getSettingsRequest.indices()[0]); + return requestFactory.fromSettingsResponse(response, index.getIndexName()); } @Override diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java index c8c532ad6..123581def 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchExceptionTranslator.java @@ -23,7 +23,6 @@ import org.elasticsearch.common.ValidationException; import org.elasticsearch.index.engine.VersionConflictEngineException; import org.elasticsearch.rest.RestStatus; - import org.springframework.dao.DataAccessException; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataIntegrityViolationException; @@ -105,10 +104,15 @@ private boolean indexAvailable(ElasticsearchException ex) { List metadata = ex.getMetadata("es.index_uuid"); if (metadata == null) { + + if (ex.getCause() instanceof ElasticsearchException) { + return indexAvailable((ElasticsearchException) ex.getCause()); + } + if (ex instanceof ElasticsearchStatusException) { return StringUtils.hasText(ObjectUtils.nullSafeToString(ex.getIndex())); } - return false; + return true; } return !CollectionUtils.contains(metadata.iterator(), "_na_"); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index a086dab1f..884a21c3a 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -49,7 +49,7 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera IndexOperations indexOps(Class clazz); /** - * get an {@link IndexOperations} that is bound to the given class + * get an {@link IndexOperations} that is bound to the given index * * @return IndexOperations */ diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 7781f65dd..300283fdf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -85,6 +85,14 @@ public interface IndexOperations { */ Document createMapping(Class clazz); + /** + * Writes the mapping to the index for the class this IndexOperations is bound to. + * @return {@literal true} if the mapping could be stored + * @since 4.1 + */ + default boolean putMapping() { + return putMapping(createMapping());} + /** * writes a mapping to the index * @@ -141,9 +149,9 @@ default boolean putMapping(Class clazz) { Map getSettings(); /** - * Get settings for a given indexName. + * Get the index settings. * - * @param includeDefaults wehther or not to include all the default settings + * @param includeDefaults whether or not to include all the default settings * @return the settings */ Map getSettings(boolean includeDefaults); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java index 9132dea67..ae0370f6c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchOperations.java @@ -40,11 +40,21 @@ public interface ReactiveElasticsearchOperations extends ReactiveDocumentOperati * Execute within a {@link ClientCallback} managing resources and translating errors. * * @param callback must not be {@literal null}. - * @param + * @param the type the Publisher emits * @return the {@link Publisher} emitting results. */ Publisher execute(ClientCallback> callback); + /** + * Execute within a {@link IndicesClientCallback} managing resources and translating errors. + * + * @param callback must not be {@literal null}. + * @param the type the Publisher emits + * @return the {@link Publisher} emitting results. + * @since 4.1 + */ + Publisher executeWithIndicesClient(IndicesClientCallback> callback); + /** * Get the {@link ElasticsearchConverter} used. * @@ -62,6 +72,22 @@ public interface ReactiveElasticsearchOperations extends ReactiveDocumentOperati */ IndexCoordinates getIndexCoordinatesFor(Class clazz); + /** + * Creates a {@link ReactiveIndexOperations} that is bound to the given index + * @param index IndexCoordinates specifying the index + * @return ReactiveIndexOperations implementation + * @since 4.1 + */ + ReactiveIndexOperations indexOps(IndexCoordinates index); + + /** + * Creates a {@link ReactiveIndexOperations} that is bound to the given class + * @param clazz the entity clazz specifiying the index information + * @return ReactiveIndexOperations implementation + * @since 4.1 + */ + ReactiveIndexOperations indexOps(Class clazz); + /** * Callback interface to be used with {@link #execute(ClientCallback)} for operating directly on * {@link ReactiveElasticsearchClient}. @@ -74,4 +100,15 @@ interface ClientCallback> { T doWithClient(ReactiveElasticsearchClient client); } + + /** + * Callback interface to be used with {@link #executeWithIndicesClient(IndicesClientCallback)} for operating directly on + * {@link ReactiveElasticsearchClient.Indices}. + * + * @param the return type + * @since 4.1 + */ + interface IndicesClientCallback> { + T doWithClient(ReactiveElasticsearchClient.Indices client); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 1d10f9743..dbb401e90 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -144,6 +144,32 @@ public void setApplicationContext(ApplicationContext applicationContext) throws } } + /** + * Set the default {@link RefreshPolicy} to apply when writing to Elasticsearch. + * + * @param refreshPolicy can be {@literal null}. + */ + public void setRefreshPolicy(@Nullable RefreshPolicy refreshPolicy) { + this.refreshPolicy = refreshPolicy; + } + + /** + * @return the current {@link RefreshPolicy}. + */ + @Nullable + public RefreshPolicy getRefreshPolicy() { + return refreshPolicy; + } + + /** + * Set the default {@link IndicesOptions} for {@link SearchRequest search requests}. + * + * @param indicesOptions can be {@literal null}. + */ + public void setIndicesOptions(@Nullable IndicesOptions indicesOptions) { + this.indicesOptions = indicesOptions; + } + /** * Set the {@link ReactiveEntityCallbacks} instance to use when invoking {@link ReactiveEntityCallbacks callbacks} * like the {@link ReactiveBeforeConvertCallback}. @@ -160,7 +186,6 @@ public void setEntityCallbacks(ReactiveEntityCallbacks entityCallbacks) { this.entityCallbacks = entityCallbacks; } - // endregion // region DocumentOperations @@ -199,25 +224,29 @@ public Flux saveAll(Mono> entitiesPubli Assert.notNull(entitiesPublisher, "Entities must not be null!"); - return entitiesPublisher.flatMapMany(entities -> { - return Flux.fromIterable(entities) // - .concatMap(entity -> maybeCallBeforeConvert(entity, index)); - }).collectList().map(Entities::new).flatMapMany(entities -> { - if (entities.isEmpty()) { - return Flux.empty(); - } + return entitiesPublisher // + .flatMapMany(entities -> Flux.fromIterable(entities) // + .concatMap(entity -> maybeCallBeforeConvert(entity, index)) // + ).collectList() // + .map(Entities::new) // + .flatMapMany(entities -> { - return doBulkOperation(entities.indexQueries(), BulkOptions.defaultOptions(), index) // - .index().flatMap(indexAndResponse -> { - T savedEntity = entities.entityAt(indexAndResponse.getT1()); - BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); + if (entities.isEmpty()) { + return Flux.empty(); + } - AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, converter.getConversionService()); - adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); + return doBulkOperation(entities.indexQueries(), BulkOptions.defaultOptions(), index) // + .index().flatMap(indexAndResponse -> { + T savedEntity = entities.entityAt(indexAndResponse.getT1()); + BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); - return maybeCallAfterSave(savedEntity, index); - }); - }); + AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, + converter.getConversionService()); + adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); + + return maybeCallAfterSave(savedEntity, index); + }); + }); } @Override @@ -730,42 +759,29 @@ protected Mono getClusterVersion() { // endregion - // Property Setters / Getters + @Override + public Publisher execute(ClientCallback> callback) { + return Flux.defer(() -> callback.doWithClient(getClient())).onErrorMap(this::translateException); + } - /** - * Set the default {@link RefreshPolicy} to apply when writing to Elasticsearch. - * - * @param refreshPolicy can be {@literal null}. - */ - public void setRefreshPolicy(@Nullable RefreshPolicy refreshPolicy) { - this.refreshPolicy = refreshPolicy; + @Override + public Publisher executeWithIndicesClient(IndicesClientCallback> callback) { + return Flux.defer(() -> callback.doWithClient(getIndicesClient())).onErrorMap(this::translateException); } - /** - * Set the default {@link IndicesOptions} for {@link SearchRequest search requests}. - * - * @param indicesOptions can be {@literal null}. - */ - public void setIndicesOptions(@Nullable IndicesOptions indicesOptions) { - this.indicesOptions = indicesOptions; + @Override + public ElasticsearchConverter getElasticsearchConverter() { + return converter; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#exctute(ClientCallback) - */ @Override - public Publisher execute(ClientCallback> callback) { - return Flux.defer(() -> callback.doWithClient(getClient())).onErrorMap(this::translateException); + public ReactiveIndexOperations indexOps(IndexCoordinates index) { + return new DefaultReactiveIndexOperations(this, index); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#getElasticsearchConverter() - */ @Override - public ElasticsearchConverter getElasticsearchConverter() { - return converter; + public ReactiveIndexOperations indexOps(Class clazz) { + return new DefaultReactiveIndexOperations(this, clazz); } @Override @@ -788,6 +804,20 @@ protected ReactiveElasticsearchClient getClient() { return this.client; } + /** + * Obtain the {@link ReactiveElasticsearchClient.Indices} to operate upon. + * + * @return never {@literal null}. + */ + protected ReactiveElasticsearchClient.Indices getIndicesClient() { + + if (client instanceof ReactiveElasticsearchClient.Indices) { + return (ReactiveElasticsearchClient.Indices) client; + } + + throw new UncategorizedElasticsearchException("No ReactiveElasticsearchClient.Indices implementation available"); + } + // endregion /** diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java new file mode 100644 index 000000000..a4c706c27 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java @@ -0,0 +1,134 @@ +/* + * Copyright 2020 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; + +import reactor.core.publisher.Mono; + +import org.springframework.data.elasticsearch.core.document.Document; + +/** + * Interface defining operations on indexes for the reactive stack. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public interface ReactiveIndexOperations { + + /** + * Create an index. + * + * @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg. + * the index already exist. + */ + Mono create(); + + /** + * Create an index with the specified settings. + * + * @param settings index settings + * @return a {@link Mono} signalling successful operation completion or an {@link Mono#error(Throwable) error} if eg. + * the index already exist. + */ + Mono create(Document settings); + + /** + * Delete an index. + * + * @return a {@link Mono} signalling operation completion or an {@link Mono#error(Throwable) error}. If the index does + * not exist, a value of {@literal false is emitted}. + */ + Mono delete(); + + /** + * checks if an index exists + * + * @return a {@link Mono} with the result of exist check + */ + Mono exists(); + + /** + * Refresh the index(es) this IndexOperations is bound to + * + * @return a {@link Mono} signalling operation completion. + */ + Mono refresh(); + + /** + * Creates the index mapping for the entity this IndexOperations is bound to. + * + * @return mapping object + */ + Mono createMapping(); + + /** + * Creates the index mapping for the given class + * + * @param clazz the clazz to create a mapping for + * @return a {@link Mono} with the mapping document + */ + Mono createMapping(Class clazz); + + /** + * Writes the mapping to the index for the class this IndexOperations is bound to. + * + * @return {@literal true} if the mapping could be stored + */ + default Mono putMapping() { + return putMapping(createMapping()); + } + + /** + * writes a mapping to the index + * + * @param mapping the Document with the mapping definitions + * @return {@literal true} if the mapping could be stored + */ + Mono putMapping(Mono mapping); + + /** + * Creates the index mapping for the given class and writes it to the index. + * + * @param clazz the clazz to create a mapping for + * @return {@literal true} if the mapping could be stored + */ + default Mono putMapping(Class clazz) { + return putMapping(createMapping(clazz)); + } + + /** + * Get mapping for the index targeted defined by this {@link ReactiveIndexOperations} + * + * @return the mapping + */ + Mono getMapping(); + + /** + * get the settings for the index + * + * @return a {@link Mono} with a {@link Document} containing the index settings + */ + default Mono getSettings() { + return getSettings(false); + } + + /** + * get the settings for the index + * + * @param includeDefaults whether or not to include all the default settings + * @return a {@link Mono} with a {@link Document} containing the index settings + */ + Mono getSettings(boolean includeDefaults); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java new file mode 100644 index 000000000..423eaa5fe --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java @@ -0,0 +1,81 @@ +/* + * Copyright 2020 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; + +import reactor.core.publisher.Mono; + +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.buffer.DataBufferUtils; +import org.springframework.core.io.buffer.DefaultDataBufferFactory; + +/** + * Utility to reactively read {@link org.springframework.core.io.Resource}s. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public abstract class ReactiveResourceUtil { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReactiveResourceUtil.class); + private static final int BUFFER_SIZE = 8_192; + + /** + * Read a {@link ClassPathResource} into a {@link reactor.core.publisher.Mono}. + * + * @param url the resource to read + * @return a {@link reactor.core.publisher.Mono} emitting the resources content or an empty Mono on error + */ + public static Mono readFileFromClasspath(String url) { + + return DataBufferUtils + .join(DataBufferUtils.read(new ClassPathResource(url), new DefaultDataBufferFactory(), BUFFER_SIZE)) + . handle((it, sink) -> { + + try (InputStream is = it.asInputStream(); + InputStreamReader in = new InputStreamReader(is, Charset.defaultCharset()); + BufferedReader br = new BufferedReader(in)) { + + StringBuilder sb = new StringBuilder(); + + String line; + while ((line = br.readLine()) != null) { + sb.append(line); + } + + sink.next(sb.toString()); + sink.complete(); + } catch (Exception e) { + LOGGER.debug(String.format("Failed to load file from url: %s: %s", url, e.getMessage())); + sink.complete(); + } finally { + DataBufferUtils.release(it); + } + }).onErrorResume(throwable -> { + LOGGER.debug(String.format("Failed to load file from url: %s: %s", url, throwable.getMessage())); + return Mono.empty(); + }); + } + + // Utility constructor + private ReactiveResourceUtil() {} +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 79c92a446..085a2f1d0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -29,8 +29,11 @@ import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; +import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.bulk.BulkRequest; @@ -52,9 +55,11 @@ import org.elasticsearch.client.Requests; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.geo.GeoDistance; +import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.DistanceUnit; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.VersionType; @@ -246,11 +251,38 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, Bul // endregion // region index management + /** + * creates a CreateIndexRequest from the rest-high-level-client library. + * + * @param index name of the index + * @param settings optional settings + * @return request + */ + @SuppressWarnings("unchecked") public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) { - CreateIndexRequest request = new CreateIndexRequest(index.getIndexName()); - if (settings != null) { + if (settings != null && !settings.isEmpty()) { + request.settings(settings); + } + return request; + } + + /** + * creates a CreateIndexRequest from the elasticsearch library, used by the reactive methods. + * + * @param indexName name of the index + * @param settings optional settings + * @return request + */ + public org.elasticsearch.action.admin.indices.create.CreateIndexRequest createIndexRequestReactive(String indexName, + @Nullable Document settings) { + + org.elasticsearch.action.admin.indices.create.CreateIndexRequest request = new org.elasticsearch.action.admin.indices.create.CreateIndexRequest( + indexName); + request.index(indexName); + + if (settings != null && !settings.isEmpty()) { request.settings(settings); } return request; @@ -268,10 +300,30 @@ public CreateIndexRequestBuilder createIndexRequestBuilder(Client client, IndexC return createIndexRequestBuilder; } + /** + * creates a GetIndexRequest from the rest-high-level-client library. + * + * @param index name of the index + * @return request + */ public GetIndexRequest getIndexRequest(IndexCoordinates index) { return new GetIndexRequest(index.getIndexNames()); } + + /** + * creates a CreateIndexRequest from the elasticsearch library, used by the reactive methods. + * + * @param indexName name of the index + * @return request + */ + public org.elasticsearch.action.admin.indices.get.GetIndexRequest getIndexRequestReactive(String indexName) { + + org.elasticsearch.action.admin.indices.get.GetIndexRequest request = new org.elasticsearch.action.admin.indices.get.GetIndexRequest(); + request.indices(indexName); + return request; + } + public IndicesExistsRequest indicesExistsRequest(IndexCoordinates index) { String[] indexNames = index.getIndexNames(); @@ -303,6 +355,15 @@ public PutMappingRequest putMappingRequest(IndexCoordinates index, Document mapp return request; } + public org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest putMappingRequestReactive( + IndexCoordinates index, Document mapping) { + org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest request = new org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest( + index.getIndexName()); + request.type("not-used-but-must-be-there"); + request.source(mapping); + return request; + } + public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoordinates index, Document mapping) { String[] indexNames = index.getIndexNames(); @@ -312,6 +373,18 @@ public PutMappingRequestBuilder putMappingRequestBuilder(Client client, IndexCoo return requestBuilder; } + public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingRequestReactive( + IndexCoordinates index) { + org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest request = new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest(); + request.indices(index.getIndexName()); + return request; + } + + public GetSettingsRequest getSettingsRequest(String indexName, boolean includeDefaults) { + return new GetSettingsRequest().indices(indexName).includeDefaults(includeDefaults); + } + + public GetMappingsRequest getMappingsRequest(IndexCoordinates index) { String[] indexNames = index.getIndexNames(); @@ -337,11 +410,13 @@ public DeleteByQueryRequest deleteByQueryRequest(DeleteQuery deleteQuery, IndexC .setAbortOnVersionConflict(false) // .setRefresh(true); - if (deleteQuery.getPageSize() != null) + if (deleteQuery.getPageSize() != null) { deleteByQueryRequest.setBatchSize(deleteQuery.getPageSize()); + } - if (deleteQuery.getScrollTimeInMillis() != null) + if (deleteQuery.getScrollTimeInMillis() != null) { deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); + } return deleteByQueryRequest; } @@ -388,8 +463,9 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, De SearchRequestBuilder source = requestBuilder.source(); - if (deleteQuery.getScrollTimeInMillis() != null) + if (deleteQuery.getScrollTimeInMillis() != null) { source.setScroll(TimeValue.timeValueMillis(deleteQuery.getScrollTimeInMillis())); + } return requestBuilder; } @@ -721,7 +797,9 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz request.preference(query.getPreference()); } - request.searchType(query.getSearchType()); + if (query.getSearchType() != null) { + request.searchType(query.getSearchType()); + } prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); @@ -1131,6 +1209,38 @@ private QueryBuilder getFilter(Query query) { return elasticsearchFilter; } + // region response stuff + + /** + * extract the index settings information for a given index + * + * @param response the Elasticsearch response + * @param indexName the index name + * @return settings as {@link Document} + */ + public Document fromSettingsResponse(GetSettingsResponse response, String indexName) { + + Document settings = Document.create(); + + if (!response.getIndexToDefaultSettings().isEmpty()) { + Settings defaultSettings = response.getIndexToDefaultSettings().get(indexName); + for (String key : defaultSettings.keySet()) { + settings.put(key, defaultSettings.get(key)); + } + } + + if (!response.getIndexToSettings().isEmpty()) { + Settings customSettings = response.getIndexToSettings().get(indexName); + for (String key : customSettings.keySet()) { + settings.put(key, customSettings.get(key)); + } + } + + return settings; + } + // endregion + + // region helper functions @Nullable private ElasticsearchPersistentEntity getPersistentEntity(@Nullable Class clazz) { return clazz != null ? elasticsearchConverter.getMappingContext().getPersistentEntity(clazz) : null; @@ -1162,6 +1272,7 @@ private String[] toArray(List values) { String[] valuesAsArray = new String[values.size()]; return values.toArray(valuesAsArray); } + // endregion private boolean hasSeqNoPrimaryTermProperty(@Nullable Class entityClass) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 8f99b528b..073432e17 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -17,6 +17,7 @@ import org.elasticsearch.index.VersionType; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentEntity; import org.springframework.lang.Nullable; @@ -137,4 +138,12 @@ default ElasticsearchPersistentProperty getRequiredSeqNoPrimaryTermProperty() { String.format("Required SeqNoPrimaryTerm property not found for %s!", this.getType())); } } + + /** + * returns the default settings for an index. + * + * @return settings as {@link Document} + * @since 4.1 + */ + Document getDefaultSettings(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java index 462e5a7aa..7c4db5762 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentEntity.java @@ -19,12 +19,13 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; +import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.index.VersionType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Setting; +import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.mapping.MappingException; import org.springframework.data.mapping.PropertyHandler; import org.springframework.data.mapping.model.BasicPersistentEntity; @@ -77,8 +78,9 @@ public SimpleElasticsearchPersistentEntity(TypeInformation typeInformation) { super(typeInformation); Class clazz = typeInformation.getType(); - if (clazz.isAnnotationPresent(Document.class)) { - Document document = clazz.getAnnotation(Document.class); + if (clazz.isAnnotationPresent(org.springframework.data.elasticsearch.annotations.Document.class)) { + org.springframework.data.elasticsearch.annotations.Document document = clazz + .getAnnotation(org.springframework.data.elasticsearch.annotations.Document.class); Assert.hasText(document.indexName(), " Unknown indexName. Make sure the indexName is defined. e.g @Document(indexName=\"foo\")"); this.indexName = document.indexName(); @@ -317,4 +319,19 @@ private String resolve(EvaluationContext context, String name) { return resolvedName != null ? resolvedName : name; } // endregion + + @Override + public Document getDefaultSettings() { + + if (isUseServerConfiguration()) { + return Document.create(); + } + + Map map = new MapBuilder() + .put("index.number_of_shards", String.valueOf(getShards())) + .put("index.number_of_replicas", String.valueOf(getReplicas())) + .put("index.refresh_interval", getRefreshInterval()).put("index.store.type", getIndexStoreType()).map(); + return Document.from(map); + } + } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 9fd0e7e2d..2d5bbd421 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -85,25 +85,18 @@ public SimpleElasticsearchRepository(ElasticsearchEntityInformation metad this.entityInformation = metadata; this.entityClass = this.entityInformation.getJavaType(); this.indexOperations = operations.indexOps(this.entityClass); + try { - if (createIndexAndMapping() && !indexOperations.exists()) { - createIndex(); - putMapping(); + if (shouldCreateIndexAndMapping() && !indexOperations.exists()) { + indexOperations.create(); + indexOperations.putMapping(entityClass); } } catch (Exception exception) { LOGGER.warn("Cannot create index: {}", exception.getMessage()); } } - private void createIndex() { - indexOperations.create(); - } - - private void putMapping() { - indexOperations.putMapping(entityClass); - } - - private boolean createIndexAndMapping() { + private boolean shouldCreateIndexAndMapping() { final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter().getMappingContext() .getRequiredPersistentEntity(entityClass); diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java index d75ed583c..d136e26ec 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepository.java @@ -18,12 +18,18 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.index.query.QueryBuilders; import org.reactivestreams.Publisher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ReactiveIndexOperations; import org.springframework.data.elasticsearch.core.SearchHit; +import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; @@ -39,24 +45,53 @@ */ public class SimpleReactiveElasticsearchRepository implements ReactiveElasticsearchRepository { + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleElasticsearchRepository.class); + private final ElasticsearchEntityInformation entityInformation; - private final ReactiveElasticsearchOperations elasticsearchOperations; + private final ReactiveElasticsearchOperations operations; + private final ReactiveIndexOperations indexOperations; public SimpleReactiveElasticsearchRepository(ElasticsearchEntityInformation entityInformation, - ReactiveElasticsearchOperations elasticsearchOperations) { + ReactiveElasticsearchOperations operations) { Assert.notNull(entityInformation, "EntityInformation must not be null!"); - Assert.notNull(elasticsearchOperations, "ElasticsearchOperations must not be null!"); + Assert.notNull(operations, "ElasticsearchOperations must not be null!"); this.entityInformation = entityInformation; - this.elasticsearchOperations = elasticsearchOperations; + this.operations = operations; + this.indexOperations = operations.indexOps(entityInformation.getJavaType()); + + createIndexAndMappingIfNeeded(); + } + + private void createIndexAndMappingIfNeeded() { + try { + + if (shouldCreateIndexAndMapping()) { + indexOperations.exists() // + .flatMap(exists -> exists ? Mono.empty() : indexOperations.create()) // + .flatMap(success -> success ? indexOperations.putMapping() : Mono.empty()) // + .block(); + } + } catch (Exception exception) { + LOGGER.warn("Cannot create index: {}", exception.getMessage()); + } + } + + private boolean shouldCreateIndexAndMapping() { + + final ElasticsearchPersistentEntity entity = operations.getElasticsearchConverter().getMappingContext() + .getRequiredPersistentEntity(entityInformation.getJavaType()); + return entity.isCreateIndexAndMapping(); } @Override public Mono save(S entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.save(entity, entityInformation.getIndexCoordinates()); + + return operations.save(entity, entityInformation.getIndexCoordinates()) + .flatMap(saved -> doRefresh().thenReturn(saved)); } @Override @@ -71,16 +106,15 @@ public Flux saveAll(Publisher entityStream) { Assert.notNull(entityStream, "EntityStream must not be null!"); - return elasticsearchOperations.saveAll(Flux.from(entityStream).collectList(), - entityInformation.getIndexCoordinates()); + return operations.saveAll(Flux.from(entityStream).collectList(), entityInformation.getIndexCoordinates()) + .concatWith(doRefresh().then(Mono.empty())); } @Override public Mono findById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.get(convertId(id), entityInformation.getJavaType(), - entityInformation.getIndexCoordinates()); + return operations.get(convertId(id), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override @@ -94,8 +128,7 @@ public Mono findById(Publisher id) { public Mono existsById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations.exists(convertId(id), entityInformation.getJavaType(), - entityInformation.getIndexCoordinates()); + return operations.exists(convertId(id), entityInformation.getIndexCoordinates()); } @Override @@ -108,14 +141,14 @@ public Mono existsById(Publisher id) { @Override public Flux findAll() { - return elasticsearchOperations.search(Query.findAll().setPageable(Pageable.unpaged()), - entityInformation.getJavaType(), entityInformation.getIndexCoordinates()).map(SearchHit::getContent); + return operations.search(Query.findAll().setPageable(Pageable.unpaged()), entityInformation.getJavaType(), + entityInformation.getIndexCoordinates()).map(SearchHit::getContent); } @Override public Flux findAll(Sort sort) { - return elasticsearchOperations.search(Query.findAll().addSort(sort).setPageable(Pageable.unpaged()), + return operations.search(Query.findAll().addSort(sort).setPageable(Pageable.unpaged()), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()).map(SearchHit::getContent); } @@ -138,24 +171,22 @@ public Flux findAllById(Publisher idStream) { .flatMapMany(query -> { IndexCoordinates index = entityInformation.getIndexCoordinates(); - return elasticsearchOperations.multiGet(query, entityInformation.getJavaType(), index); + return operations.multiGet(query, entityInformation.getJavaType(), index); }); } @Override public Mono count() { - return elasticsearchOperations.count(Query.findAll(), entityInformation.getJavaType(), - entityInformation.getIndexCoordinates()); + return operations.count(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()); } @Override public Mono deleteById(ID id) { Assert.notNull(id, "Id must not be null!"); - return elasticsearchOperations - .delete(convertId(id), entityInformation.getIndexCoordinates()) // - .then(); + return operations.delete(convertId(id), entityInformation.getIndexCoordinates()) // + .then(doRefresh()); } @Override @@ -169,8 +200,8 @@ public Mono deleteById(Publisher id) { public Mono delete(T entity) { Assert.notNull(entity, "Entity must not be null!"); - return elasticsearchOperations.delete(entity, entityInformation.getIndexCoordinates()) // - .then(); + return operations.delete(entity, entityInformation.getIndexCoordinates()) // + .then(doRefresh()); } @Override @@ -192,29 +223,37 @@ public Mono deleteAll(Publisher entityStream) { throw new IllegalStateException("Entity id must not be null!"); } return convertId(id); - }).collectList().map(objects -> { - - return new StringQuery(QueryBuilders.idsQuery() // - .addIds(objects.toArray(new String[0])) // - .toString()); - }) // - .flatMap(query -> { - - return elasticsearchOperations.delete(query, entityInformation.getJavaType(), - entityInformation.getIndexCoordinates()); - }) // - .then(); + }).collectList().map(objects -> new StringQuery(QueryBuilders.idsQuery() // + .addIds(objects.toArray(new String[0])) // + .toString())) // + .flatMap( + query -> operations.delete(query, entityInformation.getJavaType(), entityInformation.getIndexCoordinates())) // + .then(doRefresh()); } @Override public Mono deleteAll() { - return elasticsearchOperations - .delete(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // - .then(); + return operations.delete(Query.findAll(), entityInformation.getJavaType(), entityInformation.getIndexCoordinates()) // + .then(doRefresh()); } private String convertId(Object id) { - return elasticsearchOperations.getElasticsearchConverter().convertId(id); + return operations.getElasticsearchConverter().convertId(id); + } + + private Mono doRefresh() { + RefreshPolicy refreshPolicy = null; + + if (operations instanceof ReactiveElasticsearchTemplate) { + refreshPolicy = ((ReactiveElasticsearchTemplate) operations).getRefreshPolicy(); + } + + if (refreshPolicy == null || refreshPolicy == RefreshPolicy.NONE) { + return indexOperations.refresh(); + } + + return Mono.empty(); } + } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index 8146ae47d..84e0eb9f9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -497,11 +497,12 @@ public void indexExistsShouldReturnFalseIfNot() throws IOException { .verifyComplete(); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-678 public void createIndex() throws IOException { client.indices().createIndex(request -> request.index(INDEX_I)) // .as(StepVerifier::create) // + .expectNext(true) // .verifyComplete(); assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isTrue(); @@ -517,13 +518,14 @@ public void createExistingIndexErrors() throws IOException { .verifyError(ElasticsearchStatusException.class); } - @Test // DATAES-569 + @Test // DATAES-569, DATAES-678 public void deleteExistingIndex() throws IOException { syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); client.indices().deleteIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // + .expectNext(true) // .verifyComplete(); assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse(); @@ -601,6 +603,7 @@ public void updateMapping() throws IOException { client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // .as(StepVerifier::create) // + .expectNext(true) // .verifyComplete(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index ed6403719..4488ea42a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -847,6 +847,7 @@ void shouldSaveAll() { .expectNext(entity1) // .expectNext(entity2) // .verifyComplete(); + indexOperations.refresh(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); template.search(searchQuery, SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // @@ -979,8 +980,6 @@ public Person(String name, int age) { } } - // TODO: check field mapping !!! - // --> JUST some helpers private SampleEntity randomEntity(String message) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java new file mode 100644 index 000000000..c8d76704d --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java @@ -0,0 +1,358 @@ +/* + * Copyright 2018-2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import lombok.Data; +import reactor.test.StepVerifier; + +import java.time.LocalDate; + +import org.json.JSONException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONCompareMode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.data.annotation.Id; +import org.springframework.data.elasticsearch.annotations.DateFormat; +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.Mapping; +import org.springframework.data.elasticsearch.annotations.Setting; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ReactiveIndexOperationsTest.Config.class }) +public class ReactiveIndexOperationsTest { + + public static final String TESTINDEX = "reactive-index-operations-testindex"; + + @Configuration + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class, ElasticsearchRestTemplateConfiguration.class }) + static class Config {} + + @Autowired private ReactiveElasticsearchOperations operations; + + @BeforeEach + void setUp() { + deleteIndices(); + } + + @AfterEach + void tearDown() { + deleteIndices(); + } + + private void deleteIndices() { + operations.indexOps(IndexCoordinates.of(TESTINDEX + "*")).delete().block(); + } + + @Test // DATAES-678 + void shouldCreateIndexOpsForIndexCoordinates() { + + IndexCoordinates indexCoordinates = IndexCoordinates.of(TESTINDEX); + + ReactiveIndexOperations indexOperations = operations.indexOps(indexCoordinates); + + assertThat(indexOperations).isNotNull(); + } + + @Test // DATAES-678 + void shouldCreateIndexOpsForEntityClass() { + + ReactiveIndexOperations indexOperations = operations.indexOps(Entity.class); + + assertThat(indexOperations).isNotNull(); + } + + @Test // DATAES-678 + void shouldCreateIndexForName() { + + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-create")); + + indexOps.create() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateIndexForEntity() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + indexOps.create() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + + // check the settings from the class annotation + indexOps.getSettings().as(StepVerifier::create).consumeNextWith(settings -> { + assertThat(settings.get("index.number_of_replicas")).isEqualTo("2"); + assertThat(settings.get("index.number_of_shards")).isEqualTo("3"); + assertThat(settings.get("index.refresh_interval")).isEqualTo("4s"); + }).verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateIndexWithGivenSettings() { + + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-create")); + + org.springframework.data.elasticsearch.core.document.Document requiredSettings = org.springframework.data.elasticsearch.core.document.Document + .create(); + requiredSettings.put("index.number_of_replicas", 3); + requiredSettings.put("index.number_of_shards", 4); + requiredSettings.put("index.refresh_interval", "5s"); + + indexOps.create(requiredSettings) // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + + indexOps.getSettings().as(StepVerifier::create).consumeNextWith(settings -> { + assertThat(settings.get("index.number_of_replicas")).isEqualTo("3"); + assertThat(settings.get("index.number_of_shards")).isEqualTo("4"); + assertThat(settings.get("index.refresh_interval")).isEqualTo("5s"); + }).verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateIndexWithAnnotatedSettings() { + + ReactiveIndexOperations indexOps = operations.indexOps(EntityWithAnnotatedSettingsAndMappings.class); + + indexOps.create() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + + indexOps.getSettings().as(StepVerifier::create).consumeNextWith(settings -> { + assertThat(settings.get("index.number_of_replicas")).isEqualTo("0"); + assertThat(settings.get("index.number_of_shards")).isEqualTo("1"); + assertThat(settings.containsKey("index.analysis.analyzer.emailAnalyzer.tokenizer")).isTrue(); + assertThat(settings.get("index.analysis.analyzer.emailAnalyzer.tokenizer")).isEqualTo("uax_url_email"); + }).verifyComplete(); + } + + @Test // DATAES-678 + public void shouldCreateIndexUsingServerDefaultConfiguration() { + + ReactiveIndexOperations indexOps = operations.indexOps(EntityUseServerConfig.class); + + indexOps.create() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + + // check the settings from the class annotation + indexOps.getSettings().as(StepVerifier::create).consumeNextWith(settings -> { + assertThat(settings.get("index.number_of_replicas")).isEqualTo("1"); + assertThat(settings.get("index.number_of_shards")).isEqualTo("1"); + }).verifyComplete(); + } + + @Test // DATAES-678 + void shouldDeleteIfItExists() { + + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-delete")); + indexOps.create().block(); + + indexOps.delete() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldReturnFalseOnDeleteIfItDoesNotExist() { + + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-delete")); + + indexOps.delete() // + .as(StepVerifier::create) // + .expectNext(false) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldReturnExistsTrueIfIndexDoesExist() { + + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-exists")); + indexOps.create().block(); + + indexOps.exists() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldReturnExistsFalseIfIndexDoesNotExist() { + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-exists")); + + indexOps.exists() // + .as(StepVerifier::create) // + .expectNext(false) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateMappingForEntityFromProperties() { + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-mappings")); + + String expected = "{\n" + // + " \"properties\":{\n" + // + " \"text\": {\n" + // + " \"type\": \"text\"\n" + // + " },\n" + // + " \"publication-date\": {\n" + // + " \"type\": \"date\",\n" + // + " \"format\": \"basic_date\"\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + indexOps.createMapping(Entity.class) // + .as(StepVerifier::create) // + .assertNext(document -> { + try { + assertEquals(expected, document.toJson(), JSONCompareMode.NON_EXTENSIBLE); + } catch (JSONException e) { + fail("", e); + } + }) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateMappingForEntityFromMappingAnnotation() { + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(TESTINDEX + "-mappings")); + + String expected = "{\n" + // + " \"properties\": {\n" + // + " \"email\": {\n" + // + " \"type\": \"text\",\n" + // + " \"analyzer\": \"emailAnalyzer\"\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + indexOps.createMapping(EntityWithAnnotatedSettingsAndMappings.class) // + .as(StepVerifier::create) // + .assertNext(document -> { + try { + assertEquals(expected, document.toJson(), JSONCompareMode.NON_EXTENSIBLE); + } catch (JSONException e) { + fail("", e); + } + }) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldCreateMappingBoundEntity() { + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + String expected = "{\n" + // + " \"properties\":{\n" + // + " \"text\": {\n" + // + " \"type\": \"text\"\n" + // + " },\n" + // + " \"publication-date\": {\n" + // + " \"type\": \"date\",\n" + // + " \"format\": \"basic_date\"\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + indexOps.createMapping() // + .as(StepVerifier::create) // + .assertNext(document -> { + try { + assertEquals(expected, document.toJson(), JSONCompareMode.NON_EXTENSIBLE); + } catch (JSONException e) { + fail("", e); + } + }) // + .verifyComplete(); + } + + @Test // DATAES-678 + void shouldPutAndGetMapping() { + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + String expected = "{\n" + // + " \"properties\":{\n" + // + " \"text\": {\n" + // + " \"type\": \"text\"\n" + // + " },\n" + // + " \"publication-date\": {\n" + // + " \"type\": \"date\",\n" + // + " \"format\": \"basic_date\"\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + indexOps.create() // + .then(indexOps.putMapping()) // + .then(indexOps.getMapping()) // + .as(StepVerifier::create) // + .assertNext(document -> { + try { + assertEquals(expected, document.toJson(), JSONCompareMode.NON_EXTENSIBLE); + } catch (JSONException e) { + fail("", e); + } + }).verifyComplete(); + } + + @Data + @Document(indexName = TESTINDEX, shards = 3, replicas = 2, refreshInterval = "4s") + static class Entity { + @Id private String id; + @Field(type = FieldType.Text) private String text; + @Field(name = "publication-date", type = FieldType.Date, + format = DateFormat.basic_date) private LocalDate publicationDate; + } + + @Data + @Document(indexName = TESTINDEX, useServerConfiguration = true) + static class EntityUseServerConfig { + @Id private String id; + } + + @Data + @Document(indexName = TESTINDEX) + @Setting(settingPath = "/settings/test-settings.json") + @Mapping(mappingPath = "/mappings/test-mappings.json") + static class EntityWithAnnotatedSettingsAndMappings { + @Id private String id; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtilTest.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtilTest.java new file mode 100644 index 000000000..a1504cffb --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtilTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2020 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; + +import static org.assertj.core.api.Assertions.*; +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import reactor.test.StepVerifier; + +import org.json.JSONException; +import org.junit.jupiter.api.Test; + +/** + * @author Peter-Josef Meisch + */ +class ReactiveResourceUtilTest { + + @Test + void shouldReadFromClasspath() { + + String expected = "{\n" + // + " \"index\": {\n" + // + " \"number_of_shards\": \"1\",\n" + // + " \"number_of_replicas\": \"0\",\n" + // + " \"analysis\": {\n" + // + " \"analyzer\": {\n" + // + " \"emailAnalyzer\": {\n" + // + " \"type\": \"custom\",\n" + // + " \"tokenizer\": \"uax_url_email\"\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + ReactiveResourceUtil.readFileFromClasspath("/settings/test-settings.json") // + .as(StepVerifier::create) // + .consumeNextWith(actual -> { + try { + assertEquals(expected, actual, false); + } catch (JSONException e) { + fail("", e); + } + }) // + .verifyComplete(); + + } + + @Test + void shouldReturnEmptyMonoOnNonExistingResource() { + ReactiveResourceUtil.readFileFromClasspath("/this/should/really/not/exist") // + .as(StepVerifier::create) // + .verifyComplete(); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index d0c517305..05c2bed0f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -48,7 +48,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.reactivestreams.Publisher; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -59,7 +58,6 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.TestUtils; -import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Highlight; @@ -359,11 +357,11 @@ public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); } - @Test // DATAES-519, DATAES-767, DATAES-822 - public void deleteByIdShouldErrorWhenIndexDoesNotExist() { + @Test // DATAES-519, DATAES-767, DATAES-822, DATAES-678 + public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { repository.deleteById("does-not-exist") // .as(StepVerifier::create) // - .verifyError(UncategorizedElasticsearchException.class); + .verifyComplete(); } @Test // DATAES-519 From 1de1aeb2c7ec80580cb2b4b1d98b724277862463 Mon Sep 17 00:00:00 2001 From: Been24 <33019455+Been24@users.noreply.github.com> Date: Wed, 17 Jun 2020 00:46:07 +0800 Subject: [PATCH 0196/1191] DATAES - 865 - Fix MappingElasticsearchConverter writing an Object property containing a Map. Original PR: #482 --- .../core/convert/MappingElasticsearchConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 4d85bda96..077975cf1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -596,7 +596,7 @@ private Object writeMapValue(Map value, ElasticsearchPersistentP Map target = new LinkedHashMap<>(); Streamable> mapSource = Streamable.of(value.entrySet()); - if (!typeHint.getActualType().getType().equals(Object.class) + if (typeHint.getActualType() != null && !typeHint.getActualType().getType().equals(Object.class) && isSimpleType(typeHint.getMapValueType().getType())) { mapSource.forEach(it -> { From 92f16846abaf7266de1e9669aadd3bd24f5b64a1 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 16 Jun 2020 18:57:38 +0200 Subject: [PATCH 0197/1191] DATAES-865 - Polishing. --- .../MappingElasticsearchConverter.java | 4 ++- ...appingElasticsearchConverterUnitTests.java | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 077975cf1..21092c010 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -596,7 +596,9 @@ private Object writeMapValue(Map value, ElasticsearchPersistentP Map target = new LinkedHashMap<>(); Streamable> mapSource = Streamable.of(value.entrySet()); - if (typeHint.getActualType() != null && !typeHint.getActualType().getType().equals(Object.class) + TypeInformation actualType = typeHint.getActualType(); + + if (actualType != null && !actualType.getType().equals(Object.class) && isSimpleType(typeHint.getMapValueType().getType())) { mapSource.forEach(it -> { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java index 2ae0e2304..56ccb761f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverterUnitTests.java @@ -789,6 +789,30 @@ void shouldReadEntityWithListOfGeoPoints() { assertThat(entity.locations).containsExactly(new GeoPoint(12.34, 23.45), new GeoPoint(34.56, 45.67)); } + @Test // DATAES-865 + void shouldWriteEntityWithMapAsObject() throws JSONException { + + Map map = new LinkedHashMap<>(); + map.put("foo", "bar"); + + EntityWithObject entity = new EntityWithObject(); + entity.setId("42"); + entity.setContent(map); + + String expected = "{\n" + // + " \"id\": \"42\",\n" + // + " \"content\": {\n" + // + " \"foo\": \"bar\"\n" + // + " }\n" + // + "}\n"; // + + Document document = Document.create(); + + mappingElasticsearchConverter.write(entity, document); + + assertEquals(expected, document.toJson(), false); + } + private String pointTemplate(String name, Point point) { return String.format(Locale.ENGLISH, "\"%s\":{\"lat\":%.1f,\"lon\":%.1f}", name, point.getX(), point.getY()); } @@ -1016,4 +1040,10 @@ static class GeoPointListEntity { @Id String id; List locations; } + + @Data + static class EntityWithObject { + @Id private String id; + private Object content; + } } From 9bf1c094576e437fb8b105cf115ac77fc44e3040 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 19 Jun 2020 14:43:53 +0200 Subject: [PATCH 0198/1191] DATAES-867 - Adopt to changes in Reactor Netty 1.0. Move to HttpClient configuration API instead of using TcpClient. --- .../DefaultReactiveElasticsearchClient.java | 17 ++++++++--------- .../elasticsearch/client/RestClientsTest.java | 8 +++++--- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 5e8e688e8..e7dc921fc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -27,8 +27,7 @@ import reactor.core.publisher.FluxSink; import reactor.core.publisher.Mono; import reactor.netty.http.client.HttpClient; -import reactor.netty.tcp.ProxyProvider; -import reactor.netty.tcp.TcpClient; +import reactor.netty.transport.ProxyProvider; import java.io.IOException; import java.lang.reflect.Method; @@ -98,6 +97,7 @@ import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; import org.reactivestreams.Publisher; + import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; import org.springframework.data.elasticsearch.client.ElasticsearchHost; @@ -239,14 +239,14 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client Duration connectTimeout = clientConfiguration.getConnectTimeout(); Duration soTimeout = clientConfiguration.getSocketTimeout(); - TcpClient tcpClient = TcpClient.create(); + HttpClient httpClient = HttpClient.create(); if (!connectTimeout.isNegative()) { - tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis())); + httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis())); } if (!soTimeout.isNegative()) { - tcpClient = tcpClient.doOnConnected(connection -> connection // + httpClient = httpClient.doOnConnected(connection -> connection // .addHandlerLast(new ReadTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS)) .addHandlerLast(new WriteTimeoutHandler(soTimeout.toMillis(), TimeUnit.MILLISECONDS))); } @@ -258,12 +258,11 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client if (hostPort.length != 2) { throw new IllegalArgumentException("invalid proxy configuration " + proxy + ", should be \"host:port\""); } - tcpClient = tcpClient.proxy(proxyOptions -> proxyOptions.type(ProxyProvider.Proxy.HTTP).host(hostPort[0]) + httpClient = httpClient.proxy(proxyOptions -> proxyOptions.type(ProxyProvider.Proxy.HTTP).host(hostPort[0]) .port(Integer.parseInt(hostPort[1]))); } String scheme = "http"; - HttpClient httpClient = HttpClient.from(tcpClient); if (clientConfiguration.useSsl()) { @@ -839,7 +838,7 @@ private Publisher handleClientError(String logId, Request reque /** * checks if the given content body contains an {@link ElasticsearchException}, if yes it is returned in a Mono.error. * Otherwise the content is returned in the Mono - * + * * @param content the content to analyze * @param mediaType the returned media type * @param status the response status @@ -860,7 +859,7 @@ private static Mono contentOrError(String content, String mediaType, Res /** * tries to parse an {@link ElasticsearchException} from the given body content - * + * * @param content the content to analyse * @param mediaType the type of the body content * @return an {@link ElasticsearchException} or {@literal null}. diff --git a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java index 23f3a5704..0fcd8340b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/RestClientsTest.java @@ -11,6 +11,7 @@ import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -26,6 +27,7 @@ /** * @author Peter-Josef Meisch */ +@Disabled("SocketException: Socket closed happens on the CLI build while running the test individually succeeds") public class RestClientsTest { @ParameterizedTest // DATAES-700 @@ -125,7 +127,7 @@ default void accept(WireMockServer wiremockConsumer) { /** * starts a Wiremock server and calls consumer with the server as argument. Stops the server after consumer execution. - * + * * @param consumer the consumer */ private void wireMockServer(WiremockConsumer consumer) { @@ -147,7 +149,7 @@ private void wireMockServer(WiremockConsumer consumer) { interface ClientUnderTest { /** * Pings the configured server. - * + * * @return */ boolean ping() throws Exception; @@ -215,7 +217,7 @@ public boolean ping() throws Exception { /** * Provides the factories to use in the parameterized tests - * + * * @return stream of factories */ static Stream clientUnderTestFactorySource() { From d428db704e60191bdcca6887ff49612e5b7c7e6c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Fri, 19 Jun 2020 14:51:07 +0200 Subject: [PATCH 0199/1191] DATAES-868 - Upgrade to Netty 4.1.50.Final. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5bb3b77f..b78b67e0e 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 7.7.1 2.9.1 2.4.0-SNAPSHOT - 4.1.39.Final + 4.1.50.Final spring.data.elasticsearch From 7cd871a4197dd184f37148744c3fe5ae5d2379f7 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 21 Jun 2020 17:06:15 +0200 Subject: [PATCH 0200/1191] DATAES-870 - Workaround for reactor-netty error. Original PR: #484 --- .../client/reactive/DefaultReactiveElasticsearchClient.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index e7dc921fc..aa1afc410 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -239,7 +239,11 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client Duration connectTimeout = clientConfiguration.getConnectTimeout(); Duration soTimeout = clientConfiguration.getSocketTimeout(); - HttpClient httpClient = HttpClient.create(); + // DATAES-870: previously: HttpClient httpClient = HttpClient.create(); + // disable pooling of connections (see https://github.com/spring-projects/spring-framework/issues/22464) + // otherwise we get errors: "Connection prematurely closed BEFORE response; nested exception is + // java.lang.RuntimeException: Connection prematurely closed BEFORE response" + HttpClient httpClient = HttpClient.newConnection().compress(true); if (!connectTimeout.isNegative()) { httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis())); From 36f09078814643a52f60a1f3e0370c8a3d4362cc Mon Sep 17 00:00:00 2001 From: zh32 Date: Sun, 21 Jun 2020 17:24:53 +0200 Subject: [PATCH 0201/1191] DATAES-866 - Implement suggest query in reactive client. Original PR: #483 --- .../DefaultReactiveElasticsearchClient.java | 8 +++++ .../reactive/ReactiveElasticsearchClient.java | 23 +++++++++++++++ .../core/ReactiveElasticsearchTemplate.java | 20 +++++++++++++ .../core/ReactiveSearchOperations.java | 21 ++++++++++++++ .../ReactiveElasticsearchClientTests.java | 29 +++++++++++++++++++ 5 files changed, 101 insertions(+) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index aa1afc410..975bdf999 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -96,6 +96,7 @@ import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHits; import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.suggest.Suggest; import org.reactivestreams.Publisher; import org.springframework.data.elasticsearch.client.ClientConfiguration; @@ -132,6 +133,7 @@ * @author Henrique Amaral * @author Roman Puchkovskiy * @author Russell Parry + * @author Thomas Geese * @since 3.2 * @see ClientConfiguration * @see ReactiveRestClients @@ -890,6 +892,12 @@ private static ElasticsearchException getElasticsearchException(String content, } } + @Override + public Flux suggest(HttpHeaders headers, SearchRequest searchRequest) { + return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // + .map(SearchResponse::getSuggest); + } + private static void buildExceptionMessages(StringBuilder sb, Throwable t) { sb.append(t.getMessage()); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 193390733..6c09f685b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -52,6 +52,7 @@ import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.suggest.Suggest; import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.http.HttpHeaders; @@ -67,6 +68,7 @@ * @author Mark Paluch * @author Peter-Josef Meisch * @author Henrique Amaral + * @author Thomas Geese * @since 3.2 * @see ClientConfiguration * @see ReactiveRestClients @@ -417,6 +419,27 @@ default Flux search(SearchRequest searchRequest) { */ Flux search(HttpHeaders headers, SearchRequest searchRequest); + /** + * Execute the given {@link SearchRequest} against the {@literal search} API. + * + * @param searchRequest must not be {@literal null}. + * @return the {@link Flux} emitting {@link Suggest suggestions} one by one. + * @since 4.1 + */ + default Flux suggest(SearchRequest searchRequest) { + return suggest(HttpHeaders.EMPTY, searchRequest); + } + + /** + * Execute the given {@link SearchRequest} against the {@literal search} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param searchRequest must not be {@literal null}. + * @return the {@link Flux} emitting {@link Suggest suggestions} one by one. + * @since 4.1 + */ + Flux suggest(HttpHeaders headers, SearchRequest searchRequest); + /** * Execute the given {@link SearchRequest} with aggregations against the {@literal search} API. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index dbb401e90..a03d4b351 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -41,6 +41,8 @@ import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.suggest.Suggest; +import org.elasticsearch.search.suggest.SuggestBuilder; import org.reactivestreams.Publisher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -90,6 +92,7 @@ * @author Aleksei Arsenev * @author Roman Puchkovskiy * @author Russell Parry + * @author Thomas Geese * @since 3.2 */ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations, ApplicationContextAware { @@ -640,6 +643,23 @@ public Flux aggregate(Query query, Class entityType, IndexCoordi return doAggregate(query, entityType, index); } + @Override + public Flux suggest(SuggestBuilder suggestion, Class entityType) { + return suggest(suggestion, getIndexCoordinatesFor(entityType)); + } + + @Override + public Flux suggest(SuggestBuilder suggestion, IndexCoordinates index) { + return doSuggest(suggestion, index); + } + + private Flux doSuggest(SuggestBuilder suggestion, IndexCoordinates index) { + return Flux.defer(() -> { + SearchRequest request = requestFactory.searchRequest(suggestion, index); + return Flux.from(execute(client -> client.suggest(request))); + }); + } + private Flux doAggregate(Query query, Class entityType, IndexCoordinates index) { return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, entityType, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java index 47eada0de..18127c3e9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveSearchOperations.java @@ -20,6 +20,8 @@ import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.aggregations.Aggregation; +import org.elasticsearch.search.suggest.Suggest; +import org.elasticsearch.search.suggest.SuggestBuilder; import org.springframework.data.domain.Pageable; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.Query; @@ -32,6 +34,7 @@ * * @author Peter-Josef Meisch * @author Russell Parry + * @author Thomas Geese * @since 4.0 */ public interface ReactiveSearchOperations { @@ -206,4 +209,22 @@ default Flux> search(Query query, Class entityType, IndexCoo * @since 4.0 */ Flux aggregate(Query query, Class entityType, IndexCoordinates index); + + /** + * Does a suggest query + * + * @param suggestion the query + * @param entityType must not be {@literal null}. + * @return the suggest response + */ + Flux suggest(SuggestBuilder suggestion, Class entityType); + + /** + * Does a suggest query + * + * @param suggestion the query + * @param index the index to run the query against + * @return the suggest response + */ + Flux suggest(SuggestBuilder suggestion, IndexCoordinates index); } diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index 84e0eb9f9..218384119 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -53,6 +53,8 @@ import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.StringTerms; import org.elasticsearch.search.builder.SearchSourceBuilder; +import org.elasticsearch.search.suggest.SuggestBuilder; +import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -71,6 +73,7 @@ * @author Peter-Josef Meisch * @author Henrique Amaral * @author Russell Parry + * @author Thomas Geese */ @SpringIntegrationTest @ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @@ -681,6 +684,32 @@ public void aggregateReturnsAggregationResults() throws IOException { .expectNextMatches(aggregation -> aggregation.getType().equals(StringTerms.NAME)).verifyComplete(); } + @Test // DATAES-866 + public void suggestReturnsSuggestionResults() throws IOException { + syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + Map jsonMap = Collections.singletonMap("properties", + Collections.singletonMap("firstname", Collections.singletonMap("type", "completion"))); + syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); + + addSourceDocument().ofType(TYPE_I).to(INDEX_I); + + SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion( + "firstname", + new CompletionSuggestionBuilder("firstname").prefix("ch") + ); + + SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); + searchSourceBuilder.suggest(suggestBuilder); + + SearchRequest request = new SearchRequest(INDEX_I) // + .source(searchSourceBuilder); + + client + .suggest(request).as(StepVerifier::create).expectNextMatches(suggestions -> suggestions + .getSuggestion("firstname").getEntries().get(0).getOptions().get(0).getText().string().equals("chade")) + .verifyComplete(); + } + private AddToIndexOfType addSourceDocument() { return add(DOC_SOURCE); } From 6332534ea1a383d7fda659395aa69977b274d6b5 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 21 Jun 2020 19:41:28 +0200 Subject: [PATCH 0202/1191] DATAES-866 - Polishing. --- .../DefaultReactiveElasticsearchClient.java | 1 - .../reactive/ReactiveElasticsearchClient.java | 14 ++++++++++++++ .../core/ReactiveElasticsearchTemplate.java | 2 +- .../reactive/ReactiveElasticsearchClientTests.java | 6 ++---- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 975bdf999..1da705115 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -98,7 +98,6 @@ import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.suggest.Suggest; import org.reactivestreams.Publisher; - import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; import org.springframework.data.elasticsearch.client.ElasticsearchHost; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 6c09f685b..afa2352ef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -419,6 +419,20 @@ default Flux search(SearchRequest searchRequest) { */ Flux search(HttpHeaders headers, SearchRequest searchRequest); + /** + * Execute the given {@link SearchRequest} against the {@literal search} API. + * + * @param consumer never {@literal null}. + * @return the {@link Flux} emitting {@link Suggest suggestions} one by one. + * @since 4.1 + */ + default Flux suggest(Consumer consumer) { + + SearchRequest request = new SearchRequest(); + consumer.accept(request); + return suggest(request); + } + /** * Execute the given {@link SearchRequest} against the {@literal search} API. * diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index a03d4b351..0b4de71c8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -645,7 +645,7 @@ public Flux aggregate(Query query, Class entityType, IndexCoordi @Override public Flux suggest(SuggestBuilder suggestion, Class entityType) { - return suggest(suggestion, getIndexCoordinatesFor(entityType)); + return doSuggest(suggestion, getIndexCoordinatesFor(entityType)); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index 218384119..b5bc533a6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -693,10 +693,8 @@ public void suggestReturnsSuggestionResults() throws IOException { addSourceDocument().ofType(TYPE_I).to(INDEX_I); - SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion( - "firstname", - new CompletionSuggestionBuilder("firstname").prefix("ch") - ); + SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("firstname", + new CompletionSuggestionBuilder("firstname").prefix("ch")); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); searchSourceBuilder.suggest(suggestBuilder); From 5b1e179e885ee1d9e7dab33e7f3eb963391f9b96 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 23 Jun 2020 09:01:10 +0200 Subject: [PATCH 0203/1191] DATAES-870 - Polishing. Simplify single-node flow. --- .../reactive/SingleNodeHostProvider.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java index eae140c90..77679e2fc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java @@ -15,7 +15,6 @@ */ package org.springframework.data.elasticsearch.client.reactive; -import org.springframework.http.HttpHeaders; import reactor.core.publisher.Mono; import java.net.InetSocketAddress; @@ -25,6 +24,7 @@ import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.ElasticsearchHost.State; import org.springframework.data.elasticsearch.client.NoReachableHostException; +import org.springframework.http.HttpHeaders; import org.springframework.web.reactive.function.client.WebClient; /** @@ -60,20 +60,20 @@ public Mono clusterInfo() { .head().uri("/") .headers(httpHeaders -> httpHeaders.addAll(headersSupplier.get())) // .exchange() // - .flatMap(it -> { + .map(it -> { if (it.statusCode().isError()) { state = ElasticsearchHost.offline(endpoint); } else { state = ElasticsearchHost.online(endpoint); } - return Mono.just(state); + return state; }).onErrorResume(throwable -> { state = ElasticsearchHost.offline(endpoint); clientProvider.getErrorListener().accept(throwable); return Mono.just(state); }) // - .flatMap(it -> Mono.just(new ClusterInformation(Collections.singleton(it)))); + .map(it -> new ClusterInformation(Collections.singleton(it))); } /* @@ -96,14 +96,16 @@ public Mono lookupActiveHost(Verification verification) { return Mono.just(endpoint); } - return clusterInfo().flatMap(it -> { + return clusterInfo().handle((information, sink) -> { - ElasticsearchHost host = it.getNodes().iterator().next(); + ElasticsearchHost host = information.getNodes().iterator().next(); if (host.isOnline()) { - return Mono.just(host.getEndpoint()); + + sink.next(host.getEndpoint()); + return; } - return Mono.error(() -> new NoReachableHostException(Collections.singleton(host))); + sink.error(new NoReachableHostException(Collections.singleton(host))); }); } From 011d2d574057543235a57a6a00de639a29ddfe34 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 23 Jun 2020 09:25:08 +0200 Subject: [PATCH 0204/1191] DATAES-870 - Consume response body to release connection directly. We now ensure that response bodies from ClientResponse get released as part of our result handling. This is to prevent cancel signals issuing the connection release so that the connection release can be synchronized (awaited) before any subsequent requests get issued. Connection release should be part of the Framework but the fallback interferes with Reactor Netty's HttpClient therefore we're ensuring proper resource disposal. --- .../reactive/DefaultReactiveElasticsearchClient.java | 12 ++++-------- .../client/reactive/MultiNodeHostProvider.java | 11 ++++++----- .../client/reactive/RawActionResponse.java | 12 +++++++++++- .../client/reactive/SingleNodeHostProvider.java | 4 ++-- .../reactive/MultiNodeHostProviderUnitTests.java | 2 ++ .../reactive/ReactiveMockClientTestsUtils.java | 1 + 6 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 1da705115..a4f6555c5 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -240,11 +240,7 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client Duration connectTimeout = clientConfiguration.getConnectTimeout(); Duration soTimeout = clientConfiguration.getSocketTimeout(); - // DATAES-870: previously: HttpClient httpClient = HttpClient.create(); - // disable pooling of connections (see https://github.com/spring-projects/spring-framework/issues/22464) - // otherwise we get errors: "Connection prematurely closed BEFORE response; nested exception is - // java.lang.RuntimeException: Connection prematurely closed BEFORE response" - HttpClient httpClient = HttpClient.newConnection().compress(true); + HttpClient httpClient = HttpClient.create().compress(true); if (!connectTimeout.isNegative()) { httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.toIntExact(connectTimeout.toMillis())); @@ -305,7 +301,7 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client public Mono ping(HttpHeaders headers) { return sendRequest(new MainRequest(), requestCreator.ping(), RawActionResponse.class, headers) // - .map(response -> response.statusCode().is2xxSuccessful()) // + .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // .onErrorResume(NoReachableHostException.class, error -> Mono.just(false)).next(); } @@ -355,7 +351,7 @@ public Flux multiGet(HttpHeaders headers, MultiGetRequest multiGetReq public Mono exists(HttpHeaders headers, GetRequest getRequest) { return sendRequest(getRequest, requestCreator.exists(), RawActionResponse.class, headers) // - .map(response -> response.statusCode().is2xxSuccessful()) // + .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // .next(); } @@ -555,7 +551,7 @@ public Mono bulk(HttpHeaders headers, BulkRequest bulkRequest) { public Mono existsIndex(HttpHeaders headers, GetIndexRequest request) { return sendRequest(request, requestCreator.indexExists(), RawActionResponse.class, headers) // - .map(response -> response.statusCode().is2xxSuccessful()) // + .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // .next(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java index cac75f0b1..86e65ffd9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProvider.java @@ -15,7 +15,6 @@ */ package org.springframework.data.elasticsearch.client.reactive; -import org.springframework.http.HttpHeaders; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -33,6 +32,7 @@ import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.ElasticsearchHost.State; import org.springframework.data.elasticsearch.client.NoReachableHostException; +import org.springframework.http.HttpHeaders; import org.springframework.lang.Nullable; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.WebClient; @@ -121,15 +121,15 @@ private Mono findActiveForSate(State state) { .map(ElasticsearchHost::getEndpoint).next(); } - private ElasticsearchHost updateNodeState(Tuple2 tuple2) { + private ElasticsearchHost updateNodeState(Tuple2 tuple2) { - State state = tuple2.getT2().statusCode().isError() ? State.OFFLINE : State.ONLINE; + State state = tuple2.getT2(); ElasticsearchHost elasticsearchHost = new ElasticsearchHost(tuple2.getT1(), state); hosts.put(tuple2.getT1(), elasticsearchHost); return elasticsearchHost; } - private Flux> nodes(@Nullable State state) { + private Flux> nodes(@Nullable State state) { return Flux.fromIterable(hosts()) // .filter(entry -> state == null || entry.getState().equals(state)) // @@ -144,7 +144,8 @@ private Flux> nodes(@Nullable State st clientProvider.getErrorListener().accept(throwable); }); - return Mono.just(host).zipWith(exchange); + return Mono.just(host).zipWith(exchange + .flatMap(it -> it.releaseBody().thenReturn(it.statusCode().isError() ? State.OFFLINE : State.ONLINE))); }) // .onErrorContinue((throwable, o) -> clientProvider.getErrorListener().accept(throwable)); } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java index c763ca7b0..424907fa2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RawActionResponse.java @@ -15,11 +15,12 @@ */ package org.springframework.data.elasticsearch.client.reactive; -import org.elasticsearch.common.io.stream.StreamOutput; +import reactor.core.publisher.Mono; import java.io.IOException; import org.elasticsearch.action.ActionResponse; +import org.elasticsearch.common.io.stream.StreamOutput; import org.springframework.http.HttpStatus; import org.springframework.http.client.reactive.ClientHttpResponse; @@ -73,4 +74,13 @@ public T body(BodyExtractor extractor) { @Override public void writeTo(StreamOutput out) throws IOException { } + + /** + * Ensure the response body is released to properly release the underlying connection. + * + * @return + */ + public Mono releaseBody() { + return delegate.releaseBody(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java index 77679e2fc..253ea5bfc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/SingleNodeHostProvider.java @@ -60,13 +60,13 @@ public Mono clusterInfo() { .head().uri("/") .headers(httpHeaders -> httpHeaders.addAll(headersSupplier.get())) // .exchange() // - .map(it -> { + .flatMap(it -> { if (it.statusCode().isError()) { state = ElasticsearchHost.offline(endpoint); } else { state = ElasticsearchHost.online(endpoint); } - return state; + return it.releaseBody().thenReturn(state); }).onErrorResume(throwable -> { state = ElasticsearchHost.offline(endpoint); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java index 830c69de4..1b2f89ea8 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/MultiNodeHostProviderUnitTests.java @@ -117,9 +117,11 @@ public void triesDeadHostsIfNoActiveFound() { mock.when(HOST_2).get(requestHeadersUriSpec -> { ClientResponse response1 = mock(ClientResponse.class); + when(response1.releaseBody()).thenReturn(Mono.empty()); Receive.error(response1); ClientResponse response2 = mock(ClientResponse.class); + when(response2.releaseBody()).thenReturn(Mono.empty()); Receive.ok(response2); when(requestHeadersUriSpec.exchange()).thenReturn(Mono.just(response1), Mono.just(response2)); diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java index 6fedf27a5..7fc1e5ca4 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveMockClientTestsUtils.java @@ -243,6 +243,7 @@ public WebClient get(InetSocketAddress endpoint) { Mockito.when(headersUriSpec.exchange()).thenReturn(Mono.just(response)); Mockito.when(bodySpy.exchange()).thenReturn(Mono.just(response)); Mockito.when(response.statusCode()).thenReturn(HttpStatus.ACCEPTED); + Mockito.when(response.releaseBody()).thenReturn(Mono.empty()); headersUriSpecMap.putIfAbsent(key, headersUriSpec); bodyUriSpecMap.putIfAbsent(key, bodySpy); From 604f23384bace920a37657018aa8becac68ea358 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 Jun 2020 11:48:17 +0200 Subject: [PATCH 0205/1191] DATAES-824 - Updated changelog. --- src/main/resources/changelog.txt | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 5eac8b3bd..0a5f2ded8 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,42 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.1.0-M1 (2020-06-25) +---------------------------------------- +* DATAES-870 - Workaround for reactor-netty error. +* DATAES-868 - Upgrade to Netty 4.1.50.Final. +* DATAES-867 - Adopt to changes in Reactor Netty 1.0. +* DATAES-866 - Implement suggest search in reactive client. +* DATAES-865 - Fix MappingElasticsearchConverter writing an Object property containing a Map. +* DATAES-863 - Improve server error response handling. +* DATAES-859 - Don't use randomNumeric() in tests. +* DATAES-858 - Use standard Spring code of conduct. +* DATAES-857 - Registered simple types are not read from list. +* DATAES-853 - Cleanup tests that do not delete test indices. +* DATAES-852 - Upgrade to Elasticsearch 7.7.1. +* DATAES-850 - Add warning and documentation for missing TemporalAccessor configuration. +* DATAES-848 - Add the name of the index to SearchHit. +* DATAES-847 - Add missing DateFormat values. +* DATAES-845 - MappingElasticsearchConverter crashes when writing lists containing null values. +* DATAES-844 - Improve TOC formatting for migration guides. +* DATAES-841 - Remove deprecated type mappings code. +* DATAES-840 - Consolidate index name SpEL resolution. +* DATAES-839 - ReactiveElasticsearchTemplate should use RequestFactory. +* DATAES-838 - Update to Elasticsearch 7.7.0. +* DATAES-836 - Fix typo in Javadocs. +* DATAES-835 - Fix code sample in documentation for scroll API. +* DATAES-832 - findAllById repository method returns iterable with null elements for not found ids. +* DATAES-831 - SearchOperations.searchForStream does not use requested maxResults. +* DATAES-829 - Deprecate AbstractElasticsearchRepository and cleanup SimpleElasticsearchRepository. +* DATAES-828 - Fields of type date need to have a format defined. +* DATAES-827 - Repositories should not try to create an index when it already exists. +* DATAES-826 - Add method to IndexOperations to write an index mapping from a entity class. +* DATAES-825 - Update readme to use latest spring.io docs. +* DATAES-824 - Release 4.1 M1 (2020.0.0). +* DATAES-678 - Introduce ReactiveIndexOperations. +* DATAES-263 - Inner Hits support. + + Changes in version 4.0.1.RELEASE (2020-06-10) --------------------------------------------- * DATAES-857 - Registered simple types are not read from list. @@ -1173,3 +1209,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 223ff411452df28cde7a0f9e0411443f657e8756 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 Jun 2020 11:48:20 +0200 Subject: [PATCH 0206/1191] DATAES-824 - Prepare 4.1 M1 (2020.0.0). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index b78b67e0e..c8f3b56fd 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.4.0-SNAPSHOT + 2.4.0-M1 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.7.1 2.9.1 - 2.4.0-SNAPSHOT + 2.4.0-M1 4.1.50.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 47e942ed4..19bc47157 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.0 GA +Spring Data Elasticsearch 4.1 M1 (2020.0.0) Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -15,3 +15,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From db2a6b84a91b8a56d77fc510dc2f5b4596d0cd9e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 Jun 2020 11:48:51 +0200 Subject: [PATCH 0207/1191] DATAES-824 - Release version 4.1 M1 (2020.0.0). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c8f3b56fd..fac303cbc 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.1.0-SNAPSHOT + 4.1.0-M1 org.springframework.data.build From ef836cb0388d063bf8c6eebf199b5b0a9b231233 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 Jun 2020 11:58:21 +0200 Subject: [PATCH 0208/1191] DATAES-824 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fac303cbc..c8f3b56fd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.1.0-M1 + 4.1.0-SNAPSHOT org.springframework.data.build From c6b227602995092757a422c8afd93f91b39d1cb9 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Thu, 25 Jun 2020 11:58:24 +0200 Subject: [PATCH 0209/1191] DATAES-824 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index c8f3b56fd..b78b67e0e 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.4.0-M1 + 2.4.0-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.7.1 2.9.1 - 2.4.0-M1 + 2.4.0-SNAPSHOT 4.1.50.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 44a669d66c8289fef146c3cab56a1c03d0050812 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 25 Jun 2020 21:57:47 +0200 Subject: [PATCH 0210/1191] DATAES-864 - Rework alias management. Original PR: #486 --- ...elasticsearch-migration-guide-4.0-4.1.adoc | 4 + .../DefaultReactiveElasticsearchClient.java | 225 +++++++++--------- .../reactive/ReactiveElasticsearchClient.java | 71 ++++++ .../client/reactive/RequestCreator.java | 12 + .../client/util/RequestConverters.java | 29 +++ .../core/AbstractDefaultIndexOperations.java | 30 ++- .../core/DefaultIndexOperations.java | 20 ++ .../core/DefaultReactiveIndexOperations.java | 48 +++- .../core/DefaultTransportIndexOperations.java | 29 ++- .../elasticsearch/core/IndexOperations.java | 73 +++++- .../core/ReactiveIndexOperations.java | 53 +++++ .../elasticsearch/core/RequestFactory.java | 130 +++++++++- .../core/client/support/AliasData.java | 55 ----- .../core/client/support/package-info.java | 3 - .../elasticsearch/core/index/AliasAction.java | 72 ++++++ .../core/index/AliasActionParameters.java | 167 +++++++++++++ .../core/index/AliasActions.java | 63 +++++ .../elasticsearch/core/index/AliasData.java | 80 +++++++ .../core/index/package-info.java | 3 + .../core/query/AliasBuilder.java | 2 + .../elasticsearch/core/query/AliasQuery.java | 3 + .../core/ElasticsearchTemplateTests.java | 57 ++++- .../core/ReactiveIndexOperationsTest.java | 45 ++++ .../core/RequestFactoryTests.java | 125 ++++++++++ 24 files changed, 1194 insertions(+), 205 deletions(-) delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java delete mode 100644 src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/AliasAction.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/AliasActions.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/AliasData.java diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index fbe2009b8..9f4c1fc45 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -11,9 +11,13 @@ It is possible to define a property of en entity as the id property by naming it This behaviour is now deprecated and will produce a warning. PLease us the `@Id` annotation to mark a property as being the id property. +.Index mappings In the `ReactiveElasticsearchClient.Indices` interface the `updateMapping` methods are deprecated in favour of the `putMapping` methods. They do the same, but `putMapping` is consistent with the naming in the Elasticsearch API: +.Alias handling +In the `IndexOperations` interface the methods `addAlias(AliasQuery)`, `removeAlias(AliasQuery)` and `queryForAlias()` have been deprecated. The new methods `alias(AliasAction)`, `getAliases(String...)` and `getAliasesForIndex(String...)` offer more functionality and a cleaner API. + [[elasticsearch-migration-guide-4.0-4.1.removal]] == Removals diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index a4f6555c5..c5edd1e71 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -48,6 +48,8 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.ActionRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -82,6 +84,7 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.Request; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.DeprecationHandler; @@ -169,13 +172,6 @@ public DefaultReactiveElasticsearchClient(HostProvider hostProvider, RequestCrea this.requestCreator = requestCreator; } - public void setHeadersSupplier(Supplier headersSupplier) { - - Assert.notNull(headersSupplier, "headersSupplier must not be null"); - - this.headersSupplier = headersSupplier; - } - /** * Create a new {@link DefaultReactiveElasticsearchClient} aware of the given nodes in the cluster.
* NOTE If the cluster requires authentication be sure to provide the according {@link HttpHeaders} @@ -293,6 +289,13 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client return provider; } + public void setHeadersSupplier(Supplier headersSupplier) { + + Assert.notNull(headersSupplier, "headersSupplier must not be null"); + + this.headersSupplier = headersSupplier; + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.http.HttpHeaders) @@ -420,6 +423,12 @@ public Flux search(HttpHeaders headers, SearchRequest searchRequest) .flatMap(Flux::fromIterable); } + @Override + public Flux suggest(HttpHeaders headers, SearchRequest searchRequest) { + return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // + .map(SearchResponse::getSuggest); + } + /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#aggregate(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest) @@ -541,98 +550,6 @@ public Mono bulk(HttpHeaders headers, BulkRequest bulkRequest) { .publishNext(); } - // --> INDICES - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#existsIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.get.GetIndexRequest) - */ - @Override - public Mono existsIndex(HttpHeaders headers, GetIndexRequest request) { - - return sendRequest(request, requestCreator.indexExists(), RawActionResponse.class, headers) // - .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // - .next(); - } - - @Override - public Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest request) { - - return sendRequest(request, requestCreator.indexDelete(), AcknowledgedResponse.class, headers) // - .map(AcknowledgedResponse::isAcknowledged) // - .next(); - } - - @Override - public Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest) { - - return sendRequest(createIndexRequest, requestCreator.indexCreate(), AcknowledgedResponse.class, headers) // - .map(AcknowledgedResponse::isAcknowledged) // - .next(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#openIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.open.OpenIndexRequest) - */ - @Override - public Mono openIndex(HttpHeaders headers, OpenIndexRequest request) { - - return sendRequest(request, requestCreator.indexOpen(), AcknowledgedResponse.class, headers) // - .then(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#closeIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.close.CloseIndexRequest) - */ - @Override - public Mono closeIndex(HttpHeaders headers, CloseIndexRequest closeIndexRequest) { - - return sendRequest(closeIndexRequest, requestCreator.indexClose(), AcknowledgedResponse.class, headers) // - .then(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#refreshIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.refresh.RefreshRequest) - */ - @Override - public Mono refreshIndex(HttpHeaders headers, RefreshRequest refreshRequest) { - - return sendRequest(refreshRequest, requestCreator.indexRefresh(), RefreshResponse.class, headers) // - .then(); - } - - @Override - public Mono putMapping(HttpHeaders headers, PutMappingRequest putMappingRequest) { - - return sendRequest(putMappingRequest, requestCreator.putMapping(), AcknowledgedResponse.class, headers) // - .map(AcknowledgedResponse::isAcknowledged) // - .next(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.Indices#flushIndex(org.springframework.http.HttpHeaders, org.elasticsearch.action.admin.indices.flush.FlushRequest) - */ - @Override - public Mono flushIndex(HttpHeaders headers, FlushRequest flushRequest) { - - return sendRequest(flushRequest, requestCreator.flushIndex(), FlushResponse.class, headers) // - .then(); - } - - @Override - public Mono getMapping(HttpHeaders headers, GetMappingsRequest getMappingsRequest) { - return sendRequest(getMappingsRequest, requestCreator.getMapping(), GetMappingsResponse.class, headers).next(); - } - - @Override - public Mono getSettings(HttpHeaders headers, GetSettingsRequest getSettingsRequest) { - return sendRequest(getSettingsRequest, requestCreator.getSettings(), GetSettingsResponse.class, headers).next(); - } - /* * (non-Javadoc) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient.ReactiveElasticsearchClientCallback) @@ -738,18 +655,91 @@ private Mono sendRequest(WebClient webClient, String logId, Requ .onErrorReturn(ConnectException.class, ClientResponse.create(HttpStatus.SERVICE_UNAVAILABLE).build()); } - private Lazy bodyExtractor(Request request) { + // region indices operations + @Override + public Mono createIndex(HttpHeaders headers, CreateIndexRequest createIndexRequest) { - return Lazy.of(() -> { + return sendRequest(createIndexRequest, requestCreator.indexCreate(), AcknowledgedResponse.class, headers) // + .map(AcknowledgedResponse::isAcknowledged) // + .next(); + } - try { - return EntityUtils.toString(request.getEntity()); - } catch (IOException e) { - throw new RequestBodyEncodingException("Error encoding request", e); - } - }); + @Override + public Mono closeIndex(HttpHeaders headers, CloseIndexRequest closeIndexRequest) { + + return sendRequest(closeIndexRequest, requestCreator.indexClose(), AcknowledgedResponse.class, headers) // + .then(); + } + + @Override + public Mono existsIndex(HttpHeaders headers, GetIndexRequest request) { + + return sendRequest(request, requestCreator.indexExists(), RawActionResponse.class, headers) // + .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // + .next(); + } + + @Override + public Mono deleteIndex(HttpHeaders headers, DeleteIndexRequest request) { + + return sendRequest(request, requestCreator.indexDelete(), AcknowledgedResponse.class, headers) // + .map(AcknowledgedResponse::isAcknowledged) // + .next(); + } + + @Override + public Mono flushIndex(HttpHeaders headers, FlushRequest flushRequest) { + + return sendRequest(flushRequest, requestCreator.flushIndex(), FlushResponse.class, headers) // + .then(); } + @Override + public Mono getMapping(HttpHeaders headers, GetMappingsRequest getMappingsRequest) { + return sendRequest(getMappingsRequest, requestCreator.getMapping(), GetMappingsResponse.class, headers).next(); + } + + @Override + public Mono getSettings(HttpHeaders headers, GetSettingsRequest getSettingsRequest) { + return sendRequest(getSettingsRequest, requestCreator.getSettings(), GetSettingsResponse.class, headers).next(); + } + + @Override + public Mono putMapping(HttpHeaders headers, PutMappingRequest putMappingRequest) { + + return sendRequest(putMappingRequest, requestCreator.putMapping(), AcknowledgedResponse.class, headers) // + .map(AcknowledgedResponse::isAcknowledged) // + .next(); + } + + @Override + public Mono openIndex(HttpHeaders headers, OpenIndexRequest request) { + + return sendRequest(request, requestCreator.indexOpen(), AcknowledgedResponse.class, headers) // + .then(); + } + + @Override + public Mono refreshIndex(HttpHeaders headers, RefreshRequest refreshRequest) { + + return sendRequest(refreshRequest, requestCreator.indexRefresh(), RefreshResponse.class, headers) // + .then(); + } + + @Override + public Mono updateAliases(HttpHeaders headers, IndicesAliasesRequest indicesAliasesRequest) { + return sendRequest(indicesAliasesRequest, requestCreator.updateAlias(), AcknowledgedResponse.class, headers) + .map(AcknowledgedResponse::isAcknowledged).next(); + } + + @Override + public Mono getAliases(HttpHeaders headers, GetAliasesRequest getAliasesRequest) { + return sendRequest(getAliasesRequest, requestCreator.getAlias(), GetAliasesResponse.class, headers).publishNext(); + } + + // endregion + + // region helper functions private Publisher readResponseBody(String logId, Request request, ClientResponse response, Class responseType) { @@ -807,6 +797,20 @@ private static XContentParser createParser(String mediaType, String content) thr DeprecationHandler.THROW_UNSUPPORTED_OPERATION, content); } + private Lazy bodyExtractor(Request request) { + + return Lazy.of(() -> { + + try { + return EntityUtils.toString(request.getEntity()); + } catch (IOException e) { + throw new RequestBodyEncodingException("Error encoding request", e); + } + }); + } + // endregion + + // region error and exception handling private Publisher handleServerError(Request request, ClientResponse response) { int statusCode = response.statusCode().value(); @@ -835,7 +839,6 @@ private Publisher handleClientError(String logId, Request reque .flatMap(content -> doDecode(response, responseType, content)); } - // region ElasticsearchException helper /** * checks if the given content body contains an {@link ElasticsearchException}, if yes it is returned in a Mono.error. * Otherwise the content is returned in the Mono @@ -887,12 +890,6 @@ private static ElasticsearchException getElasticsearchException(String content, } } - @Override - public Flux suggest(HttpHeaders headers, SearchRequest searchRequest) { - return sendRequest(searchRequest, requestCreator.search(), SearchResponse.class, headers) // - .map(SearchResponse::getSuggest); - } - private static void buildExceptionMessages(StringBuilder sb, Throwable t) { sb.append(t.getMessage()); diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index afa2352ef..170d065a1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -22,6 +22,8 @@ import java.util.Collection; import java.util.function.Consumer; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -47,6 +49,7 @@ import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; @@ -1125,5 +1128,73 @@ default Mono getMapping(GetMappingsRequest getMappingsReque * @since 4.1 */ Mono getMapping(HttpHeaders headers, GetMappingsRequest getMappingsRequest); + + /** + * Execute the given {@link IndicesAliasesRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono updateAliases(Consumer consumer) { + IndicesAliasesRequest indicesAliasesRequest = new IndicesAliasesRequest(); + consumer.accept(indicesAliasesRequest); + return updateAliases(indicesAliasesRequest); + } + + /** + * Execute the given {@link IndicesAliasesRequest} against the {@literal indices} API. + * + * @param indicesAliasesRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono updateAliases(IndicesAliasesRequest indicesAliasesRequest) { + return updateAliases(HttpHeaders.EMPTY, indicesAliasesRequest); + } + + /** + * Execute the given {@link IndicesAliasesRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param indicesAliasesRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + Mono updateAliases(HttpHeaders headers, IndicesAliasesRequest indicesAliasesRequest); + + /** + * Execute the given {@link GetAliasesRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono getAliases(Consumer consumer) { + GetAliasesRequest getAliasesRequest = new GetAliasesRequest(); + consumer.accept(getAliasesRequest); + return getAliases(getAliasesRequest); + } + + /** + * Execute the given {@link GetAliasesRequest} against the {@literal indices} API. + * + * @param getAliasesRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono getAliases(GetAliasesRequest getAliasesRequest) { + return getAliases(HttpHeaders.EMPTY, getAliasesRequest); + } + + /** + * Execute the given {@link GetAliasesRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param getAliasesRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + Mono getAliases(HttpHeaders headers, GetAliasesRequest getAliasesRequest); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java index 44d05c8e2..d3bda5488 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java @@ -3,6 +3,8 @@ import java.io.IOException; import java.util.function.Function; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -147,4 +149,14 @@ default Function getMapping() { return RequestConverters::getMapping; } + /** + * @since 4.1 + */ + default Function updateAlias() { + return RequestConverters::updateAliases; + } + + default Function getAlias() { + return RequestConverters::getAlias; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index 796260a10..5519871d9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -25,6 +25,8 @@ import java.util.StringJoiner; import org.apache.http.HttpEntity; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.lucene.util.BytesRef; @@ -33,6 +35,8 @@ import org.elasticsearch.action.admin.cluster.storedscripts.DeleteStoredScriptRequest; import org.elasticsearch.action.admin.cluster.storedscripts.GetStoredScriptRequest; import org.elasticsearch.action.admin.cluster.storedscripts.PutStoredScriptRequest; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; @@ -802,6 +806,31 @@ public static Request getSettings(GetSettingsRequest getSettingsRequest) { return request; } + public static Request updateAliases(IndicesAliasesRequest indicesAliasesRequest) { + Request request = new Request(HttpPost.METHOD_NAME, "/_aliases"); + + RequestConverters.Params parameters = new RequestConverters.Params(request); + parameters.withTimeout(indicesAliasesRequest.timeout()); + parameters.withMasterTimeout(indicesAliasesRequest.masterNodeTimeout()); + request + .setEntity(RequestConverters.createEntity(indicesAliasesRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE)); + return request; + } + + public static Request getAlias(GetAliasesRequest getAliasesRequest) { + + String[] indices = getAliasesRequest.indices() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.indices(); + String[] aliases = getAliasesRequest.aliases() == null ? Strings.EMPTY_ARRAY : getAliasesRequest.aliases(); + String endpoint = RequestConverters.endpoint(indices, "_alias", aliases); + + Request request = new Request(HttpGet.METHOD_NAME, endpoint); + + RequestConverters.Params params = new RequestConverters.Params(request); + params.withIndicesOptions(getAliasesRequest.indicesOptions()); + params.withLocal(getAliasesRequest.local()); + return request; + } + static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) { try { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 8851fb91d..959ff0233 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; +import java.util.Set; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.cluster.metadata.AliasMetaData; @@ -31,6 +32,7 @@ import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.index.AliasData; import org.springframework.data.elasticsearch.core.index.MappingBuilder; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -181,6 +183,25 @@ public boolean removeAlias(AliasQuery query) { protected abstract boolean doRemoveAlias(AliasQuery query, IndexCoordinates index); + @Override + public Map> getAliases(String... aliasNames) { + + Assert.notEmpty(aliasNames, "aliasNames must not be empty"); + + return doGetAliases(aliasNames, null); + } + + @Override + public Map> getAliasesForIndex(String... indexNames) { + + Assert.notEmpty(indexNames, "indexNames must not be empty"); + + return doGetAliases(null, indexNames); + } + + protected abstract Map> doGetAliases(@Nullable String[] aliasNames, + @Nullable String[] indexNames); + @Override public Document createMapping() { return createMapping(checkForBoundClass()); @@ -223,13 +244,8 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { return elasticsearchConverter.getMappingContext().getRequiredPersistentEntity(clazz); } - /** - * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed - * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. - * - * @return IndexCoordinates - */ - protected IndexCoordinates getIndexCoordinates() { + @Override + public IndexCoordinates getIndexCoordinates() { return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index ca121aaad..29acbbb9d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -19,6 +19,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; @@ -35,6 +36,8 @@ import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetaData; 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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; @@ -145,6 +148,23 @@ protected List doQueryForAlias(IndexCoordinates index) { }); } + @Override + protected Map> doGetAliases(@Nullable String[] aliasNames, @Nullable String[] indexNames) { + + GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(aliasNames, indexNames); + + return restTemplate.execute(client -> requestFactory + .convertAliasesResponse(client.indices().getAlias(getAliasesRequest, RequestOptions.DEFAULT).getAliases())); + } + + @Override + public boolean alias(AliasActions aliasActions) { + + IndicesAliasesRequest request = requestFactory.indicesAliasesRequest(aliasActions); + return restTemplate + .execute(client -> client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged()); + } + @Override protected Map doGetSettings(IndexCoordinates index, boolean includeDefaults) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java index 94d30dcd1..3c97e450f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java @@ -20,11 +20,17 @@ import reactor.core.publisher.Mono; +import java.util.Map; +import java.util.Set; + +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; +import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.client.GetAliasesResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -33,6 +39,8 @@ import org.springframework.data.elasticsearch.annotations.Setting; 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.MappingBuilder; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -138,7 +146,9 @@ public Mono refresh() { return Mono.from(operations.executeWithIndicesClient( client -> client.refreshIndex(refreshRequest(getIndexCoordinates().getIndexNames())))); } + // endregion + // region mappings @Override public Mono createMapping() { return createMapping(checkForBoundClass()); @@ -176,7 +186,9 @@ public Mono getMapping() { return Mono.just(document); }); } + // endregion + // region settings @Override public Mono getSettings(boolean includeDefaults) { @@ -189,14 +201,36 @@ public Mono getSettings(boolean includeDefaults) { // endregion + // region aliases + @Override + public Mono alias(AliasActions aliasActions) { + + IndicesAliasesRequest request = requestFactory.indicesAliasesRequest(aliasActions); + return Mono.from(operations.executeWithIndicesClient(client -> client.updateAliases(request))); + } + + @Override + public Mono>> getAliases(String... aliasNames) { + return getAliases(aliasNames, null); + } + + @Override + public Mono>> getAliasesForIndex(String... indexNames) { + return getAliases(null, indexNames); + } + + private Mono>> getAliases(@Nullable String[] aliasNames, @Nullable String[] indexNames) { + + GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(aliasNames, indexNames); + return Mono.from(operations.executeWithIndicesClient(client -> client.getAliases(getAliasesRequest))) + .map(GetAliasesResponse::getAliases).map(requestFactory::convertAliasesResponse); + } + + // endregion + // region helper functions - /** - * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed - * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. - * - * @return IndexCoordinates - */ - private IndexCoordinates getIndexCoordinates() { + @Override + public IndexCoordinates getIndexCoordinates() { return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 3d15ebf11..7b20df10e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -15,10 +15,11 @@ */ package org.springframework.data.elasticsearch.core; -import static org.elasticsearch.client.Requests.*; - +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; @@ -33,8 +34,11 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.collect.ImmutableOpenMap; 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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; @@ -135,6 +139,27 @@ protected List doQueryForAlias(IndexCoordinates index) { return client.admin().indices().getAliases(getAliasesRequest).actionGet().getAliases().get(index.getIndexName()); } + @Override + protected Map> doGetAliases(String[] aliasNames, String[] indexNames) { + + GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(aliasNames, indexNames); + + ImmutableOpenMap> aliases = client.admin().indices().getAliases(getAliasesRequest) + .actionGet().getAliases(); + + Map> aliasesResponse = new LinkedHashMap<>(); + aliases.keysIt().forEachRemaining(index -> aliasesResponse.put(index, new HashSet<>(aliases.get(index)))); + return requestFactory.convertAliasesResponse(aliasesResponse); + } + + @Override + public boolean alias(AliasActions aliasActions) { + + IndicesAliasesRequestBuilder indicesAliasesRequestBuilder = requestFactory.indicesAliasesRequestBuilder(client, + aliasActions); + return indicesAliasesRequestBuilder.execute().actionGet().isAcknowledged(); + } + @Override protected Map doGetSettings(IndexCoordinates index, boolean includeDefaults) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 300283fdf..be42d708f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -17,9 +17,12 @@ import java.util.List; import java.util.Map; +import java.util.Set; import org.elasticsearch.cluster.metadata.AliasMetaData; 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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; @@ -36,6 +39,7 @@ */ public interface IndexOperations { + //region index management /** * Create an index. * @@ -69,7 +73,9 @@ public interface IndexOperations { * Refresh the index(es) this IndexOperations is bound to */ void refresh(); + //endregion + //region mappings /** * Creates the index mapping for the entity this IndexOperations is bound to. * @@ -87,11 +93,13 @@ public interface IndexOperations { /** * Writes the mapping to the index for the class this IndexOperations is bound to. + * * @return {@literal true} if the mapping could be stored * @since 4.1 */ default boolean putMapping() { - return putMapping(createMapping());} + return putMapping(createMapping()); + } /** * writes a mapping to the index @@ -103,6 +111,7 @@ default boolean putMapping() { /** * Creates the index mapping for the given class and writes it to the index. + * * @param clazz the clazz to create a mapping for * @return {@literal true} if the mapping could be stored * @since 4.1 @@ -110,27 +119,49 @@ default boolean putMapping() { default boolean putMapping(Class clazz) { return putMapping(createMapping(clazz)); } + //endregion + //region settings /** * Get mapping for an index defined by a class. * * @return the mapping */ Map getMapping(); + /** + * Get the index settings. + * + * @return the settings + */ + Map getSettings(); + /** + * Get the index settings. + * + * @param includeDefaults whether or not to include all the default settings + * @return the settings + */ + Map getSettings(boolean includeDefaults); + //endregion + + //region aliases /** * Add an alias. * * @param query query defining the alias * @return true if the alias was created + * @deprecated since 4.1 use {@link #alias(AliasActions)} */ + @Deprecated boolean addAlias(AliasQuery query); /** * Get the alias informations for a specified index. * * @return alias information + * @deprecated since 4.1, use {@link #getAliases(String...)} or {@link #getAliasesForIndex(String...)}. */ + @Deprecated List queryForAlias(); /** @@ -138,21 +169,45 @@ default boolean putMapping(Class clazz) { * * @param query query defining the alias * @return true if the alias was removed + * @deprecated since 4.1 use {@link #alias(AliasActions)} */ + @Deprecated boolean removeAlias(AliasQuery query); /** - * Get the index settings. - * - * @return the settings + * Executes the given {@link AliasActions}. + * + * @param aliasActions the actions to execute + * @return if the operation is acknowledged by Elasticsearch + * @since 4.1 */ - Map getSettings(); + boolean alias(AliasActions aliasActions); /** - * Get the index settings. + * gets information about aliases + * @param aliasNames alias names, must not be {@literal null} + * @return a {@link Map} from index names to {@link AliasData} for that index + * @since 4.1 + */ + Map> getAliases(String... aliasNames); + + /** + * gets information about aliases + * @param indexNames index names, must not be {@literal null} + * @return a {@link Map} from index names to {@link AliasData} for that index + * @since 4.1 + */ + Map> getAliasesForIndex(String... indexNames); + //endregion + + //region helper functions + /** + * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed + * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. * - * @param includeDefaults whether or not to include all the default settings - * @return the settings + * @return IndexCoordinates + * @since 4.1 */ - Map getSettings(boolean includeDefaults); + IndexCoordinates getIndexCoordinates(); + //endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java index a4c706c27..8fb7b5885 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java @@ -17,7 +17,13 @@ import reactor.core.publisher.Mono; +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.mapping.IndexCoordinates; /** * Interface defining operations on indexes for the reactive stack. @@ -27,6 +33,7 @@ */ public interface ReactiveIndexOperations { + // region index management /** * Create an index. * @@ -65,7 +72,9 @@ public interface ReactiveIndexOperations { * @return a {@link Mono} signalling operation completion. */ Mono refresh(); + // endregion + // region mappings /** * Creates the index mapping for the entity this IndexOperations is bound to. * @@ -114,7 +123,9 @@ default Mono putMapping(Class clazz) { * @return the mapping */ Mono getMapping(); + // endregion + // region settings /** * get the settings for the index * @@ -131,4 +142,46 @@ default Mono getSettings() { * @return a {@link Mono} with a {@link Document} containing the index settings */ Mono getSettings(boolean includeDefaults); + // endregion + + // region aliases + /** + * Executes the given {@link AliasActions}. + * + * @param aliasActions the actions to execute + * @return if the operation is acknowledged by Elasticsearch + * @since 4.1 + */ + Mono alias(AliasActions aliasActions); + + /** + * gets information about aliases + * + * @param aliasNames alias names, must not be {@literal null} + * @return a {@link Mono} of {@link Map} from index names to {@link AliasData} for that index + * @since 4.1 + */ + Mono>> getAliases(String... aliasNames); + + /** + * gets information about aliases + * + * @param indexNames alias names, must not be {@literal null} + * @return a {@link Mono} of {@link Map} from index names to {@link AliasData} for that index + * @since 4.1 + */ + Mono>> getAliasesForIndex(String... indexNames); + // endregion + + // region helper functions + /** + * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed + * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. + * + * @return IndexCoordinates + * @ince 4.1 + */ + IndexCoordinates getIndexCoordinates(); + + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 085a2f1d0..da17603a1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -21,21 +21,23 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequestBuilder; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.delete.DeleteRequest; @@ -55,9 +57,11 @@ import org.elasticsearch.client.Requests; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; -import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.PutMappingRequest; +import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.DistanceUnit; @@ -86,6 +90,10 @@ import org.springframework.data.elasticsearch.ElasticsearchException; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; +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.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -150,6 +158,10 @@ public GetAliasesRequest getAliasesRequest(IndexCoordinates index) { return new GetAliasesRequest().indices(indexNames); } + public GetAliasesRequest getAliasesRequest(@Nullable String[] aliasNames, @Nullable String[] indexNames) { + return new GetAliasesRequest(aliasNames).indices(indexNames); + } + public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { IndicesAliasesRequest.AliasActions aliasAction = aliasAction(query, index); IndicesAliasesRequest request = new IndicesAliasesRequest(); @@ -157,6 +169,79 @@ public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoo return request; } + public IndicesAliasesRequest indicesAliasesRequest(AliasActions aliasActions) { + + IndicesAliasesRequest request = new IndicesAliasesRequest(); + aliasActions.getActions().forEach(aliasAction -> { + + IndicesAliasesRequest.AliasActions aliasActionsES = null; + + if (aliasAction instanceof AliasAction.Add) { + AliasAction.Add add = (AliasAction.Add) aliasAction; + IndicesAliasesRequest.AliasActions addES = IndicesAliasesRequest.AliasActions.add(); + + AliasActionParameters parameters = add.getParameters(); + addES.indices(parameters.getIndices()); + addES.aliases(parameters.getAliases()); + addES.routing(parameters.getRouting()); + addES.indexRouting(parameters.getIndexRouting()); + addES.searchRouting(parameters.getSearchRouting()); + addES.isHidden(parameters.getHidden()); + addES.writeIndex(parameters.getWriteIndex()); + + Query filterQuery = parameters.getFilterQuery(); + + if (filterQuery != null) { + + if (filterQuery instanceof CriteriaQuery && parameters.getFilterQueryClass() != null) { + CriteriaQuery query = (CriteriaQuery) filterQuery; + elasticsearchConverter.updateQuery(query, parameters.getFilterQueryClass()); + } + + QueryBuilder queryBuilder = getFilter(filterQuery); + + if (queryBuilder == null) { + queryBuilder = getQuery(filterQuery); + } + + addES.filter(queryBuilder); + } + + aliasActionsES = addES; + } else if (aliasAction instanceof AliasAction.Remove) { + AliasAction.Remove remove = (AliasAction.Remove) aliasAction; + IndicesAliasesRequest.AliasActions removeES = IndicesAliasesRequest.AliasActions.remove(); + + AliasActionParameters parameters = remove.getParameters(); + removeES.indices(parameters.getIndices()); + removeES.aliases(parameters.getAliases()); + + aliasActionsES = removeES; + } else if (aliasAction instanceof AliasAction.RemoveIndex) { + AliasAction.RemoveIndex removeIndex = (AliasAction.RemoveIndex) aliasAction; + IndicesAliasesRequest.AliasActions removeIndexES = IndicesAliasesRequest.AliasActions.removeIndex(); + + AliasActionParameters parameters = removeIndex.getParameters(); + removeIndexES.indices(parameters.getIndices()[0]); + + aliasActionsES = removeIndexES; + } + + if (aliasActionsES != null) { + request.addAliasAction(aliasActionsES); + } + }); + + return request; + } + + public IndicesAliasesRequestBuilder indicesAliasesRequestBuilder(Client client, AliasActions aliasActions) { + + IndicesAliasesRequestBuilder requestBuilder = client.admin().indices().prepareAliases(); + indicesAliasesRequest(aliasActions).getAliasActions().forEach(requestBuilder::addAliasAction); + return requestBuilder; + } + public IndicesAliasesRequest indicesRemoveAliasesRequest(AliasQuery query, IndexCoordinates index) { String[] indexNames = index.getIndexNames(); @@ -310,7 +395,6 @@ public GetIndexRequest getIndexRequest(IndexCoordinates index) { return new GetIndexRequest(index.getIndexNames()); } - /** * creates a CreateIndexRequest from the elasticsearch library, used by the reactive methods. * @@ -384,7 +468,6 @@ public GetSettingsRequest getSettingsRequest(String indexName, boolean includeDe return new GetSettingsRequest().indices(indexName).includeDefaults(includeDefaults); } - public GetMappingsRequest getMappingsRequest(IndexCoordinates index) { String[] indexNames = index.getIndexNames(); @@ -398,6 +481,41 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest get return new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest().indices(indexNames); } + public Map> convertAliasesResponse( + ImmutableOpenMap> aliasesResponse) { + + Map> mapped = new LinkedHashMap<>(); + Iterator keysIt = aliasesResponse.keysIt(); + while (keysIt.hasNext()) { + String key = keysIt.next(); + + List aliasMetaData = aliasesResponse.get(key); + mapped.put(key, new LinkedHashSet<>(aliasMetaData)); + } + + return convertAliasesResponse(mapped); + } + + public Map> convertAliasesResponse(Map> aliasesResponse) { + Map> converted = new LinkedHashMap<>(); + aliasesResponse.forEach((index, aliasMetaDataSet) -> { + Set aliasDataSet = new LinkedHashSet<>(); + + aliasMetaDataSet.forEach(aliasMetaData -> { + Document filter = null; + CompressedXContent aliasMetaDataFilter = aliasMetaData.getFilter(); + if (aliasMetaDataFilter != null) { + filter = Document.parse(aliasMetaDataFilter.string()); + } + aliasDataSet.add(AliasData.of(aliasMetaData.alias(), filter, aliasMetaData.indexRouting(), + aliasMetaData.getSearchRouting(), aliasMetaData.writeIndex(), aliasMetaData.isHidden())); + }); + + converted.put(index, aliasDataSet); + }); + return converted; + } + // endregion // region delete diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java deleted file mode 100644 index 3fda69c8c..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/client/support/AliasData.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018-2020 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.client.support; - -public class AliasData { - private String filter = null; - private String routing = null; - private String search_routing = null; - private String index_routing = null; - - public String getFilter() { - return filter; - } - - public void setFilter(String filter) { - this.filter = filter; - } - - public String getRouting() { - return routing; - } - - public void setRouting(String routing) { - this.routing = routing; - } - - public String getSearch_routing() { - return search_routing; - } - - public void setSearch_routing(String search_routing) { - this.search_routing = search_routing; - } - - public String getIndex_routing() { - return index_routing; - } - - public void setIndex_routing(String index_routing) { - this.index_routing = index_routing; - } -} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java deleted file mode 100644 index bbd425849..000000000 --- a/src/main/java/org/springframework/data/elasticsearch/core/client/support/package-info.java +++ /dev/null @@ -1,3 +0,0 @@ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.data.elasticsearch.core.client.support; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasAction.java b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasAction.java new file mode 100644 index 000000000..82c095a10 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasAction.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 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; + +/** + * A single action to be contained in {@link AliasActions}. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public abstract class AliasAction { + + private final AliasActionParameters parameters; + + protected AliasAction(AliasActionParameters parameters) { + + Assert.notNull(parameters, "parameters must not be null"); + Assert.notEmpty(parameters.getIndices(), "parameters must have an indexname set"); + + this.parameters = parameters; + } + + public AliasActionParameters getParameters() { + return parameters; + } + + /** + * {@link AliasAction} to add an alias. + */ + public static class Add extends AliasAction { + + public Add(AliasActionParameters parameters) { + super(parameters); + } + } + + /** + * {@link AliasAction} to remove an alias. + */ + public static class Remove extends AliasAction { + + public Remove(AliasActionParameters parameters) { + super(parameters); + } + } + + /** + * {@link AliasAction} to remove an index. + */ + public static class RemoveIndex extends AliasAction { + + public RemoveIndex(AliasActionParameters parameters) { + super(parameters); + } + } + +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java new file mode 100644 index 000000000..d9634a433 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java @@ -0,0 +1,167 @@ +/* + * Copyright 2020 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.data.elasticsearch.core.query.Query; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Value class capturing the arguments for an {@link AliasAction}.   + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public class AliasActionParameters { + private final String[] indices; + @Nullable private final String[] aliases; + @Nullable private final Query filterQuery; + @Nullable private final Class filterQueryClass; + @Nullable private final Boolean isHidden; + @Nullable private final Boolean isWriteIndex; + @Nullable private final String routing; + @Nullable private final String indexRouting; + @Nullable private final String searchRouting; + + private AliasActionParameters(String[] indices, @Nullable String[] aliases, @Nullable Boolean isHidden, + @Nullable Boolean isWriteIndex, @Nullable String routing, @Nullable String indexRouting, + @Nullable String searchRouting, @Nullable Query filterQuery, @Nullable Class filterQueryClass) { + this.indices = indices; + this.aliases = aliases; + this.isHidden = isHidden; + this.isWriteIndex = isWriteIndex; + this.routing = routing; + this.indexRouting = indexRouting; + this.searchRouting = searchRouting; + this.filterQuery = filterQuery; + this.filterQueryClass = filterQueryClass; + } + + public static Builder builder() { + return new Builder(); + } + + public String[] getIndices() { + return indices; + } + + @Nullable + public String[] getAliases() { + return aliases; + } + + @Nullable + public Boolean getHidden() { + return isHidden; + } + + @Nullable + public Boolean getWriteIndex() { + return isWriteIndex; + } + + @Nullable + public String getRouting() { + return routing; + } + + @Nullable + public String getIndexRouting() { + return indexRouting; + } + + @Nullable + public String getSearchRouting() { + return searchRouting; + } + + @Nullable + public Query getFilterQuery() { + return filterQuery; + } + + @Nullable + public Class getFilterQueryClass() { + return filterQueryClass; + } + + public static final class Builder { + @Nullable private String[] indices; + @Nullable private String[] aliases; + @Nullable private Query filterQuery; + @Nullable private Class filterQueryClass; + @Nullable private Boolean isHidden; + @Nullable private Boolean isWriteIndex; + @Nullable private String routing; + @Nullable private String indexRouting; + @Nullable private String searchRouting; + + private Builder() {} + + public Builder withIndices(String... indices) { + this.indices = indices; + return this; + } + + public Builder withAliases(String... aliases) { + this.aliases = aliases; + return this; + } + + public Builder withFilterQuery(Query filterQuery) { + return withFilterQuery(filterQuery, null); + } + + public Builder withFilterQuery(Query filterQuery, @Nullable Class filterQueryClass) { + this.filterQuery = filterQuery; + this.filterQueryClass = filterQueryClass; + return this; + } + + public Builder withIsHidden(Boolean isHidden) { + this.isHidden = isHidden; + return this; + } + + public Builder withIsWriteIndex(Boolean isWriteIndex) { + this.isWriteIndex = isWriteIndex; + return this; + } + + public Builder withRouting(String routing) { + this.routing = routing; + return this; + } + + public Builder withIndexRouting(String indexRouting) { + this.indexRouting = indexRouting; + return this; + } + + public Builder withSearchRouting(String searchRouting) { + this.searchRouting = searchRouting; + return this; + } + + public AliasActionParameters build() { + + Assert.notNull(indices, "indices must bes set"); + + return new AliasActionParameters(indices, aliases, isHidden, isWriteIndex, routing, indexRouting, searchRouting, + filterQuery, filterQueryClass); + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActions.java b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActions.java new file mode 100644 index 000000000..a83d07ead --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActions.java @@ -0,0 +1,63 @@ +/* + * Copyright 2020 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.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.springframework.lang.Nullable; + +/** + * Class to define to actions to execute in alias management functions. + * {@see https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-aliases.html} + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public class AliasActions { + + private final List actions = new ArrayList<>(); + + /** + * Creates an {@link AliasActions} object with the passed in action elements. + * + * @param actions {@link AliasAction} elements + */ + public AliasActions(@Nullable AliasAction... actions) { + add(actions); + } + + public List getActions() { + return Collections.unmodifiableList(actions); + } + + /** + * Adds {@link AliasAction} elements to this {@link AliasActions} + * + * @param actions elements to add + * @return this object + */ + public AliasActions add(@Nullable AliasAction... actions) { + + if (actions != null) { + this.actions.addAll(Arrays.asList(actions)); + } + + return this; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasData.java b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasData.java new file mode 100644 index 000000000..35801058a --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasData.java @@ -0,0 +1,80 @@ +/* + * Copyright 2020 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.data.elasticsearch.core.document.Document; +import org.springframework.lang.Nullable; + +/** + * value object to describe alias information. + * + * @author Peter-Josef Meisch + */ +public class AliasData { + private String alias; + @Nullable Document filter; + @Nullable private String indexRouting; + @Nullable private String searchRouting; + @Nullable private Boolean isWriteIndex; + @Nullable private Boolean isHidden; + + private AliasData(String alias, @Nullable Document filter, @Nullable String indexRouting, + @Nullable String searchRouting, Boolean isWriteIndex, Boolean isHidden) { + this.alias = alias; + this.filter = filter; + this.indexRouting = indexRouting; + this.searchRouting = searchRouting; + this.isWriteIndex = isWriteIndex; + this.isHidden = isHidden; + } + + public static AliasData of(String alias, + @Nullable Document filter, + @Nullable String indexRouting, + @Nullable String searchRouting, + @Nullable Boolean isWriteIndex, + @Nullable Boolean isHidden) { + return new AliasData(alias, filter, indexRouting, searchRouting, isWriteIndex, isHidden); + } + + public String getAlias() { + return alias; + } + + public Document getFilter() { + return filter; + } + + @Nullable + public String getIndexRouting() { + return indexRouting; + } + + @Nullable + public String getSearchRouting() { + return searchRouting; + } + + @Nullable + public Boolean isWriteIndex() { + return isWriteIndex; + } + + @Nullable + public Boolean isHidden() { + return isHidden; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java b/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java index 2fd24e9c7..464fa781c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/package-info.java @@ -1,3 +1,6 @@ +/** + * Classes related to Elasticsearch index management. + */ @org.springframework.lang.NonNullApi @org.springframework.lang.NonNullFields package org.springframework.data.elasticsearch.core.index; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java index a679555eb..86a223bdc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasBuilder.java @@ -18,12 +18,14 @@ import java.util.Map; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.data.elasticsearch.core.index.AliasActions; import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** * @author Mohsin Husen * @author Peter-Josef Meisch + * @deprecated since 4.1, use {@link org.springframework.data.elasticsearch.core.IndexOperations#alias(AliasActions)}. */ public class AliasBuilder { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java index c17eaeb28..bdb984ef0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/AliasQuery.java @@ -18,6 +18,7 @@ import java.util.Map; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.data.elasticsearch.core.index.AliasActions; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -26,7 +27,9 @@ * * @author Mohsin Husen * @author Peter-Josef Meisch + * @deprecated since 4.1, use {@link org.springframework.data.elasticsearch.core.IndexOperations#alias(AliasActions)} */ +@Deprecated public class AliasQuery { public AliasQuery(String aliasName) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index e17f58d47..490372ad8 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -39,6 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -75,6 +76,10 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.util.StreamUtils; @@ -215,7 +220,7 @@ public void shouldReturnObjectForGivenId() { assertThat(sampleEntity1).isEqualTo(sampleEntity); } - @Test + @Test // DATAES-52 public void shouldReturnObjectsForGivenIdsUsingMultiGet() { // given @@ -277,7 +282,7 @@ public void shouldReturnNullObjectForNotExistingIdUsingMultiGet() { assertThat(sampleEntities.get(2)).isEqualTo(sampleEntity2); } - @Test + @Test // DATAES-52 public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { // given @@ -2739,6 +2744,54 @@ public void shouldAddAlias() { assertThat(aliases.get(0).alias()).isEqualTo(aliasName); } + @Test // DATAES-864 + void shouldAddAliasesWithAliasActions() { + + AliasActions aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder() + .withIndices(indexOperations.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + indexOperations.alias(aliasActions); + + List aliases = indexOperations.queryForAlias(); + assertThat(aliases).hasSize(2); + assertThat(aliases.stream().map(AliasMetaData::alias).collect(Collectors.toList())).contains("aliasA", "aliasB"); + } + + @Test // DATAES-864 + void shouldRemoveAliasesWithAliasActions() { + + AliasActions aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder() + .withIndices(indexOperations.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + indexOperations.alias(aliasActions); + + aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Remove(AliasActionParameters.builder() + .withIndices(indexOperations.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + indexOperations.alias(aliasActions); + + List aliases = indexOperations.queryForAlias(); + assertThat(aliases).hasSize(0); + } + + @Test // DATAES-864 + void shouldGetAliasData() { + AliasActions aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder() + .withIndices(indexOperations.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + indexOperations.alias(aliasActions); + + Map> aliasDatas = indexOperations.getAliases("aliasA"); + + Set aliasData = aliasDatas.get(indexOperations.getIndexCoordinates().getIndexName()); + + assertThat(aliasData.stream().map(AliasData::getAlias)).containsExactly("aliasA"); + } + @Test // DATAES-70 public void shouldAddAliasForVariousRoutingValues() { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java index c8d76704d..9edf8a414 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java @@ -19,9 +19,11 @@ import static org.skyscreamer.jsonassert.JSONAssert.*; import lombok.Data; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.time.LocalDate; +import java.util.Set; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; @@ -38,6 +40,10 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; +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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; @@ -333,6 +339,45 @@ void shouldPutAndGetMapping() { }).verifyComplete(); } + @Test // DATAES-864 + void shouldCreateAlias() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + AliasActions aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder() + .withIndices(indexOps.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + indexOps.create().flatMap(success -> { + if (success) { + return indexOps.alias(aliasActions); + } else { + return Mono.just(false); + } + }).as(StepVerifier::create).expectNext(true).verifyComplete(); + } + + @Test // DATAES-864 + void shouldGetAliasData() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + AliasActions aliasActions = new AliasActions(); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder() + .withIndices(indexOps.getIndexCoordinates().getIndexNames()).withAliases("aliasA", "aliasB").build())); + + assertThat(indexOps.create().block()).isTrue(); + assertThat(indexOps.alias(aliasActions).block()).isTrue(); + + indexOps.getAliases("aliasA") // + .as(StepVerifier::create) // + .assertNext(aliasDatas -> { // + Set aliasData = aliasDatas.get(indexOps.getIndexCoordinates().getIndexName()); + assertThat(aliasData.stream().map(AliasData::getAlias)).containsExactly("aliasA"); + }) // + .verifyComplete(); + } + @Data @Document(indexName = TESTINDEX, shards = 3, replicas = 2, refreshInterval = "4s") static class Entity { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index 336261f5d..acfc5084d 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -20,9 +20,11 @@ import static org.mockito.Mockito.*; import static org.skyscreamer.jsonassert.JSONAssert.*; +import java.io.IOException; import java.util.Arrays; import java.util.HashSet; +import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.index.IndexAction; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequestBuilder; @@ -30,6 +32,9 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.Client; +import org.elasticsearch.common.xcontent.ToXContent; +import org.elasticsearch.common.xcontent.XContentHelper; +import org.elasticsearch.common.xcontent.XContentType; import org.json.JSONException; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -43,6 +48,9 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +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.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.Criteria; @@ -250,6 +258,123 @@ void shouldNotRequestSeqNoAndPrimaryTermViaSearchRequestBuilderWhenEntityClassIs assertThat(builder.request().source().seqNoAndPrimaryTerm()).isNull(); } + @Test // DATAES-864 + void shouldBuildIndicesAliasRequest() throws IOException, JSONException { + + AliasActions aliasActions = new AliasActions(); + + aliasActions.add(new AliasAction.Add( + AliasActionParameters.builder().withIndices("index1", "index2").withAliases("alias1").build())); + aliasActions.add( + new AliasAction.Remove(AliasActionParameters.builder().withIndices("index3").withAliases("alias1").build())); + + aliasActions.add(new AliasAction.RemoveIndex(AliasActionParameters.builder().withIndices("index3").build())); + + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder().withIndices("index4").withAliases("alias4") + .withRouting("routing").withIndexRouting("indexRouting").withSearchRouting("searchRouting").withIsHidden(true) + .withIsWriteIndex(true).build())); + + Query query = new CriteriaQuery(new Criteria("lastName").is("Smith")); + aliasActions.add(new AliasAction.Add(AliasActionParameters.builder().withIndices("index5").withAliases("alias5") + .withFilterQuery(query, Person.class).build())); + + String expected = "{\n" + // + " \"actions\": [\n" + // + " {\n" + // + " \"add\": {\n" + // + " \"indices\": [\n" + // + " \"index1\",\n" + // + " \"index2\"\n" + // + " ],\n" + // + " \"aliases\": [\n" + // + " \"alias1\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"remove\": {\n" + // + " \"indices\": [\n" + // + " \"index3\"\n" + // + " ],\n" + // + " \"aliases\": [\n" + // + " \"alias1\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"remove_index\": {\n" + // + " \"indices\": [\n" + // + " \"index3\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"add\": {\n" + // + " \"indices\": [\n" + // + " \"index4\"\n" + // + " ],\n" + // + " \"aliases\": [\n" + // + " \"alias4\"\n" + // + " ],\n" + // + " \"routing\": \"routing\",\n" + // + " \"index_routing\": \"indexRouting\",\n" + // + " \"search_routing\": \"searchRouting\",\n" + // + " \"is_write_index\": true,\n" + // + " \"is_hidden\": true\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"add\": {\n" + // + " \"indices\": [\n" + // + " \"index5\"\n" + // + " ],\n" + // + " \"aliases\": [\n" + // + " \"alias5\"\n" + // + " ],\n" + // + " \"filter\": {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Smith\",\n" + // + " \"fields\": [\n" + // + " \"last-name^1.0\"\n" + // + " ],\n" + // + " \"type\": \"best_fields\",\n" + // + " \"default_operator\": \"and\",\n" + // + " \"max_determinized_states\": 10000,\n" + // + " \"enable_position_increments\": true,\n" + // + " \"fuzziness\": \"AUTO\",\n" + // + " \"fuzzy_prefix_length\": 0,\n" + // + " \"fuzzy_max_expansions\": 50,\n" + // + " \"phrase_slop\": 0,\n" + // + " \"escape\": false,\n" + // + " \"auto_generate_synonyms_phrase_query\": true,\n" + // + " \"fuzzy_transpositions\": true,\n" + // + " \"boost\": 1.0\n" + // + " }\n" + // + " }\n" + // + " ],\n" + // + " \"adjust_pure_negative\": true,\n" + // + " \"boost\": 1.0\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + "}"; // + + IndicesAliasesRequest indicesAliasesRequest = requestFactory.indicesAliasesRequest(aliasActions); + + String json = requestToString(indicesAliasesRequest); + + assertEquals(expected, json, false); + } + + private String requestToString(ToXContent request) throws IOException { + return XContentHelper.toXContent(request, XContentType.JSON, true).utf8ToString(); + } + static class Person { @Nullable @Id String id; @Nullable @Field(name = "last-name") String lastName; From 7d8bc81fdd362cb43eeb297ee016f4aa951f3abf Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 26 Jun 2020 23:13:19 +0200 Subject: [PATCH 0211/1191] DATAES-869 - Update to Elasticsearch 7.8. Original PR: #487 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 2 +- .../asciidoc/reference/elasticsearch-new.adoc | 10 +++++-- .../core/AbstractDefaultIndexOperations.java | 6 ++-- .../core/DefaultIndexOperations.java | 4 +-- .../core/DefaultTransportIndexOperations.java | 8 +++--- .../core/ElasticsearchOperations.java | 4 +-- .../elasticsearch/core/IndexOperations.java | 27 ++++++++++-------- .../elasticsearch/core/RequestFactory.java | 10 +++---- .../core/DocumentAdaptersUnitTests.java | 10 +++---- .../core/ElasticsearchTemplateTests.java | 22 +++++++------- ...on-7.7.1.jar => analysis-common-7.8.0.jar} | Bin 198666 -> 199093 bytes .../plugin-descriptor.properties | 4 +-- ....1.jar => elasticsearch-dissect-7.8.0.jar} | Bin 24687 -> 24686 bytes ...7.7.1.jar => elasticsearch-grok-7.8.0.jar} | Bin 33956 -> 34340 bytes ...mmon-7.7.1.jar => ingest-common-7.8.0.jar} | Bin 115865 -> 116176 bytes .../plugin-descriptor.properties | 4 +-- ...on-7.7.1.jar => lang-expression-7.8.0.jar} | Bin 65744 -> 65528 bytes .../plugin-descriptor.properties | 4 +-- ...icsearch-scripting-painless-spi-7.8.0.jar} | Bin 27849 -> 27848 bytes ...less-7.7.1.jar => lang-painless-7.8.0.jar} | Bin 561388 -> 561387 bytes .../plugin-descriptor.properties | 4 +-- .../plugin-descriptor.properties | 4 +-- .../reindex/plugin-descriptor.properties | 4 +-- .../plugin-descriptor.properties | 4 +-- .../repository-url/repository-url-7.7.1.jar | Bin 14721 -> 0 bytes .../repository-url/repository-url-7.8.0.jar | Bin 0 -> 14772 bytes 27 files changed, 71 insertions(+), 62 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.7.1.jar => analysis-common-7.8.0.jar} (75%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.7.1.jar => elasticsearch-dissect-7.8.0.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.7.1.jar => elasticsearch-grok-7.8.0.jar} (67%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.7.1.jar => ingest-common-7.8.0.jar} (83%) rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.7.1.jar => lang-expression-7.8.0.jar} (58%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.7.1.jar => elasticsearch-scripting-painless-spi-7.8.0.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.7.1.jar => lang-painless-7.8.0.jar} (93%) delete mode 100644 src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.1.jar create mode 100644 src/test/resources/test-home-dir/modules/repository-url/repository-url-7.8.0.jar diff --git a/pom.xml b/pom.xml index b78b67e0e..f30d4ce9e 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.7.1 + 7.8.0 2.9.1 2.4.0-SNAPSHOT 4.1.50.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index ab746ec20..6d34045cb 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -35,7 +35,7 @@ The following table shows the Elasticsearch versions that are used by Spring Dat [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.7.1 |2.3.xfootnote:cdv[] +| 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.8.0 |2.3.xfootnote:cdv[] | Neumann | 4.0.x | 7.6.2 |2.3.x | Moore | 3.2.x |6.8.10 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 27f0faeb9..bd7816177 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -1,6 +1,13 @@ [[new-features]] = What's new +[[new-features.4-1-0]] +== New in Spring Data Elasticsearch 4.1 + +* Upgrade to Elasticsearch 7.8.0 +* Improved API for alias management +* Introduction of `ReactiveIndexOperations` for index management + [[new-features.4-0-0]] == New in Spring Data Elasticsearch 4.0 @@ -11,8 +18,7 @@ * Removal of the Jackson `ObjectMapper`, now using the <> * Cleanup of the API in the `*Operations` interfaces, grouping and renaming methods so that they match the Elasticsearch API, deprecating the old methods, aligning with other Spring Data modules. * Introduction of `SearchHit` class to represent a found document together with the relevant result metadata for this document (i.e. _sortValues_). -* Introduction of the `SearchHits` class to represent a whole search result together with the -metadata for the complete search result (i.e. _max_score_). +* Introduction of the `SearchHits` class to represent a whole search result together with the metadata for the complete search result (i.e. _max_score_). * Introduction of `SearchPage` class to represent a paged result containing a `SearchHits` instance. * Introduction of the `GeoDistanceOrder` class to be able to create sorting by geographical distance * Implementation of Auditing Support diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 959ff0233..866671eff 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -22,7 +22,7 @@ import java.util.Set; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.common.settings.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -170,11 +170,11 @@ public boolean addAlias(AliasQuery query) { protected abstract boolean doAddAlias(AliasQuery query, IndexCoordinates index); @Override - public List queryForAlias() { + public List queryForAlias() { return doQueryForAlias(getIndexCoordinates()); } - protected abstract List doQueryForAlias(IndexCoordinates index); + protected abstract List doQueryForAlias(IndexCoordinates index); @Override public boolean removeAlias(AliasQuery query) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 29acbbb9d..305d06dd1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -34,7 +34,7 @@ import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.GetMappingsResponse; import org.elasticsearch.client.indices.PutMappingRequest; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.index.AliasActions; import org.springframework.data.elasticsearch.core.index.AliasData; @@ -136,7 +136,7 @@ protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { } @Override - protected List doQueryForAlias(IndexCoordinates index) { + protected List doQueryForAlias(IndexCoordinates index) { GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index 7b20df10e..fc7a4da9f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -33,7 +33,7 @@ import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.client.Client; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; @@ -133,7 +133,7 @@ protected boolean doRemoveAlias(AliasQuery query, IndexCoordinates index) { } @Override - protected List doQueryForAlias(IndexCoordinates index) { + protected List doQueryForAlias(IndexCoordinates index) { GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(index); return client.admin().indices().getAliases(getAliasesRequest).actionGet().getAliases().get(index.getIndexName()); @@ -144,10 +144,10 @@ protected Map> doGetAliases(String[] aliasNames, String[] GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(aliasNames, indexNames); - ImmutableOpenMap> aliases = client.admin().indices().getAliases(getAliasesRequest) + ImmutableOpenMap> aliases = client.admin().indices().getAliases(getAliasesRequest) .actionGet().getAliases(); - Map> aliasesResponse = new LinkedHashMap<>(); + Map> aliasesResponse = new LinkedHashMap<>(); aliases.keysIt().forEachRemaining(index -> aliasesResponse.put(index, new HashSet<>(aliases.get(index)))); return requestFactory.convertAliasesResponse(aliasesResponse); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 884a21c3a..8866f2b7f 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.Objects; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -291,7 +291,7 @@ default boolean removeAlias(AliasQuery query, IndexCoordinates index) { * @deprecated since 4.0, use {@link #indexOps(IndexCoordinates)} and {@link IndexOperations#queryForAlias()} */ @Deprecated - default List queryForAlias(String indexName) { + default List queryForAlias(String indexName) { return indexOps(IndexCoordinates.of(indexName)).queryForAlias(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index be42d708f..8631f4611 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -19,7 +19,7 @@ import java.util.Map; import java.util.Set; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.index.AliasActions; import org.springframework.data.elasticsearch.core.index.AliasData; @@ -39,7 +39,7 @@ */ public interface IndexOperations { - //region index management + // region index management /** * Create an index. * @@ -73,9 +73,9 @@ public interface IndexOperations { * Refresh the index(es) this IndexOperations is bound to */ void refresh(); - //endregion + // endregion - //region mappings + // region mappings /** * Creates the index mapping for the entity this IndexOperations is bound to. * @@ -119,15 +119,16 @@ default boolean putMapping() { default boolean putMapping(Class clazz) { return putMapping(createMapping(clazz)); } - //endregion + // endregion - //region settings + // region settings /** * Get mapping for an index defined by a class. * * @return the mapping */ Map getMapping(); + /** * Get the index settings. * @@ -142,9 +143,9 @@ default boolean putMapping(Class clazz) { * @return the settings */ Map getSettings(boolean includeDefaults); - //endregion + // endregion - //region aliases + // region aliases /** * Add an alias. * @@ -162,7 +163,7 @@ default boolean putMapping(Class clazz) { * @deprecated since 4.1, use {@link #getAliases(String...)} or {@link #getAliasesForIndex(String...)}. */ @Deprecated - List queryForAlias(); + List queryForAlias(); /** * Remove an alias. @@ -185,6 +186,7 @@ default boolean putMapping(Class clazz) { /** * gets information about aliases + * * @param aliasNames alias names, must not be {@literal null} * @return a {@link Map} from index names to {@link AliasData} for that index * @since 4.1 @@ -193,14 +195,15 @@ default boolean putMapping(Class clazz) { /** * gets information about aliases + * * @param indexNames index names, must not be {@literal null} * @return a {@link Map} from index names to {@link AliasData} for that index * @since 4.1 */ Map> getAliasesForIndex(String... indexNames); - //endregion + // endregion - //region helper functions + // region helper functions /** * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. @@ -209,5 +212,5 @@ default boolean putMapping(Class clazz) { * @since 4.1 */ IndexCoordinates getIndexCoordinates(); - //endregion + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index da17603a1..944a60711 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -59,7 +59,7 @@ import org.elasticsearch.client.indices.GetIndexRequest; import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.PutMappingRequest; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.geo.GeoDistance; @@ -482,21 +482,21 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest get } public Map> convertAliasesResponse( - ImmutableOpenMap> aliasesResponse) { + ImmutableOpenMap> aliasesResponse) { - Map> mapped = new LinkedHashMap<>(); + Map> mapped = new LinkedHashMap<>(); Iterator keysIt = aliasesResponse.keysIt(); while (keysIt.hasNext()) { String key = keysIt.next(); - List aliasMetaData = aliasesResponse.get(key); + List aliasMetaData = aliasesResponse.get(key); mapped.put(key, new LinkedHashSet<>(aliasMetaData)); } return convertAliasesResponse(mapped); } - public Map> convertAliasesResponse(Map> aliasesResponse) { + public Map> convertAliasesResponse(Map> aliasesResponse) { Map> converted = new LinkedHashMap<>(); aliasesResponse.forEach((index, aliasMetaDataSet) -> { Set aliasDataSet = new LinkedHashSet<>(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java index 37dca2fd5..fe189f59c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/DocumentAdaptersUnitTests.java @@ -140,7 +140,7 @@ public void shouldAdaptSearchResponse() throws IOException { new DocumentField("field", Collections.singletonList("value"))); SearchShardTarget shard = new SearchShardTarget("node", new ShardId("index", "uuid", 42), null, null); - SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields, null); searchHit.shard(shard); searchHit.setSeqNo(1); searchHit.setPrimaryTerm(2); @@ -168,7 +168,7 @@ public void searchResponseShouldReturnContainsKey() { fields.put("string", new DocumentField("string", Collections.singletonList("value"))); fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); - SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields, null); SearchDocument document = DocumentAdapters.from(searchHit); @@ -185,7 +185,7 @@ public void searchResponseShouldReturnContainsValue() { fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); fields.put("null", new DocumentField("null", Collections.emptyList())); - SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields, null); SearchDocument document = DocumentAdapters.from(searchHit); @@ -202,7 +202,7 @@ public void shouldRenderToJson() { fields.put("string", new DocumentField("string", Collections.singletonList("value"))); fields.put("bool", new DocumentField("bool", Arrays.asList(true, true, false))); - SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields); + SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), fields, null); SearchDocument document = DocumentAdapters.from(searchHit); @@ -215,7 +215,7 @@ public void shouldAdaptSearchResponseSource() { BytesArray source = new BytesArray("{\"field\":\"value\"}"); SearchShardTarget shard = new SearchShardTarget("node", new ShardId("index", "uuid", 42), null, null); - SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), Collections.emptyMap()); + SearchHit searchHit = new SearchHit(123, "my-id", new Text("type"), Collections.emptyMap(), null); searchHit.shard(shard); searchHit.sourceRef(source).score(42); searchHit.version(22); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 490372ad8..2d24c4c66 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -47,7 +47,7 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.update.UpdateRequest; -import org.elasticsearch.cluster.metadata.AliasMetaData; +import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.index.VersionType; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; @@ -2739,7 +2739,7 @@ public void shouldAddAlias() { indexOperations.addAlias(aliasQuery); // then - List aliases = indexOperations.queryForAlias(); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); } @@ -2753,9 +2753,9 @@ void shouldAddAliasesWithAliasActions() { indexOperations.alias(aliasActions); - List aliases = indexOperations.queryForAlias(); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).hasSize(2); - assertThat(aliases.stream().map(AliasMetaData::alias).collect(Collectors.toList())).contains("aliasA", "aliasB"); + assertThat(aliases.stream().map(AliasMetadata::alias).collect(Collectors.toList())).contains("aliasA", "aliasB"); } @Test // DATAES-864 @@ -2773,7 +2773,7 @@ void shouldRemoveAliasesWithAliasActions() { indexOperations.alias(aliasActions); - List aliases = indexOperations.queryForAlias(); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).hasSize(0); } @@ -2829,10 +2829,10 @@ public void shouldAddAliasForVariousRoutingValues() { operations.index(indexQuery, IndexCoordinates.of(alias1)); // then - List aliasMetaData = indexOperations.queryForAlias(); + List aliasMetaData = indexOperations.queryForAlias(); assertThat(aliasMetaData).isNotEmpty(); - AliasMetaData aliasMetaData1 = aliasMetaData.get(0); + AliasMetadata aliasMetaData1 = aliasMetaData.get(0); assertThat(aliasMetaData1).isNotNull(); if (aliasMetaData1.alias().equals(alias1)) { assertThat(aliasMetaData1.indexRouting()).isEqualTo("0"); @@ -2842,7 +2842,7 @@ public void shouldAddAliasForVariousRoutingValues() { fail("unknown alias"); } - AliasMetaData aliasMetaData2 = aliasMetaData.get(1); + AliasMetadata aliasMetaData2 = aliasMetaData.get(1); assertThat(aliasMetaData2).isNotNull(); if (aliasMetaData2.alias().equals(alias1)) { assertThat(aliasMetaData2.indexRouting()).isEqualTo("0"); @@ -2894,9 +2894,9 @@ public void shouldAddAliasWithGivenRoutingValue() { long count = operations.count(query, IndexCoordinates.of(alias)); // then - List aliases = indexOperations.queryForAlias(); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); - AliasMetaData aliasMetaData = aliases.get(0); + AliasMetadata aliasMetaData = aliases.get(0); assertThat(aliasMetaData.alias()).isEqualTo(alias); assertThat(aliasMetaData.searchRouting()).isEqualTo("0"); assertThat(aliasMetaData.indexRouting()).isEqualTo("0"); @@ -2919,7 +2919,7 @@ public void shouldRemoveAlias() { // when indexOperations.addAlias(aliasQuery); - List aliases = indexOperations.queryForAlias(); + List aliases = indexOperations.queryForAlias(); assertThat(aliases).isNotNull(); assertThat(aliases.get(0).alias()).isEqualTo(aliasName); diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.1.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.0.jar similarity index 75% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.7.1.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.0.jar index 1ebf4a14cebefc8fe4241095e394c18d7b09ce34..6d6696194791ba213cedb81b357b1601d2d35edd 100644 GIT binary patch delta 35473 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⁢Ge4HrTsK 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 P1Aj{ZIn}xaV2<*CnUAuetTD|(5 zQ>VIWHzy%P#Umgp$$~?`fq=lkfNX|zCLn%8{A-jb-;v(+KtVv%6NK;q`YLlW1I!ry zOb^6x-PDPhONl-+^89q$XRL9XQ4V%5?0D&72rlnfh40Tl5o#VK2U^~D z^!trfP@2axByGi#mQFMQjHS2Ouj;Q9QR$Tnxj1%Y!8PCa=A1i8B+FwBh0LQ?&^5_d-DcvLz z{U(n1O0r)$$Em08CEge4kkw zvxCfIet}wZE7E0V;A!yjS_8!U$)xzOVJZNbpF#hh{y~3*Z)*A-ZjTHCVn7c9f&l^o zA}_AixC$DH4DKJ&nPiIE0p9f2lAw|PXT{K%{<9uvT>sg6G(niZekI}!tNgTrZ=j56 zwqW3dX*HLiFs*nIVCdlgi)zhv1CxRIZzXL4X7O*2sT4FA?7zLN956+2r2l1^_f>bL z1P1{Lf=(lq1EWr({{ka!b+-m%`gg>k9~2hyza!b-KyCl+;oyTB{+Fil9_{X5KA#cL zUWos~fJLC8|D4(vg8vqJ(|rGYUeI9Ru>VCB)PntO)&KDE@SN#U{^DaL^*PX_2||HG zwc750GXFyYH3fYE{g37$0xBIg7zoHdc$%@qUz*p4V3=vdvtTfd`x&JFU

>{=p!2 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 H4buMung-3< diff --git a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties index 976f2f897..cc693279d 100644 --- a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds "built in" analyzers to Elasticsearch. # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=analysis-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.7.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.0.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.7.1.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.0.jar index 70314609896d929e5dbd75913dc583748b0a73ff..f43a0b827bac44ff8ba3e742aa6f5d887f46eb57 100644 GIT binary patch delta 1231 zcmaEVfbrb{M&1B#W)?061`ZB}iF3|Pr|9&s4d!Y42!0BG~=Vz%iBr~=; zJwIt3wY*2n)9tdwteLBFC!ATkD)d0s)A@%Yx5tOf>OH_VC;ZdH3Tqba>n0qJGPbbA zF7~L}6P~h0=EEez7RHpRXTmjB@2Ov7l;Apl`rbLoCm+9P?m3gT+G+dqb$2ZT`oH~G znp=7~Y|*jJ3;Zq5{xgrtxUp;NN2N%|#|C|I=C|3*SJ?gt@Sk?dTyf(@)4e|~oITnd za>{bbzmF2nPd%}EyCJk!z5Bp6KNYX)HE-i87q!_d-E?HwYVY{D)nl30_WSG$l#)Lv zMx@Mprs?TDX=AFH0IRso(#nGohCg~1i*tuwp6Tj&*u!1SId$v%i5q`6wcj%G&3i7E z(tPs7jkT6bc3N+pb%4*x`oONoF->bPPCohLZNBxd*sR1T?TyYyFX|%#-f7Oc&HEVV z@H0EkIX5|0a2InFkd_is1k-jx`e3?1$Q(p(zGd#r3Sw+hTEqwzP#0xm0y9>+y9#o{ zA`@hUf%pfo#2=H}5EaT2w>ZHftj1p;npfH%fJiCWwm}%HgsLEn9H-w9HP^It*ulE8 zTx^)ZjHSwI9K4K7BFylFGx>Lf32MrjY!hiJ5A<2UmMxFka`_n;;&d1oL>LfYN#lme z6C#!6fu0WFW89G21C)9K#KH(A3`-jQCtr$GG6ni303^%=m1BXc5n%Z1$RotSkYAJz z3{ixeK>pW^l4ddxnrs*+GC3-W2jud}nLwc=kdTZHn(BZXjR!>E0}bBI!@yt(H=luF zOXD1n26wQ2ofv7xN0TQ;t4yBf#5uV%MhGm*8!gS$E(uhm3>4;?93CwV5l)b1njj4p z_D$f^LUCMxcxt!aGN3i@fmk2Kx(7O7EnB0dz^1HLBp|Efq!~RXe~eR^ygN=D?9PqApuOk_cIWpfVX%-* zyfl-a3)CW+$+Kf2dSAy#Gx@lIg|%Zv!FF>^=w^Khv|Egwfx!aqA5h>|`vMi}PyQSa Zv84;BcUJ&d@2MD($;ab=;fAZ7UfwtxDO>Xe$P=aAnl8a=@;*`ya9WOQ3)<*<|g-+!SJ~7FJXWt2z{PIh?_kOz_%f$OQ@yxGX zmFfWxT?3B%-1=bGMX!VB%x-;L(R3|IVo!d#ZeE~e!M=HGmS)!`<-Ypy%BehDJ;*CN zaL4oDIkVNaXC9xMBO6({ZL`g!Q;E5Jr;JViJ-sMrv*M0q)Vd0j>8pNQGO5mN`g~9* zbyk2=@g$LKvj>__uha*+Wd_!?ADrE|>FwU53g`a4RcEWstt?2qnLJB)8gE9)eiMbL z9<^Ib{42Y0#Y~HhZFXJ43 z=Gx{xlVb#TF)sqrl0u4L+Ez#(Oy>)kgXqoo9IKeXj46_AV8-OPIv>CS`wVVzf*J3{ z7cqhv#{<+jxMA@N(j4ig!w#02ZS@7B_v*PZn_E zoqR41VorDER?dyUj3dd+z+eS8hk;>Bqm(FE@mVXb$rmK~C!dRkXb?~B)>{Tt_#TM$ zQ8Xxv12t$(u8$E0h4|$EG15$85@0hv7;sPaiiPNxdK_C94zzFzFklQ&^nX@_TF5y$ zAzBFR%SR`lRz6^7VCWTKU@%5eJVP0*_-BC7WX%|e$xT;Mi=MMFFvI|3P76ixNo}y= zZZ}ShV2O;CX8K_SwOC@ZWjw^J4#}M_TYxTP1zK){V%B>Tuwnrxw#m0+APIg$lr+;> zbFlD-C>5~78~(V6*#q@|0tPEE5y8QhMqyj9!t^+Ca3~!B+CRr0C}cfZB8~?vbQc&? r@lIe>vhf;Vp#|~MOtCItp$GBG5LMAYjqX4p&B;LtVr*|BKz0BCIOE8D diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.7.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.8.0.jar similarity index 67% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.7.1.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.8.0.jar index dd9c83d52521461f296e80329b9173acb8dddca2..43b2785edf4eef5b0033bd1f8a1784c5890417be 100644 GIT binary patch delta 8358 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 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.8.0.jar similarity index 83% rename from src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.7.1.jar rename to src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.8.0.jar index 8cb83e99573a18100362acf22ac3c79ac6186f07..aaf99310713b55a4927f950c7bf9f944328df862 100644 GIT binary patch delta 12049 zcmZWvWk6J0*PcUncXvojcS}i!iXb4}Ae{q>bPq6qAYIZO(jcHTC@9jXfFgn@CF*x( z#(RCapZ=J`+H0@g^QO`Wxd_1@gU^0P>gE6hVwk2x z5A`z|cNr2U>88IRj=p0aZ=%S-Z79U4#j8txPm`yty|%|2qsh)rx&>a^+Q)4LW)%&=n%y_l2k@DwLgA$p( zpGn{F&mt~1TW3?aC2z>rO(x4$G29Ajb5-YP9eTl(;plR~Ud$M1@Km(LBF;(B?<5QZ zs(lr6JFLu`4kpEodz+g*&3nK$*CElqWLh||(csA)3hD20di>`vz6!J3oY0=M1~IG% z3Q*vc#5E>KcXi69P>XSM|&hMFoA~rT4D!EF_B-w^uTN6SF@V)3k*cRX2z#h=!lPYeAa*X-(do_ z08&`WX)B6-{pu?mB&Ef&0x7G9F2b8c-V>z(zxgO1%MmLJb{52#{hDfp83t z3OtCsFd&dd99SJQ7kt7JpoN;Q+#tU}@_Qw;!NyXJ-KuJaxK)C6oz0*I!9TiNAF**^({UzqGQRn=+>76E%)QhrdUMi6Q}i2i(!FM9Nr{K` zTl~Rx-+KrS-8?K+6^Hz^(4i+Crqm84&bS)c%Nt3Kk&M|?HgZk$MF*2*+EqLcg2)04 zcg5^zf+?~-U(_D3(`V5(uhUQc z=A#(p9L%;&!}ntjX zm?oIm;Ck?(wT4EJd9l+Unki@2PQYIo)vngzlz=6YRcUgAnr7}Z(eQrvCk)nrLBCZe zyr%pBN#|X`rR1B=9*a>{Y2UOx7dMmq_TPS$HR2lV(%sdiTI=;1OpeLhxvt=1|Hj@^ zx=u*jpM)p(4c1Uq>W}(QvA6t;gyy?j_0Uv{PWw^_HbkEkwg*o1&p_{dbxt6zUC6x? zJwcEC=$=r_aX1_kjp5KqQpjVbeZg_uA8zX3UZ$ts5us->%=n$$FpH-cgU4B2 zJ!{S~{jRq8GwN7A=Oka;;2rDMnb+aGCT3AYf0(- zsDSn4OuoB0rYLjPvfCIL2ZJO#g_sv43 z=dS!9(O(M;pXntkyHY8ZwBXN|CfZ)fdBVOZ(v+3-iDv4{=6uPjYD~8*+ZXAeH|nbn z7RPfHw*o*_3b7? z<9|OG{j$QL#6sb9njW^g9kzcoS@8SfD_;a-M@>KbjN6;ThQ~8=$)viUav2%%=^ZTe zWj87_ubVpv2Nt*|F*np!KGwVK58>o7H7Hk!)Gs`b@;Acg787OKrn`3Ltn|8H_`m$@hL~E;%hK71Qcq>dD3nu z)KK#nebg!LTl%yc01#_ zsL7%zeaD{t_}y$;YHG5VLTYDTDG@@M39uHq(oF?7HX|tAoNZ}N@lf@X)w0z4RiVvF zowlxqKeHd9SN#SkiHr5DYhSK8+`_dKb!7Lp^Se&_m_9x)JqtoNQ(35`F4~4yb4!V} zFxjq1Ss-n8C7tnjgEdl{-NRg>M|jTph0v(KT#a>1e7=#9ebE|PeA>Qdc^)paKfYUf zN2)m83rALH#srCtxt^06@ou`_$a_Od(iWVTx#v~)2Y00yUm25;c$typzqS3C;Hxyc zJfCRha46!y=XlYWt#IW>4z-84eBCDQo_)%5x8qI%^ZU}IG!{RL(<$(lj;egTEzN@y zPa#V)tT6`Mw`)9@^nY4Qcg@tU^HS>T#K+$cnW{7yfxda9iNP|%_i&F|Q^4hyoUP+{ zk0vdVP{7Pf;ww`9!qf5DS`qghF(fA7DunLs{cA%n zPaM+ZyE}SRKAIp+fL=2${xUM4YBuzK7Xondy!f@U-LaDbNvsi)%sym zWpQzN^{$F%E56>x71!f(U%Ztsd}hx;RhcRNUe9Ww;%T$Y`xo0|Uc}AB$sf;F^n(ND zI~QgPZNA#IU-R^L_Ht8~KCQLW(|qL6RQ$r&M?Xvl+vSXMhiWDsPiS!@-SbH9cf7E6 zQ+&8aLNe62;gJjG7piWcIVy4Dx(rRHVwNEx-@SWPW>)3Xe2h5Fd>*FJQx*e};e56l z-}Q#v7tmU7mnl)*Yj^(WFN;~`H)8T!U3Gv{K`Lt@(mhouAd>umg@<`7iu{6lT{+!R z;Sp{~oUt{TW{Np;Y3|W$E-%c?ZX6GS{oE1uzD}`_@>#mW6_vLJL(>QP8_#3= z7EWYeLe0ZH?iOITvqa|xUa1wR;;lB+G!=jN*flMJZ{gHW+$G+fM<-uY6m%Y$wtR&ib1au;(2UYS2>|y=}HoM)JV4w2T?r&F*)d@$gu_ zqSfhxt9O)nTcHs*4(VPv4efv5ZxY@+bsAOf)*Acr!5MqEnQrxkvy|#|x3sfk z(4+U)r@XkHpAqrWum6Nkol#&=`0`4@f3FDg?0C9)Pg{oKeBY3t8~?gDZaR4Ov8N{L z#HUQHBR`;NA(SvlcM?X^^I>kRBdb#)KVS=1%VQ;YrI}3ro7o&RHf8zAcctDRf`wU= zUZm77E`9_5%pJ(7qdnIII6}?~%@>K+Q8Pv-Co4X3txYQdw4mmUaC3kT)!4_dfg%y9 z1BR%M4nx0*kqhyxN8_kzs2rAxhFmhYs5z(0p+g{}Sg;LmE_mu7KmzYG2e6uJ;&f5+ zM5q%mkt=Rad7u_WDq;3TeTbFrqeif?Uq?sE)4WE%zY5ALzysy+z=gU2`gV3@UsJ%#NAP|ijCG3MC7P23eW`$T0xE~#(LG*(Y zwE%?hLJa^1iW^A(jPloLQ+HFh0-IN?mP!Wst+o<~bZq{I2CdiuZ40-&k&N8dmMqCE z|I8Ir%?OpEnK>h;A`9L!?1$xLEgVXD)eHje&c?xOCt+&=xWKuCzktqH8SfVr`ngAp zN2|YAAI;9fi4`%ed8-MF2^4VOU%jZbj-_+BQeI9u4qYJ2dXgQtkzHP4GM-#Z-{NMh z^?Ic|%|KvWnD&a9bC*NCLuHDuyRkn{V@q+xUHLXG4)>(6Oq@a^6@zP(cF|c{x409p zkIdLo=Z*$%p90#PjWNbSe7ZERI#GGpe?}ep~yx&E+GNYJRi4qwDTXxWgNF zG8F<*ZWm}OTaJoXYDd0c3DZ2Si&l}c?v2qify9ifd!FAGoT3x4^0eBt=&LfcN3-8P zE4y-wQ>13(l;iWe&vWjLf{kSYvA41XHu!0MNF1^y1f7r8CB$uD7j(uekLR!Z!HPUz zl+6<);0f%zxw_^_QL=GQ!$g?zHQ71S44Nf|md3Q8rY`(a`v!XYuj$SzhGuFluJOnb zCP-ONIn3Y*kl$!>C!d@Xk9)JV?D(Yfp`;f3D}R+7qC7f#wb@~VDO%x)$BE)6m0lVN ziO*t5v!(n^S<@oFAC>vo<&DFiv}Sl@yI3^y&q-iJ2Lb#gXOWS>3Q2!4lj0E`?Y1rF z1I4Wa=wVb?Uz7xz^{xs@{eTOut6j}AndoM2!f3r&3u}&@*D^uXGG$9_IOiF@diGLl zs!jvfu@76~XLs)^t6(#_hjxkPn;B~d=jV{6FMN5o!}3Vy=Cs$fs>I{GEWIZVB-HCF z`{zjny_&XG5NZ)kRg1m@`_M+6YYdO1mYQyvRzSzx53kNe@xsGyLss4`j1T2fF5vD= zZbTJ-ie{XW31Y2zlhB!=WB08P&T36hBtNuEni5M;%&4&6C2;jlOs!g~L6iTK32*ra z{koe>6M)4?Lt^?Ikw6vK5QCYGpJUdJKvM>#9-U2He!uGL#zCU}@`VF?z(P;+shrxG zUj$TRosxiBUGCuHuKyQ^+v3*^gNMo-931wQG;FC9Rg>~}vp-QL&jzKzyj=FG2ZhCO z-`XWc80qMGmzP*Kw^W;K>`y^_qoVrrB*!~QC6h46hQkOlRqYZ8bD!%<_QY;DkXmWy&NUHx zzAx;^vDvD|P**k!m-R?HAfj#Glz5U&{yyDf$v`sl21ix{_fiJp%Mq8 z-?jMtxUSD`UMbYlb95v!VbM6edauZ({D5Gzq43>QlS^^E8TrXxsRDo1?iRct4&&!f z{@sW{V+<5%^z}Ks9>4^(o(i_`} zQ*QT}D{6n#6Hja2?dYjUe^%ZFd(nE3#N%Ayr#tqmrRW-8r(izb$-05^6&M2z$&8s^ zhM4_He)`*$i^1I|A#R)^DingD_s>2-vpF~Deb2q0T;T0q?|f)GwQI?uG^-RmXzJ=Pn@QPyq=qcrM%xW<$qeaq>LUVOh#+1MR7LZ}n zzy4OryH!=IB1G)Ad-aeaSJhxxYvw8R2Ia4$-APbNvu6!n+6tLB#fNTjuWB#SJBm&fIeOA6^$`X#T+RQ9OP9GJ2+fQ8 ziMd6PM8AU{bqbX%u2pBOO^N@GE><4UkzKLf>NHL1p4uDEP%0k-87X)J3he*3sYCKzMBO``qf58}-htX+}3#_uc+9@2@OEUWk@>}0hkUo?DLdhaS`U2i&( zYm{v9r5JDDV`o)h`0(2wCvrQDOb4p<-M;kOJ(**?^E~~N*AftyL?1 zD5!n#TvQ(II#SfjN9YukS7{#coJ+LI#hg9-@xxhPbnW8&a8f|Gj&=<)r_PIRDEVc? z+~o;zq>IYg11A?edzBHMHbwNOt=&bT6tYAcSFZh78=mo{@dOw@xrZ1$JL&PEXqWt4 zHlKm7*aCa6s#9Q z_VuG3>Tq*ys$d*ZrwdG*-z7mQjAhf*&mXhie|z*U|LUf%c(2;a-fnJ&7eeG^&Bv7H zKd#i~WBvA?NSo=}k;>&H=#3S`wIY8Z8k*m`rY3Z%97!b%;9Kp~^$f;b_)$%h4A(M zrr3_IjMoP&{tZ7><12%0{E|Pv9b=P|I94B>@rCZ}cX)nxbG(3f#7!wgg^Z6`*4Dlk z4PcjvUN|AsbWGU{DwjXJ_AV?@iJRENCdP zLnj3rn!-rXd4AF%eVE%c-`kTyu8;Ivvg3CGKF?7i|Dda#D zu)aziE{GO$LWQp{r+qZ_u{mhy$P&Bqy}_N>ew|8Ap60EaI+NZLC2P6V!do;KqXzyA z%5+Z^&ebhbsRgJxU9~!RuxAa*;|2q)Ru`2;)^wyl8+qsLdc0XD#h(4qYQPz>W*{fK z`~mM(#0!IU7KL9@Q|o&-0pDwMTFagfW7jrLUS5071TF0B+bWRyaD2x%q+WRBMV|DB zArUiHm+Q2!$^*0FNX(oGmze{_zdHrQ@wYN91JF#`bc_zg5*r#7m0Dhe7W5NQr||3P zJW`0}HVwVDq$)t+_J+fJ~(+s$#Xl$bM;j| z^tsk~AGZ@dv?4MDCPL?ZmYO3REh^xxc*fe*tZHZ@9Cchx0p^6K=MNGf@4)g9#(9I_9L2Nx3`^9rC@f&5iLa1&@!f)2U zw(Q)7=L9QBXlMOyO?XoT zFC+YpZ~tW(ANpB(ZPseaEq|`G(M_iIN<3C#c>i+`Ie5#3RzyG(obX>{J6r%jZIn z-BeoVEtJ`=O-0Z@pf=c$7c{ELcUqzp7{_ILQ2vSIgSMLF_Vb+&DqA-Wl9f(=RG(t< zHsq_?6FP=r(kT#AqFJrqAbhN>H1$3T{oYHzRoAaypnhkP+b-LaRXM)XGQL)7@@q_? zaR+eRo~ibfFV>Ym$<&-aF=V8gNydyAj56e^&@*&d zzH6lqR|_=b&Ye}~Jzl5swZ*TfsVCdAPF8$8bQFOeHaV-RV)TFxJN@c{Oln5gRAlKL zChYXwASk2e$MW@0QTTFZMiool{%h+?l83c<9^$`Q3a%-&w8w;FayBR=+&)g&sI4Dr z7f%ovVl(1qWAYHURDP;7Tpd(z{j@OqEr)MRzw1sSPwt#IW{At_EP0h|N_njQkyG#Z z4wSHmbo%U*r>mc*^}OkF*v^$>=B}u;{sI0GnNukK@~8$?jQBJsLy#%nY~HiR*c&PW zWJVmNT4NQwa1qj~?SL)y>yBxGOuZ3dOyQmB>Rg-CK321t&uTt!Zc{pPnAE?r9LS*? zJ7U^UJ)&%7AxjNm?2QyW;I-LORlKumfWlGNUY@tVcqp7bAfY{ z70&mdg(-C(D@3qoqIzyV^S(YrVjkO$%|6VW+00t>Kj_K) z2~zRQTT*r23?bMuzv6K(l5YN1BlvxvRZ1z2E7_o0SYTn0!d+@3YTAb&mQ?1)+rY@k zmYBIv>@|Cwnc9b`Y~R>=HJ;O}@%5%K&-_ff%Ltu6~&iz^`gO1f=$!O&-2Y_Vk!5a}AO{VEaemBwB3?CM3jtBVMZ&sC8@ z;ZaKRUZ`#6{qJ~9Uu+)UXTt2k^S2n~I;A-4V{N~+Y?v)|fBmUbD7E;bdRy)bkJvYZ zPzo9-OT@TbT{7CYuK}2>3ij6m4g^F?Bn~Dpxp_;ed!~%$8l42aT@rB5?xl(4ac623 znUGcJ#LBC0R-d-wd;4%6YTeje>mYN@9Coybv-0NjsNx78&O9|O_YwED#{+|N|cI!HiVo^b#CX$`p7Cm!+rqPc*a;uG+b!A=F82hoO!8l z=WaDeefer|OV6MdtM~hL(;jtB_0O3E3{26H6D-eDElV!m8VK2?Mcc607Bk+8j;W<_ zcu{Y3iC(-y641FVuU?H@>!79`eA1u#-OvyfNDOB9&v} z%4U}>tv)WhU6`5q8R`-lwzAuUb78vSq8cJ=uUU(?Un}g3w@A!kMPj2VPT-bPr21y= zy-RQ8&Rf^8k~Ujtu+Z*An(bLr(-fmAf12+PHs_@$f^l0upZn+qqxFBgw-FcA z@4-@t>Ul{|iy}p$A6p)Oz$>D9(B*sDJ+nRE*O%jMss4LqyB9kBo`DuudRA9>S+PtM zi~X_Ma@ja1;ZL18_gBe2-xvz(om&hsXok*)C5)_i+=haJ9d-#PjAq#_3dh{~y-49~ zWL+gVMZ6NYB~?Ca1FMON-?^}j-tN3EzRq@6TO(7SJ z9ES8yYI;jI>$o&;@HvW&N=z}C7R3FajcX6cNZle`9b^pN=GC4jz0M`-OF#glIsKoP z6JS_23j{vGMP4CEXPKk!ixN+eH|Xu!_JA1%^7QS;!2;Gk38Ipr~t^DvkcHs z=XWN!fH3NO4BGn+bumxsF^D>tdqf7LqpsSwqe4(jbnJPkvpuKzWE4f?7dP^wy%7$u zq3-NyR_@}GB9dl*S7Ig?69RE1fIuW*jm+$bqeQB9+!XLx01}!TZwc8Pm{r4=mk%1@ zgaZI}yKyM6j2i8cDGTcCt|0^Xg*v0OZ6S8K2XD}S_-ZVwo#LkK_H&@9EJYd7&-*dV*FGVCxh7-Q1Jh!)c}040Rfdn{-gc#3xSY8 zekwa6I?%&E6#)cD_~!@!g$N=WT)G$_U_tok$NHUAJn(Gx918*w{kJ;=(h|8&2KUwg z*x|%Y00CUD79d0NtLt*(hl1mwgMJmi#4k$)SB8T8O6mYE+^Z9yMg%6juLB$uj}|%T zuMU6q#g*PR9bBTIFZ14SSTp{aUhU=@S%*_B@mSo2&u4!UJUr{GJqc`!=)0G5uu3E zs1mq>6wwlFa-|d$@sSctic2D{s3I_^A-UW=8z=@qGtYunlE1{ob{&C93SLnSkRwNt zZUaYA&_~!n7M|7y+8q(A8$BRZ(-6*D35fm2l4~Kh8Uvsuck%!0LJ1Qj*5^+EVt7~M zACLciKm&nDU4o*03&{@7hBWa0M$k`)Gx#1c)_F8gx*I56<`O%}9VELm=pq==XCnB& zuC-)2*iryva1M;Y%gVakMJfv;*2accb%U-&gcM63s2aKhC`<^he-}(@gdk)~d>NQ= za`4$IKnA{E1|T0S!D~xFb`uYj)zHfRSdA88pBr9qWl=yFr7HqF@@^eOK?=TylD!1} zfe#`Zgy8fo;GGJ>z##|$?}Lykjhp;q0Ypl1owb&I2YrVHdRgw0khh@-FG;~a*8pTl zz}FGju0$Y&fT2T(1cGds>;fC~68;TJg1=4ryRzUX-1G_ak+x`#}9akPtDskASo?jD#e7 zA50(jGB8dME%BXT3)ORE%kxg~5eFi8JP|bqZ}P7OwP*k~yubBN98cAQ&0#YLGfBcc zYp~!vbpQblB0#@B9VmlG^Z-<7)(Z&K*N{H5ajmZ30RdlN|2Kim-XH-plQY6^Hvf|) zPeAE8D=0)y{vZ-WC~&a#7g69pHcebu+x7>AV}Sv2Ih@sZkisWSiQsR^{>ejxdhQ7P zlzV@MMuj!fvcnW+=M!M0T>F2ehxQOT^aRKK&;Dg6K!l6uhuQU}hE z((67j{w+O!ukrpHi+xmvuz^YMehbUC=ca-#$w?pI+2 zHvdx)|J`kXVXSm10KfC0`uyF2{98rIV<^M;I$rBuSO3R-} zi$mDyy~01E|4$K9t^ivUR8bwlB`Gs9EvgYyS&Sx%pP8HpzDx$*#Qs~}0Yts(x{m6k z)CkVhh+w;d2O-)6DHL=j zI&dP`0%P{_!thZ%Y7DUY5yKBMfd5IpzpMEF0?SMKFR;LWfc;(9|2JcuQ&FA%S?bdv ztK-WrU(ixPWZ(Z^HW|QB{NVikXFrdOHAGY$B9d7l3)L<>_-6shKMYbKk5N?DVSw&G w+W~N?PLEbx2+tV;SdhWljUc=%gufXAu2Eou03Z-c@V_nx1ma!{+0!ky@jUX)|Au1}cw1j}LzzQlI(%oGuAtBw}4I&^2 z|Ce3A*USC?xX*RpXJ*dl%*>gYlf9u=;)1W>Ybc{*T!lceu_2RwwUPKN_~4HQ*^iXZ z#sCDO9eIZeW~$Zsu!V=HmgpaOUAd)bH|}k49?SOQk)%V>_Ary;PpqAMajkDkn;`-umgjX<4{0$-nY4)bFY? z?L4tX`#Y>d2lT2|`u>bT1t~(?BFqho9h|6H$qIA!QY+r`qjTC-qOp~!1rcwLZNk6q z_W}K0S~?f#NC<(LaY7)Z5C}w7PUmjPFz}iX-P5lYZb4j)J^}vHLK%p`Uky+If_Cu_ z_y>h+>W~qlL;m7jNV-9VkS+3{5(F15EF5wQR?s1k(<|_zNfrckIY3iVG`fd=Ayi^f z6pD%b;EtR{Lw+PyyCGQ>fe(NWD3Y)@1MUSc)#5RVP$o2pjTBb0Cqp$CmN`ICo4oH+qT*lk?qF~XYX z+aF$aSMgWuuOA*JLRfe#k^(F^-{!YTi0d@tRB?TLs(f^dFlG@W=H84kw@#a}mX^-_ z&c;~_im!N4c%x4{8gLJ!$?Yky_*jf0t=-4oxMZkUm!}HkYzx_)EVEtvsv7tsdM6;> zX6072&<0`o;%L3Y;B1@EA}5SOg=?sLX92r)wyUF0fM!L&xk;ARwAJlr*vOMdzfLWg zz7;;r&54I5l-cR4+ZVe%)0Xq3o@9C1t1P~%_?V-6r@mL`9FkP^lXuy`N|6*RmNKfO ziCyV=w13b2A$IFq(<9aqe8*ZdBU8m(0cYWGrLtSnfmu&VYhMu<8II<|$VCP|PK7q! zC&?EoZO{%Jh@Y8am#K07eP>UOI8djhQIBFQn#(kQX+0?6_mFT-&Ci>MaJ7#ju>~De z6Pj)IQIAa-RgDLkT|Df?gfi29KW}NmIUmh_k^B`e zi!0~N`%Zm>{vf8A+$6&`cB+w+?Az>BIUAb5oJ#V@UK%-U)gn0x)sH8@&u4aN;-iSM zyW>LEP-1PdY?B~^jPCmAzZE5CLBcij!yi! zWy7zCEr0DZpBP9Ti4+wPpgukhoOqU6Qk`fEdul!O+pT*=nSJZw8@Do7`6nAQb4mws zm5IsjuU_MbUZ3Tdb@@m;i8GR3KopXBldjj;{2B}Vms5sw@N?E z!bTYf-V)~$e#lcyv{Cv#V$ z^SXq$*SZ@Pn14@`l!n3j8|&IB!YVz!s!+7V#o_3Y8@eql-k=})dCTeK`*A-k~uV<6+LIKXe`QZqngk< zO>KWeCWxhCs5M-P=rF#4i#21;XkpM@YneuNs!3lf3ukxle+qqaBjx?RmD`i#T@H7J zq?6yer@o{k-O0s)CG}|diLbBvaPQ<`_0ZEVyEX%&Yhv4i$A_@$)Avux_Ll}!s%>ei zxlP+-w<1!7tP=mxa zu9LQ%q2bx___kOJ;w%zk!ixC(Bvbmi!CL)7Q;jZ1Xtm6Ypqo6Y>T0F0gy88)@W4j} z?bgf}0@Kz%8Um++mQN2V%BqD6SJ}5D-N;S|O`8>G%*icjPGOi^^Gu;F@ypQgTJ`|D z?m2^2j%0EiHt2Weh5qQycR>UDHM@)%C5pER?>9;kHkh z$KQ^%jd#Xm?Cbru`7l<7q!o!@5>KZt;HQvHe<55slP@BGEi38bs$%TOoCb}R1}#R< zUT|EK%LOqgMA#d&*~L^pGPy_ zz-dYFFBU@;F4llFN|a@n8Z|XxJ^>z}CY0`DP2?O?LSv?nngS}*SHiHdAP{0gBn&uH z;KRG05W&{9b*w4Q>o_|{O$n~)_mvk5_4{Hne^d6+l%^*Q!g^qy^?I_!)#~uW=7wPm zXU)S{qYS~x4H<3K>FZCRJhp4b-+pBNka9b&vwiLpAeUtEZgju4=VYRQ8+NweSpa!9 z6YmT4k?#x_Ud7?sr06TnAMGn*X?e45pUL*{20WH`w6v%EGvSDyj(R4SxVM%&S#*}h z49O?S_dAVgLKHMP3iZ~UN^<@4<4Ph$ zip4VUdhq4cl$0UF0~~f5eL;C>4&)lxpO_5oG?cB}Dy&|6x~n984|*S~%KgSIey_8L zCW2!m`9Ws1j^Rp$_k%R?C^p;X*OO@PnQuJ`3*0xvhTY_seHTkY+t*T^26uU(CC6`s zA)Voso#ZU0rf?9Af$@P%c6sYvH6u+g@1a0yjG;%!Xa^;XGb5tIYbn53RXxWY>(!_w z-+RwnezE3i7+CrZpO^!De|oH$m>^aH(n%xm)bA<*Pge<}4K!&6(+7Xwy21tR zvs?GH-_9>*MfwTHgaN2L=c9F(-){9I&8d2y-vr>7h;k|s=C~8fxEUy?yYYXvzu)>T zz>+yLS1v?^QLa`Xf?s@NyLq)m(lsefa z|CH!l4bxNeTf+3>s!6J>9Lsxm>v^ih+6jL<@g!}pJhT<#Rqm%)ih)Nm2~WOi*>=tN zj@1=c!WJge^VV_G)zbE&B8JbnxAo_;lj7qO7$^JZ9#@N;XlKZ(E^gBH&hZi84s^u3 zW^%9hPa1x7U3_9y`Fiw--c* zCR(MF!`;6eL*PG3R>3Y~n?G}>A*LwxW#+7qgU?u=7Cmm&xWLnzkG|iPs9pp zU@iM_^uDPKKddR<{*m3Sr%hq~?uDc4zJ#wbimaheYdR(@wa-5J*H#p%&fx0oF;?kB`$ae zruv~Ie0^ckUv5agV1reSOb9 zlOImBz1E=1!G8SW=OX*;g99_Y=5!Ob$IH?ma|Q3G)hD|^Q-w{gQx5YDXFPfAQB1bj zDQB(s0H-eI2i+V~#Y1KKX-|Ek2mBsyIIPdkFK_iTwi&bg4!N1&Eq4+z=;cinvO1x1PI_9ZG;tbiohId_dfl~QlSZ)u~y+c zyEhRhSpZo{u+E>IhoXz)Czb{G-ns293ej#-|F&ef(NqVEHXZ@fJMBV(8Sz|b z?4C`2duh}`9YuY23bII)pP0hfOjyZgV+$cs-k*I_TE<%a$#FM^%69Qqw{S-BBA$M_ zC&1VUFYpe&&zek4hSnkC81X1Rgq9ye$6x_RI}FP=+d?RG2Zn8s;MByrx)3tSyeWng zW5Ag70q?q=WygnFqx<=dP1PQu69)e2U6HzIzH!tHqEjE#X*tc+f;Q#)4vX|Dhs4(B0RQ%WhL9V94$_w|8U}uRiYoJzTMSENhD1BC;Y8NP;9Fy?S zz$qEYyQU!_JV_bGp6cqBDcK=drXCPene~vDmtnxhxJnf({~nhH zO-NfvHJkXxoORL;ySB@m@K^0X;glC~Pj5Tc#$IDFd>3DPVmcxtB0BRquToW3LmJx@ zjr?1CMYD7ujB_AH21i%Fy42v>reUMeeXk#n(AJW__cP5dj&x4Y*vyhR=k#FpmG^dx zZ74F5+cXiDW;>ShGWNc|mPA-U)W>Z>XQp(g%N0MgI-{bKlPcSjn=vaN24EH4Z_Qz* zZp^Xo9JTiT-lyTDFOnu^>K^8u&Ct1YAj3)Zy3)^{9hRaJOwoOhyOWZ$j*+uM@vG{7 zJJC1><+rQ7w4)TMAFFxMber#LRIyU(6CAQzZ8P4_IJ66?6$CnHRHdn37uU8?-utw{ zv4^4C!>Q&FYpBE>Wzk3)`IaYmI3tQDQSHtu_Hl~LVBC7F70$+zD5nAr4H^Nz+r%yN z9%T$UvA3|t6T!p5?sfh(J6K|Bdk0aDYl?(7u({35jIFF@ngeRsl!Xd+Xd-u5CX^HS zi*cu_uMya?ODPUqy*9-O!E;c!QAKK6ap^*FXH;&Q$V}C5dI(ZZdYej66GU z*LSK*^ucoXibr5m(=lCjX|fQPG*;}D)myzW?0%4>v^_RVcYeh z-8xT!1ou9>F6{vi-*c^bR(9=sA{O7Do#dw{bRnV$Y-y>yDme+31}zv3J}sGq=gU>U zVov=OM2?4TXS^@?P26Lc^ruw@e|@o;HbDf50u&~>^<%Moj(BnlB!RFb*>}8Ob00TtBzpu&5LJCe^(h(Jw4m>XGnE=PZAATkDsoi?5xe zN-AtS#a{rR`h8%_aFi2bOaF_?R%59lNDdu8ET;R3fys@8wgY~Hr2@BZ^O%NWE384= zpmv{#-X~;~IFIO)soJBdz6Mb#4YC{+#o1Jt$Lk#$-P_Uhz?(_EdBifZqV!?Gc=D_8 z%nVa``UA-apT&=Z;_f#q(0#e7xXgB)Tgg=t7Tj-7`9&#k(VstU7Jd|6raKEnePuSy zI+Vif(^l?TGt8~=AJb^DR@~U9_;8T9YPl&VKwu(kKEo;WQs~B zgybx1{F0H;L3c_AzSZ&I3?Jg{1g6KibRw_2J+JlRe^78D4th1nyOE?n`l2@`?+9aU z9VQ_|`+|H{nZlkupFN>%z%p!JXnQHgqCXcoB8a{#Pj$sZ#VP()$yHixdueOKl3C{R4&Gf z%2gweGg(5X?CKWSU*5%}T3UmPb`^8&U+b5*QmzZR> zPwJW8p&VqgV_kTDcMy6&W_AZ}jV`as^|pV(jA#m5OUn`a6`m^G`}4sq^0~d(%tfqK zFWEQU<)40-!s{q={!O)rVLi+KtaqI~d$npO(cstZ4?U?X>=QpezUdq0nAq4*O0lxK z!e)EV)T>8BB7Hl~EqBtRKJ=lH@N~HDpvmp|Muq9Q43Qnj?tL2eaq_`KyRFP4QLiS2 zhSq{z@zaEBCyb{)M`yB+Px;S68dBF_mrrDdg6Q+cz&j@=EX3OY@Z7t)1w0;4bzVcQ z2PT-;Z=*-c5lg;Upa!V`yx5lL`>xujOp|IdP1 zFXnSI*m4l_Vyy}{S0OJk4DUxn-gBJ?sKn8OD`j!Gh2b5Tj3Ipo_KFlBYBi!in3333e_^jOLciZx0Uimmljvbz=%wafhukCY2kqM(BlogD=&kc zH1CGYX56QAa<022P?CkKY&S8tl;BVquU7aaa1}?vI1d&b;uRaHUdHHo6^jDP3fe+& zW8&Irq;u5D7jduUKng5%HgRLs6heEcIn%&19$!T?kxh=uMjkh)dyW0OC@+fbH16#VYPvy1-<h6>JuVTlPT7QqKgTjkE|Ucw%wc~43@ zXj<;S?tZ5)tT?5!yNR1Qp&6kqJ|BS|Gx<5(T0F(7GXD|(_=A=Coy%p!x{iLBydFJo9&$icP+&Z2)?@)Yqx(!dO+i>|^19kHE)Kqk{E@0?RnE3pY zB>9zWpCK&cSJki^wvJdyqLX_k`52rF`n>p&Fpa5(rmWplji_It z@Z8xLOzi39za}M{9~)l5^YhCQQ0m#iC*OgHWWe;o6x9NZ(%-g0Hp3qHp51TZWU+?@ zGG;2mjs>=619P3pt{!j&^k^_oKF2X_uFkD~sq>VKs(4LvZiLy&pW;bn1m9w(S(6d7(xJQ+C4qPf*B}6tt=*V;8*UD$EIAASd!iKwm#}v1C@hZ5b07~S( zw&DgUFhqb9i_a>)%L8tme_?hC)$} z1sbj(uPz^Y0PCnjgHIvA8A@)(5n#kb2Va9A3X%YB=2OA3!5T z|K|w_!Xp_FxcrC&QI`w|(*0lW8&Gc-Adoblas+V-z(fx|bI>3F3LW2ooCWZIlK)A7 zziB?Y#BgU~GK75!fG2oSr!SabDMtQ*uKM#w1o?dz3I!{_t1Y*N@?Yh^7KrQ=fC^0r zd@KPaMT~GdpL5$oRNRD?t zK!+rX=Yqsu9ymj|2;yxnK!PN4XM)6jKBO9`J74<0sx;+*%p7q(Aj7Z{UHb|^dx&VjQKe&QW$^r0@n*a0m1H7!bb4ha@RRl37ApN&H$~q83 zP6G+-Ap?*gh_e6qM7bH{gzLgBR(KGdO#l>$yjRndj+(U0by762jl&Pc<_6qIDN%c#6sbpkofyB;=j7+CxI@P z{5xc1etSa~Pm&J)zp%WShQ#fyh9aGfRKv3Z?2sZ8OnAY+5k+uO1*mgDZwSMCd$Ew} z(Op!6zi%o2tHn8Dwg_PQ-{T5IXVo7w!_q-0qMAPj;Ub39|2S7dGAcV993T@gvcxYr z*R}pa8UbcEK7zacPf)Bs(NoO>UyskqBr}GNq;Xo|EnbJE~q3oclODF~G-*mumv- z5SitvwSPSO0L^g6985QR{Qs)qdvuXMxBgnL)(Dy+cJ@CbZz3(vF9oR3t9PfasG@-QXwdK4BoS=?f{h*a$NBYNtf6TX0@?($fCV*(HsX@CM!k(rB}bz?&$)c_m_)--?u z+4%3N{eKIV3@6yQ6u5^J8`$1Pd;5Q8nlKMa9dPpnz1U@;#u3@$s}@k*8~i9fxOHPi zLVXug+O+|pWCh(r(ROnyfmlr3$iU}(C7Hr3R zsYgH#zy^OCD%gm=1~s zI++=1uG&RZ`ROC6@Pwg%c^;`3(?9#$|C;S$1Rxj+{*3BBTV1f~Urw}eQ&flGGf!qD z;#_Xs;0)-Lsw@A^V2lSSQE;-yhpXBAYy7Kf0V+TO0W^YD2weIiz@;zB5vX{q0!@gu zM>VFa{$to(u;QRQxr0<>AmAawD*vptX22?ie)Q@>UKo++3tU0mZvHcs5FrB%hGOl6 zfviU@03K5Bv>U3O`C#}sfB_(Q$=!QCsII{PAp2X`taHpPT|pa@!5R5-xa|iboLhlA zNZmaybSVqJ0N_QgWsuZ7aDjuK8jVaF9>hsA07a@G;W2672ddBwsvvYpg){^*KN;Z- zQiLd&i0YK~~fy<|RZJ?1CWWx*c35qPk`R^qz$kj;954KeS$A=5-=-)$` f<`ex9(c22#CdC9NNeILg{7;n`R3r&3u8{u+b|YQ8 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties index 14fe41c79..fd7fea1bf 100644 --- a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=ingest-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.7.1.jar b/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.0.jar similarity index 58% rename from src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.7.1.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.0.jar index f30f83b91df4a6f4d8efc1016e9e493caefda5f3..fa1321e3d360b310f76747155a747565baa85004 100644 GIT binary patch delta 21843 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 delta 22069 zcmZ6yV{oR+7w(-*Y}>YN+qP{xnJ2bw+cqY)t%+?-oSfNvSDo|z->R-!tGep`(zsUl z-M{PQ8)Pm36i!hF1QZ$w2oe%#FQ_{KjvVf9Q1o+s1J?lt0#Zv5!~y6jPg)N$B6j0^ zAcX2`N9vBdBTMuola{c`jS&?j|7QQQfj*X)a1{ULmxAHsj2M`)p0l2knlBnqL$+h7 zU4Vw5De31>@gPsEg{1@?mNL-Wq2jj5xX2~}RfD!Z`D%|Os~#f1>$3>08o}%D%Q(d% zJ4%bA0zS^UVUK0Z8w-FzKN3?SEy7Hs{L@3gyzEAjz3J1p%{E7g8&X}TXZr0!F-H4>#Ikb_ycO@8ex%G&!ASdd$gK3NKv+jh~ zL+|=Po|}kHi>KAbi!gb30XGH1`hGMBk5h3Srdj*JkVv&n02siP5#TmXjIAULK`PB* zJ7zLb;Zqd6!20>rg8)9Sr+JTy04Wp7>Zyx0MhdQChwV4<;L4OW z2=Bc^c;?^=QYtEQ+*CIRA@#nb?Lj_>f8_K1|As%{@3=QN?}yqU00HUK0s)}{0RhR0 zsR}i%0f!-g_yu(*86$Oq{GFX70%W3pqX;s?ztIhu{oh!NEc8!onie$#`8P3)`~?1Y zKIuc;dQ*P@0aYd4p$Y@DCNb*a0n%FQe<_ivYD0~KMdZ_WW_1P~>~E~B*;C>427~#a z69x#2gX`@w)2Wn0jdCy3~a2#sQ)Vrd7s!tUKs zx?f2;T6si|rP^cS?8{M#p>_l~RO6;!x!MhT=o&1cV@Y>yRaNA`%E<`b0pd6Dj65Ug zeCLCZp8V6%k`-4J=b1or3Oc7fI`*7)m~tKLVR+0bTXlD0(lGCzM!dmJ7^@2^4|v5f z@!{k%3I^=5j%{FETwn>#%T8=_5L-6Agl@T^V%)hK7XqwGsK^>Fuxxl)aVWezxCGpB zsc`WL7;Cfw`?QbTamV~r0E1$oul(685}_IV&NkI7sHs783l?j{8M$OUS;D=CS@_e@ zngP>2ZuEL=GvqK%qcNDNUpcE(wQ=K$_Fb{F2cnflcf-GdKYQMopxze&hW%&fA-eZD zl2T5|z;tdROjCbGLya!W!{7G|hzM}u78>Dqgn3eHZ_-!pR*mS90K4yRg0bIn!%7_9 zM1@09dEuI4c;3^{B!06vu1i;h39XuLDWC@wJ8@cKdGbcXZ9RmA!7HL$P_3@A6`4xb z>-y@%k7d0Khs+JpqQyq3dwYh>Y>IN0xxdql%15(=CTV4rW9S0*erUE-p3|oM=KTy~ zl%_GUBAS_pP|Z{^0Q6_>!KaneB~sLfO)i~R==G!Nmi*-1E;_E=^A2qm8hb@O zgIRlA^2q*77UvQ5&LWm`_b`*3$ov%p>xaw%b)~M*4YfsHg;OWKg11$oKAcsme>INA zk8ko(8|FkGl{DJpswxrm_5C&&=v}ekRlpEM*d*8r?{GE+?=vU zLirBv8>q`HmlM6~5}5F`u+0}zM9y@5p6T(J;X9cz0ero6!tJ8tm&FU_1r$e^oLZCz zH|{~^Ni>{@2g)cl4y+EJj|=z3maSWY^Fiw2k{0LxtL?wpzBSVb?!$*)PG_PG|=;74Ga;21;qP znT{~qf5mT-cu_^?1z+X&CZ&vk(o-{~VP5(TJ$j~QG5by%yb05=8fCNxN`)pX_${5n zCcO)GQ(oHnM(o*rS?ZknxA0DlP*pRMo(y*8muf)SRrGu*1IElsqK(?IJGTt>7E}&u zSt|bU4PGWt>adXVjGG;B4`zUzvM^Go)qI&~p-KK)Wn1pko;Fmxn%l`|^yz0*jOyrW z9n;YxI>WaVuK1>lMxHY(i0_J zkBgEQ*%SN!c9o+>_=IpmbESxH5j`O7VR64>N$2~-3guhwkBH-L5}f@x0m@x}mLZZi zA%>*l-x}+7fF*m7IZ~)1q6Phq7lYbr1_*2jDOfg!0FW3szVXS^+Zh?RaBd4-hw0(o z?A}AfFozpOFWRa-vl@Zu9Bz`|a76F&G`F>71T5qlvc{{lAfWm1afe*yVW8tK{$nWK&{OUmeRIho;l-go@84cx2LqHBHA; zdKA7-E8-rvIo!4tU+eMfw%Cb!qv_Wgk~3hQmCwl8D_T|eth&aGF}yi4I+T|6uY~#s z(+Nkz6N*&YbEWDUj-_F5`o>)ZG~4>cwAmb~hYsZ}GDhQyY@ptwJ-^h>GAdI)51A*7 zdZ86z)923_@aqkfi^h7koxddVgc@qT(Ny%>h_`eGPg2)fVh(bOv={(^t6jp7!~>FN zPZON8cuK#B*R~Pykz{u>BcFgmu6KPZOSXjMFaz0s;bzmnF zyQJ0z;kd2wHr(Wso9p0Kcip3W)H!2wBDWeXNigJ3KH?s9NpP<-mg8G=phXI@p7Q;M zcvtbX1(aq=A8ALcb8fr0)=CGpbpYjJVm^b6OUYYn1#V2*rDx!|MC#R!jDK!KErfX| zoYt9aS1Cf-h}yQ~(4NnrbM^W{xp+-6t8v_YgDAx|Anlf&g4;yXd-IX2?#PW2=@$w4 zsApF%wM@Ys_5$Eb^h zA5=_jlypxs$fKkKyO?}Yq**zXUWHG?FyCSmK;fP45H-Sf0REM}!HFMBgYEc9o_x$u z|7dG#weWdz(iN(B5`!K)0G5~%T|o%0InCvze<#ueL8 zQJ*`ukwQ^62hjX5jR?ZEgn`B2$nZ?&umBT0zG*n{9-AXcS9nGeu&<%6X3YcfH7o2g zoFPtdW_V>x{kMj$6R>3Vo2&*}`r5`Xig?*gZn8`IC!W8f);Kc9$E3kaQ;Ja~7MR%E z9adr=uATJL2CSYq)oJ_l>Rfp41Nl@2wL)J5wv;hKLx}Dx?3fSLd(f?z?Gsqz4glA! zkhynuVdmttv&S>!2*ucCNgd@RBB3dO6XstDOjwa}>+W8t5a%B4`^)^FY0D&yaAmKM z#EU`?Ucb5ukoO#Iwa>wfG;w1g2A7Op|9tcz|K`ChHp0vPFh`Yav(uKi3G5K|zo{hQ z`hxf*H+xYHZb0EfO@QolwMp@Cb^x@UKC}05)(>~8jw=uV$kEZ9768*Ncnrm=?4nC| z+T6#gc9g8P6m(#3B&%rs)ORpqWUFiolgFov8U>hx9E z(q?QjJDB8FX4F)TSl$83e%CabpE%94tP{JqEnfGazjt|Cyp7WwfiWubdcBX(P6YEU2`#lM#pz9c7kilqEMSb!Y$O%)Uk+%Nb;aZUQb!Znz=#LVePC1^3I zLSfMgV1~8kwH0qkc+<1StZRE(d4jhEK#AXe|BP$?Qbw#p&Rv}I8;?bre_~kh)Mf5u z?#{E{$p<}!!|$&L27f4CnL@ZLCs9^WB$F|oYjJhWt%vDEiguk!)1E{d_0Q_HT0rN( zgY4)Gefj|PNyqF-JH>=oS*v*jahvskj+3>$6yuP&?B=5d7WrbxL3pVi`sTV@gfe;Z zWg+gWkc)Q%2$btk!qOa6j8P?)l1H$MPt|#!qAM8^s$_{vPcNQ}zbpSAXEIBG}c1X-Mr#t=`vKs&Q_GV+z;brzxc1cLmXt zahToWPD`lr*TMTw#>gU=u_mH}6fem{Zd*Y_Tl27nryuK&G+qreP|15nB!F3t`pKgw zat!i>0ShPHx%kkTxvufNhw9<0n9I)=IVIv5P%o!kc3I=Maj!6#rQ#oqthz&(bTy83 z%s0tY8XJpmg&)bwj#wI$VZ#b+_DCZcu6us5*Cz(5Yg(?L*%@e-IJ*Wr_M%8g^^Qoo3QP7$%Djw z)QNhg+ALYh7DuO@p{AG^^_WlCwo=WZcA)r`E5S$SR2c0VbT_q8u1)02X67^;rMIY^ zSCbDMnfEnhGjJ*3WkLfyoD5VE>M3+;Rar8$eq3rYaoAq3>JGGTcmwuQ2)z>wPbm=s zU(?i~HIjh0Z1X42rEp=zVX!IFyAuzjuP`!?r6hCn4LO`GRm@bG1rQYM&V$*)5{I=m zlaV}V_b>}%4Up(d<|Aii1nBRqG3mw$^U-CwI9Cam=%pAZ;>9*gT@uLzJ(KsLI$w_% zDswSo(956wwYdl;F#$e?0OdM7kJB90rlMx%kgg>hNOdD51M1}T?#h10xVJ_)bLb_V z!k;*)6&`tW8OE<@NW)nZA0h1xakcE-;@|gc{4f^c#7=x;>3orH35zP`zT zJM0Lu2!N84?nVW{o&Ux-+>jHBUVF$xdJ&GLz7jk{{gWQH<}eB|9x>C-f-X+4ioI=| zLg#T3u!vE)bA~77&o&->U~7fZoK`$i-z@7s?Q4IpgcgLW*QOX~@Y~ z5DpkgcAsU&3YiBKd6X;sAb1Tf9Z@i0v^AWTEAeuu8JDgAmkvxDI{4js@v2{Mb4>>F zOz6h_jGnH^($ME~voHfyQJr%bT23Y4N{kiX(|2NL-rUL>2c)jcv z;3z~e06YwyLN~b6vbt#m5@J6>k~EBVJ;lgDt_N8|2(VF*6wF;(L7%d9~)ie zYBBedTpHNh54N5N#ddR<{IXu&O>2}pfNQjLR-HO&~IpRKXT*@l%fZ}CX>0EP;AY+(~b0jV$q0>W(6Xz{mbfMy|^ zb;jLS{ya&E*qVm9JsP|yw~aP(gJN+L|7^lat){Dip~qUf<{%5Z`J?=ZE?n6uC)!V8 zCFre{?KCVQ^I97!=#nguG5`kRCPN?A=@xo!q zKO@2sUvvSI`HSI5$Ehi0Nr_z308X`hWs#Iv>xjiOlL)IbroaM0&n%=1cq(2iHhmF1Kmo1B=3PB? z-GURkCe~K<1e6JYct*%FIRSMaw|c%_T>@mKp=vyx40R$UK#{a}{gfg(IcB)>Lm2J? z>OmPLEB$ar&{M9usckd7cu8YWd?2DIqob7r)t8vKbK@|A-;hmJSBHnDyt|!)V_X6zPD~P$ z5C}`N^?r`F@HU?jz{HMnVWu#`XFje2zj_FbyLLzoRKb7{J#i-2DzAkl%iA~D%TY>~ zoK;^p2n4%!`HsmdUaW}V7$T;pC%{p6@X6NQNk2gSZBuj=A`&*pOh-4O8r6bkASYf71~G3Z@qCv zEQsgFo_-P822PSSHeMVO*9jX6q@iAO+VbCO#KB=ov=s-z%3FRw#4B4qWm40~Sj1P$ ze9N;;dig;?v!`epw-Y{G$Ydp8uyAK~ z7SQ9=(w)*%9XhJnb`SGdIdkaeO}9SD zN}lL56|AHy1QgG=_34D`9oAXMTk$W}Xhdw6e&4Qn017-P+}SoK;s}bBGDpbuaJ{TH z0?N!x9Eyogd ztVg#oXI9tb;@zQ#ZT_B)7fMcOH^$Bo3U+UnD>C#0TZ3kP9~J7!`i-GI(NBK@>ldE0 zWKLmufC3){!Tc>r?e#Wtnh^h#`OyDb0Owp}9C z#w4@f2i4wTW9VIyD96u{*t31>ualj%_8z6dDs}f<8LE@v**lnui9S+YUMIGUO4KZ7 zs_BZu|J&_J}rwj50Hcb4(#p42El(5R_yGQ6C6D%-Rd@Q$Jv%C?Rl>C}RF?U9uAx`Qu?X@8H*nt@mm zJF{Z!Vpx_{ilXgaLfr*VpWIOkbL-yN&*LF#vK2E_Y9T|}JR)VU&HgI#>IqNt>Dn@uv*-upTi(99 zXbIJk0hw}*b*c5t;OA`A7M&D;b&DXRZFD%Xsm_5z1FMnrt!XQYP!>b}PWwS_o0?0NhORqUGC^5^MBv7#7t@?5I^9$muV zXwP$A@et4^#m2)*7 z_)o4OQyLW6j>(f&9N?LwL@z0O54lS|dj4LMixmA0u{3FQ2*@^bzJ#&Q84{0s=c3q2 zbm(Kv7I{U`VK(E>^bBG<6T;uahh7zUE z?NN#ZG<|3lRq0@p2Z~Wi(mIl&<^h+JyVOJ{ve>mdB#n!bp5*wUr^=+;Ed)8Q8^6)E zXJ>{dB%jvFID{!?h9{Lm%)r{YGwIGq7b&lr^yd5Rn;EHkUhfEt+@9ppZP*0~*EdSN zK{UvloTGIrTcc*3NlsQF>}c>h+_$@ zc=(+;*K?=xIq(a5C}Pu2f=?mu%q!742DP9wUQ z%RZ++BX&V9@5-pdj5*Kn5%_5Lc!fDh%3Laq+Ybvxoaaxts3ytq(M6JMdMQ_ZtqMT} zqPEcn=~ns4SNY}3$3E5KjXe)1%Ko+{jns96LCR1Kdfa4~Fmht1tLz5M5ZAag@lyvj zZ}qalM_fPwDOn%5S4a&gMO~Z^$@cso#V~5ECAbDa^Lc9Axy|E;=#L3siHZ4ca~YDf zQEEhRVkjDcr{-X8k^oVM=uHpP0fUsH(Ar8(J%I%E+KEB8I4ME(2SBv1NV8t=$?{Nf zdY}~>P1k;@B_pD|y7x*x$vm2Iti1pCp#xny1TDZEuMVteo3G&3lS7_sTga^G@^W9U zOkaPloNW61ONWDJ99sy6d=^QMZ-p*9+@+V@B2a@qohQ+=HDjw}z=`x=QPlv9bZYZAj#O}G3|@g} zc!@E_w+(TEC9&af%3_nh1z@E{UUk68?GqsMvhp5Ekz}^FAd^`)tc7Gh*yVa5>AB}O zSRAqAPsaP*TVUG#ECt0f4Z#9ml6nY;k>PyfHy+{C7`&l~h-H9;zMCb7r&qez(7Z5@ z<|=$p zI+}I6nV1;rUr&Vhxrdf7S9Zi(Lqt(p;EklrHVV`WKPZAy$QY~wPHrD z*luM0=?RQP4Wi(Oq|uW)of%C#_VwkQ>1`ajkTSQwr&}@ov?V`22g4H{>~h?lCSpNp z|Q9p|`dC)Kh z3tM8A$#9rVuRSCg@p-;#{Av^N(Zc%l%lK8Wv5B;&iM6MRwx>zgeXASLf96+Ioc`O5Zheh8oPBVj+#Wr6YMOVmm;6qX%Y2X^Cv{<}0 zMf0PT9o4<;xi{;lpfMdY$69$WGBU&T7}RJ)G!~3nEK`Y;%VflAYFv&TWbhzeL9mhm zX=}p{u1{!YTafv0`)A>BbiHiyW3&haWbK`j$(v}x@%LHlo}SKf^`7=iGFPP%Z@fV$~C`{(aQS(D~ zC_S4ACag=3geXYmA8o)*_e2!?rHR)Od-hs0*@=E#l{^M4_^zUj^q zk}~?&i_R3pzXKIP_-1ebQ0;j`xn9`OcX>E5c2po8SQ8o%Q)_Ny%qv$A+R0Qe!dx++ zRWEMRTi`?8sd^*@_Gh^`)4p=Qfa$#>P890%zMby9-T+W0_snfDLJoVnF+VGfO31SE zn8JR>29FcbwxnMeW#;zl4_Ko2rH>fLMKpk&s(Bt&0jDOT>-aZE8a*1rrl&3ZvV``k zpP35wwGxy*mnWZ`G|g@%+o%IAKMFTI0VOR7LnFRh z^mdp0=htE}&5ErBq#k7{pxEG7P!(g&PpR*r8nDy+RZWVmL@x9L(~G<_jmV7W#lCuX z$lSi5uM~X?ILaYATg>l~mmbrm?7TvQCP97mKgB&D1Y6a}*l1Rq5+VXtk2gaI_#!Q# zHu8Y`nq|k++4MVdoMNiWojHdRZnX04h@TY06gzDVLmuQ8WnrTOQg>AAT)we`Ei-}I z8WB}PuZZk#xMa0tZkbd#baL#OiPNz5FRWDfGT8Pq*qNyKGK0eln7I8av@t@yViSd^ zS#ze7g~FAH(}7v$MalBNl(~^C=5cL_1u_Aa^qFU>xgbPoe_UKp=S%Sl=ieGFW+3KtD=;Xu%(X(5=`@SfX+!ZJwD)`3+;sN z;;vX~%tR|rLMtw!`&7be8(!jtk;0J6Q|tdc?1Fs?~&D zMRSI^N{~pck+o7$2&N(0x;_@Yp-d-QT{}>(IoZwt zKgg25gxA$#v;O!W;+0VxS|7muKCsNh{S6VWqH^kn_fqP;lFo#L9TmdnA6Cl^l*t3D zH-$F_bRFq?iAB;r%xe!$VQ*$Sm_e)&HjXH_PyVbA8O?|XqRJTtL_G@k|o?$&v%@O!7+DbrqHFn^NuAUlK zbX^uvwV)DxpD1i+I>;(nWFz#0S5_qP-xdWOV{$}r8i%Eds->DP`KiEO%==*y`7s)u z&-zLtm7tPSlNl7L2aw?S2Fl%+X2X4j z(>0Q`j>WD;a+uO$mTVT3Hav$vg;btc3!iG>m1*_duNGy z-od0O1uURmaZ`rN;PwgfM3`OlC{tqXO|Cv+o9^AG3V0aflA5Hs!;iA#a)B{WXyl%JYtyhs$Qh0?72G&TbsA%JhJx;UjErN?x!_! zpA||%EF_EpY#(P2PMCip-rTBZcj%gYGGt@_%r^=;{FA5I(0!lvWo~`pm_=1mUWqv% zU{^t{dC#iP@a56!-(`w-TbOhDo!VhCQ(E!{7W5K#QVGvPFceJo9p3REHJB z6I4STZw3FCSCb?Qfr=#hEOFd6UwDZcy-!j`<#ZP13<~LNkG<&TNON>F zW;?VGmZ;JaXl$|H7jCr^z?n>fO@6h&Z-RIdkr?%aF)~fzYLyWbN9SJ0)@`Oiy2p#) z<;gD2fGaO*p72G#SPaD>s^%*1aO!j3uv@V8JFZa6gv)J`JRNUD9GUDQe0}<|I!XR+ z;Xj3E4>U((wTBzn5;0tyx}fiA7tTDiXVHJ33mG9uV?{0fz!JX2ycr$#Ho5{yy& zlShk0D{r$V5Pnd0k7lv1an8j)ut?t7K_4jXfYjWf=||S*%R7`&`jQ3WK)#q+xu= zeAi-fDSf7!V!;!Pc*d+8(_sFlt5*NY2fScPvoZN>P%WCvKgjWfF0ySg$j2+2@fw%{ z94RC?!Xn=dEC|RBJXOR}sE@O%^2$bnI6E4xgV~$a2nt4kH&`Wgz%8?&-5*#~%hkN$ zN`%hv51@1a@`g7gJ(*cv96^5C8IHzHa|`!j+Cx&~bH<@)8J?a;M)hj9VHwtCLv@93Se=6TGfcu=8`NCC zdBD#SRoCs0dD9wMe?Xs@9aE<)3$~c9kuE1{6Y{-58OL&Jc|BSg*K&fzk~;6Jj_k2A z&2rOtE)N(*$y&e*$aJ+uEBb5_0^G(1N=27H!w3dGDv?L*IO057RVN#eN0ITh?_u50 zc0WMi;q4h>6x(YWI}5GjiK!O(#K+*30MEKfPch$18*UQy~WS~u= zaar1aP~8>OgAiK#wv&1lVwf2I@e|?EcL~ zcyG6BML9!jMR@wXic6Z4I9}gBTDmKp!)s@Hw;cG5WrR?oXrC5jpN!+9ni5B934sEUIeIEU2+H!c$h@@5dCdQ#^w0t*T6M1=z4hA5c{vUS_Kdg<6uo z&^yHRnDb0|aiu4>b@x?Wa`~~9MKX1qqr7RXT%y#}7mm>_w4}0h0M)5dI3faB9{6;I zT7uIP@LS0BU%lnQEF4b^s=4Z%?U7+q!q8e&*@d;Iax6+wY-g{ms`RgW0#moq0H=eNq=cjnWtM zRG;UKW_~JfQ-qz-0IaqHjJ!v#;pcBv%F~z{3DxX&bz|MLoQN}-2<$Xt;bZ-rn)4C5 zoZ$ZKqw7v{eY)vBlF2Q^R4uuI*oIY$pI#t0S|;nufjhW~Sdwr1T)EGm2 zkEv&^jSDooHMA!KOlc@LLX29tFV)BFL$1`9?1wMa>$W#$0W}DBUxS=VzUlbr8lAjL z;$eqn?UDE@c?1PzODAlslmZzz=Xvd^_86-jhXkQr^16Un1czO=S1Gf7@H;1WahYL? zA&R{sz2gVeR{m%0Jiir-KCm0}x58iw`y+*jQDB=dZkw+~*S_pBo$4=(A-sJ;-*1@z z`zi|h4-VeM5_tUMUwr8I9?mOJ5`3Bh;6ejO4E0+Mk~SDjIiHR$vITsqO3%8g1yre6 zsA5tCW$vxqLhG0`YSMn@GIXEoOF>=13zu*7Ptc#B@1!`Mq>>uaIn6)WIe$5|yuOa- znXlJphCbl-03W{a0ud2i35rh4Qa>f8b{nt)6NoKj_hm@iy(QtGnFVy8`Km45WW@(wFIolu*V*#iup5Lj3BsFkJ?cr+3G!}Rs23*L28Z;ECllWkMED>zd982iYlbn5+sprOB zwqs}kNsgAxF7AvC=DZUy2G$5Fzz5OGXljF9jOoOu;8rgUCR8*e>^|!zzBIyhgja}g zUxmJ>@IWn^$yLVd2ZJFdce46#D&hwHfeUQ<3r`TL&;XKm*w3*0QU^Q9FnU%SD_b;H zS;ndC<2994WK0Qd;S8e}BEQHYg>72g19Kio^A+!S5&c0lJPjj8-Lzay0NZ4(^I*;9 z*1>ECB4$>AQ&=;5cGg3ibu4!`OIy@KQng8LJeuB)K~OEe`Lv$e@EGBCsSS~vQFJ4ZR}J8>Mn z6OnJiFFIK(%G2}_A6OLz0Dw1nE%gUK8<&*W&+j$I&C=wmfj)MF+lT2w(G0sg;%@BvFjRo)^pG;o*?78a9yRmAfp_30d`iJP^ zv~!&c-DEP_Mz7b_qgt(jgdHR%`ghutt261Cg0e$ZUYcr{h4oQ1z^B!wbc>4f62*4; zaJB$>3l^qTpCx`;!_b@tG~GK7H3C{LICc9Z1ADDe%AT!E5$xc%m1j(;eCjnD%5)No zQRnASCJ{))NC`{bTfe2vX`OVG>x$T{`=>v%VM3T1K%_OP4(sDjx$3(I>N8_adAn8e2Ek%(Gl!dh zles%Wk&mYx(>vk@%HwzBUDvv=J%NL?^v&$pF#_Z3FI-;Ie zS7z{-k+8!jde=)O+IP|S9L}%&kuTBL^pb5(@>?j`#8oQ*lFXqVJc#B<jAow_a;8eR2fgSXRcL+;26&adExcXj(}>KRGW(NwI_e)Q1R{cI zF4@9D2neFL9;lS=kC$m1mWsr5Z=WPn>b~My5~gn|ur^?HL@I*q35dtZRpUdZ-?KT( znZh5u_!bxSfvNIdSm`02=8G?byD#=`X81Vq-65KE{N2>vH0q~w=2k>L>He#J1-mas zFa0muns!}YIqfSN3l{o1lOA!8j%Cih8*bF>1sF=2sAEdYde@Fo)xJ&CitoKjb%skV zdxscE>|py5UB<$I`39Y+6PBzYaY5~!s%L7*=0H+lD? zvX#bko#s5<#MATVK3uwDcGtezgOFbue^85nqY#LG8BeR17fVf>oQVWgi@MHMVlF_q z7=X=FD^n$|6#(hFWv0osgJg#JHd<;DVpMR@dg{+%*)H$lilDb@>!`TBKstPOHB82+ zOI`sRb14XLmwks#&B@4l|M6*p$sxXD9|>}RNx>!4fEod%3oLAftdWveY-2=5w*5

q1K6+8k;YEUQ%{;C2V_| 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 NPcXn>6AQWMFWg=pbER8Win)*g&LC z|BJmyO`yug=}T@u>dp}^%zLxY`N;O<>T9f$TI{ki$&zKqOmOrl%-rtvS|?YiMqaytom@y4LK)1JDxIpp7_C0E$z0){kJ>g-w9~}@Ug4Gk~wPs#kEXK-X60MT6pqn&qHA+JyK#m%vdIweDj4dPn=H3s_hMPe%bozRHc``n7HA0Pj$YW`*v^crH3+- za+3Qp-^*LNn)*YZjCeiNAZfg2I*PIJy}-orSDpV@KF zxyjLjyO?u;w1ki%n6?qp2h({%7GQd%kPV35{6KaZ3z%W0v6>aks8reqVI1%XCmkV0Ah0B=Sn5oSpC07Xkesx;GVkd)%&c~CRj|AjUB z0$p++s7eoR1_Q&E###` z1we&dd<+c6C<+y2!3rhQ#leyHKUd11WCGQ?pg1Md3vO_Hwi;OR_Oqvr wf`E#Rfr`CQ6dU+J6{}93Z_PGYK8pwJz=RxWrdPf|DXq!Nb7a_NCWABq099DzWB>pF delta 1424 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties index f821931b2..da98f3f1e 100644 --- a/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=An easy, safe and fast scripting language for Elasticsearch # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=lang-painless @@ -35,7 +35,7 @@ classname=org.elasticsearch.painless.PainlessPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties index 6c32f77ab..9fecb3d88 100644 --- a/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds advanced field mappers # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=mapper-extras @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.mapper.MapperExtrasPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties index 73cf92448..b7f269bce 100644 --- a/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=The Reindex module adds APIs to reindex from one index to another or update documents in place. # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=reindex @@ -35,7 +35,7 @@ classname=org.elasticsearch.index.reindex.ReindexPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties index e7117d26a..620644659 100644 --- a/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for URL repository # # 'version': plugin's version -version=7.7.1 +version=7.8.0 # # 'name': the plugin name name=repository-url @@ -35,7 +35,7 @@ classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.7.1 +elasticsearch.version=7.8.0 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.1.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.7.1.jar deleted file mode 100644 index c3b47b7aea36b2c013ae4c38b843fba95a2ede6c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14721 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 bP3(``Iyp&DuwO`|pRZ_80DujqU!VRTCCmMY diff --git a/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.8.0.jar b/src/test/resources/test-home-dir/modules/repository-url/repository-url-7.8.0.jar new file mode 100644 index 0000000000000000000000000000000000000000..3d31b03ef6f032cb1eaeae9d8d0a5008d40cfc62 GIT binary patch literal 14772 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 bE&jNrQ Date: Sun, 28 Jun 2020 16:48:20 +0200 Subject: [PATCH 0212/1191] DATAES-874 - Deprecate parent-id related methods and fields. Original PR: #488 --- ...elasticsearch-migration-guide-4.0-4.1.adoc | 3 +++ .../elasticsearch/annotations/Parent.java | 3 ++- .../elasticsearch/core/EntityOperations.java | 5 ++++ .../core/index/MappingBuilder.java | 2 +- .../ElasticsearchPersistentEntity.java | 8 +++++++ .../ElasticsearchPersistentProperty.java | 2 ++ .../SimpleElasticsearchPersistentEntity.java | 6 +++-- .../elasticsearch/core/query/IndexQuery.java | 2 +- .../core/query/IndexQueryBuilder.java | 3 ++- .../ElasticsearchEntityInformation.java | 4 ++++ ...MappingElasticsearchEntityInformation.java | 1 + .../core/index/MappingBuilderTests.java | 23 ------------------- 12 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index 9f4c1fc45..b5f98598a 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -18,6 +18,9 @@ They do the same, but `putMapping` is consistent with the naming in the Elastics .Alias handling In the `IndexOperations` interface the methods `addAlias(AliasQuery)`, `removeAlias(AliasQuery)` and `queryForAlias()` have been deprecated. The new methods `alias(AliasAction)`, `getAliases(String...)` and `getAliasesForIndex(String...)` offer more functionality and a cleaner API. +.Parent-ID +Usage of a parent-id has been removed from Elasticsearch since version 6. We now deprecate the corresponding fields and methods. + [[elasticsearch-migration-guide-4.0-4.1.removal]] == Removals diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java b/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java index d919f32f0..4c74c353d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/Parent.java @@ -23,8 +23,9 @@ * Parent * * @author Philipp Jardas + * @deprecated since 4.1, not supported anymore by Elasticsearch */ - +@Deprecated @Persistent @Inherited @Retention(RetentionPolicy.RUNTIME) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index c6e7ea75b..c5f0bd104 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -235,14 +235,18 @@ interface AdaptibleEntity extends Entity { * Returns whether the entity has a parent. * * @return {@literal true} if the entity has a parent that has an {@literal id}. + * @deprecated since 4.1, not supported anymore by Elasticsearch */ + @Deprecated boolean hasParent(); /** * Returns the parent Id. Can be {@literal null}. * * @return can be {@literal null}. + * @deprecated since 4.1, not supported anymore by Elasticsearch */ + @Deprecated @Nullable Object getParentId(); @@ -589,6 +593,7 @@ public boolean hasParent() { * (non-Javadoc) * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#getParentId() */ + @Deprecated @Override public Object getParentId() { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 69e0ca806..d42203f3e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -78,7 +78,7 @@ public class MappingBuilder { private static final String FIELD_INDEX = "index"; private static final String FIELD_PROPERTIES = "properties"; - private static final String FIELD_PARENT = "_parent"; + @Deprecated private static final String FIELD_PARENT = "_parent"; private static final String FIELD_CONTEXT_NAME = "name"; private static final String FIELD_CONTEXT_TYPE = "type"; private static final String FIELD_CONTEXT_PATH = "path"; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index 073432e17..b2f8c267d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -53,9 +53,17 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends BasicPersistentEntit private short replicas; private @Nullable String refreshInterval; private @Nullable String indexStoreType; - private @Nullable String parentType; - private @Nullable ElasticsearchPersistentProperty parentIdProperty; + @Deprecated private @Nullable String parentType; + @Deprecated private @Nullable ElasticsearchPersistentProperty parentIdProperty; private @Nullable ElasticsearchPersistentProperty scoreProperty; private @Nullable ElasticsearchPersistentProperty seqNoPrimaryTermProperty; private @Nullable String settingPath; @@ -135,12 +135,14 @@ public String getRefreshInterval() { @Nullable @Override + @Deprecated public String getParentType() { return parentType; } @Nullable @Override + @Deprecated public ElasticsearchPersistentProperty getParentIdProperty() { return parentIdProperty; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index fa0ba5748..bbe059d54 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -31,7 +31,7 @@ public class IndexQuery { @Nullable private Object object; @Nullable private Long version; @Nullable private String source; - @Nullable private String parentId; + @Deprecated @Nullable private String parentId; @Nullable private Long seqNo; @Nullable private Long primaryTerm; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 588f557d5..b4a7250f2 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -31,7 +31,7 @@ public class IndexQueryBuilder { @Nullable private Object object; @Nullable private Long version; @Nullable private String source; - @Nullable private String parentId; + @Deprecated @Nullable private String parentId; @Nullable private Long seqNo; @Nullable private Long primaryTerm; @@ -55,6 +55,7 @@ public IndexQueryBuilder withSource(String source) { return this; } + @Deprecated public IndexQueryBuilder withParentId(String parentId) { this.parentId = parentId; return this; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java index 4f1be7414..8acb03d97 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/ElasticsearchEntityInformation.java @@ -42,6 +42,10 @@ public interface ElasticsearchEntityInformation extends EntityInformation @Nullable VersionType getVersionType(); + /** + * @deprecated since 4.1, not supported anymore by Elasticsearch + */ + @Deprecated @Nullable String getParentId(T entity); } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java index 304f11954..543dc5849 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/MappingElasticsearchEntityInformation.java @@ -74,6 +74,7 @@ public VersionType getVersionType() { return persistentEntity.getVersionType(); } + @Deprecated @Override public String getParentId(T entity) { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index a8101bef3..61426d849 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -169,16 +169,6 @@ public void shouldAddStockPriceDocumentToIndex() { assertThat(entry.getPrice()).isCloseTo(BigDecimal.valueOf(price), Percentage.withPercentage(0.01)); } - @Test // DATAES-568 - public void shouldCreateMappingForSpecifiedParentType() throws JSONException { - - String expected = "{\"_parent\":{\"type\":\"parentType\"},\"properties\":{}}"; - - String mapping = getMappingBuilder().buildPropertyMapping(MinimalChildEntity.class); - - assertEquals(expected, mapping, false); - } - @Test // DATAES-76 public void shouldBuildMappingWithSuperclass() throws JSONException { @@ -668,19 +658,6 @@ static class MultiFieldEntity { } } - /** - * MinimalChildEntity - * - * @author Peter-Josef Meisch - */ - @Document(indexName = "test-index-minimal") - static class MinimalChildEntity { - - @Nullable @Id private String id; - - @Nullable @Parent(type = "parentType") private String parentId; - } - /** * @author Rizwan Idrees * @author Mohsin Husen From 3782c8e738ef46088c16116a0f73aaa71fb511da Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 29 Jun 2020 22:00:47 +0200 Subject: [PATCH 0213/1191] DATAES-875 - MappingElasticsearchConverter.updateQuery not called at all places. Original PR: #489 --- .../core/ElasticsearchRestTemplate.java | 2 +- .../core/ElasticsearchTemplate.java | 2 +- .../core/ReactiveElasticsearchTemplate.java | 7 +--- .../elasticsearch/core/RequestFactory.java | 42 ++++++------------- .../core/convert/ElasticsearchConverter.java | 26 ++++++++++-- .../MappingElasticsearchConverter.java | 2 +- 6 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index cc82a7eba..094d03633 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -171,7 +171,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) Assert.notNull(index, "index must not be null"); Assert.notEmpty(query.getIds(), "No Id define for Query"); - MultiGetRequest request = requestFactory.multiGetRequest(query, index); + MultiGetRequest request = requestFactory.multiGetRequest(query, clazz, index); MultiGetResponse result = execute(client -> client.mget(request, RequestOptions.DEFAULT)); DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 0892a1fa0..07b794813 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -186,7 +186,7 @@ public List multiGet(Query query, Class clazz, IndexCoordinates index) Assert.notNull(index, "index must not be null"); Assert.notEmpty(query.getIds(), "No Ids defined for Query"); - MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, index); + MultiGetRequestBuilder builder = requestFactory.multiGetRequestBuilder(client, query, clazz, index); DocumentCallback callback = new ReadDocumentCallback<>(elasticsearchConverter, clazz, index); List documents = DocumentAdapters.from(builder.execute().actionGet()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 0b4de71c8..b1b06ff0d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -69,7 +69,6 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.BulkOptions; -import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.IndexQuery; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; @@ -267,7 +266,7 @@ public Flux multiGet(Query query, Class clazz, IndexCoordinates index) DocumentCallback callback = new ReadDocumentCallback<>(converter, clazz, index); - MultiGetRequest request = requestFactory.multiGetRequest(query, index); + MultiGetRequest request = requestFactory.multiGetRequest(query, clazz, index); return Flux.from(execute(client -> client.multiGet(request))) // .concatMap(result -> callback.doWith(DocumentAdapters.from(result))); } @@ -617,10 +616,6 @@ public Flux> search(Query query, Class entityType, Class private Flux doFind(Query query, Class clazz, IndexCoordinates index) { - if (query instanceof CriteriaQuery) { - converter.updateQuery((CriteriaQuery) query, clazz); - } - return Flux.defer(() -> { SearchRequest request = requestFactory.searchRequest(query, clazz, index); request = prepareSearchRequest(request); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 944a60711..a8761b740 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -60,7 +59,6 @@ import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; -import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.settings.Settings; @@ -192,12 +190,7 @@ public IndicesAliasesRequest indicesAliasesRequest(AliasActions aliasActions) { Query filterQuery = parameters.getFilterQuery(); if (filterQuery != null) { - - if (filterQuery instanceof CriteriaQuery && parameters.getFilterQueryClass() != null) { - CriteriaQuery query = (CriteriaQuery) filterQuery; - elasticsearchConverter.updateQuery(query, parameters.getFilterQueryClass()); - } - + elasticsearchConverter.updateQuery(filterQuery, parameters.getFilterQueryClass()); QueryBuilder queryBuilder = getFilter(filterQuery); if (queryBuilder == null) { @@ -343,7 +336,6 @@ public BulkRequestBuilder bulkRequestBuilder(Client client, List queries, Bul * @param settings optional settings * @return request */ - @SuppressWarnings("unchecked") public CreateIndexRequest createIndexRequest(IndexCoordinates index, @Nullable Document settings) { CreateIndexRequest request = new CreateIndexRequest(index.getIndexName()); @@ -481,21 +473,6 @@ public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest get return new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest().indices(indexNames); } - public Map> convertAliasesResponse( - ImmutableOpenMap> aliasesResponse) { - - Map> mapped = new LinkedHashMap<>(); - Iterator keysIt = aliasesResponse.keysIt(); - while (keysIt.hasNext()) { - String key = keysIt.next(); - - List aliasMetaData = aliasesResponse.get(key); - mapped.put(key, new LinkedHashSet<>(aliasMetaData)); - } - - return convertAliasesResponse(mapped); - } - public Map> convertAliasesResponse(Map> aliasesResponse) { Map> converted = new LinkedHashMap<>(); aliasesResponse.forEach((index, aliasMetaDataSet) -> { @@ -622,19 +599,24 @@ public GetRequestBuilder getRequestBuilder(Client client, String id, IndexCoordi return client.prepareGet(index.getIndexName(), null, id); } - public MultiGetRequest multiGetRequest(Query query, IndexCoordinates index) { + public MultiGetRequest multiGetRequest(Query query, Class clazz, IndexCoordinates index) { + MultiGetRequest multiGetRequest = new MultiGetRequest(); - getMultiRequestItems(query, index).forEach(multiGetRequest::add); + getMultiRequestItems(query, clazz, index).forEach(multiGetRequest::add); return multiGetRequest; } - public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, IndexCoordinates index) { + public MultiGetRequestBuilder multiGetRequestBuilder(Client client, Query searchQuery, Class clazz, + IndexCoordinates index) { + MultiGetRequestBuilder multiGetRequestBuilder = client.prepareMultiGet(); - getMultiRequestItems(searchQuery, index).forEach(multiGetRequestBuilder::add); + getMultiRequestItems(searchQuery, clazz, index).forEach(multiGetRequestBuilder::add); return multiGetRequestBuilder; } - private List getMultiRequestItems(Query searchQuery, IndexCoordinates index) { + private List getMultiRequestItems(Query searchQuery, Class clazz, IndexCoordinates index) { + + elasticsearchConverter.updateQuery(searchQuery, clazz); List items = new ArrayList<>(); if (!isEmpty(searchQuery.getFields())) { @@ -830,6 +812,7 @@ public SearchRequestBuilder searchRequestBuilder(Client client, SuggestBuilder s public SearchRequest searchRequest(Query query, @Nullable Class clazz, IndexCoordinates index) { + elasticsearchConverter.updateQuery(query, clazz); SearchRequest searchRequest = prepareSearchRequest(query, clazz, index); QueryBuilder elasticsearchQuery = getQuery(query); QueryBuilder elasticsearchFilter = getFilter(query); @@ -851,6 +834,7 @@ public SearchRequest searchRequest(Query query, @Nullable Class clazz, IndexC public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nullable Class clazz, IndexCoordinates index) { + elasticsearchConverter.updateQuery(query, clazz); SearchRequestBuilder searchRequestBuilder = prepareSearchRequestBuilder(query, client, clazz, index); QueryBuilder elasticsearchQuery = getQuery(query); QueryBuilder elasticsearchFilter = getFilter(query); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java index 8b34b1915..1b1e6d103 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchConverter.java @@ -20,6 +20,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.lang.Nullable; @@ -83,15 +84,34 @@ default Document mapObject(@Nullable Object source) { } // endregion + // region query /** * Updates a query by renaming the property names in the query to the correct mapped field names and the values to the * converted values if the {@link ElasticsearchPersistentProperty} for a property has a - * {@link org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter}. + * {@link org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter}. If + * domainClass is null, it's a noop; handling null here eliminates null checks in the caller. * + * @param query the query that is internally updated + * @param domainClass the class of the object that is searched with the query + */ + default void updateQuery(Query query, @Nullable Class domainClass) { + + if (domainClass != null) { + + if (query instanceof CriteriaQuery) { + updateCriteriaQuery((CriteriaQuery) query, domainClass); + } + } + } + + /** + * Updates a {@link CriteriaQuery} by renaming the property names in the query to the correct mapped field names and + * the values to the converted values if the {@link ElasticsearchPersistentProperty} for a property has a + * {@link org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter}. + * * @param criteriaQuery the query that is internally updated * @param domainClass the class of the object that is searched with the query */ - // region query - void updateQuery(CriteriaQuery criteriaQuery, Class domainClass); + void updateCriteriaQuery(CriteriaQuery criteriaQuery, Class domainClass); // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 21092c010..15c53ee88 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -748,7 +748,7 @@ private boolean isSimpleType(Class type) { // region queries @Override - public void updateQuery(CriteriaQuery criteriaQuery, Class domainClass) { + public void updateCriteriaQuery(CriteriaQuery criteriaQuery, Class domainClass) { ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(domainClass); if (persistentEntity != null) { From bfe9d290a6ea915d0e94358929b937953571a511 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 30 Jun 2020 21:13:22 +0200 Subject: [PATCH 0214/1191] DATAES-876 - Add seqno and primary term to entity on initial save. Original PR: #490 --- ...elasticsearch-migration-guide-4.0-4.1.adoc | 8 ++- .../core/AbstractElasticsearchTemplate.java | 38 +++++++++----- .../core/DocumentOperations.java | 16 +++--- .../core/ElasticsearchRestTemplate.java | 18 ++++--- .../core/ElasticsearchTemplate.java | 13 +++-- .../core/IndexedObjectInformation.java | 52 +++++++++++++++++++ .../core/ElasticsearchTemplateTests.java | 23 ++++++++ 7 files changed, 135 insertions(+), 33 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java diff --git a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc index b5f98598a..8765ffcce 100644 --- a/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc +++ b/src/main/asciidoc/reference/elasticsearch-migration-guide-4.0-4.1.adoc @@ -16,7 +16,8 @@ In the `ReactiveElasticsearchClient.Indices` interface the `updateMapping` metho They do the same, but `putMapping` is consistent with the naming in the Elasticsearch API: .Alias handling -In the `IndexOperations` interface the methods `addAlias(AliasQuery)`, `removeAlias(AliasQuery)` and `queryForAlias()` have been deprecated. The new methods `alias(AliasAction)`, `getAliases(String...)` and `getAliasesForIndex(String...)` offer more functionality and a cleaner API. +In the `IndexOperations` interface the methods `addAlias(AliasQuery)`, `removeAlias(AliasQuery)` and `queryForAlias()` have been deprecated. +The new methods `alias(AliasAction)`, `getAliases(String...)` and `getAliasesForIndex(String...)` offer more functionality and a cleaner API. .Parent-ID Usage of a parent-id has been removed from Elasticsearch since version 6. We now deprecate the corresponding fields and methods. @@ -38,3 +39,8 @@ With the introduction of the `ReactiveIndexOperations` it became necessary to ch * the `createIndex` variants now return a `Mono` instead of a `Mono` to signal successful index creation. * the `updateMapping` variants now return a `Mono` instead of a `Mono` to signal successful mappings storage. + +=== Return types of DocumentOperartions.bulkIndex methods + +These methods were returing a `List` containing the ids of the new indexed records. +Now they return a `List`; these objects contain the id and information about optimistic locking (seq_no and primary_term) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index e20b231bc..0d7a1530f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -25,6 +25,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.search.MultiSearchRequest; @@ -59,6 +60,7 @@ import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.VersionInfo; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.callback.EntityCallbacks; import org.springframework.data.util.CloseableIterator; import org.springframework.data.util.Streamable; @@ -175,11 +177,9 @@ public Iterable save(Iterable entities, IndexCoordinates index) { .collect(Collectors.toList()); if (!indexQueries.isEmpty()) { - List ids = bulkIndex(indexQueries, index); - Iterator idIterator = ids.iterator(); - entities.forEach(entity -> { - setPersistentEntityId(entity, idIterator.next()); - }); + List indexedObjectInformations = bulkIndex(indexQueries, index); + Iterator iterator = indexedObjectInformations.iterator(); + entities.forEach(entity -> updateIndexedObject(entity, iterator.next())); } return indexQueries.stream().map(IndexQuery::getObject).map(entity -> (T) entity).collect(Collectors.toList()); @@ -250,12 +250,12 @@ public String delete(Object entity, IndexCoordinates index) { } @Override - public List bulkIndex(List queries, Class clazz) { + public List bulkIndex(List queries, Class clazz) { return bulkIndex(queries, getIndexCoordinatesFor(clazz)); } @Override - public List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz) { + public List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz) { return bulkIndex(queries, bulkOptions, getIndexCoordinatesFor(clazz)); } @@ -473,7 +473,7 @@ public IndexCoordinates getIndexCoordinatesFor(Class clazz) { * @param bulkResponse * @return the list of the item id's */ - protected List checkForBulkOperationFailure(BulkResponse bulkResponse) { + protected List checkForBulkOperationFailure(BulkResponse bulkResponse) { if (bulkResponse.hasFailures()) { Map failedDocuments = new HashMap<>(); @@ -488,17 +488,31 @@ protected List checkForBulkOperationFailure(BulkResponse bulkResponse) { failedDocuments); } - return Stream.of(bulkResponse.getItems()).map(BulkItemResponse::getId).collect(Collectors.toList()); - } + return Stream.of(bulkResponse.getItems()).map(bulkItemResponse -> { + DocWriteResponse response = bulkItemResponse.getResponse(); + if (response != null) { + return IndexedObjectInformation.of(response.getId(), response.getSeqNo(), response.getPrimaryTerm()); + } else { + return IndexedObjectInformation.of(bulkItemResponse.getId(), null, null); + } - protected void setPersistentEntityId(Object entity, String id) { + }).collect(Collectors.toList()); + } + protected void updateIndexedObject(Object entity, IndexedObjectInformation indexedObjectInformation) { ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + PersistentPropertyAccessor propertyAccessor = persistentEntity.getPropertyAccessor(entity); ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); // Only deal with text because ES generated Ids are strings! if (idProperty != null && idProperty.getType().isAssignableFrom(String.class)) { - persistentEntity.getPropertyAccessor(entity).setProperty(idProperty, id); + propertyAccessor.setProperty(idProperty, indexedObjectInformation.getId()); + } + + if (persistentEntity.hasSeqNoPrimaryTermProperty()) { + ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty(); + propertyAccessor.setProperty(seqNoPrimaryTermProperty, + new SeqNoPrimaryTerm(indexedObjectInformation.getSeqNo(), indexedObjectInformation.getPrimaryTerm())); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 005aff73c..47941263d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -157,10 +157,10 @@ public interface DocumentOperations { * * @param queries the queries to execute in bulk * @param clazz the entity class - * @return the ids of the indexed objects + * @return the information about the indexed objects * @since 4.1 */ - default List bulkIndex(List queries, Class clazz) { + default List bulkIndex(List queries, Class clazz) { return bulkIndex(queries, BulkOptions.defaultOptions(), clazz); } @@ -168,9 +168,9 @@ default List bulkIndex(List queries, Class clazz) { * Bulk index all objects. Will do save or update. * * @param queries the queries to execute in bulk - * @return the ids of the indexed objects + * @return the information about of the indexed objects */ - default List bulkIndex(List queries, IndexCoordinates index) { + default List bulkIndex(List queries, IndexCoordinates index) { return bulkIndex(queries, BulkOptions.defaultOptions(), index); } @@ -180,19 +180,19 @@ default List bulkIndex(List queries, IndexCoordinates index) * @param queries the queries to execute in bulk * @param bulkOptions options to be added to the bulk request * @param clazz the entity class - * @return the ids of the indexed objects + * @return the information about of the indexed objects * @since 4.1 */ - List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz); + List bulkIndex(List queries, BulkOptions bulkOptions, Class clazz); /** * Bulk index all objects. Will do save or update. * * @param queries the queries to execute in bulk * @param bulkOptions options to be added to the bulk request - * @return the ids of the indexed objects + * @return the information about of the indexed objects */ - List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); + List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index); /** * Bulk update all objects. Will do update. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 094d03633..0ac9be2cb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -26,6 +26,7 @@ import org.elasticsearch.action.get.MultiGetRequest; import org.elasticsearch.action.get.MultiGetResponse; import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.search.ClearScrollRequest; import org.elasticsearch.action.search.MultiSearchRequest; import org.elasticsearch.action.search.MultiSearchResponse; @@ -142,17 +143,18 @@ public String index(IndexQuery query, IndexCoordinates index) { maybeCallbackBeforeConvertWithQuery(query, index); IndexRequest request = requestFactory.indexRequest(query, index); - String documentId = execute(client -> client.index(request, RequestOptions.DEFAULT).getId()); + IndexResponse indexResponse = execute(client -> client.index(request, RequestOptions.DEFAULT)); // We should call this because we are not going through a mapper. Object queryObject = query.getObject(); if (queryObject != null) { - setPersistentEntityId(queryObject, documentId); + updateIndexedObject(queryObject, + IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), indexResponse.getPrimaryTerm())); } maybeCallbackAfterSaveWithQuery(query, index); - return documentId; + return indexResponse.getId(); } @Override @@ -186,7 +188,8 @@ protected boolean doExists(String id, IndexCoordinates index) { } @Override - public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + public List bulkIndex(List queries, BulkOptions bulkOptions, + IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); @@ -234,13 +237,14 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { return new UpdateResponse(result); } - private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + private List doBulkOperation(List queries, BulkOptions bulkOptions, + IndexCoordinates index) { maybeCallbackBeforeConvertWithQueries(queries, index); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); - List ids = checkForBulkOperationFailure( + List indexedObjectInformations = checkForBulkOperationFailure( execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); maybeCallbackAfterSaveWithQueries(queries, index); - return ids; + return indexedObjectInformations; } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 07b794813..ce71d7480 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -162,7 +162,8 @@ public String index(IndexQuery query, IndexCoordinates index) { // We should call this because we are not going through a mapper. Object queryObject = query.getObject(); if (queryObject != null) { - setPersistentEntityId(queryObject, documentId); + updateIndexedObject(queryObject, + IndexedObjectInformation.of(documentId, response.getSeqNo(), response.getPrimaryTerm())); } maybeCallbackAfterSaveWithQuery(query, index); @@ -201,16 +202,17 @@ protected boolean doExists(String id, IndexCoordinates index) { } @Override - public List bulkIndex(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + public List bulkIndex(List queries, BulkOptions bulkOptions, + IndexCoordinates index) { Assert.notNull(queries, "List of IndexQuery must not be null"); Assert.notNull(bulkOptions, "BulkOptions must not be null"); - List ids = doBulkOperation(queries, bulkOptions, index); + List indexedObjectInformations = doBulkOperation(queries, bulkOptions, index); maybeCallbackAfterSaveWithQueries(queries, index); - return ids; + return indexedObjectInformations; } @Override @@ -257,7 +259,8 @@ public UpdateResponse update(UpdateQuery query, IndexCoordinates index) { return new UpdateResponse(result); } - private List doBulkOperation(List queries, BulkOptions bulkOptions, IndexCoordinates index) { + private List doBulkOperation(List queries, BulkOptions bulkOptions, + IndexCoordinates index) { maybeCallbackBeforeConvertWithQueries(queries, index); BulkRequestBuilder bulkRequest = requestFactory.bulkRequestBuilder(client, queries, bulkOptions, index); return checkForBulkOperationFailure(bulkRequest.execute().actionGet()); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java new file mode 100644 index 000000000..436f58e23 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 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; + +import org.springframework.lang.Nullable; + +/** + * Value class capturing information about a newly indexed document in Elasticsearch. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public class IndexedObjectInformation { + private final String id; + @Nullable private final Long seqNo; + @Nullable private final Long primaryTerm; + + private IndexedObjectInformation(String id, @Nullable Long seqNo, @Nullable Long primaryTerm) { + this.id = id; + this.seqNo = seqNo; + this.primaryTerm = primaryTerm; + } + + public static IndexedObjectInformation of(String id, @Nullable Long seqNo, @Nullable Long primaryTerm) { + return new IndexedObjectInformation(id, seqNo, primaryTerm); + } + + public String getId() { + return id; + } + + public long getSeqNo() { + return seqNo; + } + + public long getPrimaryTerm() { + return primaryTerm; + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 2d24c4c66..40d9537b1 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -3156,6 +3156,29 @@ void shouldDoExistsWithIndexCoordinates() { assertThat(operations.exists("42", index)).isTrue(); } + @Test // DATAES-876 + void shouldReturnSeqNoPrimaryTermOnSave() { + OptimisticEntity original = new OptimisticEntity(); + original.setMessage("It's fine"); + OptimisticEntity saved = operations.save(original); + + assertThatSeqNoPrimaryTermIsFilled(saved); + } + + @Test // DATAES-876 + void shouldReturnSeqNoPrimaryTermOnBulkSave() { + OptimisticEntity original1 = new OptimisticEntity(); + original1.setMessage("It's fine 1"); + OptimisticEntity original2 = new OptimisticEntity(); + original2.setMessage("It's fine 2"); + + Iterable saved = operations.save(Arrays.asList(original1, original2)); + + saved.forEach(optimisticEntity -> { + assertThatSeqNoPrimaryTermIsFilled(optimisticEntity); + }); + } + @Test // DATAES-799 void getShouldReturnSeqNoPrimaryTerm() { OptimisticEntity original = new OptimisticEntity(); From 168bc2dab5b81baac892b9ee6ad4dbe9b4a3b290 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Jul 2020 21:37:09 +0200 Subject: [PATCH 0215/1191] DATAES-877 - Update test logging dependency. Original PR: #491 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f30d4ce9e..3179a9b98 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ 2.6 7.8.0 - 2.9.1 + 2.13.2 2.4.0-SNAPSHOT 4.1.50.Final spring.data.elasticsearch From df4e6c449d4b5cf7a9196d88045f7b7af9060311 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 2 Jul 2020 06:41:35 +0200 Subject: [PATCH 0216/1191] DATAES-878 - Wrong value for TermVector. Original PR: #492 --- .../data/elasticsearch/annotations/TermVector.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java index ba8ec1c14..d5ee7cdd0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/TermVector.java @@ -20,5 +20,5 @@ * @since 4.0 */ public enum TermVector { - none, no, yes, with_positions, with_offsets, woth_positions_offsets, with_positions_payloads, with_positions_offets_payloads + none, no, yes, with_positions, with_offsets, with_positions_offsets, with_positions_payloads, with_positions_offets_payloads } From 0f940b36d7a89257694ed85639f1a89c4eb2a35a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 10 Jul 2020 21:19:11 +0200 Subject: [PATCH 0217/1191] DATAES-883 - Fix log level on resource load error. Original PR: #493 --- .../data/elasticsearch/core/ReactiveResourceUtil.java | 4 ++-- .../data/elasticsearch/core/ResourceUtil.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java index 423eaa5fe..ee0abf55d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveResourceUtil.java @@ -65,13 +65,13 @@ public static Mono readFileFromClasspath(String url) { sink.next(sb.toString()); sink.complete(); } catch (Exception e) { - LOGGER.debug(String.format("Failed to load file from url: %s: %s", url, e.getMessage())); + LOGGER.warn(String.format("Failed to load file from url: %s: %s", url, e.getMessage())); sink.complete(); } finally { DataBufferUtils.release(it); } }).onErrorResume(throwable -> { - LOGGER.debug(String.format("Failed to load file from url: %s: %s", url, throwable.getMessage())); + LOGGER.warn(String.format("Failed to load file from url: %s: %s", url, throwable.getMessage())); return Mono.empty(); }); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java index 17973223c..852ae3bdd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ResourceUtil.java @@ -38,8 +38,8 @@ public abstract class ResourceUtil { /** * Read a {@link ClassPathResource} into a {@link String}. * - * @param url - * @return + * @param url url the file url + * @return the contents of the file or null if it could not be read */ @Nullable public static String readFileFromClasspath(String url) { @@ -48,7 +48,7 @@ public static String readFileFromClasspath(String url) { try (InputStream is = classPathResource.getInputStream()) { return StreamUtils.copyToString(is, Charset.defaultCharset()); } catch (Exception e) { - LOGGER.debug(String.format("Failed to load file from url: %s: %s", url, e.getMessage())); + LOGGER.warn(String.format("Failed to load file from url: %s: %s", url, e.getMessage())); return null; } } From 0944d1654a244f6b65ab098f2f978b5df129c88b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 10 Jul 2020 21:50:31 +0200 Subject: [PATCH 0218/1191] DATAES-842 - Documentation fixes. Oriignal PR: #494 --- CI.adoc | 6 +++--- README.adoc | 4 ++++ src/main/asciidoc/reference/elasticsearch-auditing.adoc | 8 ++++---- .../asciidoc/reference/elasticsearch-object-mapping.adoc | 4 ++-- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CI.adoc b/CI.adoc index 8fa861021..207950573 100644 --- a/CI.adoc +++ b/CI.adoc @@ -1,8 +1,8 @@ = Continuous Integration -image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2Fmaster&subject=Moore%20(master)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] -image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2F3.1.x&subject=Lovelace%20(3.1.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] -image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2F2.1.x&subject=Ingalls%20(2.1.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] +image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2Fmaster&subject=2020.0.0%20(master)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] +image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2F4.0.x&subject=Neumann%20(4.0.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] +image:https://jenkins.spring.io/buildStatus/icon?job=spring-data-elasticsearch%2F3.2.x&subject=Moore%20(3.2.x)[link=https://jenkins.spring.io/view/SpringData/job/spring-data-elasticsearch/] == Running CI tasks locally diff --git a/README.adoc b/README.adoc index 69a0d9524..590bef71d 100644 --- a/README.adoc +++ b/README.adoc @@ -197,6 +197,10 @@ If you want to build with the regular `mvn` command, you will need https://maven _Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please sign the https://cla.pivotal.io/sign/spring[Contributor’s Agreement] before submitting your first pull request._ +IMPORTANT: When contributing, please make sure an issue exists in Jira and comment on this issue with how you want to address it. By this we not only know that someone is working on an issue, we can also align architectural questions and possible solutions before work is invested. We so can prevent that much work is put into Pull Requests that have little +or no chances of being merged. + + === Building reference documentation Building the documentation builds also the project without running tests. diff --git a/src/main/asciidoc/reference/elasticsearch-auditing.adoc b/src/main/asciidoc/reference/elasticsearch-auditing.adoc index 4b805cbdf..63726588e 100644 --- a/src/main/asciidoc/reference/elasticsearch-auditing.adoc +++ b/src/main/asciidoc/reference/elasticsearch-auditing.adoc @@ -37,18 +37,18 @@ public class Person implements Persistable { private Instant lastModifiedDate; private String lastModifiedBy; - public Long getId() { <1> + public Long getId() { // <.> return id; } @Override public boolean isNew() { - return id == null || (createdDate == null && createdBy == null); <2> + return id == null || (createdDate == null && createdBy == null); // <.> } } ---- -<1> the getter also is the required implementation from the interface -<2> an object is new if it either has no `id` or none of fields containing creation attributes are set. +<.> the getter is the required implementation from the interface +<.> an object is new if it either has no `id` or none of fields containing creation attributes are set. === Activating auditing diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index b1023af3f..43d1b3bb6 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -28,7 +28,7 @@ The `MappingElasticsearchConverter` uses metadata to drive the mapping of object The following annotations are available: * `@Document`: Applied at the class level to indicate this class is a candidate for mapping to the database. The most important attributes are: -** `indexName`: the name of the index to store this entity in +** `indexName`: the name of the index to store this entity in. This can contain a SpEL template expression like `"log-#{T(java.time.LocalDate).now().toString()}"` ** `type`: [line-through]#the mapping type. If not set, the lowercased simple name of the class is used.# (deprecated since version 4.0) ** `shards`: the number of shards for the index. ** `replicas`: the number of replicas for the index. @@ -48,7 +48,7 @@ The following annotations are available: ** `analyzer`, `searchAnalyzer`, `normalizer` for specifying custom custom analyzers and normalizer. * `@GeoPoint`: marks a field as _geo_point_ datatype. Can be omitted if the field is an instance of the `GeoPoint` class. -NOTE: Properties that derive from `TemporalAccessor` must either have a `@Field` annotation of type `FieldType.Date` or a custom converter must be registerd for this type. + +NOTE: Properties that derive from `TemporalAccessor` must either have a `@Field` annotation of type `FieldType.Date` or a custom converter must be registered for this type. + If you are using a custom date format, you need to use _uuuu_ for the year instead of _yyyy_. This is due to a https://www.elastic.co/guide/en/elasticsearch/reference/current/migrate-to-java-time.html#java-time-migration-incompatible-date-formats[change in Elasticsearch 7]. The mapping metadata infrastructure is defined in a separate spring-data-commons project that is technology agnostic. From bdcecd095002e7bf2ab74abd5370e750eafd5c3a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 17 Jul 2020 21:11:40 +0200 Subject: [PATCH 0219/1191] DATAES-612 - Add support for index templates. Original PR: #495 --- .../asciidoc/reference/elasticsearch-new.adoc | 1 + .../elasticsearch/ElasticsearchException.java | 2 +- .../DefaultReactiveElasticsearchClient.java | 54 +++- .../reactive/ReactiveElasticsearchClient.java | 145 ++++++++++ .../client/reactive/RequestCreator.java | 35 +++ .../client/util/RequestConverters.java | 62 ++++- .../core/AbstractDefaultIndexOperations.java | 65 ++--- .../core/DefaultIndexOperations.java | 62 ++++- .../core/DefaultReactiveIndexOperations.java | 95 ++++++- .../core/DefaultTransportIndexOperations.java | 104 ++++++- .../elasticsearch/core/IndexOperations.java | 107 +++++++- .../core/ReactiveIndexOperations.java | 103 ++++++- .../elasticsearch/core/RequestFactory.java | 259 ++++++++++++++++-- .../core/index/AliasActionParameters.java | 12 +- .../core/index/DeleteTemplateRequest.java | 36 +++ .../core/index/ExistsTemplateRequest.java | 36 +++ .../core/index/GetTemplateRequest.java | 36 +++ .../core/index/PutTemplateRequest.java | 136 +++++++++ .../core/index/TemplateData.java | 123 +++++++++ .../core/query/FetchSourceFilter.java | 11 +- .../core/query/MoreLikeThisQuery.java | 8 +- .../data/elasticsearch/core/query/Query.java | 6 +- .../core/query/SourceFilter.java | 7 +- .../core/ReactiveIndexOperationsTest.java | 155 +++++++++++ .../core/RequestFactoryTests.java | 67 +++++ .../ElasticsearchDateConverterTests.java | 4 +- .../core/index/TemplateTests.java | 192 +++++++++++++ .../core/index/TemplateTransportTests.java | 25 ++ 28 files changed, 1834 insertions(+), 114 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/DeleteTemplateRequest.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/ExistsTemplateRequest.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/GetTemplateRequest.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/PutTemplateRequest.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/index/TemplateData.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTests.java create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTransportTests.java diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index bd7816177..68159d431 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -7,6 +7,7 @@ * Upgrade to Elasticsearch 7.8.0 * Improved API for alias management * Introduction of `ReactiveIndexOperations` for index management +* Index templates support [[new-features.4-0-0]] == New in Spring Data Elasticsearch 4.0 diff --git a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java index aed85fa99..126a6830c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java +++ b/src/main/java/org/springframework/data/elasticsearch/ElasticsearchException.java @@ -25,7 +25,7 @@ * @author Rizwan Idrees * @author Mohsin Husen * @author Peter-Josef Meisch - * @deprecated since 4.0, use {@link org.springframework.dao.UncategorizedDataAccessException} + * @deprecated since 4.0, use {@link UncategorizedElasticsearchException} */ @Deprecated public class ElasticsearchException extends RuntimeException { diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index c5edd1e71..321f9f4ae 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -64,6 +64,7 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; @@ -86,6 +87,10 @@ import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.Request; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesResponse; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.NamedXContentRegistry; @@ -266,10 +271,9 @@ private static WebClientProvider getWebClientProvider(ClientConfiguration client Optional sslContext = clientConfiguration.getSslContext(); if (sslContext.isPresent()) { - httpClient = httpClient.secure(sslContextSpec -> { - sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null, IdentityCipherSuiteFilter.INSTANCE, - ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false)); - }); + httpClient = httpClient + .secure(sslContextSpec -> sslContextSpec.sslContext(new JdkSslContext(sslContext.get(), true, null, + IdentityCipherSuiteFilter.INSTANCE, ApplicationProtocolConfig.DISABLED, ClientAuth.NONE, null, false))); } else { httpClient = httpClient.secure(); } @@ -589,8 +593,8 @@ private static GetResult getResponseToGetResult(GetResponse response) { // --> - private Flux sendRequest(Req request, Function converter, - Class responseType, HttpHeaders headers) { + private Flux sendRequest(REQ request, Function converter, Class responseType, + HttpHeaders headers) { return sendRequest(converter.apply(request), responseType, headers); } @@ -737,6 +741,32 @@ public Mono getAliases(HttpHeaders headers, GetAliasesReques return sendRequest(getAliasesRequest, requestCreator.getAlias(), GetAliasesResponse.class, headers).publishNext(); } + @Override + public Mono putTemplate(HttpHeaders headers, PutIndexTemplateRequest putIndexTemplateRequest) { + return sendRequest(putIndexTemplateRequest, requestCreator.putTemplate(), AcknowledgedResponse.class, headers) + .map(AcknowledgedResponse::isAcknowledged).next(); + } + + @Override + public Mono getTemplate(HttpHeaders headers, + GetIndexTemplatesRequest getIndexTemplatesRequest) { + return (sendRequest(getIndexTemplatesRequest, requestCreator.getTemplates(), GetIndexTemplatesResponse.class, + headers)).next(); + } + + @Override + public Mono existsTemplate(HttpHeaders headers, IndexTemplatesExistRequest indexTemplatesExistRequest) { + return sendRequest(indexTemplatesExistRequest, requestCreator.templatesExist(), RawActionResponse.class, headers) // + .flatMap(response -> response.releaseBody().thenReturn(response.statusCode().is2xxSuccessful())) // + .next(); + } + + @Override + public Mono deleteTemplate(HttpHeaders headers, DeleteIndexTemplateRequest deleteIndexTemplateRequest) { + return sendRequest(deleteIndexTemplateRequest, requestCreator.deleteTemplate(), AcknowledgedResponse.class, headers) + .map(AcknowledgedResponse::isAcknowledged).next(); + } + // endregion // region helper functions @@ -758,7 +788,7 @@ private Publisher readResponseBody(String logId, Request reques if (response.statusCode().is4xxClientError()) { ClientLogger.logRawResponse(logId, response.statusCode()); - return handleClientError(logId, request, response, responseType); + return handleClientError(logId, response, responseType); } return response.body(BodyExtractors.toMono(byte[].class)) // @@ -825,8 +855,7 @@ private Publisher handleServerError(Request request, ClientResp request.getMethod(), request.getEndpoint(), statusCode), status))); } - private Publisher handleClientError(String logId, Request request, ClientResponse response, - Class responseType) { + private Publisher handleClientError(String logId, ClientResponse response, Class responseType) { int statusCode = response.statusCode().value(); RestStatus status = RestStatus.fromCode(statusCode); @@ -874,12 +903,13 @@ private static ElasticsearchException getElasticsearchException(String content, try { XContentParser parser = createParser(mediaType, content); // we have a JSON object with an error and a status field - XContentParser.Token token = parser.nextToken(); // Skip START_OBJECT + parser.nextToken(); // Skip START_OBJECT + XContentParser.Token token; do { token = parser.nextToken(); - if (parser.currentName().equals("error")) { + if ("error".equals(parser.currentName())) { return ElasticsearchException.failureFromXContent(parser); } } while (token == XContentParser.Token.FIELD_NAME); @@ -906,7 +936,7 @@ private static void buildExceptionMessages(StringBuilder sb, Throwable t) { * * @author Christoph Strobl */ - class ClientStatus implements Status { + static class ClientStatus implements Status { private final Collection connectedHosts; diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java index 170d065a1..61f1e6005 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java @@ -36,6 +36,7 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.delete.DeleteRequest; @@ -50,6 +51,10 @@ import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.client.GetAliasesResponse; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesResponse; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; @@ -610,6 +615,7 @@ default Mono bulk(BulkRequest bulkRequest) { * @param callback the {@link ReactiveElasticsearchClientCallback callback} wielding the actual command to run. * @return the {@link Mono} emitting the {@link ClientResponse} once subscribed. */ + @SuppressWarnings("JavaDoc") Mono execute(ReactiveElasticsearchClientCallback callback); /** @@ -1196,5 +1202,144 @@ default Mono getAliases(GetAliasesRequest getAliasesRequest) * @since 4.1 */ Mono getAliases(HttpHeaders headers, GetAliasesRequest getAliasesRequest); + + /** + * Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono putTemplate(Consumer consumer, String templateName) { + PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest(templateName); + consumer.accept(putIndexTemplateRequest); + return putTemplate(putIndexTemplateRequest); + } + + /** + * Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API. + * + * @param putIndexTemplateRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + default Mono putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) { + return putTemplate(HttpHeaders.EMPTY, putIndexTemplateRequest); + } + + /** + * Execute the given {@link PutIndexTemplateRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param putIndexTemplateRequest must not be {@literal null} + * @return a {@link Mono} signalling operation completion. + * @since 4.1 + */ + Mono putTemplate(HttpHeaders headers, PutIndexTemplateRequest putIndexTemplateRequest); + + /** + * Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return a {@link Mono} with the GetIndexTemplatesResponse. + * @since 4.1 + */ + default Mono getTemplate(Consumer consumer) { + + GetIndexTemplatesRequest getIndexTemplatesRequest = new GetIndexTemplatesRequest(); + consumer.accept(getIndexTemplatesRequest); + return getTemplate(getIndexTemplatesRequest); + } + + /** + * Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API. + * + * @param getIndexTemplatesRequest must not be {@literal null} + * @return a {@link Mono} with the GetIndexTemplatesResponse. + * @since 4.1 + */ + default Mono getTemplate(GetIndexTemplatesRequest getIndexTemplatesRequest) { + return getTemplate(HttpHeaders.EMPTY, getIndexTemplatesRequest); + } + + /** + * Execute the given {@link GetIndexTemplatesRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param getIndexTemplatesRequest must not be {@literal null} + * @return a {@link Mono} with the GetIndexTemplatesResponse. + * @since 4.1 + */ + Mono getTemplate(HttpHeaders headers, GetIndexTemplatesRequest getIndexTemplatesRequest); + + /** + * Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + default Mono existsTemplate(Consumer consumer) { + + IndexTemplatesExistRequest indexTemplatesExistRequest = new IndexTemplatesExistRequest(); + consumer.accept(indexTemplatesExistRequest); + return existsTemplate(indexTemplatesExistRequest); + } + + /** + * Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API. + * + * @param indexTemplatesExistRequest must not be {@literal null} + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + default Mono existsTemplate(IndexTemplatesExistRequest indexTemplatesExistRequest) { + return existsTemplate(HttpHeaders.EMPTY, indexTemplatesExistRequest); + } + + /** + * Execute the given {@link IndexTemplatesExistRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param indexTemplatesExistRequest must not be {@literal null} + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + Mono existsTemplate(HttpHeaders headers, IndexTemplatesExistRequest indexTemplatesExistRequest); + + /** + * Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API. + * + * @param consumer never {@literal null}. + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + default Mono deleteTemplate(Consumer consumer) { + + DeleteIndexTemplateRequest deleteIndexTemplateRequest = new DeleteIndexTemplateRequest(); + consumer.accept(deleteIndexTemplateRequest); + return deleteTemplate(deleteIndexTemplateRequest); + } + + /** + * Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API. + * + * @param deleteIndexTemplateRequest must not be {@literal null} + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + default Mono deleteTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest) { + return deleteTemplate(HttpHeaders.EMPTY, deleteIndexTemplateRequest); + } + + /** + * Execute the given {@link DeleteIndexTemplateRequest} against the {@literal indices} API. + * + * @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}. + * @param deleteIndexTemplateRequest must not be {@literal null} + * @return the {@link Mono} emitting {@literal true} if the template exists, {@literal false} otherwise. + * @since 4.1 + */ + Mono deleteTemplate(HttpHeaders headers, DeleteIndexTemplateRequest deleteIndexTemplateRequest); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java index d3bda5488..2c3fb0ae6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/RequestCreator.java @@ -15,6 +15,7 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.get.GetRequest; @@ -27,6 +28,9 @@ import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.client.Request; import org.elasticsearch.client.core.CountRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.client.util.RequestConverters; @@ -156,7 +160,38 @@ default Function updateAlias() { return RequestConverters::updateAliases; } + /** + * @since 4.1 + */ default Function getAlias() { return RequestConverters::getAlias; } + + /** + * @since 4.1 + */ + default Function putTemplate() { + return RequestConverters::putTemplate; + } + + /** + * @since 4.1 + */ + default Function getTemplates() { + return RequestConverters::getTemplates; + } + + /** + * @since 4.1 + */ + default Function templatesExist() { + return RequestConverters::templatesExist; + } + + /** + * @since 4.1 + */ + default Function deleteTemplate() { + return RequestConverters::deleteTemplate; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java index 5519871d9..8297a6748 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/util/RequestConverters.java @@ -25,8 +25,11 @@ import java.util.StringJoiner; import org.apache.http.HttpEntity; +import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.lucene.util.BytesRef; @@ -47,6 +50,7 @@ import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.explain.ExplainRequest; @@ -67,6 +71,9 @@ import org.elasticsearch.client.RethrottleRequest; import org.elasticsearch.client.core.CountRequest; import org.elasticsearch.client.indices.AnalyzeRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.common.Priority; import org.elasticsearch.common.Strings; @@ -743,7 +750,9 @@ public static Request indexCreate(CreateIndexRequest createIndexRequest) { public static Request indexRefresh(RefreshRequest refreshRequest) { String[] indices = refreshRequest.indices() == null ? Strings.EMPTY_ARRAY : refreshRequest.indices(); - Request request = new Request(HttpMethod.POST.name(), RequestConverters.endpoint(indices, "_refresh")); + // using a GET here as reactor-netty set the transfer-encoding to chunked on POST requests which blocks on + // Elasticsearch when no body is sent. + Request request = new Request(HttpMethod.GET.name(), RequestConverters.endpoint(indices, "_refresh")); Params parameters = new Params(request); parameters.withIndicesOptions(refreshRequest.indicesOptions()); @@ -831,6 +840,57 @@ public static Request getAlias(GetAliasesRequest getAliasesRequest) { return request; } + public static Request putTemplate(PutIndexTemplateRequest putIndexTemplateRequest) { + String endpoint = (new RequestConverters.EndpointBuilder()) // + .addPathPartAsIs("_template") // + .addPathPart(putIndexTemplateRequest.name()) // + .build(); // + + Request request = new Request(HttpPut.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + params.withMasterTimeout(putIndexTemplateRequest.masterNodeTimeout()); + if (putIndexTemplateRequest.create()) { + params.putParam("create", Boolean.TRUE.toString()); + } + + if (Strings.hasText(putIndexTemplateRequest.cause())) { + params.putParam("cause", putIndexTemplateRequest.cause()); + } + + request.setEntity( + RequestConverters.createEntity(putIndexTemplateRequest, RequestConverters.REQUEST_BODY_CONTENT_TYPE)); + return request; + } + + public static Request getTemplates(GetIndexTemplatesRequest getIndexTemplatesRequest) { + final String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_template") + .addCommaSeparatedPathParts(getIndexTemplatesRequest.names()).build(); + final Request request = new Request(HttpGet.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + params.withLocal(getIndexTemplatesRequest.isLocal()); + params.withMasterTimeout(getIndexTemplatesRequest.getMasterNodeTimeout()); + return request; + } + + public static Request templatesExist(IndexTemplatesExistRequest indexTemplatesExistRequest) { + final String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_template") + .addCommaSeparatedPathParts(indexTemplatesExistRequest.names()).build(); + final Request request = new Request(HttpHead.METHOD_NAME, endpoint); + final RequestConverters.Params params = new RequestConverters.Params(request); + params.withLocal(indexTemplatesExistRequest.isLocal()); + params.withMasterTimeout(indexTemplatesExistRequest.getMasterNodeTimeout()); + return request; + } + + public static Request deleteTemplate(DeleteIndexTemplateRequest deleteIndexTemplateRequest) { + String name = deleteIndexTemplateRequest.name(); + String endpoint = new RequestConverters.EndpointBuilder().addPathPartAsIs("_template").addPathPart(name).build(); + Request request = new Request(HttpDelete.METHOD_NAME, endpoint); + RequestConverters.Params params = new RequestConverters.Params(request); + params.withMasterTimeout(deleteIndexTemplateRequest.masterNodeTimeout()); + return request; + } + static HttpEntity createEntity(ToXContent toXContent, XContentType xContentType) { try { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java index 866671eff..3f9ac3b35 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractDefaultIndexOperations.java @@ -19,15 +19,14 @@ import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; -import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; import org.elasticsearch.cluster.metadata.AliasMetadata; -import org.elasticsearch.common.settings.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.elasticsearch.ElasticsearchException; +import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.Setting; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; @@ -93,19 +92,29 @@ public boolean create() { Document settings = null; if (boundClass != null) { - Class clazz = boundClass; + settings = createSettings(boundClass); + } - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - settings = loadSettings(settingPath); - } + return doCreate(getIndexCoordinates(), settings); + } - if (settings == null) { - settings = getRequiredPersistentEntity(clazz).getDefaultSettings(); - } + @Override + public Document createSettings(Class clazz) { + + Assert.notNull(clazz, "clazz must not be null"); + + Document settings = null; + + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + settings = loadSettings(settingPath); } - return doCreate(getIndexCoordinates(), settings); + if (settings == null) { + settings = getRequiredPersistentEntity(clazz).getDefaultSettings(); + } + + return settings; } @Override @@ -234,9 +243,15 @@ protected Document buildMapping(Class clazz) { String mapping = new MappingBuilder(elasticsearchConverter).buildPropertyMapping(clazz); return Document.parse(mapping); } catch (Exception e) { - throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); + throw new UncategorizedElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e); } } + + @Override + public Document createSettings() { + return createSettings(checkForBoundClass()); + } + // endregion // region Helper functions @@ -246,7 +261,7 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { @Override public IndexCoordinates getIndexCoordinates() { - return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : boundIndex; + return (boundClass != null) ? getIndexCoordinatesFor(boundClass) : Objects.requireNonNull(boundIndex); } public IndexCoordinates getIndexCoordinatesFor(Class clazz) { @@ -266,27 +281,5 @@ private Document loadSettings(String settingPath) { } return null; } - - protected Document convertSettingsResponseToMap(GetSettingsResponse response, String indexName) { - - Document settings = Document.create(); - - if (!response.getIndexToDefaultSettings().isEmpty()) { - Settings defaultSettings = response.getIndexToDefaultSettings().get(indexName); - for (String key : defaultSettings.keySet()) { - settings.put(key, defaultSettings.get(key)); - } - } - - if (!response.getIndexToSettings().isEmpty()) { - Settings customSettings = response.getIndexToSettings().get(indexName); - for (String key : customSettings.keySet()) { - settings.put(key, customSettings.get(key)); - } - } - - return settings; - } // endregion - } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java index 305d06dd1..f30c9aafa 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultIndexOperations.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch.core; import java.util.ArrayList; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -27,17 +26,27 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.client.GetAliasesResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesResponse; import org.elasticsearch.client.indices.GetMappingsRequest; import org.elasticsearch.client.indices.GetMappingsResponse; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; @@ -111,7 +120,6 @@ protected Map doGetMapping(IndexCoordinates index) { GetMappingsResponse mapping = client.indices().getMapping(mappingsRequest, RequestOptions.DEFAULT); // we only return data for the first index name that was requested (always have done so) String index1 = mappingsRequest.indices()[0]; - Map result = new LinkedHashMap<>(); return mapping.mappings().get(index1).getSourceAsMap(); }); } @@ -174,7 +182,7 @@ protected Map doGetSettings(IndexCoordinates index, boolean incl GetSettingsResponse response = restTemplate.execute(client -> client.indices() // .getSettings(getSettingsRequest, RequestOptions.DEFAULT)); - return convertSettingsResponseToMap(response, getSettingsRequest.indices()[0]); + return requestFactory.fromSettingsResponse(response, getSettingsRequest.indices()[0]); } @Override @@ -186,5 +194,53 @@ protected void doRefresh(IndexCoordinates index) { restTemplate.execute(client -> client.indices().refresh(refreshRequest, RequestOptions.DEFAULT)); } + @Override + public boolean putTemplate(PutTemplateRequest putTemplateRequest) { + + Assert.notNull(putTemplateRequest, "putTemplateRequest must not be null"); + + PutIndexTemplateRequest putIndexTemplateRequest = requestFactory.putIndexTemplateRequest(putTemplateRequest); + return restTemplate.execute( + client -> client.indices().putTemplate(putIndexTemplateRequest, RequestOptions.DEFAULT).isAcknowledged()); + } + + @Override + public TemplateData getTemplate(GetTemplateRequest getTemplateRequest) { + + Assert.notNull(getTemplateRequest, "getTemplateRequest must not be null"); + + // getIndexTemplate throws an error on non-existing template names + if (!existsTemplate(new ExistsTemplateRequest(getTemplateRequest.getTemplateName()))) { + return null; + } + + GetIndexTemplatesRequest getIndexTemplatesRequest = requestFactory.getIndexTemplatesRequest(getTemplateRequest); + GetIndexTemplatesResponse getIndexTemplatesResponse = restTemplate + .execute(client -> client.indices().getIndexTemplate(getIndexTemplatesRequest, RequestOptions.DEFAULT)); + return requestFactory.getTemplateData(getIndexTemplatesResponse, getTemplateRequest.getTemplateName()); + } + + @Override + public boolean existsTemplate(ExistsTemplateRequest existsTemplateRequest) { + + Assert.notNull(existsTemplateRequest, "existsTemplateRequest must not be null"); + + IndexTemplatesExistRequest putIndexTemplateRequest = requestFactory + .indexTemplatesExistsRequest(existsTemplateRequest); + return restTemplate + .execute(client -> client.indices().existsTemplate(putIndexTemplateRequest, RequestOptions.DEFAULT)); + } + + @Override + public boolean deleteTemplate(DeleteTemplateRequest deleteTemplateRequest) { + + Assert.notNull(deleteTemplateRequest, "deleteTemplateRequest must not be null"); + + DeleteIndexTemplateRequest deleteIndexTemplateRequest = requestFactory + .deleteIndexTemplateRequest(deleteTemplateRequest); + return restTemplate.execute( + client -> client.indices().deleteTemplate(deleteIndexTemplateRequest, RequestOptions.DEFAULT).isAcknowledged()); + } + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java index 3c97e450f..9c7379eb6 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultReactiveIndexOperations.java @@ -30,7 +30,11 @@ import org.elasticsearch.action.admin.indices.get.GetIndexRequest; import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest; 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.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -41,7 +45,12 @@ 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.MappingBuilder; +import org.springframework.data.elasticsearch.core.index.PutTemplateRequest; +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; @@ -90,21 +99,12 @@ public DefaultReactiveIndexOperations(ReactiveElasticsearchOperations operations public Mono create() { String indexName = getIndexCoordinates().getIndexName(); - Document settings = null; if (boundClass != null) { - Class clazz = boundClass; - - if (clazz.isAnnotationPresent(Setting.class)) { - String settingPath = clazz.getAnnotation(Setting.class).settingPath(); - - return loadDocument(settingPath, "@Setting").flatMap(document -> doCreate(indexName, document)); - } - - settings = getRequiredPersistentEntity(clazz).getDefaultSettings(); + return createSettings(boundClass).flatMap(settings -> doCreate(indexName, settings)); + } else { + return doCreate(indexName, null); } - - return doCreate(indexName, settings); } @Override @@ -113,8 +113,8 @@ public Mono create(Document settings) { } private Mono doCreate(String indexName, @Nullable Document settings) { - CreateIndexRequest request = requestFactory.createIndexRequestReactive(getIndexCoordinates().getIndexName(), - settings); + + CreateIndexRequest request = requestFactory.createIndexRequestReactive(indexName, settings); return Mono.from(operations.executeWithIndicesClient(client -> client.createIndex(request))); } @@ -189,6 +189,24 @@ public Mono getMapping() { // endregion // region settings + + @Override + public Mono createSettings() { + return createSettings(checkForBoundClass()); + } + + @Override + public Mono createSettings(Class clazz) { + + if (clazz.isAnnotationPresent(Setting.class)) { + String settingPath = clazz.getAnnotation(Setting.class).settingPath(); + + return loadDocument(settingPath, "@Setting"); + } + + return Mono.just(getRequiredPersistentEntity(clazz).getDefaultSettings()); + } + @Override public Mono getSettings(boolean includeDefaults) { @@ -225,6 +243,55 @@ private Mono>> getAliases(@Nullable String[] aliasNam return Mono.from(operations.executeWithIndicesClient(client -> client.getAliases(getAliasesRequest))) .map(GetAliasesResponse::getAliases).map(requestFactory::convertAliasesResponse); } + // endregion + + // region templates + @Override + public Mono putTemplate(PutTemplateRequest putTemplateRequest) { + + Assert.notNull(putTemplateRequest, "putTemplateRequest must not be null"); + + PutIndexTemplateRequest putIndexTemplateRequest = requestFactory.putIndexTemplateRequest(putTemplateRequest); + return Mono.from(operations.executeWithIndicesClient(client -> client.putTemplate(putIndexTemplateRequest))); + } + + @Override + public Mono getTemplate(GetTemplateRequest getTemplateRequest) { + + Assert.notNull(getTemplateRequest, "getTemplateRequest must not be null"); + + GetIndexTemplatesRequest getIndexTemplatesRequest = requestFactory.getIndexTemplatesRequest(getTemplateRequest); + return Mono.from(operations.executeWithIndicesClient(client -> client.getTemplate(getIndexTemplatesRequest))) + .flatMap(response -> { + if (response != null) { + TemplateData templateData = requestFactory.getTemplateData(response, getTemplateRequest.getTemplateName()); + if (templateData != null) { + return Mono.just(templateData); + } + } + return Mono.empty(); + }); + } + + @Override + public Mono existsTemplate(ExistsTemplateRequest existsTemplateRequest) { + + Assert.notNull(existsTemplateRequest, "existsTemplateRequest must not be null"); + + IndexTemplatesExistRequest indexTemplatesExistRequest = requestFactory + .indexTemplatesExistsRequest(existsTemplateRequest); + return Mono.from(operations.executeWithIndicesClient(client -> client.existsTemplate(indexTemplatesExistRequest))); + } + + @Override + public Mono deleteTemplate(DeleteTemplateRequest deleteTemplateRequest) { + + Assert.notNull(deleteTemplateRequest, "deleteTemplateRequest must not be null"); + + DeleteIndexTemplateRequest deleteIndexTemplateRequest = requestFactory + .deleteIndexTemplateRequest(deleteTemplateRequest); + return Mono.from(operations.executeWithIndicesClient(client -> client.deleteTemplate(deleteIndexTemplateRequest))); + } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java index fc7a4da9f..5bdce272d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DefaultTransportIndexOperations.java @@ -16,6 +16,7 @@ package org.springframework.data.elasticsearch.core; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -32,13 +33,27 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; +import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest; +import org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesResponse; +import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest; import org.elasticsearch.client.Client; import org.elasticsearch.cluster.metadata.AliasMetadata; +import org.elasticsearch.cluster.metadata.IndexTemplateMetadata; import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.compress.CompressedXContent; +import org.elasticsearch.common.settings.Settings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; import org.springframework.lang.Nullable; @@ -53,6 +68,8 @@ */ class DefaultTransportIndexOperations extends AbstractDefaultIndexOperations implements IndexOperations { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultTransportIndexOperations.class); + private final Client client; public DefaultTransportIndexOperations(Client client, ElasticsearchConverter elasticsearchConverter, @@ -140,7 +157,7 @@ protected List doQueryForAlias(IndexCoordinates index) { } @Override - protected Map> doGetAliases(String[] aliasNames, String[] indexNames) { + protected Map> doGetAliases(@Nullable String[] aliasNames, @Nullable String[] indexNames) { GetAliasesRequest getAliasesRequest = requestFactory.getAliasesRequest(aliasNames, indexNames); @@ -183,4 +200,89 @@ protected void doRefresh(IndexCoordinates index) { client.admin().indices().refresh(request).actionGet(); } + @Override + public boolean putTemplate(PutTemplateRequest putTemplateRequest) { + + Assert.notNull(putTemplateRequest, "putTemplateRequest must not be null"); + + PutIndexTemplateRequest putIndexTemplateRequest = requestFactory.putIndexTemplateRequest(client, + putTemplateRequest); + return client.admin().indices().putTemplate(putIndexTemplateRequest).actionGet().isAcknowledged(); + } + + @Override + public TemplateData getTemplate(GetTemplateRequest getTemplateRequest) { + + Assert.notNull(getTemplateRequest, "getTemplateRequest must not be null"); + + GetIndexTemplatesRequest getIndexTemplatesRequest = requestFactory.getIndexTemplatesRequest(client, + getTemplateRequest); + GetIndexTemplatesResponse getIndexTemplatesResponse = client.admin().indices() + .getTemplates(getIndexTemplatesRequest).actionGet(); + for (IndexTemplateMetadata indexTemplateMetadata : getIndexTemplatesResponse.getIndexTemplates()) { + + if (indexTemplateMetadata.getName().equals(getTemplateRequest.getTemplateName())) { + + Document settings = Document.create(); + Settings templateSettings = indexTemplateMetadata.settings(); + templateSettings.keySet().forEach(key -> settings.put(key, templateSettings.get(key))); + + Map aliases = new LinkedHashMap<>(); + ImmutableOpenMap aliasesResponse = indexTemplateMetadata.aliases(); + Iterator keysItAliases = aliasesResponse.keysIt(); + while (keysItAliases.hasNext()) { + String key = keysItAliases.next(); + aliases.put(key, requestFactory.convertAliasMetadata(aliasesResponse.get(key))); + } + + Map mappingsDoc = new LinkedHashMap<>(); + ImmutableOpenMap mappingsResponse = indexTemplateMetadata.mappings(); + Iterator keysItMappings = mappingsResponse.keysIt(); + while (keysItMappings.hasNext()) { + String key = keysItMappings.next(); + mappingsDoc.put(key, mappingsResponse.get(key).string()); + } + String mappingsJson = mappingsDoc.get("_doc"); + Document mapping = null; + if (mappingsJson != null) { + try { + mapping = Document.from((Map) Document.parse(mappingsJson).get("_doc")); + } catch (Exception e) { + LOGGER.warn("Got invalid mappings JSON: {}", mappingsJson); + } + } + + TemplateData templateData = TemplateData.builder() + .withIndexPatterns(indexTemplateMetadata.patterns().toArray(new String[0])) // + .withSettings(settings) // + .withMapping(mapping) // + .withAliases(aliases) // + .withOrder(indexTemplateMetadata.order()) // + .withVersion(indexTemplateMetadata.version()).build(); + + return templateData; + } + } + + return null; + } + + @Override + public boolean existsTemplate(ExistsTemplateRequest existsTemplateRequest) { + + Assert.notNull(existsTemplateRequest, "existsTemplateRequest must not be null"); + + // client.admin().indices() has no method for checking the existence + return getTemplate(new GetTemplateRequest(existsTemplateRequest.getTemplateName())) != null; + } + + @Override + public boolean deleteTemplate(DeleteTemplateRequest deleteTemplateRequest) { + + Assert.notNull(deleteTemplateRequest, "deleteTemplateRequest must not be null"); + + DeleteIndexTemplateRequest deleteIndexTemplateRequest = requestFactory.deleteIndexTemplateRequest(client, + deleteTemplateRequest); + return client.admin().indices().deleteTemplate(deleteIndexTemplateRequest).actionGet().isAcknowledged(); + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java index 8631f4611..2d5cc8b92 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java @@ -23,8 +23,14 @@ 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.AliasQuery; +import org.springframework.lang.Nullable; /** * The operations for the @@ -122,6 +128,23 @@ default boolean putMapping(Class clazz) { // endregion // region settings + /** + * Creates the index settings for the entity this IndexOperations is bound to. + * + * @return a settings document. + * @since 4.1 + */ + Document createSettings(); + + /** + * Creates the index settings from the annotations on the given class + * + * @param clazz the class to create the index settings from + * @return a settings document. + * @since 4.1 + */ + Document createSettings(Class clazz); + /** * Get mapping for an index defined by a class. * @@ -157,7 +180,7 @@ default boolean putMapping(Class clazz) { boolean addAlias(AliasQuery query); /** - * Get the alias informations for a specified index. + * Get the alias information for a specified index. * * @return alias information * @deprecated since 4.1, use {@link #getAliases(String...)} or {@link #getAliasesForIndex(String...)}. @@ -203,6 +226,87 @@ default boolean putMapping(Class clazz) { Map> getAliasesForIndex(String... indexNames); // endregion + // region templates + /** + * Creates an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html). + * + * @param putTemplateRequest template request parameters + * @return true if successful + * @since 4.1 + */ + boolean putTemplate(PutTemplateRequest putTemplateRequest); + + /** + * gets an index template using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param templateName the template name + * @return TemplateData, {@literal null} if no template with the given name exists. + * @since 4.1 + */ + @Nullable + default TemplateData getTemplate(String templateName) { + return getTemplate(new GetTemplateRequest(templateName)); + } + + /** + * gets an index template using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param getTemplateRequest the request parameters + * @return TemplateData, {@literal null} if no template with the given name exists. + * @since 4.1 + */ + @Nullable + TemplateData getTemplate(GetTemplateRequest getTemplateRequest); + + /** + * check if an index template exists using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param templateName the template name + * @return {@literal true} if the index exists + * @since 4.1 + */ + default boolean existsTemplate(String templateName) { + return existsTemplate(new ExistsTemplateRequest(templateName)); + } + + /** + * check if an index template exists using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param existsTemplateRequest the request parameters + * @return {@literal true} if the index exists + * @since 4.1 + */ + boolean existsTemplate(ExistsTemplateRequest existsTemplateRequest); + + /** + * Deletes an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html). + * + * @param templateName the template name + * @return true if successful + * @since 4.1 + */ + default boolean deleteTemplate(String templateName) { + return deleteTemplate(new DeleteTemplateRequest(templateName)); + } + + /** + * Deletes an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html). + * + * @param deleteTemplateRequest template request parameters + * @return true if successful + * @since 4.1 + */ + boolean deleteTemplate(DeleteTemplateRequest deleteTemplateRequest); + + // endregion + // region helper functions /** * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed @@ -212,5 +316,6 @@ default boolean putMapping(Class clazz) { * @since 4.1 */ IndexCoordinates getIndexCoordinates(); + // endregion } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java index 8fb7b5885..2896e3e86 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperations.java @@ -23,6 +23,11 @@ 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; /** @@ -126,6 +131,23 @@ default Mono putMapping(Class clazz) { // endregion // region settings + /** + * Creates the index settings for the entity this IndexOperations is bound to. + * + * @return a settings document. + * @since 4.1 + */ + Mono createSettings(); + + /** + * Creates the index settings from the annotations on the given class + * + * @param clazz the class to create the index settings from + * @return a settings document. + * @since 4.1 + */ + Mono createSettings(Class clazz); + /** * get the settings for the index * @@ -173,13 +195,92 @@ default Mono getSettings() { Mono>> getAliasesForIndex(String... indexNames); // endregion + // region templates + /** + * Creates an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @param putTemplateRequest template request parameters + * @return Mono of {@literal true} if the template could be stored + * @since 4.1 + */ + Mono putTemplate(PutTemplateRequest putTemplateRequest); + + /** + * gets an index template using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param templateName the template name + * @return Mono of TemplateData, {@literal Mono.empty()} if no template with the given name exists. + * @since 4.1 + */ + default Mono getTemplate(String templateName) { + return getTemplate(new GetTemplateRequest(templateName)); + } + + /** + * gets an index template using the legacy Elasticsearch + * interface/Users/peter/Entwicklung/Projekte/spring-data-elasticsearch/src/main/java/org/springframework/data/elasticsearch/core/IndexOperations.java. + * + * @param getTemplateRequest the request parameters + * @return Mono of TemplateData, {@literal Mono.empty()} if no template with the given name exists. + * @since 4.1 + */ + Mono getTemplate(GetTemplateRequest getTemplateRequest); + + /** + * Checks if an index template exists using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @param templateName the template name + * @return Mono of {@literal true} if the template exists + * @since 4.1 + */ + default Mono existsTemplate(String templateName) { + return existsTemplate(new ExistsTemplateRequest(templateName)); + } + + /** + * Checks if an index template exists using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @param existsTemplateRequest template request parameters + * @return Mono of {@literal true} if the template exists + * @since 4.1 + */ + Mono existsTemplate(ExistsTemplateRequest existsTemplateRequest); + + /** + * Deletes an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @param templateName the template name + * @return Mono of {@literal true} if the template could be deleted + * @since 4.1 + */ + default Mono deleteTemplate(String templateName) { + return deleteTemplate(new DeleteTemplateRequest(templateName)); + } + + /** + * Deletes an index template using the legacy Elasticsearch interface (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @param deleteTemplateRequest template request parameters + * @return Mono of {@literal true} if the template could be deleted + * @since 4.1 + */ + Mono deleteTemplate(DeleteTemplateRequest deleteTemplateRequest); + + // endregion + // region helper functions /** * get the current {@link IndexCoordinates}. These may change over time when the entity class has a SpEL constructed * index name. When this IndexOperations is not bound to a class, the bound IndexCoordinates are returned. * * @return IndexCoordinates - * @ince 4.1 + * @since 4.1 */ IndexCoordinates getIndexCoordinates(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index a8761b740..fc6c9688a 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -19,14 +19,17 @@ import static org.springframework.util.CollectionUtils.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import org.elasticsearch.action.admin.indices.alias.Alias; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest; import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequestBuilder; import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest; @@ -37,6 +40,7 @@ import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsRequest; import org.elasticsearch.action.admin.indices.settings.get.GetSettingsResponse; +import org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkRequestBuilder; import org.elasticsearch.action.delete.DeleteRequest; @@ -56,9 +60,15 @@ import org.elasticsearch.client.Requests; import org.elasticsearch.client.indices.CreateIndexRequest; import org.elasticsearch.client.indices.GetIndexRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesRequest; +import org.elasticsearch.client.indices.GetIndexTemplatesResponse; import org.elasticsearch.client.indices.GetMappingsRequest; +import org.elasticsearch.client.indices.IndexTemplateMetadata; +import org.elasticsearch.client.indices.IndexTemplatesExistRequest; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; +import org.elasticsearch.common.collect.ImmutableOpenMap; import org.elasticsearch.common.compress.CompressedXContent; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.common.settings.Settings; @@ -92,6 +102,11 @@ 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -466,8 +481,8 @@ public GetMappingsRequest getMappingsRequest(IndexCoordinates index) { return new GetMappingsRequest().indices(indexNames); } - public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest(Client client, - IndexCoordinates index) { + public org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest getMappingsRequest( + @SuppressWarnings("unused") Client client, IndexCoordinates index) { String[] indexNames = index.getIndexNames(); return new org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest().indices(indexNames); @@ -477,22 +492,217 @@ public Map> convertAliasesResponse(Map> converted = new LinkedHashMap<>(); aliasesResponse.forEach((index, aliasMetaDataSet) -> { Set aliasDataSet = new LinkedHashSet<>(); + aliasMetaDataSet.forEach(aliasMetaData -> aliasDataSet.add(convertAliasMetadata(aliasMetaData))); + converted.put(index, aliasDataSet); + }); + return converted; + } + + public AliasData convertAliasMetadata(AliasMetadata aliasMetaData) { + Document filter = null; + CompressedXContent aliasMetaDataFilter = aliasMetaData.getFilter(); + if (aliasMetaDataFilter != null) { + filter = Document.parse(aliasMetaDataFilter.string()); + } + AliasData aliasData = AliasData.of(aliasMetaData.alias(), filter, aliasMetaData.indexRouting(), + aliasMetaData.getSearchRouting(), aliasMetaData.writeIndex(), aliasMetaData.isHidden()); + return aliasData; + } + + public PutIndexTemplateRequest putIndexTemplateRequest(PutTemplateRequest putTemplateRequest) { + + PutIndexTemplateRequest request = new PutIndexTemplateRequest(putTemplateRequest.getName()) + .patterns(Arrays.asList(putTemplateRequest.getIndexPatterns())); + + if (putTemplateRequest.getSettings() != null) { + request.settings(putTemplateRequest.getSettings()); + } + + if (putTemplateRequest.getMappings() != null) { + request.mapping(putTemplateRequest.getMappings()); + } + + request.order(putTemplateRequest.getOrder()).version(putTemplateRequest.getVersion()); + + AliasActions aliasActions = putTemplateRequest.getAliasActions(); + + if (aliasActions != null) { + aliasActions.getActions().forEach(aliasAction -> { + AliasActionParameters parameters = aliasAction.getParameters(); + String[] parametersAliases = parameters.getAliases(); + + if (parametersAliases != null) { + for (String aliasName : parametersAliases) { + Alias alias = new Alias(aliasName); + + if (parameters.getRouting() != null) { + alias.routing(parameters.getRouting()); + } + + if (parameters.getIndexRouting() != null) { + alias.indexRouting(parameters.getIndexRouting()); + } + + if (parameters.getSearchRouting() != null) { + alias.searchRouting(parameters.getSearchRouting()); + } + + if (parameters.getHidden() != null) { + alias.isHidden(parameters.getHidden()); + } - aliasMetaDataSet.forEach(aliasMetaData -> { - Document filter = null; - CompressedXContent aliasMetaDataFilter = aliasMetaData.getFilter(); - if (aliasMetaDataFilter != null) { - filter = Document.parse(aliasMetaDataFilter.string()); + if (parameters.getWriteIndex() != null) { + alias.writeIndex(parameters.getWriteIndex()); + } + + Query filterQuery = parameters.getFilterQuery(); + + if (filterQuery != null) { + elasticsearchConverter.updateQuery(filterQuery, parameters.getFilterQueryClass()); + QueryBuilder queryBuilder = getFilter(filterQuery); + + if (queryBuilder == null) { + queryBuilder = getQuery(filterQuery); + } + + alias.filter(queryBuilder); + } + + request.alias(alias); + } } - aliasDataSet.add(AliasData.of(aliasMetaData.alias(), filter, aliasMetaData.indexRouting(), - aliasMetaData.getSearchRouting(), aliasMetaData.writeIndex(), aliasMetaData.isHidden())); }); + } - converted.put(index, aliasDataSet); - }); - return converted; + return request; } + /** + * The version for the transport client needs a different PutIndexTemplateRequest class + */ + public org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest putIndexTemplateRequest( + @SuppressWarnings("unused") Client client, PutTemplateRequest putTemplateRequest) { + org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest request = new org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateRequest( + putTemplateRequest.getName()).patterns(Arrays.asList(putTemplateRequest.getIndexPatterns())); + + if (putTemplateRequest.getSettings() != null) { + request.settings(putTemplateRequest.getSettings()); + } + + if (putTemplateRequest.getMappings() != null) { + request.mapping("_doc", putTemplateRequest.getMappings()); + } + + request.order(putTemplateRequest.getOrder()).version(putTemplateRequest.getVersion()); + + AliasActions aliasActions = putTemplateRequest.getAliasActions(); + + if (aliasActions != null) { + aliasActions.getActions().forEach(aliasAction -> { + AliasActionParameters parameters = aliasAction.getParameters(); + String[] parametersAliases = parameters.getAliases(); + if (parametersAliases != null) { + + for (String aliasName : parametersAliases) { + Alias alias = new Alias(aliasName); + + if (parameters.getRouting() != null) { + alias.routing(parameters.getRouting()); + } + + if (parameters.getIndexRouting() != null) { + alias.indexRouting(parameters.getIndexRouting()); + } + + if (parameters.getSearchRouting() != null) { + alias.searchRouting(parameters.getSearchRouting()); + } + + if (parameters.getHidden() != null) { + alias.isHidden(parameters.getHidden()); + } + + if (parameters.getWriteIndex() != null) { + alias.writeIndex(parameters.getWriteIndex()); + } + + Query filterQuery = parameters.getFilterQuery(); + + if (filterQuery != null) { + elasticsearchConverter.updateQuery(filterQuery, parameters.getFilterQueryClass()); + QueryBuilder queryBuilder = getFilter(filterQuery); + + if (queryBuilder == null) { + queryBuilder = getQuery(filterQuery); + } + + alias.filter(queryBuilder); + } + + request.alias(alias); + } + } + }); + } + + return request; + } + + public GetIndexTemplatesRequest getIndexTemplatesRequest(GetTemplateRequest getTemplateRequest) { + return new GetIndexTemplatesRequest(getTemplateRequest.getTemplateName()); + } + + @Nullable + public TemplateData getTemplateData(GetIndexTemplatesResponse getIndexTemplatesResponse, String templateName) { + for (IndexTemplateMetadata indexTemplateMetadata : getIndexTemplatesResponse.getIndexTemplates()) { + + if (indexTemplateMetadata.name().equals(templateName)) { + + Document settings = Document.create(); + Settings templateSettings = indexTemplateMetadata.settings(); + templateSettings.keySet().forEach(key -> settings.put(key, templateSettings.get(key))); + + Map aliases = new LinkedHashMap<>(); + + ImmutableOpenMap aliasesResponse = indexTemplateMetadata.aliases(); + Iterator keysIt = aliasesResponse.keysIt(); + while (keysIt.hasNext()) { + String key = keysIt.next(); + aliases.put(key, convertAliasMetadata(aliasesResponse.get(key))); + } + TemplateData templateData = TemplateData.builder() + .withIndexPatterns(indexTemplateMetadata.patterns().toArray(new String[0])) // + .withSettings(settings) // + .withMapping(Document.from(indexTemplateMetadata.mappings().getSourceAsMap())) // + .withAliases(aliases) // + .withOrder(indexTemplateMetadata.order()) // + .withVersion(indexTemplateMetadata.version()).build(); + + return templateData; + } + } + return null; + } + + public org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest getIndexTemplatesRequest( + Client client, GetTemplateRequest getTemplateRequest) { + return new org.elasticsearch.action.admin.indices.template.get.GetIndexTemplatesRequest( + getTemplateRequest.getTemplateName()); + } + + public IndexTemplatesExistRequest indexTemplatesExistsRequest(ExistsTemplateRequest existsTemplateRequest) { + return new IndexTemplatesExistRequest(existsTemplateRequest.getTemplateName()); + } + + public DeleteIndexTemplateRequest deleteIndexTemplateRequest(DeleteTemplateRequest deleteTemplateRequest) { + return new DeleteIndexTemplateRequest(deleteTemplateRequest.getTemplateName()); + } + + public org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest deleteIndexTemplateRequest( + Client client, DeleteTemplateRequest deleteTemplateRequest) { + return new org.elasticsearch.action.admin.indices.template.delete.DeleteIndexTemplateRequest( + deleteTemplateRequest.getTemplateName()); + } // endregion // region delete @@ -524,10 +734,12 @@ public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, In .setRefresh(true); if (query.isLimiting()) { + // noinspection ConstantConditions deleteByQueryRequest.setBatchSize(query.getMaxResults()); } if (query.hasScrollTime()) { + // noinspection ConstantConditions deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); } @@ -752,10 +964,7 @@ public MoreLikeThisQueryBuilder moreLikeThisQueryBuilder(MoreLikeThisQuery query String indexName = index.getIndexName(); MoreLikeThisQueryBuilder.Item item = new MoreLikeThisQueryBuilder.Item(indexName, query.getId()); - String[] fields = null; - if (query.getFields() != null) { - fields = query.getFields().toArray(new String[] {}); - } + String[] fields = query.getFields().toArray(new String[] {}); MoreLikeThisQueryBuilder moreLikeThisQueryBuilder = QueryBuilders.moreLikeThisQuery(fields, null, new MoreLikeThisQueryBuilder.Item[] { item }); @@ -817,11 +1026,7 @@ public SearchRequest searchRequest(Query query, @Nullable Class clazz, IndexC QueryBuilder elasticsearchQuery = getQuery(query); QueryBuilder elasticsearchFilter = getFilter(query); - if (elasticsearchQuery != null) { - searchRequest.source().query(elasticsearchQuery); - } else { - searchRequest.source().query(QueryBuilders.matchAllQuery()); - } + searchRequest.source().query(elasticsearchQuery); if (elasticsearchFilter != null) { searchRequest.source().postFilter(elasticsearchFilter); @@ -839,11 +1044,7 @@ public SearchRequestBuilder searchRequestBuilder(Client client, Query query, @Nu QueryBuilder elasticsearchQuery = getQuery(query); QueryBuilder elasticsearchFilter = getFilter(query); - if (elasticsearchQuery != null) { - searchRequestBuilder.setQuery(elasticsearchQuery); - } else { - searchRequestBuilder.setQuery(QueryBuilders.matchAllQuery()); - } + searchRequestBuilder.setQuery(elasticsearchQuery); if (elasticsearchFilter != null) { searchRequestBuilder.setPostFilter(elasticsearchFilter); @@ -888,6 +1089,7 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz } if (query.isLimiting()) { + // noinspection ConstantConditions sourceBuilder.size(query.getMaxResults()); } @@ -899,9 +1101,7 @@ private SearchRequest prepareSearchRequest(Query query, @Nullable Class clazz request.preference(query.getPreference()); } - if (query.getSearchType() != null) { - request.searchType(query.getSearchType()); - } + request.searchType(query.getSearchType()); prepareSort(query, sourceBuilder, getPersistentEntity(clazz)); @@ -965,6 +1165,7 @@ private SearchRequestBuilder prepareSearchRequestBuilder(Query query, Client cli } if (query.isLimiting()) { + // noinspection ConstantConditions searchRequestBuilder.setSize(query.getMaxResults()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java index d9634a433..79cd8ccfc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/AliasActionParameters.java @@ -20,7 +20,7 @@ import org.springframework.util.Assert; /** - * Value class capturing the arguments for an {@link AliasAction}.   + * Value class capturing the arguments for an {@link AliasAction}. * * @author Peter-Josef Meisch * @since 4.1 @@ -54,6 +54,14 @@ public static Builder builder() { return new Builder(); } + /** + * a Builder to create AliasActionParameters to be used when creating index templates. Automatically sets the index + * name to an empty string, as this is not used in templates + */ + public static Builder builderForTemplate() { + return new Builder().withIndices(""); + } + public String[] getIndices() { return indices; } @@ -158,7 +166,7 @@ public Builder withSearchRouting(String searchRouting) { public AliasActionParameters build() { - Assert.notNull(indices, "indices must bes set"); + Assert.notNull(indices, "indices must be set"); return new AliasActionParameters(indices, aliases, isHidden, isWriteIndex, routing, indexRouting, searchRouting, filterQuery, filterQueryClass); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/DeleteTemplateRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/index/DeleteTemplateRequest.java new file mode 100644 index 000000000..34ac13695 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/DeleteTemplateRequest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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 + */ +public class DeleteTemplateRequest { + private final String templateName; + + public DeleteTemplateRequest(String templateName) { + + Assert.notNull(templateName, "templateName must not be null"); + + this.templateName = templateName; + } + + public String getTemplateName() { + return templateName; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/ExistsTemplateRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/index/ExistsTemplateRequest.java new file mode 100644 index 000000000..87f641246 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/ExistsTemplateRequest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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 + */ +public class ExistsTemplateRequest { + private final String templateName; + + public ExistsTemplateRequest(String templateName) { + + Assert.notNull(templateName, "templateName must not be null"); + + this.templateName = templateName; + } + + public String getTemplateName() { + return templateName; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/GetTemplateRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/index/GetTemplateRequest.java new file mode 100644 index 000000000..48fe1d9fa --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/GetTemplateRequest.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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 + */ +public class GetTemplateRequest { + private final String templateName; + + public GetTemplateRequest(String templateName) { + + Assert.notNull(templateName, "templateName must not be null"); + + this.templateName = templateName; + } + + public String getTemplateName() { + return templateName; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/PutTemplateRequest.java b/src/main/java/org/springframework/data/elasticsearch/core/index/PutTemplateRequest.java new file mode 100644 index 000000000..e12ab3d94 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/PutTemplateRequest.java @@ -0,0 +1,136 @@ +/* + * Copyright 2020 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.data.elasticsearch.core.document.Document; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +/** + * Request to create an index template. This is to create legacy templates (@see + * https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-templates-v1.html) + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +public class PutTemplateRequest { + private final String name; + private final String[] indexPatterns; + @Nullable final private Document settings; + @Nullable final private Document mappings; + @Nullable final AliasActions aliasActions; + private final int order; + @Nullable final Integer version; + + private PutTemplateRequest(String name, String[] indexPatterns, @Nullable Document settings, + @Nullable Document mappings, @Nullable AliasActions aliasActions, int order, @Nullable Integer version) { + this.name = name; + this.indexPatterns = indexPatterns; + this.settings = settings; + this.mappings = mappings; + this.aliasActions = aliasActions; + this.order = order; + this.version = version; + } + + public String getName() { + return name; + } + + public String[] getIndexPatterns() { + return indexPatterns; + } + + @Nullable + public Document getSettings() { + return settings; + } + + @Nullable + public Document getMappings() { + return mappings; + } + + @Nullable + public AliasActions getAliasActions() { + return aliasActions; + } + + public int getOrder() { + return order; + } + + @Nullable + public Integer getVersion() { + return version; + } + + public static TemplateRequestBuilder builder(String name, String... indexPatterns) { + return new TemplateRequestBuilder(name, indexPatterns); + } + + public static final class TemplateRequestBuilder { + private final String name; + private final String[] indexPatterns; + @Nullable private Document settings; + @Nullable private Document mappings; + @Nullable AliasActions aliasActions; + private int order = 0; + @Nullable Integer version; + + private TemplateRequestBuilder(String name, String... indexPatterns) { + + Assert.notNull(name, "name must not be null"); + Assert.notNull(indexPatterns, "indexPatterns must not be null"); + + this.name = name; + this.indexPatterns = indexPatterns; + } + + public TemplateRequestBuilder withSettings(Document settings) { + this.settings = settings; + return this; + } + + public TemplateRequestBuilder withMappings(Document mappings) { + this.mappings = mappings; + return this; + } + + public TemplateRequestBuilder 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 TemplateRequestBuilder withOrder(int order) { + this.order = order; + return this; + } + + public TemplateRequestBuilder withVersion(@Nullable Integer version) { + this.version = version; + return this; + } + + public PutTemplateRequest build() { + return new PutTemplateRequest(name, indexPatterns, settings, mappings, aliasActions, order, version); + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/TemplateData.java b/src/main/java/org/springframework/data/elasticsearch/core/index/TemplateData.java new file mode 100644 index 000000000..a8322fb95 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/TemplateData.java @@ -0,0 +1,123 @@ +/* + * Copyright 2020 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; + +/** + * Data returned for template information retrieval. + * + * @author Peter-Josef Meisch + */ +public class TemplateData { + @Nullable private final String[] indexPatterns; + @Nullable Document settings; + @Nullable Document mapping; + @Nullable private final Map aliases; + int order; + @Nullable Integer version; + + private TemplateData(@Nullable String[] indexPatterns, @Nullable Document settings, @Nullable Document mapping, + @Nullable Map aliases, int order, @Nullable Integer version) { + this.indexPatterns = indexPatterns; + this.settings = settings; + this.mapping = mapping; + this.order = order; + this.version = version; + this.aliases = aliases; + } + + public static TemplateDataBuilder builder() { + return new TemplateDataBuilder(); + } + + @Nullable + public String[] getIndexPatterns() { + return indexPatterns; + } + + @Nullable + public Document getSettings() { + return settings; + } + + @Nullable + public Document getMapping() { + return mapping; + } + + @Nullable + public Map getAliases() { + return aliases; + } + + public int getOrder() { + return order; + } + + @Nullable + public Integer getVersion() { + return version; + } + + public static final class TemplateDataBuilder { + @Nullable Document settings; + @Nullable Document mapping; + int order; + @Nullable Integer version; + @Nullable private String[] indexPatterns; + @Nullable private Map aliases; + + private TemplateDataBuilder() {} + + public TemplateDataBuilder withIndexPatterns(String[] indexPatterns) { + this.indexPatterns = indexPatterns; + return this; + } + + public TemplateDataBuilder withSettings(Document settings) { + this.settings = settings; + return this; + } + + public TemplateDataBuilder withMapping(Document mapping) { + this.mapping = mapping; + return this; + } + + public TemplateDataBuilder withOrder(int order) { + this.order = order; + return this; + } + + public TemplateDataBuilder withVersion(Integer version) { + this.version = version; + return this; + } + + public TemplateDataBuilder withAliases(Map aliases) { + this.aliases = aliases; + return this; + } + + public TemplateData build() { + return new TemplateData(indexPatterns, settings, mapping, aliases, order, version); + } + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java index 93bc6e495..6e89746a9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/FetchSourceFilter.java @@ -15,17 +15,20 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.lang.Nullable; + /** * SourceFilter implementation for providing includes and excludes. * - * @Author Jon Tsiros + * @author Jon Tsiros + * @author Peter-Josef Meisch */ public class FetchSourceFilter implements SourceFilter { - private final String[] includes; - private final String[] excludes; + @Nullable private final String[] includes; + @Nullable private final String[] excludes; - public FetchSourceFilter(final String[] includes, final String[] excludes) { + public FetchSourceFilter(@Nullable final String[] includes, @Nullable final String[] excludes) { this.includes = includes; this.excludes = excludes; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java index 025a7b576..90976e72c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/MoreLikeThisQuery.java @@ -34,14 +34,14 @@ public class MoreLikeThisQuery { @Nullable private String id; - private List searchIndices = new ArrayList<>(); - private List searchTypes = new ArrayList<>(); - private List fields = new ArrayList<>(); + private final List searchIndices = new ArrayList<>(); + private final List searchTypes = new ArrayList<>(); + private final List fields = new ArrayList<>(); @Nullable private String routing; @Nullable private Float percentTermsToMatch; @Nullable private Integer minTermFreq; @Nullable private Integer maxQueryTerms; - private List stopWords = new ArrayList<>(); + private final List stopWords = new ArrayList<>(); @Nullable private Integer minDocFreq; @Nullable private Integer maxDocFreq; @Nullable private Integer minWordLen; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java index 62656dd29..47f5d216c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Query.java @@ -232,7 +232,8 @@ default Optional getHighlightQuery() { boolean getTrackTotalHits(); /** - * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete queries. + * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete + * queries. Must not return {@literal null} when {@link #hasScrollTime()} returns {@literal true}. * * @return the scrolltime settings * @since 4.0 @@ -241,7 +242,8 @@ default Optional getHighlightQuery() { Duration getScrollTime(); /** - * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete queries. + * For queries that are used in delete request, these are internally handled by Elasticsearch as scroll/bulk delete + * queries. * * @param scrollTime the scrolltime settings * @since 4.0 diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java index cb7d9a33e..3591cfbe9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SourceFilter.java @@ -15,14 +15,19 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.lang.Nullable; + /** * SourceFilter for providing includes and excludes. * - * @Author Jon Tsiros + * @author Jon Tsiros + * @author Peter-Josef Meisch */ public interface SourceFilter { + @Nullable String[] getIncludes(); + @Nullable String[] getExcludes(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java index 9edf8a414..178711c5c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveIndexOperationsTest.java @@ -23,7 +23,9 @@ import reactor.test.StepVerifier; import java.time.LocalDate; +import java.util.Map; import java.util.Set; +import java.util.UUID; import org.json.JSONException; import org.junit.jupiter.api.AfterEach; @@ -44,10 +46,16 @@ 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.TemplateData; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -378,6 +386,128 @@ void shouldGetAliasData() { .verifyComplete(); } + @Test // DATAES-612 + void shouldPutTemplate() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class) + .block(); + org.springframework.data.elasticsearch.core.document.Document settings = indexOps + .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 = indexOps.putTemplate(putTemplateRequest).block(); + assertThat(acknowledged).isTrue(); + } + + @Test // DATAES-612 + void shouldReturnNullOnNonExistingGetTemplate() { + + String templateName = "template" + UUID.randomUUID().toString(); + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + GetTemplateRequest getTemplateRequest = new GetTemplateRequest(templateName); + indexOps.getTemplate(getTemplateRequest).as(StepVerifier::create).verifyComplete(); + } + + @Test // DATAES-612 + void shouldGetTemplate() throws JSONException { + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class) + .block(); + org.springframework.data.elasticsearch.core.document.Document settings = indexOps + .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 = indexOps.putTemplate(putTemplateRequest).block(); + assertThat(acknowledged).isTrue(); + + GetTemplateRequest getTemplateRequest = new GetTemplateRequest(putTemplateRequest.getName()); + TemplateData templateData = indexOps.getTemplate(getTemplateRequest).block(); + + assertThat(templateData).isNotNull(); + assertThat(templateData.getIndexPatterns()).containsExactlyInAnyOrder(putTemplateRequest.getIndexPatterns()); + assertEquals(settings.toJson(), templateData.getSettings().toJson(), false); + assertEquals(mapping.toJson(), templateData.getMapping().toJson(), false); + Map aliases = templateData.getAliases(); + assertThat(aliases).hasSize(2); + AliasData alias1 = aliases.get("alias1"); + assertThat(alias1.getAlias()).isEqualTo("alias1"); + AliasData alias2 = aliases.get("alias2"); + assertThat(alias2.getAlias()).isEqualTo("alias2"); + assertThat(templateData.getOrder()).isEqualTo(putTemplateRequest.getOrder()); + assertThat(templateData.getVersion()).isEqualTo(putTemplateRequest.getVersion()); + } + + @Test // DATAES-612 + void shouldCheckExists() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + String templateName = "template" + UUID.randomUUID().toString(); + ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName); + + boolean exists = indexOps.existsTemplate(existsTemplateRequest).block(); + assertThat(exists).isFalse(); + + PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") // + .withOrder(11) // + .withVersion(42) // + .build(); + + boolean acknowledged = indexOps.putTemplate(putTemplateRequest).block(); + assertThat(acknowledged).isTrue(); + + exists = indexOps.existsTemplate(existsTemplateRequest).block(); + assertThat(exists).isTrue(); + } + + @Test // DATAES-612 + void shouldDeleteTemplate() { + + ReactiveIndexOperations indexOps = operations.indexOps(Entity.class); + + String templateName = "template" + UUID.randomUUID().toString(); + ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName); + + PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") // + .withOrder(11) // + .withVersion(42) // + .build(); + + boolean acknowledged = indexOps.putTemplate(putTemplateRequest).block(); + assertThat(acknowledged).isTrue(); + + boolean exists = indexOps.existsTemplate(existsTemplateRequest).block(); + assertThat(exists).isTrue(); + + acknowledged = indexOps.deleteTemplate(new DeleteTemplateRequest(templateName)).block(); + assertThat(acknowledged).isTrue(); + + exists = indexOps.existsTemplate(existsTemplateRequest).block(); + assertThat(exists).isFalse(); + } + @Data @Document(indexName = TESTINDEX, shards = 3, replicas = 2, refreshInterval = "4s") static class Entity { @@ -400,4 +530,29 @@ static class EntityUseServerConfig { static class EntityWithAnnotatedSettingsAndMappings { @Id private String id; } + + @Document(indexName = "test-template", shards = 3, replicas = 2, 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(String id) { + this.id = id; + } + + @Nullable + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } + } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java index acfc5084d..df8a9ef87 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/RequestFactoryTests.java @@ -32,6 +32,7 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequestBuilder; import org.elasticsearch.client.Client; +import org.elasticsearch.client.indices.PutIndexTemplateRequest; import org.elasticsearch.common.xcontent.ToXContent; import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentType; @@ -51,6 +52,7 @@ 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.PutTemplateRequest; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.elasticsearch.core.query.Criteria; @@ -371,6 +373,71 @@ void shouldBuildIndicesAliasRequest() throws IOException, JSONException { assertEquals(expected, json, false); } + @Test // DATAES-612 + void shouldCreatePutIndexTemplateRequest() throws JSONException, IOException { + + String expected = "{\n" + // + " \"index_patterns\": [\n" + // + " \"test-*\"\n" + // + " ],\n" + // + " \"order\": 42,\n" + // + " \"version\": 7,\n" + // + " \"settings\": {\n" + // + " \"index\": {\n" + // + " \"number_of_replicas\": \"2\",\n" + // + " \"number_of_shards\": \"3\",\n" + // + " \"refresh_interval\": \"7s\",\n" + // + " \"store\": {\n" + // + " \"type\": \"oops\"\n" + // + " }\n" + // + " }\n" + // + " },\n" + // + " \"mappings\": {\n" + // + " \"properties\": {\n" + // + " \"price\": {\n" + // + " \"type\": \"double\"\n" + // + " }\n" + // + " }\n" + // + " },\n" + // + " \"aliases\":{\n" + // + " \"alias1\": {},\n" + // + " \"alias2\": {},\n" + // + " \"alias3\": {\n" + // + " \"routing\": \"11\"\n" + // + " }\n" + // + " }\n" + // + "}\n"; // + + org.springframework.data.elasticsearch.core.document.Document settings = org.springframework.data.elasticsearch.core.document.Document + .create(); + settings.put("index.number_of_replicas", 2); + settings.put("index.number_of_shards", 3); + settings.put("index.refresh_interval", "7s"); + settings.put("index.store.type", "oops"); + + org.springframework.data.elasticsearch.core.document.Document mappings = org.springframework.data.elasticsearch.core.document.Document + .parse("{\"properties\":{\"price\":{\"type\":\"double\"}}}"); + + AliasActions aliasActions = new AliasActions( + new AliasAction.Add(AliasActionParameters.builderForTemplate().withAliases("alias1", "alias2").build()), + new AliasAction.Add( + AliasActionParameters.builderForTemplate().withAliases("alias3").withRouting("11").build())); + + PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("test-template", "test-*") // + .withSettings(settings) // + .withMappings(mappings) // + .withAliasActions(aliasActions) // + .withOrder(42) // + .withVersion(7) // + .build(); // + + PutIndexTemplateRequest putIndexTemplateRequest = requestFactory.putIndexTemplateRequest(putTemplateRequest); + + String json = requestToString(putIndexTemplateRequest); + System.out.println(json); + assertEquals(expected, json, false); + } + private String requestToString(ToXContent request) throws IOException { return XContentHelper.toXContent(request, XContentType.JSON, true).utf8ToString(); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java index a99f9ec2c..b2e991395 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/convert/ElasticsearchDateConverterTests.java @@ -58,7 +58,7 @@ void shouldParseTemporalAccessorFromString() { @Test // DATAES-792 void shouldConvertLegacyDateToString() { GregorianCalendar calendar = GregorianCalendar - .from(ZonedDateTime.of(LocalDateTime.of(2020, 04, 19, 19, 44), ZoneId.of("UTC"))); + .from(ZonedDateTime.of(LocalDateTime.of(2020, 4, 19, 19, 44), ZoneId.of("UTC"))); Date legacyDate = calendar.getTime(); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); @@ -70,7 +70,7 @@ void shouldConvertLegacyDateToString() { @Test // DATAES-792 void shouldParseLegacyDateFromString() { GregorianCalendar calendar = GregorianCalendar - .from(ZonedDateTime.of(LocalDateTime.of(2020, 04, 19, 19, 44), ZoneId.of("UTC"))); + .from(ZonedDateTime.of(LocalDateTime.of(2020, 4, 19, 19, 44), ZoneId.of("UTC"))); Date legacyDate = calendar.getTime(); ElasticsearchDateConverter converter = ElasticsearchDateConverter.of(DateFormat.basic_date_time); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTests.java new file mode 100644 index 000000000..af298e9e0 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTests.java @@ -0,0 +1,192 @@ +/* + * Copyright 2020 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 java.util.Map; +import java.util.UUID; + +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.annotation.Id; +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.core.ElasticsearchOperations; +import org.springframework.data.elasticsearch.core.IndexOperations; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; +import org.springframework.lang.Nullable; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@SpringIntegrationTest +@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) +public class TemplateTests { + + @Autowired ElasticsearchOperations operations; + + @Test // DATAES-612 + void shouldCreateTemplate() { + + IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care")); + + org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class); + org.springframework.data.elasticsearch.core.document.Document settings = indexOps + .createSettings(TemplateClass.class); + + 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) // + .build(); + + boolean acknowledged = indexOps.putTemplate(putTemplateRequest); + + assertThat(acknowledged).isTrue(); + } + + @Test // DATAES-612 + void shouldReturnNullOnNonExistingGetTemplate() { + + String templateName = "template" + UUID.randomUUID().toString(); + IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care")); + + GetTemplateRequest getTemplateRequest = new GetTemplateRequest(templateName); + TemplateData templateData = indexOps.getTemplate(getTemplateRequest); + + assertThat(templateData).isNull(); + } + + @Test // DATAES-612 + void shouldGetTemplate() throws JSONException { + IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care")); + + org.springframework.data.elasticsearch.core.document.Document mapping = indexOps.createMapping(TemplateClass.class); + org.springframework.data.elasticsearch.core.document.Document settings = indexOps + .createSettings(TemplateClass.class); + + 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 = indexOps.putTemplate(putTemplateRequest); + assertThat(acknowledged).isTrue(); + + GetTemplateRequest getTemplateRequest = new GetTemplateRequest(putTemplateRequest.getName()); + TemplateData templateData = indexOps.getTemplate(getTemplateRequest); + + assertThat(templateData).isNotNull(); + assertThat(templateData.getIndexPatterns()).containsExactlyInAnyOrder(putTemplateRequest.getIndexPatterns()); + assertEquals(settings.toJson(), templateData.getSettings().toJson(), false); + assertEquals(mapping.toJson(), templateData.getMapping().toJson(), false); + Map aliases = templateData.getAliases(); + assertThat(aliases).hasSize(2); + AliasData alias1 = aliases.get("alias1"); + assertThat(alias1.getAlias()).isEqualTo("alias1"); + AliasData alias2 = aliases.get("alias2"); + assertThat(alias2.getAlias()).isEqualTo("alias2"); + assertThat(templateData.getOrder()).isEqualTo(putTemplateRequest.getOrder()); + assertThat(templateData.getVersion()).isEqualTo(putTemplateRequest.getVersion()); + } + + @Test // DATAES-612 + void shouldCheckExists() { + IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care")); + + String templateName = "template" + UUID.randomUUID().toString(); + ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName); + + boolean exists = indexOps.existsTemplate(existsTemplateRequest); + assertThat(exists).isFalse(); + + PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") // + .withOrder(11) // + .withVersion(42) // + .build(); + + boolean acknowledged = indexOps.putTemplate(putTemplateRequest); + assertThat(acknowledged).isTrue(); + + exists = indexOps.existsTemplate(existsTemplateRequest); + assertThat(exists).isTrue(); + } + + @Test // DATAES-612 + void shouldDeleteTemplate() { + + IndexOperations indexOps = operations.indexOps(IndexCoordinates.of("dont-care")); + + String templateName = "template" + UUID.randomUUID().toString(); + ExistsTemplateRequest existsTemplateRequest = new ExistsTemplateRequest(templateName); + + PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder(templateName, "log-*") // + .withOrder(11) // + .withVersion(42) // + .build(); + + boolean acknowledged = indexOps.putTemplate(putTemplateRequest); + assertThat(acknowledged).isTrue(); + + boolean exists = indexOps.existsTemplate(existsTemplateRequest); + assertThat(exists).isTrue(); + + acknowledged = indexOps.deleteTemplate(new DeleteTemplateRequest(templateName)); + assertThat(acknowledged).isTrue(); + + exists = indexOps.existsTemplate(existsTemplateRequest); + assertThat(exists).isFalse(); + + } + + @Document(indexName = "test-template", shards = 3, replicas = 2, 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(String id) { + this.id = id; + } + + @Nullable + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTransportTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTransportTests.java new file mode 100644 index 000000000..dc23cd1f4 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/TemplateTransportTests.java @@ -0,0 +1,25 @@ +/* + * Copyright 2020 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.data.elasticsearch.junit.jupiter.ElasticsearchTemplateConfiguration; +import org.springframework.test.context.ContextConfiguration; + +/** + * @author Peter-Josef Meisch + */ +@ContextConfiguration(classes = { ElasticsearchTemplateConfiguration.class }) +public class TemplateTransportTests extends TemplateTests {} From ddee81f82ed5c445d9d99f51992856713c2b8fd1 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 18 Jul 2020 19:34:00 +0200 Subject: [PATCH 0220/1191] DATAES-886 - Complete reactive auditing. Original PR: #496 --- .../reference/elasticsearch-auditing.adoc | 15 ++- .../ElasticsearchAuditingRegistrar.java | 111 +----------------- .../EnableReactiveElasticsearchAuditing.java | 70 +++++++++++ .../config/PersistentEntitiesFactoryBean.java | 54 +++++++++ ...eactiveElasticsearchAuditingRegistrar.java | 77 ++++++++++++ .../event/ReactiveAuditingEntityCallback.java | 12 +- .../ReactiveAuditingIntegrationTest.java | 17 +-- .../ReactiveAuditingEntityCallbackTests.java | 14 +-- .../junit/jupiter/ClusterConnection.java | 6 +- 9 files changed, 241 insertions(+), 135 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/EnableReactiveElasticsearchAuditing.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/PersistentEntitiesFactoryBean.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/config/ReactiveElasticsearchAuditingRegistrar.java diff --git a/src/main/asciidoc/reference/elasticsearch-auditing.adoc b/src/main/asciidoc/reference/elasticsearch-auditing.adoc index 63726588e..f465e4e74 100644 --- a/src/main/asciidoc/reference/elasticsearch-auditing.adoc +++ b/src/main/asciidoc/reference/elasticsearch-auditing.adoc @@ -3,7 +3,7 @@ === Preparing entities -In order for the auditing code to be able to decide wether an entity instance is new, the entity must implement the `Persistable` interface which is defined as follows: +In order for the auditing code to be able to decide whether an entity instance is new, the entity must implement the `Persistable` interface which is defined as follows: [source,java] ---- @@ -52,7 +52,7 @@ public class Person implements Persistable { === Activating auditing -After the entities have been set up and providing the `AuditorAware` the Auditing must be activated by setting the `@EnableElasticsearchAuditing` on a configuration class: +After the entities have been set up and providing the `AuditorAware` - or `ReactiveAuditorAware` - the Auditing must be activated by setting the `@EnableElasticsearchAuditing` on a configuration class: [source,java] ---- @@ -64,5 +64,16 @@ class MyConfiguration { } ---- +When using the reactive stack this must be: +[source,java] +---- +@Configuration +@EnableReactiveElasticsearchRepositories +@EnableReactiveElasticsearchAuditing +class MyConfiguration { + // configuration code +} +---- + If your code contains more than one `AuditorAware` bean for different types, you must provide the name of the bean to use as an argument to the `auditorAwareRef` parameter of the `@EnableElasticsearchAuditing` annotation. diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java index 1b9b765f2..a52dbc193 100644 --- a/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java +++ b/src/main/java/org/springframework/data/elasticsearch/config/ElasticsearchAuditingRegistrar.java @@ -17,24 +17,16 @@ import java.lang.annotation.Annotation; -import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; -import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.auditing.IsNewAwareAuditingHandler; import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport; import org.springframework.data.auditing.config.AuditingConfiguration; import org.springframework.data.config.ParsingUtils; -import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.event.AuditingEntityCallback; -import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; -import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.repository.util.ReactiveWrappers; import org.springframework.util.Assert; /** @@ -45,41 +37,16 @@ */ class ElasticsearchAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAnnotation() - */ @Override protected Class getAnnotation() { return EnableElasticsearchAuditing.class; } - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditingHandlerBeanName() - */ @Override protected String getAuditingHandlerBeanName() { return "elasticsearchAuditingHandler"; } - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry) - */ - @Override - public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) { - - Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!"); - Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); - - super.registerBeanDefinitions(annotationMetadata, registry); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#getAuditHandlerBeanDefinitionBuilder(org.springframework.data.auditing.config.AuditingConfiguration) - */ @Override protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) { @@ -87,18 +54,13 @@ protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingCon BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class); - BeanDefinitionBuilder definition = BeanDefinitionBuilder - .genericBeanDefinition(ElasticsearchMappingContextLookup.class); + BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class); definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); builder.addConstructorArgValue(definition.getBeanDefinition()); return configureDefaultAuditHandlerAttributes(configuration, builder); } - /* - * (non-Javadoc) - * @see org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport#registerAuditListener(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry) - */ @Override protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition, BeanDefinitionRegistry registry) { @@ -106,76 +68,9 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!"); Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); - BeanDefinitionBuilder listenerBeanDefinitionBuilder = BeanDefinitionBuilder - .rootBeanDefinition(AuditingEntityCallback.class); - listenerBeanDefinitionBuilder - .addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry)); - - registerInfrastructureBeanWithId(listenerBeanDefinitionBuilder.getBeanDefinition(), - AuditingEntityCallback.class.getName(), registry); - - if (ReactiveWrappers.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR)) { - registerReactiveAuditingEntityCallback(registry, auditingHandlerDefinition.getSource()); - } - } - - private void registerReactiveAuditingEntityCallback(BeanDefinitionRegistry registry, Object source) { - - BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class); - + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingEntityCallback.class); builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry)); - builder.getRawBeanDefinition().setSource(source); - - registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(), - registry); - } - - /** - * Simple helper to be able to wire the {@link MappingContext} from a {@link MappingElasticsearchConverter} bean - * available in the application context. - * - * @author Oliver Gierke - */ - static class ElasticsearchMappingContextLookup implements - FactoryBean, ElasticsearchPersistentProperty>> { - - private final MappingElasticsearchConverter converter; - - /** - * Creates a new {@link ElasticsearchMappingContextLookup} for the given {@link MappingElasticsearchConverter}. - * - * @param converter must not be {@literal null}. - */ - public ElasticsearchMappingContextLookup(MappingElasticsearchConverter converter) { - this.converter = converter; - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObject() - */ - @Override - public MappingContext, ElasticsearchPersistentProperty> getObject() - throws Exception { - return converter.getMappingContext(); - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#getObjectType() - */ - @Override - public Class getObjectType() { - return MappingContext.class; - } - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.FactoryBean#isSingleton() - */ - @Override - public boolean isSingleton() { - return true; - } + registerInfrastructureBeanWithId(builder.getBeanDefinition(), AuditingEntityCallback.class.getName(), registry); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/config/EnableReactiveElasticsearchAuditing.java b/src/main/java/org/springframework/data/elasticsearch/config/EnableReactiveElasticsearchAuditing.java new file mode 100644 index 000000000..4420ed105 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/EnableReactiveElasticsearchAuditing.java @@ -0,0 +1,70 @@ +/* + * Copyright 2020 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.config; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Import; +import org.springframework.data.auditing.DateTimeProvider; +import org.springframework.data.domain.AuditorAware; + +/** + * Annotation to enable auditing in Elasticsearch using reactive infrastructure via annotation configuration. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +@Inherited +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Import(ReactiveElasticsearchAuditingRegistrar.class) +public @interface EnableReactiveElasticsearchAuditing { + + /** + * Configures the {@link AuditorAware} bean to be used to lookup the current principal. + * + * @return + */ + String auditorAwareRef() default ""; + + /** + * Configures whether the creation and modification dates are set. Defaults to {@literal true}. + * + * @return + */ + boolean setDates() default true; + + /** + * Configures whether the entity shall be marked as modified on creation. Defaults to {@literal true}. + * + * @return + */ + boolean modifyOnCreate() default true; + + /** + * Configures a {@link DateTimeProvider} bean name that allows customizing the {@link org.joda.time.DateTime} to be + * used for setting creation and modification dates. + * + * @return + */ + String dateTimeProviderRef() default ""; +} diff --git a/src/main/java/org/springframework/data/elasticsearch/config/PersistentEntitiesFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/config/PersistentEntitiesFactoryBean.java new file mode 100644 index 000000000..17ad8c333 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/PersistentEntitiesFactoryBean.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 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.config; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; +import org.springframework.data.mapping.context.PersistentEntities; + +/** + * Simple helper to be able to wire the {@link PersistentEntities} from a {@link MappingElasticsearchConverter} bean + * available in the application context. + * + * @author Oliver Gierke + * @author Mark Paluch + * @author Christoph Strobl + * @author Peter-Josef Meisch + * @since 4.1 + */ +class PersistentEntitiesFactoryBean implements FactoryBean { + + private final MappingElasticsearchConverter converter; + + /** + * Creates a new {@link PersistentEntitiesFactoryBean} for the given {@link MappingElasticsearchConverter}. + * + * @param converter must not be {@literal null}. + */ + public PersistentEntitiesFactoryBean(MappingElasticsearchConverter converter) { + this.converter = converter; + } + + @Override + public PersistentEntities getObject() { + return PersistentEntities.of(converter.getMappingContext()); + } + + @Override + public Class getObjectType() { + return PersistentEntities.class; + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/config/ReactiveElasticsearchAuditingRegistrar.java b/src/main/java/org/springframework/data/elasticsearch/config/ReactiveElasticsearchAuditingRegistrar.java new file mode 100644 index 000000000..e74bcf1a2 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/config/ReactiveElasticsearchAuditingRegistrar.java @@ -0,0 +1,77 @@ +/* + * Copyright 2020 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.config; + +import java.lang.annotation.Annotation; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler; +import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport; +import org.springframework.data.auditing.config.AuditingConfiguration; +import org.springframework.data.config.ParsingUtils; +import org.springframework.data.elasticsearch.core.event.ReactiveAuditingEntityCallback; +import org.springframework.util.Assert; + +/** + * {@link ImportBeanDefinitionRegistrar} to enable {@link EnableReactiveElasticsearchAuditing} annotation. + * + * @author Peter-Josef Meisch + * @since 4.1 + */ +class ReactiveElasticsearchAuditingRegistrar extends AuditingBeanDefinitionRegistrarSupport { + + @Override + protected Class getAnnotation() { + return EnableReactiveElasticsearchAuditing.class; + } + + @Override + protected String getAuditingHandlerBeanName() { + return "reactiveElasticsearchAuditingHandler"; + } + + @Override + protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) { + + Assert.notNull(configuration, "AuditingConfiguration must not be null!"); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class); + + BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class); + definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); + + builder.addConstructorArgValue(definition.getBeanDefinition()); + return configureDefaultAuditHandlerAttributes(configuration, builder); + } + + @Override + protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition, + BeanDefinitionRegistry registry) { + + Assert.notNull(auditingHandlerDefinition, "BeanDefinition must not be null!"); + Assert.notNull(registry, "BeanDefinitionRegistry must not be null!"); + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveAuditingEntityCallback.class); + builder.addConstructorArgValue(ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), registry)); + + registerInfrastructureBeanWithId(builder.getBeanDefinition(), ReactiveAuditingEntityCallback.class.getName(), + registry); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java index 69a803684..213d02f24 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallback.java @@ -19,7 +19,7 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.core.Ordered; -import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.mapping.callback.EntityCallback; import org.springframework.util.Assert; @@ -33,15 +33,15 @@ */ public class ReactiveAuditingEntityCallback implements ReactiveBeforeConvertCallback, Ordered { - private final ObjectFactory auditingHandlerFactory; + private final ObjectFactory auditingHandlerFactory; /** - * Creates a new {@link ReactiveAuditingEntityCallback} using the given {@link IsNewAwareAuditingHandler} provided by - * the given {@link ObjectFactory}. + * Creates a new {@link ReactiveAuditingEntityCallback} using the given {@link ReactiveIsNewAwareAuditingHandler} + * provided by the given {@link ObjectFactory}. * * @param auditingHandlerFactory must not be {@literal null}. */ - public ReactiveAuditingEntityCallback(ObjectFactory auditingHandlerFactory) { + public ReactiveAuditingEntityCallback(ObjectFactory auditingHandlerFactory) { Assert.notNull(auditingHandlerFactory, "IsNewAwareAuditingHandler must not be null!"); @@ -50,7 +50,7 @@ public ReactiveAuditingEntityCallback(ObjectFactory a @Override public Mono onBeforeConvert(Object entity, IndexCoordinates index) { - return Mono.just(auditingHandlerFactory.getObject().markAudited(entity)); + return auditingHandlerFactory.getObject().markAudited(entity); } @Override diff --git a/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java index 29436c001..4a83ffc07 100644 --- a/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/config/ReactiveAuditingIntegrationTest.java @@ -17,8 +17,9 @@ import static org.assertj.core.api.Assertions.*; +import reactor.core.publisher.Mono; + import java.time.LocalDateTime; -import java.util.Optional; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,8 +31,8 @@ import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.domain.AuditorAware; import org.springframework.data.domain.Persistable; +import org.springframework.data.domain.ReactiveAuditorAware; import org.springframework.data.elasticsearch.core.event.ReactiveBeforeConvertCallback; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; @@ -49,23 +50,23 @@ @ContextConfiguration(classes = { ReactiveAuditingIntegrationTest.Config.class }) public class ReactiveAuditingIntegrationTest { - public static AuditorAware auditorProvider() { - return new AuditorAware() { + public static ReactiveAuditorAware auditorProvider() { + return new ReactiveAuditorAware() { int count = 0; @Override - public Optional getCurrentAuditor() { - return Optional.of("Auditor " + (++count)); + public Mono getCurrentAuditor() { + return Mono.just("Auditor " + (++count)); } }; } @Import({ ReactiveElasticsearchRestTemplateConfiguration.class }) - @EnableElasticsearchAuditing(auditorAwareRef = "auditorAware") + @EnableReactiveElasticsearchAuditing(auditorAwareRef = "auditorAware") static class Config { @Bean - public AuditorAware auditorAware() { + public ReactiveAuditorAware auditorAware() { return auditorProvider(); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java index 364b2b9af..a6e43416f 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/event/ReactiveAuditingEntityCallbackTests.java @@ -18,6 +18,7 @@ import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; import java.time.LocalDateTime; @@ -31,7 +32,7 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; -import org.springframework.data.auditing.IsNewAwareAuditingHandler; +import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext; import org.springframework.data.mapping.context.PersistentEntities; @@ -44,14 +45,14 @@ @ExtendWith(MockitoExtension.class) class ReactiveAuditingEntityCallbackTests { - IsNewAwareAuditingHandler handler; + ReactiveIsNewAwareAuditingHandler handler; ReactiveAuditingEntityCallback callback; @BeforeEach void setUp() { SimpleElasticsearchMappingContext context = new SimpleElasticsearchMappingContext(); context.getPersistentEntity(Sample.class); - handler = spy(new IsNewAwareAuditingHandler(PersistentEntities.of(context))); + handler = spy(new ReactiveIsNewAwareAuditingHandler(PersistentEntities.of(context))); callback = new ReactiveAuditingEntityCallback(() -> handler); } @@ -81,13 +82,10 @@ void shouldReturnObjectFromHandler() { sample1.setId("1"); Sample sample2 = new Sample(); sample2.setId("2"); - doReturn(sample2).when(handler).markAudited(any()); + doReturn(Mono.just(sample2)).when(handler).markAudited(any()); callback.onBeforeConvert(sample1, IndexCoordinates.of("index")) // - .as(StepVerifier::create) // - .consumeNextWith(it -> { // - assertThat(it).isSameAs(sample2); // - }).verifyComplete(); + .as(StepVerifier::create).expectNext(sample2).verifyComplete(); } static class Sample { diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java index 825636d00..eb5d624b6 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java @@ -30,9 +30,9 @@ /** * This class manages the connection to an Elasticsearch Cluster, starting a local one if necessary. The information - * about the ClusterConnection is stored botha s a varaible in the instance for direct aaces from JUnit 5 and in a - * static ThreadLocal acessible with the {@link ClusterConnection#clusterConnectionInfo()} method - * to be integrated in the Spring setup + * about the ClusterConnection is stored both as a variable in the instance for direct access from JUnit 5 and in a + * static ThreadLocal accessible with the {@link ClusterConnection#clusterConnectionInfo()} + * method to be integrated in the Spring setup * * @author Peter-Josef Meisch */ From a4cb8ef57c3aa41e0c5a8885c40f24e478ad264c Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 22 Jul 2020 09:31:11 +0200 Subject: [PATCH 0221/1191] DATAES-860 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 0a5f2ded8..cd032ece1 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.1.19.RELEASE (2020-07-22) +---------------------------------------------- +* DATAES-860 - Release 3.1.19 (Lovelace SR19). + + Changes in version 4.1.0-M1 (2020-06-25) ---------------------------------------- * DATAES-870 - Workaround for reactor-netty error. @@ -1210,3 +1215,4 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From c9e813ff724676ba45615388bfa90a15cff8749a Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 22 Jul 2020 09:55:26 +0200 Subject: [PATCH 0222/1191] DATAES-861 - Updated changelog. --- src/main/resources/changelog.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index cd032ece1..cd1f0f178 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,11 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 3.2.9.RELEASE (2020-07-22) +--------------------------------------------- +* DATAES-861 - Release 3.2.9 (Moore SR9). + + Changes in version 3.1.19.RELEASE (2020-07-22) ---------------------------------------------- * DATAES-860 - Release 3.1.19 (Lovelace SR19). @@ -1215,4 +1220,5 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 04977680ed300e19e13e86f5f87dad87a4ce1b5f Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 22 Jul 2020 10:20:41 +0200 Subject: [PATCH 0223/1191] DATAES-862 - Updated changelog. --- src/main/resources/changelog.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index cd1f0f178..0beb68a36 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,15 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.2.RELEASE (2020-07-22) +--------------------------------------------- +* DATAES-883 - Fix log level on resource load error. +* DATAES-878 - Wrong value for TermVector(woth_positions_offsets). +* DATAES-865 - Fix MappingElasticsearchConverter writing an Object property containing a Map. +* DATAES-863 - Improve server error response handling. +* DATAES-862 - Release 4.0.2 (Neumann SR2). + + Changes in version 3.2.9.RELEASE (2020-07-22) --------------------------------------------- * DATAES-861 - Release 3.2.9 (Moore SR9). @@ -1220,5 +1229,6 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From fe458612e9159c11d5486dbe250415d40cc7a48b Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 28 Jul 2020 15:39:46 +0200 Subject: [PATCH 0224/1191] DATAES-858 - Fix link to code of conduct. --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 590bef71d..f5e77b47a 100644 --- a/README.adoc +++ b/README.adoc @@ -19,7 +19,7 @@ This project is lead and maintained by the community. == Code of Conduct -This project is governed by the link:CODE_OF_CONDUCT.adoc[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io. +This project is governed by the https://github.com/spring-projects/.github/blob/e3cc2ff230d8f1dca06535aa6b5a4a23815861d4/CODE_OF_CONDUCT.md[Spring Code of Conduct]. By participating, you are expected to uphold this code of conduct. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io. == Getting Started From f989cf873b0e2a5e60044ffa1af42b77b05e9012 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 29 Jul 2020 09:49:55 +0200 Subject: [PATCH 0225/1191] DATAES-891 - Returning a Stream from a Query annotated repository method crashes. Original PR: #497 --- .../AbstractElasticsearchRepositoryQuery.java | 3 +- .../query/ElasticsearchPartQuery.java | 2 -- .../query/ElasticsearchStringQuery.java | 9 ++++++ .../CustomMethodRepositoryBaseTests.java | 29 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java index 88907be50..127d2cc94 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/AbstractElasticsearchRepositoryQuery.java @@ -28,11 +28,12 @@ public abstract class AbstractElasticsearchRepositoryQuery implements RepositoryQuery { + protected static final int DEFAULT_STREAM_BATCH_SIZE = 500; protected ElasticsearchQueryMethod queryMethod; protected ElasticsearchOperations elasticsearchOperations; public AbstractElasticsearchRepositoryQuery(ElasticsearchQueryMethod queryMethod, - ElasticsearchOperations elasticsearchOperations) { + ElasticsearchOperations elasticsearchOperations) { this.queryMethod = queryMethod; this.elasticsearchOperations = elasticsearchOperations; } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 151740a7a..647941885 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -43,8 +43,6 @@ */ public class ElasticsearchPartQuery extends AbstractElasticsearchRepositoryQuery { - private static final int DEFAULT_STREAM_BATCH_SIZE = 500; - private final PartTree tree; private final ElasticsearchConverter elasticsearchConverter; private final MappingContext mappingContext; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java index f6863067d..db1905dfd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchStringQuery.java @@ -19,6 +19,7 @@ import java.util.regex.Pattern; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.data.domain.PageRequest; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHitSupport; import org.springframework.data.elasticsearch.core.SearchHits; @@ -26,6 +27,7 @@ import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.StringQuery; import org.springframework.data.repository.query.ParametersParameterAccessor; +import org.springframework.data.util.StreamUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.NumberUtils; @@ -88,6 +90,13 @@ public Object execute(Object[] parameters) { stringQuery.setPageable(accessor.getPageable()); SearchHits searchHits = elasticsearchOperations.search(stringQuery, clazz, index); result = SearchHitSupport.page(searchHits, stringQuery.getPageable()); + } else if (queryMethod.isStreamQuery()) { + if (accessor.getPageable().isUnpaged()) { + stringQuery.setPageable(PageRequest.of(0, DEFAULT_STREAM_BATCH_SIZE)); + } else { + stringQuery.setPageable(accessor.getPageable()); + } + result = StreamUtils.createStreamFromIterator(elasticsearchOperations.searchForStream(stringQuery, clazz, index)); } else if (queryMethod.isCollectionQuery()) { if (accessor.getPageable().isPaged()) { stringQuery.setPageable(accessor.getPageable()); diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index 9bffc6c0d..d2c2b3f71 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -1544,6 +1544,28 @@ private List createSampleEntities(String type, int numberOfEntitie return entities; } + @Test // DATAES-891 + void shouldStreamEntitiesWithQueryAnnotatedMethod() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + Stream stream = streamingRepository.streamEntitiesByType("abc"); + + long count = stream.peek(sampleEntity -> assertThat(sampleEntity).isInstanceOf(SampleEntity.class)).count(); + assertThat(count).isEqualTo(20); + } + + @Test // DATAES-891 + void shouldStreamSearchHitsWithQueryAnnotatedMethod() { + List entities = createSampleEntities("abc", 20); + repository.saveAll(entities); + + Stream> stream = streamingRepository.streamSearchHitsByType("abc"); + + long count = stream.peek(sampleEntity -> assertThat(sampleEntity).isInstanceOf(SearchHit.class)).count(); + assertThat(count).isEqualTo(20); + } + @Data @NoArgsConstructor @AllArgsConstructor @@ -1687,5 +1709,12 @@ public interface SampleStreamingCustomMethodRepository extends ElasticsearchRepo Stream findByType(String type); Stream findByType(String type, Pageable pageable); + + @Query("{\"bool\": {\"must\": [{\"term\": {\"type\": \"?0\"}}]}}") + Stream streamEntitiesByType(String type); + + @Query("{\"bool\": {\"must\": [{\"term\": {\"type\": \"?0\"}}]}}") + Stream> streamSearchHitsByType(String type); + } } From f19bf6482743269cd5901906c6aa3c04d4e7e464 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 4 Aug 2020 12:31:37 +0200 Subject: [PATCH 0226/1191] DATAES-893 - Adopt to changed module layout of Reactor Netty. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3179a9b98..51f6f6342 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ io.projectreactor.netty - reactor-netty + reactor-netty-http true From b30f12503dd515a0bff4657677fda2e96a066aa7 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Tue, 4 Aug 2020 12:31:59 +0200 Subject: [PATCH 0227/1191] DATAES-893 - Adopt to changes in Project Reactor. --- .../DefaultReactiveElasticsearchClient.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 321f9f4ae..c3f6f7c62 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -22,10 +22,11 @@ import io.netty.handler.ssl.JdkSslContext; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; -import reactor.core.publisher.EmitterProcessor; import reactor.core.publisher.Flux; -import reactor.core.publisher.FluxSink; +import reactor.core.publisher.FluxIdentityProcessor; import reactor.core.publisher.Mono; +import reactor.core.publisher.Processors; +import reactor.core.publisher.Sinks; import reactor.netty.http.client.HttpClient; import reactor.netty.transport.ProxyProvider; @@ -106,6 +107,7 @@ import org.elasticsearch.search.aggregations.Aggregation; import org.elasticsearch.search.suggest.Suggest; import org.reactivestreams.Publisher; + import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientLogger; import org.springframework.data.elasticsearch.client.ElasticsearchHost; @@ -465,12 +467,10 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) searchRequest.scroll(scrollTimeout); } - EmitterProcessor outbound = EmitterProcessor.create(false); - FluxSink request = outbound.sink(); - - EmitterProcessor inbound = EmitterProcessor.create(false); + Sinks.StandaloneFluxSink request = Sinks.unicast(); + FluxIdentityProcessor inbound = Processors.unicast(); - Flux exchange = outbound.startWith(searchRequest).flatMap(it -> { + Flux exchange = request.asFlux().flatMap(it -> { if (it instanceof SearchRequest) { return sendRequest((SearchRequest) it, requestCreator.search(), SearchResponse.class, headers); @@ -495,7 +495,7 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) if (isEmpty(searchResponse.getHits())) { inbound.onComplete(); - outbound.onComplete(); + request.complete(); } else { @@ -509,10 +509,13 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) }).map(SearchResponse::getHits) // .flatMap(Flux::fromIterable); - return searchHits.doOnSubscribe(ignore -> exchange.subscribe(inbound)); + return searchHits.doOnSubscribe(ignore -> { + exchange.subscribe(inbound); + request.next(searchRequest); + }); }, state -> cleanupScroll(headers, state), // - state -> cleanupScroll(headers, state), // + (state, ex) -> cleanupScroll(headers, state), // state -> cleanupScroll(headers, state)); // } From 103bf9f1b980063768ad93fbef872d79f47a62f7 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 5 Aug 2020 14:36:41 +0200 Subject: [PATCH 0228/1191] DATAES-894 - Adapt to changes in Reactor This commit updates the `DefaultReactiveElasticsearchClient` after changes in Reactor around `Processors` and `Sinks`. Original pull request: #498. --- .../DefaultReactiveElasticsearchClient.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index c3f6f7c62..8c05bca60 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -23,9 +23,8 @@ import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import reactor.core.publisher.Flux; -import reactor.core.publisher.FluxIdentityProcessor; +import reactor.core.publisher.FluxProcessor; import reactor.core.publisher.Mono; -import reactor.core.publisher.Processors; import reactor.core.publisher.Sinks; import reactor.netty.http.client.HttpClient; import reactor.netty.transport.ProxyProvider; @@ -467,8 +466,9 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) searchRequest.scroll(scrollTimeout); } - Sinks.StandaloneFluxSink request = Sinks.unicast(); - FluxIdentityProcessor inbound = Processors.unicast(); + Sinks.Many request = Sinks.many().unicast().onBackpressureBuffer(); + + FluxProcessor inbound = FluxProcessor.fromSink(Sinks.many().unicast().onBackpressureBuffer()); Flux exchange = request.asFlux().flatMap(it -> { @@ -495,7 +495,7 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) if (isEmpty(searchResponse.getHits())) { inbound.onComplete(); - request.complete(); + request.emitComplete(); } else { @@ -503,7 +503,7 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) SearchScrollRequest searchScrollRequest = new SearchScrollRequest(scrollState.getScrollId()) .scroll(scrollTimeout); - request.next(searchScrollRequest); + request.emitNext(searchScrollRequest); } }).map(SearchResponse::getHits) // @@ -511,7 +511,7 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) return searchHits.doOnSubscribe(ignore -> { exchange.subscribe(inbound); - request.next(searchRequest); + request.emitNext(searchRequest); }); }, state -> cleanupScroll(headers, state), // From 0cfb1b563ee0edcb414a71853bbb3ae162fdfeef Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 5 Aug 2020 14:48:50 +0200 Subject: [PATCH 0229/1191] DATAES-894 - Polishing. Reformat code. Add author tag. Original pull request: #498. --- .../client/reactive/DefaultReactiveElasticsearchClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java index 8c05bca60..968ffe094 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/reactive/DefaultReactiveElasticsearchClient.java @@ -142,6 +142,7 @@ * @author Roman Puchkovskiy * @author Russell Parry * @author Thomas Geese + * @author Brian Clozel * @since 3.2 * @see ClientConfiguration * @see ReactiveRestClients @@ -468,7 +469,8 @@ public Flux scroll(HttpHeaders headers, SearchRequest searchRequest) Sinks.Many request = Sinks.many().unicast().onBackpressureBuffer(); - FluxProcessor inbound = FluxProcessor.fromSink(Sinks.many().unicast().onBackpressureBuffer()); + FluxProcessor inbound = FluxProcessor + .fromSink(Sinks.many().unicast().onBackpressureBuffer()); Flux exchange = request.asFlux().flatMap(it -> { From 68bdc93a0ba1671562bb12cfcc09432c0851be2a Mon Sep 17 00:00:00 2001 From: Subhobrata Dey Date: Fri, 7 Aug 2020 06:44:37 -0700 Subject: [PATCH 0230/1191] [DATAES-433] Support join datatype. Original PR: #485 --- .../annotations/JoinTypeRelation.java | 37 ++++ .../annotations/JoinTypeRelations.java | 36 ++++ .../core/AbstractElasticsearchTemplate.java | 23 +++ .../elasticsearch/core/RequestFactory.java | 15 ++ .../MappingElasticsearchConverter.java | 8 + .../core/index/MappingBuilder.java | 45 +++++ .../elasticsearch/core/join/JoinField.java | 67 +++++++ .../ElasticsearchPersistentEntity.java | 22 +++ .../SimpleElasticsearchPersistentEntity.java | 25 +++ .../elasticsearch/core/query/IndexQuery.java | 10 ++ .../core/query/IndexQueryBuilder.java | 7 + .../data/elasticsearch/Utils.java | 4 +- .../core/ElasticsearchRestTemplateTests.java | 16 +- .../core/ElasticsearchTemplateTests.java | 164 +++++++++++++++++- 14 files changed, 463 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java create mode 100644 src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java new file mode 100644 index 000000000..f3e75d439 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Subhobrata Dey + * @since 4.1 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.ANNOTATION_TYPE) +public @interface JoinTypeRelation { + + String parent(); + + String[] children(); +} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java new file mode 100644 index 000000000..d550a0888 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Subhobrata Dey + * @since 4.1 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +@Inherited +public @interface JoinTypeRelations { + + JoinTypeRelation[] relations(); +} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 0d7a1530f..9819cc9fe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -39,6 +39,8 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.data.convert.EntityReader; import org.springframework.data.elasticsearch.BulkFailureException; +import org.springframework.data.elasticsearch.core.join.JoinField; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; @@ -532,6 +534,22 @@ private String getEntityId(Object entity) { return null; } + @Nullable + private String getEntityRouting(Object entity) { + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + ElasticsearchPersistentProperty joinProperty = persistentEntity.getJoinFieldProperty(); + + if (joinProperty != null) { + Object joinField = persistentEntity.getPropertyAccessor(entity).getProperty(joinProperty); + if (joinField != null && JoinField.class.isAssignableFrom(joinField.getClass()) + && ((JoinField) joinField).getParent() != null) { + return elasticsearchConverter.convertId(((JoinField) joinField).getParent()); + } + } + + return null; + } + @Nullable private Long getEntityVersion(Object entity) { ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); @@ -581,6 +599,11 @@ private IndexQuery getIndexQuery(T entity) { // version cannot be used together with seq_no and primary_term builder.withVersion(getEntityVersion(entity)); } + + String routing = getEntityRouting(entity); + if (routing != null) { + builder.withRouting(routing); + } return builder.build(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index fc6c9688a..a171d89bf 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -743,6 +743,10 @@ public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, In deleteByQueryRequest.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); } + if (query.getRoute() != null) { + deleteByQueryRequest.setRouting(query.getRoute()); + } + return deleteByQueryRequest; } @@ -798,6 +802,10 @@ public DeleteByQueryRequestBuilder deleteByQueryRequestBuilder(Client client, Qu source.setScroll(TimeValue.timeValueMillis(query.getScrollTime().toMillis())); } + if (query.getRoute() != null) { + source.setRouting(query.getRoute()); + } + return requestBuilder; } // endregion @@ -888,6 +896,10 @@ public IndexRequest indexRequest(IndexQuery query, IndexCoordinates index) { indexRequest.setIfPrimaryTerm(query.getPrimaryTerm()); } + if (query.getRouting() != null) { + indexRequest.routing(query.getRouting()); + } + return indexRequest; } @@ -926,6 +938,9 @@ public IndexRequestBuilder indexRequestBuilder(Client client, IndexQuery query, if (query.getPrimaryTerm() != null) { indexRequestBuilder.setIfPrimaryTerm(query.getPrimaryTerm()); } + if (query.getRouting() != null) { + indexRequestBuilder.setRouting(query.getRouting()); + } return indexRequestBuilder; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 15c53ee88..82458e5e3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -44,6 +44,7 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.document.Document; import org.springframework.data.elasticsearch.core.document.SearchDocument; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; @@ -710,6 +711,13 @@ private boolean requiresTypeHint(TypeInformation type, Class actualType, if (container.equals(type) && type.getType().equals(actualType)) { return false; } + + if (container.getRawTypeInformation().equals(type)) { + Class containerClass = container.getRawTypeInformation().getType(); + if (containerClass.equals(JoinField.class) && type.getType().equals(actualType)) { + return false; + } + } } return !conversions.isSimpleType(type.getType()) && !type.isCollectionLike() diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index d42203f3e..a1b59ab23 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -40,6 +40,8 @@ import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.GeoPointField; import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelation; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; import org.springframework.data.elasticsearch.annotations.Mapping; import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; @@ -47,6 +49,7 @@ import org.springframework.data.elasticsearch.core.completion.Completion; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.geo.GeoPoint; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.mapping.MappingException; @@ -73,6 +76,7 @@ * @author Petr Kukral * @author Peter-Josef Meisch * @author Xiao Yu + * @author Subhobrata Dey */ public class MappingBuilder { @@ -93,8 +97,11 @@ public class MappingBuilder { private static final String TYPE_DYNAMIC = "dynamic"; private static final String TYPE_VALUE_KEYWORD = "keyword"; private static final String TYPE_VALUE_GEO_POINT = "geo_point"; + private static final String TYPE_VALUE_JOIN = "join"; private static final String TYPE_VALUE_COMPLETION = "completion"; + private static final String JOIN_TYPE_RELATIONS = "relations"; + private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); private final ElasticsearchConverter elasticsearchConverter; @@ -212,6 +219,10 @@ private void buildPropertyMapping(XContentBuilder builder, boolean isRootObject, return; } + if (isJoinFieldProperty(property)) { + addJoinFieldMapping(builder, property); + } + Field fieldAnnotation = property.findAnnotation(Field.class); boolean isCompletionProperty = isCompletionProperty(property); boolean isNestedOrObjectProperty = isNestedOrObjectProperty(property); @@ -336,6 +347,36 @@ private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersist builder.endObject(); } + private void addJoinFieldMapping(XContentBuilder builder, + ElasticsearchPersistentProperty property) throws IOException { + JoinTypeRelation[] joinTypeRelations = property.getRequiredAnnotation(JoinTypeRelations.class).relations(); + + if (joinTypeRelations.length == 0) { + logger.warn("Property {}s type is JoinField but its annotation JoinTypeRelation is " + // + "not properly maintained", // + property.getFieldName()); + return; + } + builder.startObject(property.getFieldName()); + + builder.field(FIELD_PARAM_TYPE, TYPE_VALUE_JOIN); + + builder.startObject(JOIN_TYPE_RELATIONS); + + for (JoinTypeRelation joinTypeRelation: joinTypeRelations) { + String parent = joinTypeRelation.parent(); + String[] children = joinTypeRelation.children(); + + if (children.length > 1) { + builder.array(parent, children); + } else if (children.length == 1) { + builder.field(parent, children[0]); + } + } + builder.endObject(); + builder.endObject(); + } + /** * Add mapping for @MultiField annotation * @@ -423,6 +464,10 @@ private boolean isGeoPointProperty(ElasticsearchPersistentProperty property) { return property.getActualType() == GeoPoint.class || property.isAnnotationPresent(GeoPointField.class); } + private boolean isJoinFieldProperty(ElasticsearchPersistentProperty property) { + return property.getActualType() == JoinField.class; + } + private boolean isCompletionProperty(ElasticsearchPersistentProperty property) { return property.getActualType() == Completion.class; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java new file mode 100644 index 000000000..6792f0d77 --- /dev/null +++ b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java @@ -0,0 +1,67 @@ +/* + * Copyright 2020 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.join; + +import org.springframework.lang.Nullable; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Subhobrata Dey + * @since 4.1 + */ +public class JoinField { + + private final String name; + + @Nullable private ID parent; + + public JoinField() { + this("default", null); + } + + public JoinField(String name) { + this(name, null); + } + + public JoinField(String name, @Nullable ID parent) { + this.name = name; + this.parent = parent; + } + + public void setParent(@Nullable ID parent) { + this.parent = parent; + } + + @Nullable + public ID getParent() { + return parent; + } + + public String getName() { + return name; + } + + public Map getAsMap() { + Map joinMap = new HashMap<>(); + joinMap.put("name", getName()); + joinMap.put("parent", getParent()); + + return Collections.unmodifiableMap(joinMap); + } +} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index b2f8c267d..fcbea9724 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -18,6 +18,7 @@ import org.elasticsearch.index.VersionType; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentEntity; import org.springframework.lang.Nullable; @@ -33,6 +34,7 @@ * @author Ivan Greene * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public interface ElasticsearchPersistentEntity extends PersistentEntity { @@ -119,6 +121,15 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends PersistentEntity extends BasicPersistentEntit @Deprecated private @Nullable ElasticsearchPersistentProperty parentIdProperty; private @Nullable ElasticsearchPersistentProperty scoreProperty; private @Nullable ElasticsearchPersistentProperty seqNoPrimaryTermProperty; + private @Nullable ElasticsearchPersistentProperty joinFieldProperty; private @Nullable String settingPath; private @Nullable VersionType versionType; private boolean createIndexAndMapping; @@ -230,6 +232,19 @@ public void addPersistentProperty(ElasticsearchPersistentProperty property) { warnAboutBothSeqNoPrimaryTermAndVersionProperties(); } } + + if (property.getActualType() == JoinField.class) { + ElasticsearchPersistentProperty joinProperty = this.joinFieldProperty; + + if (joinProperty != null) { + throw new MappingException(String.format( + "Attempt to add Join property %s but already have property %s registered " + + "as Join property. Check your entity configuration!", + property.getField(), joinProperty.getField())); + } + + this.joinFieldProperty = property; + } } private void warnAboutBothSeqNoPrimaryTermAndVersionProperties() { @@ -273,12 +288,22 @@ public boolean hasSeqNoPrimaryTermProperty() { return seqNoPrimaryTermProperty != null; } + @Override + public boolean hasJoinFieldProperty() { + return joinFieldProperty != null; + } + @Override @Nullable public ElasticsearchPersistentProperty getSeqNoPrimaryTermProperty() { return seqNoPrimaryTermProperty; } + @Override + public ElasticsearchPersistentProperty getJoinFieldProperty() { + return joinFieldProperty; + } + // region SpEL handling /** * resolves all the names in the IndexCoordinates object. If a name cannot be resolved, the original name is returned. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index bbe059d54..8370c6ea4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -34,6 +34,7 @@ public class IndexQuery { @Deprecated @Nullable private String parentId; @Nullable private Long seqNo; @Nullable private Long primaryTerm; + @Nullable private String routing; @Nullable public String getId() { @@ -107,4 +108,13 @@ public Long getPrimaryTerm() { public void setPrimaryTerm(Long primaryTerm) { this.primaryTerm = primaryTerm; } + + @Nullable + public String getRouting() { + return routing; + } + + public void setRouting(@Nullable String routing) { + this.routing = routing; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index b4a7250f2..08b6317c4 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -34,6 +34,7 @@ public class IndexQueryBuilder { @Deprecated @Nullable private String parentId; @Nullable private Long seqNo; @Nullable private Long primaryTerm; + @Nullable private String routing; public IndexQueryBuilder withId(String id) { this.id = id; @@ -67,6 +68,11 @@ public IndexQueryBuilder withSeqNoPrimaryTerm(SeqNoPrimaryTerm seqNoPrimaryTerm) return this; } + public IndexQueryBuilder withRouting(@Nullable String routing) { + this.routing = routing; + return this; + } + public IndexQuery build() { IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(id); @@ -76,6 +82,7 @@ public IndexQuery build() { indexQuery.setVersion(version); indexQuery.setSeqNo(seqNo); indexQuery.setPrimaryTerm(primaryTerm); + indexQuery.setRouting(routing); return indexQuery; } } diff --git a/src/test/java/org/springframework/data/elasticsearch/Utils.java b/src/test/java/org/springframework/data/elasticsearch/Utils.java index cdaf0e4e6..7875f2b82 100644 --- a/src/test/java/org/springframework/data/elasticsearch/Utils.java +++ b/src/test/java/org/springframework/data/elasticsearch/Utils.java @@ -15,11 +15,13 @@ */ package org.springframework.data.elasticsearch; +import java.util.Arrays; import java.util.Collections; import java.util.UUID; import org.elasticsearch.client.Client; import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.join.ParentJoinPlugin; import org.elasticsearch.node.Node; import org.elasticsearch.node.NodeValidationException; import org.elasticsearch.transport.Netty4Plugin; @@ -53,7 +55,7 @@ public static Node getNode() { .put("cluster.routing.allocation.disk.watermark.high", "1gb")// .put("cluster.routing.allocation.disk.watermark.flood_stage", "1gb")// .build(), // - Collections.singletonList(Netty4Plugin.class)); + Arrays.asList(Netty4Plugin.class, ParentJoinPlugin.class)); } public static Client getNodeClient() throws NodeValidationException { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 0abaf7599..4f576a65b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -19,25 +19,28 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.utils.IdGenerator.*; -import lombok.Builder; -import lombok.Data; -import lombok.val; +import lombok.*; import java.lang.Object; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.SimpleQueryStringBuilder; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelation; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; @@ -118,5 +121,4 @@ void shouldUseAllOptionsFromUpdateQuery() { assertThat(fetchSourceContext.includes()).containsExactlyInAnyOrder("incl"); assertThat(fetchSourceContext.excludes()).containsExactlyInAnyOrder("excl"); } - } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 40d9537b1..0f0b1d591 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -41,6 +41,7 @@ import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.function.Function; import java.util.stream.Collectors; import org.assertj.core.util.Lists; @@ -49,6 +50,8 @@ import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.index.VersionType; +import org.elasticsearch.index.query.SimpleQueryStringBuilder; +import org.elasticsearch.join.query.ParentIdQueryBuilder; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; import org.elasticsearch.search.fetch.subphase.FetchSourceContext; @@ -68,20 +71,17 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.Document; +import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.annotations.FieldType; -import org.springframework.data.elasticsearch.annotations.InnerField; -import org.springframework.data.elasticsearch.annotations.MultiField; -import org.springframework.data.elasticsearch.annotations.Score; -import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.geo.GeoPoint; 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.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; +import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.util.StreamUtils; import org.springframework.lang.Nullable; @@ -117,9 +117,10 @@ public abstract class ElasticsearchTemplateTests { private static final String INDEX_3_NAME = "test-index-3"; protected final IndexCoordinates index = IndexCoordinates.of(INDEX_NAME_SAMPLE_ENTITY); + protected static final String INDEX_NAME_JOIN_SAMPLE_ENTITY = "test-index-sample-join-template"; @Autowired protected ElasticsearchOperations operations; - private IndexOperations indexOperations; + protected IndexOperations indexOperations; @BeforeEach public void before() { @@ -136,6 +137,10 @@ public void before() { IndexOperations indexOpsSearchHitsEntity = operations.indexOps(SearchHitsEntity.class); indexOpsSearchHitsEntity.create(); indexOpsSearchHitsEntity.putMapping(SearchHitsEntity.class); + + IndexOperations indexOpsJoinEntity = operations.indexOps(ElasticsearchRestTemplateTests.SampleJoinEntity.class); + indexOpsJoinEntity.create(); + indexOpsJoinEntity.putMapping(ElasticsearchRestTemplateTests.SampleJoinEntity.class); } @AfterEach @@ -158,6 +163,7 @@ private void deleteIndices() { operations.indexOps(HighlightEntity.class).delete(); operations.indexOps(OptimisticEntity.class).delete(); operations.indexOps(OptimisticAndVersionedEntity.class).delete(); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)).delete(); } @Test // DATAES-106 @@ -171,7 +177,6 @@ public void shouldReturnCountForGivenCriteriaQuery() { IndexQuery indexQuery = getIndexQuery(sampleEntity); operations.index(indexQuery, index); indexOperations.refresh(); - ; CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when @@ -3302,6 +3307,135 @@ void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { operations.save(forEdit); } + @Test + void shouldSupportCRUDOpsForEntityWithJoinFields() throws Exception { + String qId1 = java.util.UUID.randomUUID().toString(); + String qId2 = java.util.UUID.randomUUID().toString(); + String aId1 = java.util.UUID.randomUUID().toString(); + String aId2 = java.util.UUID.randomUUID().toString(); + + shouldSaveEntityWithJoinFields(qId1, qId2, aId1, aId2); + shouldUpdateEntityWithJoinFields(qId1, qId2, aId1, aId2); + shouldDeleteEntityWithJoinFields(qId2, aId2); + } + + void shouldSaveEntityWithJoinFields(String qId1, String qId2, String aId1, String aId2) throws Exception { + SampleJoinEntity sampleQuestionEntity1 = new SampleJoinEntity(); + sampleQuestionEntity1.setUuid(qId1); + sampleQuestionEntity1.setText("This is a question"); + + JoinField myQJoinField1 = new JoinField<>("question"); + sampleQuestionEntity1.setMyJoinField(myQJoinField1); + + SampleJoinEntity sampleQuestionEntity2 = new SampleJoinEntity(); + sampleQuestionEntity2.setUuid(qId2); + sampleQuestionEntity2.setText("This is another question"); + + JoinField myQJoinField2 = new JoinField<>("question"); + sampleQuestionEntity2.setMyJoinField(myQJoinField2); + + SampleJoinEntity sampleAnswerEntity1 = new SampleJoinEntity(); + sampleAnswerEntity1.setUuid(aId1); + sampleAnswerEntity1.setText("This is an answer"); + + JoinField myAJoinField1 = new JoinField<>("answer"); + myAJoinField1.setParent(qId1); + sampleAnswerEntity1.setMyJoinField(myAJoinField1); + + SampleJoinEntity sampleAnswerEntity2 = new SampleJoinEntity(); + sampleAnswerEntity2.setUuid(aId2); + sampleAnswerEntity2.setText("This is another answer"); + + JoinField myAJoinField2 = new JoinField<>("answer"); + myAJoinField2.setParent(qId1); + sampleAnswerEntity2.setMyJoinField(myAJoinField2); + + operations.save(Arrays.asList(sampleQuestionEntity1, sampleQuestionEntity2, + sampleAnswerEntity1, sampleAnswerEntity2), IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); + indexOperations.refresh(); + Thread.sleep(5000); + + SearchHits hits = operations.search(new NativeSearchQueryBuilder().withQuery( + new ParentIdQueryBuilder("answer", qId1)) + .build(), SampleJoinEntity.class); + + List hitIds = hits.getSearchHits().stream().map(new Function, String>() { + @Override + public String apply(SearchHit sampleJoinEntitySearchHit) { + return sampleJoinEntitySearchHit.getId(); + } + }).collect(Collectors.toList()); + + assertThat(hitIds.size()).isEqualTo(2); + assertThat(hitIds.containsAll(Arrays.asList(aId1, aId2))).isTrue(); + } + + void shouldUpdateEntityWithJoinFields(String qId1, String qId2, String aId1, String aId2) throws Exception { + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + document.put("myJoinField", new JoinField<>("answer", qId2).getAsMap()); + UpdateQuery updateQuery = UpdateQuery.builder(aId2) // + .withDocument(document) // + .withRouting(qId2) + .build(); + + List queries = new ArrayList<>(); + queries.add(updateQuery); + + // when + operations.bulkUpdate(queries, IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); + indexOperations.refresh(); + Thread.sleep(5000); + + SearchHits updatedHits = operations.search(new NativeSearchQueryBuilder().withQuery( + new ParentIdQueryBuilder("answer", qId2)) + .build(), SampleJoinEntity.class); + + List hitIds = updatedHits.getSearchHits().stream().map(new Function, String>() { + @Override + public String apply(SearchHit sampleJoinEntitySearchHit) { + return sampleJoinEntitySearchHit.getId(); + } + }).collect(Collectors.toList()); + assertThat(hitIds.size()).isEqualTo(1); + assertThat(hitIds.get(0)).isEqualTo(aId2); + + updatedHits = operations.search(new NativeSearchQueryBuilder().withQuery( + new ParentIdQueryBuilder("answer", qId1)) + .build(), SampleJoinEntity.class); + + hitIds = updatedHits.getSearchHits().stream().map(new Function, String>() { + @Override + public String apply(SearchHit sampleJoinEntitySearchHit) { + return sampleJoinEntitySearchHit.getId(); + } + }).collect(Collectors.toList()); + assertThat(hitIds.size()).isEqualTo(1); + assertThat(hitIds.get(0)).isEqualTo(aId1); + } + + void shouldDeleteEntityWithJoinFields(String qId2, String aId2) throws Exception { + Query query = new NativeSearchQueryBuilder() + .withQuery(new ParentIdQueryBuilder("answer", qId2)) + .withRoute(qId2) + .build(); + operations.delete(query, SampleJoinEntity.class, IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); + indexOperations.refresh(); + Thread.sleep(5000); + + SearchHits deletedHits = operations.search(new NativeSearchQueryBuilder().withQuery( + new ParentIdQueryBuilder("answer", qId2)) + .build(), SampleJoinEntity.class); + + List hitIds = deletedHits.getSearchHits().stream().map(new Function, String>() { + @Override + public String apply(SearchHit sampleJoinEntitySearchHit) { + return sampleJoinEntitySearchHit.getId(); + } + }).collect(Collectors.toList()); + assertThat(hitIds.size()).isEqualTo(0); + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } @@ -3482,4 +3616,18 @@ static class OptimisticAndVersionedEntity { private SeqNoPrimaryTerm seqNoPrimaryTerm; @Version private Long version; } + + @Data + @NoArgsConstructor + @AllArgsConstructor + @Builder + @Document(indexName = INDEX_NAME_JOIN_SAMPLE_ENTITY) + static class SampleJoinEntity { + @Id @Field(type = Keyword) private String uuid; + @JoinTypeRelations(relations = { + @JoinTypeRelation(parent = "question", children = {"answer"}) + }) + private JoinField myJoinField; + @Field(type = Text) private String text; + } } From 99ed967b71157b8c29e4aa7ff38fd8e596d30a9e Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Fri, 7 Aug 2020 16:07:54 +0200 Subject: [PATCH 0231/1191] DATAES-433 - Polishing. --- .../annotations/JoinTypeRelation.java | 7 +-- .../annotations/JoinTypeRelations.java | 4 +- .../core/AbstractElasticsearchTemplate.java | 6 +- .../elasticsearch/core/RequestFactory.java | 1 + .../MappingElasticsearchConverter.java | 1 + .../core/index/MappingBuilder.java | 21 ++----- .../elasticsearch/core/join/JoinField.java | 62 +++++++++---------- .../ElasticsearchPersistentEntity.java | 8 +-- .../SimpleElasticsearchPersistentEntity.java | 10 +-- .../elasticsearch/core/query/IndexQuery.java | 1 + .../core/query/IndexQueryBuilder.java | 1 + .../data/elasticsearch/Utils.java | 2 +- .../core/ElasticsearchRestTemplateTests.java | 15 ++--- .../core/ElasticsearchTemplateTests.java | 59 +++++++++--------- 14 files changed, 95 insertions(+), 103 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java index f3e75d439..05863d1e7 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelation.java @@ -17,7 +17,6 @@ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -31,7 +30,7 @@ @Target(ElementType.ANNOTATION_TYPE) public @interface JoinTypeRelation { - String parent(); + String parent(); - String[] children(); -} \ No newline at end of file + String[] children(); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java index d550a0888..072b984b9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/JoinTypeRelations.java @@ -32,5 +32,5 @@ @Inherited public @interface JoinTypeRelations { - JoinTypeRelation[] relations(); -} \ No newline at end of file + JoinTypeRelation[] relations(); +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 9819cc9fe..59702cb64 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -39,8 +39,6 @@ import org.springframework.context.ApplicationContextAware; import org.springframework.data.convert.EntityReader; import org.springframework.data.elasticsearch.BulkFailureException; -import org.springframework.data.elasticsearch.core.join.JoinField; -import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; @@ -48,6 +46,7 @@ import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -76,6 +75,7 @@ * @author Sascha Woo * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { @@ -542,7 +542,7 @@ private String getEntityRouting(Object entity) { if (joinProperty != null) { Object joinField = persistentEntity.getPropertyAccessor(entity).getProperty(joinProperty); if (joinField != null && JoinField.class.isAssignableFrom(joinField.getClass()) - && ((JoinField) joinField).getParent() != null) { + && ((JoinField) joinField).getParent() != null) { return elasticsearchConverter.convertId(((JoinField) joinField).getParent()); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index a171d89bf..7497a1713 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -121,6 +121,7 @@ * @author Peter-Josef Meisch * @author Sascha Woo * @author Roman Puchkovskiy + * @author Subhobrata Dey * @since 4.0 */ class RequestFactory { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 82458e5e3..910092a02 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -77,6 +77,7 @@ * @author Mark Paluch * @author Roman Puchkovskiy * @author Konrad Kurdej + * @author Subhobrata Dey * @since 3.2 */ public class MappingElasticsearchConverter diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index a1b59ab23..2bc5a5b31 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -32,18 +32,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.data.annotation.Transient; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.CompletionContext; -import org.springframework.data.elasticsearch.annotations.CompletionField; -import org.springframework.data.elasticsearch.annotations.DynamicMapping; -import org.springframework.data.elasticsearch.annotations.DynamicTemplates; -import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.annotations.FieldType; -import org.springframework.data.elasticsearch.annotations.GeoPointField; -import org.springframework.data.elasticsearch.annotations.InnerField; -import org.springframework.data.elasticsearch.annotations.JoinTypeRelation; -import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; -import org.springframework.data.elasticsearch.annotations.Mapping; -import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.annotations.*; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.ResourceUtil; import org.springframework.data.elasticsearch.core.completion.Completion; @@ -347,13 +336,13 @@ private void addSingleFieldMapping(XContentBuilder builder, ElasticsearchPersist builder.endObject(); } - private void addJoinFieldMapping(XContentBuilder builder, - ElasticsearchPersistentProperty property) throws IOException { + private void addJoinFieldMapping(XContentBuilder builder, ElasticsearchPersistentProperty property) + throws IOException { JoinTypeRelation[] joinTypeRelations = property.getRequiredAnnotation(JoinTypeRelations.class).relations(); if (joinTypeRelations.length == 0) { logger.warn("Property {}s type is JoinField but its annotation JoinTypeRelation is " + // - "not properly maintained", // + "not properly maintained", // property.getFieldName()); return; } @@ -363,7 +352,7 @@ private void addJoinFieldMapping(XContentBuilder builder, builder.startObject(JOIN_TYPE_RELATIONS); - for (JoinTypeRelation joinTypeRelation: joinTypeRelations) { + for (JoinTypeRelation joinTypeRelation : joinTypeRelations) { String parent = joinTypeRelation.parent(); String[] children = joinTypeRelation.children(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java index 6792f0d77..9a08dbadd 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java @@ -15,53 +15,53 @@ */ package org.springframework.data.elasticsearch.core.join; -import org.springframework.lang.Nullable; - import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.springframework.lang.Nullable; + /** * @author Subhobrata Dey * @since 4.1 */ public class JoinField { - private final String name; + private final String name; - @Nullable private ID parent; + @Nullable private ID parent; - public JoinField() { - this("default", null); - } + public JoinField() { + this("default", null); + } - public JoinField(String name) { - this(name, null); - } + public JoinField(String name) { + this(name, null); + } - public JoinField(String name, @Nullable ID parent) { - this.name = name; - this.parent = parent; - } + public JoinField(String name, @Nullable ID parent) { + this.name = name; + this.parent = parent; + } - public void setParent(@Nullable ID parent) { - this.parent = parent; - } + public void setParent(@Nullable ID parent) { + this.parent = parent; + } - @Nullable - public ID getParent() { - return parent; - } + @Nullable + public ID getParent() { + return parent; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public Map getAsMap() { - Map joinMap = new HashMap<>(); - joinMap.put("name", getName()); - joinMap.put("parent", getParent()); + public Map getAsMap() { + Map joinMap = new HashMap<>(); + joinMap.put("name", getName()); + joinMap.put("parent", getParent()); - return Collections.unmodifiableMap(joinMap); - } -} \ No newline at end of file + return Collections.unmodifiableMap(joinMap); + } +} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java index fcbea9724..ddad0ad52 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/ElasticsearchPersistentEntity.java @@ -122,8 +122,8 @@ public interface ElasticsearchPersistentEntity extends PersistentEntity extends PersistentEntity extends BasicPersistentEntity implements ElasticsearchPersistentEntity { @@ -237,10 +238,11 @@ public void addPersistentProperty(ElasticsearchPersistentProperty property) { ElasticsearchPersistentProperty joinProperty = this.joinFieldProperty; if (joinProperty != null) { - throw new MappingException(String.format( - "Attempt to add Join property %s but already have property %s registered " - + "as Join property. Check your entity configuration!", - property.getField(), joinProperty.getField())); + throw new MappingException( + String.format( + "Attempt to add Join property %s but already have property %s registered " + + "as Join property. Check your entity configuration!", + property.getField(), joinProperty.getField())); } this.joinFieldProperty = property; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java index 8370c6ea4..fb5e00b31 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQuery.java @@ -24,6 +24,7 @@ * @author Mohsin Husen * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public class IndexQuery { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java index 08b6317c4..2ac6926ba 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/IndexQueryBuilder.java @@ -24,6 +24,7 @@ * @author Mohsin Husen * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public class IndexQueryBuilder { diff --git a/src/test/java/org/springframework/data/elasticsearch/Utils.java b/src/test/java/org/springframework/data/elasticsearch/Utils.java index 7875f2b82..3aedcabb9 100644 --- a/src/test/java/org/springframework/data/elasticsearch/Utils.java +++ b/src/test/java/org/springframework/data/elasticsearch/Utils.java @@ -16,7 +16,6 @@ package org.springframework.data.elasticsearch; import java.util.Arrays; -import java.util.Collections; import java.util.UUID; import org.elasticsearch.client.Client; @@ -33,6 +32,7 @@ * @author Ilkang Na * @author Peter-Josef Meisch * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public class Utils { diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java index 4f576a65b..e773fa98a 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplateTests.java @@ -19,28 +19,25 @@ import static org.springframework.data.elasticsearch.annotations.FieldType.*; import static org.springframework.data.elasticsearch.utils.IdGenerator.*; -import lombok.*; +import lombok.Builder; +import lombok.Data; +import lombok.val; import java.lang.Object; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.elasticsearch.action.support.ActiveShardCount; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.common.unit.TimeValue; -import org.elasticsearch.index.query.SimpleQueryStringBuilder; import org.junit.jupiter.api.Test; import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.annotations.JoinTypeRelation; -import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; -import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 0f0b1d591..7137b3b4f 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -50,7 +50,6 @@ import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.cluster.metadata.AliasMetadata; import org.elasticsearch.index.VersionType; -import org.elasticsearch.index.query.SimpleQueryStringBuilder; import org.elasticsearch.join.query.ParentIdQueryBuilder; import org.elasticsearch.script.Script; import org.elasticsearch.script.ScriptType; @@ -71,8 +70,15 @@ import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; import org.springframework.data.elasticsearch.ElasticsearchException; -import org.springframework.data.elasticsearch.annotations.*; +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.InnerField; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelation; +import org.springframework.data.elasticsearch.annotations.JoinTypeRelations; +import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.annotations.Score; +import org.springframework.data.elasticsearch.annotations.ScriptedField; import org.springframework.data.elasticsearch.core.geo.GeoPoint; import org.springframework.data.elasticsearch.core.index.AliasAction; import org.springframework.data.elasticsearch.core.index.AliasActionParameters; @@ -81,7 +87,6 @@ import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; -import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.util.StreamUtils; import org.springframework.lang.Nullable; @@ -108,6 +113,7 @@ * @author Farid Azaza * @author Gyula Attila Csorogi * @author Roman Puchkovskiy + * @author Subhobrata Dey */ public abstract class ElasticsearchTemplateTests { @@ -138,9 +144,9 @@ public void before() { indexOpsSearchHitsEntity.create(); indexOpsSearchHitsEntity.putMapping(SearchHitsEntity.class); - IndexOperations indexOpsJoinEntity = operations.indexOps(ElasticsearchRestTemplateTests.SampleJoinEntity.class); + IndexOperations indexOpsJoinEntity = operations.indexOps(SampleJoinEntity.class); indexOpsJoinEntity.create(); - indexOpsJoinEntity.putMapping(ElasticsearchRestTemplateTests.SampleJoinEntity.class); + indexOpsJoinEntity.putMapping(SampleJoinEntity.class); } @AfterEach @@ -3350,14 +3356,14 @@ void shouldSaveEntityWithJoinFields(String qId1, String qId2, String aId1, Strin myAJoinField2.setParent(qId1); sampleAnswerEntity2.setMyJoinField(myAJoinField2); - operations.save(Arrays.asList(sampleQuestionEntity1, sampleQuestionEntity2, - sampleAnswerEntity1, sampleAnswerEntity2), IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); - indexOperations.refresh(); - Thread.sleep(5000); + operations.save( + Arrays.asList(sampleQuestionEntity1, sampleQuestionEntity2, sampleAnswerEntity1, sampleAnswerEntity2), + IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)).refresh(); - SearchHits hits = operations.search(new NativeSearchQueryBuilder().withQuery( - new ParentIdQueryBuilder("answer", qId1)) - .build(), SampleJoinEntity.class); + SearchHits hits = operations.search( + new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId1)).build(), + SampleJoinEntity.class); List hitIds = hits.getSearchHits().stream().map(new Function, String>() { @Override @@ -3376,8 +3382,7 @@ void shouldUpdateEntityWithJoinFields(String qId1, String qId2, String aId1, Str document.put("myJoinField", new JoinField<>("answer", qId2).getAsMap()); UpdateQuery updateQuery = UpdateQuery.builder(aId2) // .withDocument(document) // - .withRouting(qId2) - .build(); + .withRouting(qId2).build(); List queries = new ArrayList<>(); queries.add(updateQuery); @@ -3387,9 +3392,9 @@ void shouldUpdateEntityWithJoinFields(String qId1, String qId2, String aId1, Str indexOperations.refresh(); Thread.sleep(5000); - SearchHits updatedHits = operations.search(new NativeSearchQueryBuilder().withQuery( - new ParentIdQueryBuilder("answer", qId2)) - .build(), SampleJoinEntity.class); + SearchHits updatedHits = operations.search( + new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).build(), + SampleJoinEntity.class); List hitIds = updatedHits.getSearchHits().stream().map(new Function, String>() { @Override @@ -3400,9 +3405,9 @@ public String apply(SearchHit sampleJoinEntitySearchHit) { assertThat(hitIds.size()).isEqualTo(1); assertThat(hitIds.get(0)).isEqualTo(aId2); - updatedHits = operations.search(new NativeSearchQueryBuilder().withQuery( - new ParentIdQueryBuilder("answer", qId1)) - .build(), SampleJoinEntity.class); + updatedHits = operations.search( + new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId1)).build(), + SampleJoinEntity.class); hitIds = updatedHits.getSearchHits().stream().map(new Function, String>() { @Override @@ -3415,17 +3420,15 @@ public String apply(SearchHit sampleJoinEntitySearchHit) { } void shouldDeleteEntityWithJoinFields(String qId2, String aId2) throws Exception { - Query query = new NativeSearchQueryBuilder() - .withQuery(new ParentIdQueryBuilder("answer", qId2)) - .withRoute(qId2) + Query query = new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).withRoute(qId2) .build(); operations.delete(query, SampleJoinEntity.class, IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); indexOperations.refresh(); Thread.sleep(5000); - SearchHits deletedHits = operations.search(new NativeSearchQueryBuilder().withQuery( - new ParentIdQueryBuilder("answer", qId2)) - .build(), SampleJoinEntity.class); + SearchHits deletedHits = operations.search( + new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).build(), + SampleJoinEntity.class); List hitIds = deletedHits.getSearchHits().stream().map(new Function, String>() { @Override @@ -3625,9 +3628,7 @@ static class OptimisticAndVersionedEntity { static class SampleJoinEntity { @Id @Field(type = Keyword) private String uuid; @JoinTypeRelations(relations = { - @JoinTypeRelation(parent = "question", children = {"answer"}) - }) - private JoinField myJoinField; + @JoinTypeRelation(parent = "question", children = { "answer" }) }) private JoinField myJoinField; @Field(type = Text) private String text; } } From fd77f62cc4d2452aee8cfce56e037e3daa18477e Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 8 Aug 2020 20:03:50 +0200 Subject: [PATCH 0232/1191] DATAES-897 - Add documentation for Highlight annotation. Original PR: #499 --- .../reference/elasticsearch-repositories.adoc | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-repositories.adoc b/src/main/asciidoc/reference/elasticsearch-repositories.adoc index 99389ce2a..60c186967 100644 --- a/src/main/asciidoc/reference/elasticsearch-repositories.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repositories.adoc @@ -3,8 +3,58 @@ This chapter includes details of the Elasticsearch repository implementation. +.The sample `Book` entity +==== +[source,java] +---- +@Document(indexName="books") +class Book { + @Id + private String id; + + @Field(type = FieldType.text) + private String name; + + @Field(type = FieldType.text) + private String summary; + + @Field(type = FieldType.Integer) + private Integer price; + + // getter/setter ... +} +---- +==== + include::elasticsearch-repository-queries.adoc[leveloffset=+1] +include::reactive-elasticsearch-repositories.adoc[leveloffset=+1] + +[[elasticsearch.repositories.annotations]] +== Annotations for repository methods + +=== @Highlight + +The `@Highlight` annotation on a repository method defines for which fields of the returned entity highlighting should be included. To search for some text in a `Book` 's name or summary and have the found data highlighted, the following repository method can be used: + +==== +[source,java] +---- +interface BookRepository extends Repository { + + @Highlight(fields = { + @HighlightField(name = "name"), + @HighlightField(name = "summary") + }) + List> findByNameOrSummary(String text, String summary); +} +---- +==== + +It is possible to define multiple fields to be highlighted like above, and both the `@Highlight` and the `@HighlightField` annotation can further be customized with a `@HighlightParameters` annotation. Check the Javadocs for the possible configuration options. + +In the search results the highlight data can be retrieved from the `SearchHit` class. + [[elasticsearch.annotation]] == Annotation based configuration @@ -40,7 +90,8 @@ class ProductService { } ---- -<1> The `EnableElasticsearchRepositories` annotation activates the Repository support. If no base package is configured, it will use the one of the configuration class it is put on. +<1> The `EnableElasticsearchRepositories` annotation activates the Repository support. +If no base package is configured, it will use the one of the configuration class it is put on. <2> Provide a Bean named `elasticsearchTemplate` of type `ElasticsearchOperations` by using one of the configurations shown in the <> chapter. <3> Let Spring inject the Repository bean into your class. ==== @@ -145,5 +196,3 @@ Using the `Transport Client` or `Rest Client` element registers an instance of ` ---- ==== - -include::reactive-elasticsearch-repositories.adoc[leveloffset=+1] From fd23c10c163e1959362c078fd8fa4b812ce11c01 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 9 Aug 2020 16:28:35 +0200 Subject: [PATCH 0233/1191] DATAES-896 - Use mainField property of @MultiField annotation. Original PR: #500 --- .../elasticsearch/annotations/InnerField.java | 2 +- .../core/index/MappingBuilder.java | 8 ++-- ...SimpleElasticsearchPersistentProperty.java | 15 +++++-- .../core/index/MappingBuilderTests.java | 41 +++++++++++++++---- .../core/index/MappingParametersTest.java | 9 ++-- ...sticsearchPersistentPropertyUnitTests.java | 17 ++++++++ 6 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java index 05edbea2f..3f6fcb281 100644 --- a/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java +++ b/src/main/java/org/springframework/data/elasticsearch/annotations/InnerField.java @@ -29,7 +29,7 @@ * @author Aleksei Arsenev */ @Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.FIELD) +@Target(ElementType.ANNOTATION_TYPE) public @interface InnerField { String suffix(); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java index 2bc5a5b31..8f48c0d85 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/index/MappingBuilder.java @@ -133,8 +133,8 @@ public String buildPropertyMapping(Class clazz) throws ElasticsearchException } } - private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersistentEntity entity, boolean isRootObject, - String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType, + private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersistentEntity entity, + boolean isRootObject, String nestedObjectFieldName, boolean nestedOrObjectField, FieldType fieldType, @Nullable Field parentFieldAnnotation, @Nullable DynamicMapping dynamicMapping) throws IOException { boolean writeNestedProperties = !isRootObject && (isAnyPropertyAnnotatedWithField(entity) || nestedOrObjectField); @@ -146,7 +146,7 @@ private void mapEntity(XContentBuilder builder, @Nullable ElasticsearchPersisten if (nestedOrObjectField && FieldType.Nested == fieldType && parentFieldAnnotation != null && parentFieldAnnotation.includeInParent()) { - builder.field("include_in_parent", parentFieldAnnotation.includeInParent()); + builder.field("include_in_parent", true); } } @@ -396,7 +396,7 @@ private void addFieldMappingParameters(XContentBuilder builder, Annotation annot MappingParameters mappingParameters = MappingParameters.from(annotation); if (!nestedOrObjectField && mappingParameters.isStore()) { - builder.field(FIELD_PARAM_STORE, mappingParameters.isStore()); + builder.field(FIELD_PARAM_STORE, true); } mappingParameters.writeTypeAndParametersTo(builder); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java index a15fa56c6..7c3218acc 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentProperty.java @@ -26,6 +26,7 @@ import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.Parent; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.convert.ElasticsearchDateConverter; @@ -97,6 +98,10 @@ public SimpleElasticsearchPersistentProperty(Property property, throw new MappingException(String.format("Parent property %s must be of type String!", property.getName())); } + if (isAnnotationPresent(Field.class) && isAnnotationPresent(MultiField.class)) { + throw new MappingException("@Field annotation must not be used on a @MultiField property."); + } + initDateConverter(); } @@ -182,13 +187,15 @@ public Object read(String s) { @Nullable private String getAnnotatedFieldName() { - if (isAnnotationPresent(Field.class)) { + String name = null; - String name = findAnnotation(Field.class).name(); - return StringUtils.hasText(name) ? name : null; + if (isAnnotationPresent(Field.class)) { + name = findAnnotation(Field.class).name(); + } else if (isAnnotationPresent(MultiField.class)) { + name = findAnnotation(MultiField.class).mainField().name(); } - return null; + return StringUtils.hasText(name) ? name : null; } /* diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java index 61426d849..64ff01fdb 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingBuilderTests.java @@ -42,6 +42,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import org.assertj.core.data.Percentage; @@ -255,6 +256,7 @@ public void shouldMapBooks() { } @Test // DATAES-420 + @SuppressWarnings({ "rawtypes", "unchecked" }) public void shouldUseBothAnalyzer() { // given @@ -277,6 +279,7 @@ public void shouldUseBothAnalyzer() { } @Test // DATAES-492 + @SuppressWarnings("rawtypes") public void shouldUseKeywordNormalizer() { // given @@ -297,6 +300,7 @@ public void shouldUseKeywordNormalizer() { } @Test // DATAES-503 + @SuppressWarnings("rawtypes") public void shouldUseCopyTo() { // given @@ -400,12 +404,29 @@ public void shouldUseFieldNameOnCompletion() throws JSONException { assertEquals(expected, mapping, false); } - @Test // DATAES-568 + @Test // DATAES-568, DATAES-896 public void shouldUseFieldNameOnMultiField() throws JSONException { // given - String expected = "{\"properties\":{" + "\"id-property\":{\"type\":\"keyword\",\"index\":true}," - + "\"multifield-property\":{\"type\":\"text\",\"analyzer\":\"whitespace\",\"fields\":{\"prefix\":{\"type\":\"text\",\"analyzer\":\"stop\",\"search_analyzer\":\"standard\"}}}}}"; + String expected = "{\n" + // + " \"properties\": {\n" + // + " \"id-property\": {\n" + // + " \"type\": \"keyword\",\n" + // + " \"index\": true\n" + // + " },\n" + // + " \"main-field\": {\n" + // + " \"type\": \"text\",\n" + // + " \"analyzer\": \"whitespace\",\n" + // + " \"fields\": {\n" + // + " \"suff-ix\": {\n" + // + " \"type\": \"text\",\n" + // + " \"analyzer\": \"stop\",\n" + // + " \"search_analyzer\": \"standard\"\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + "}\n"; // // when String mapping = getMappingBuilder().buildPropertyMapping(FieldNameEntity.MultiFieldEntity.class); @@ -651,9 +672,10 @@ static class MultiFieldEntity { @Nullable @Id @Field("id-property") private String id; - @Nullable @Field("multifield-property") // - @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "whitespace"), otherFields = { - @InnerField(suffix = "prefix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") }) // + @Nullable // + @MultiField(mainField = @Field(name = "main-field", type = FieldType.Text, analyzer = "whitespace"), + otherFields = { + @InnerField(suffix = "suff-ix", type = FieldType.Text, analyzer = "stop", searchAnalyzer = "standard") }) // private String description; } } @@ -684,6 +706,7 @@ static class Book { * @author Stuart Stevenson * @author Mohsin Husen */ + @Data @Document(indexName = "test-index-simple-recursive-mapping-builder", replicas = 0, refreshInterval = "-1") static class SimpleRecursiveEntity { @@ -783,7 +806,7 @@ public void setMessage(String message) { */ static class SampleInheritedEntityBuilder { - private SampleInheritedEntity result; + private final SampleInheritedEntity result; public SampleInheritedEntityBuilder(String id) { result = new SampleInheritedEntity(); @@ -806,7 +829,7 @@ public SampleInheritedEntity build() { public IndexQuery buildIndex() { IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(result.getId()); + indexQuery.setId(Objects.requireNonNull(result.getId())); indexQuery.setObject(result); return indexQuery; } @@ -1030,7 +1053,7 @@ public String getValue() { @Document(indexName = "valueDoc") static class ValueDoc { - @Field(type = Text) private ValueObject valueObject; + @Nullable @Field(type = Text) private ValueObject valueObject; } @Getter diff --git a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java index f12c8e541..ffce29eec 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/index/MappingParametersTest.java @@ -8,6 +8,7 @@ import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.lang.Nullable; @@ -31,9 +32,10 @@ public void shouldCreateParametersForFieldAnnotation() { @Test // DATAES-621 public void shouldCreateParametersForInnerFieldAnnotation() { - Annotation annotation = entity.getRequiredPersistentProperty("innerField").findAnnotation(InnerField.class); - MappingParameters mappingParameters = MappingParameters.from(annotation); + MultiField multiField = entity.getRequiredPersistentProperty("mainField").findAnnotation(MultiField.class); + InnerField innerField = multiField.otherFields()[0]; + MappingParameters mappingParameters = MappingParameters.from(innerField); assertThat(mappingParameters).isNotNull(); } @@ -61,7 +63,8 @@ public void shouldNotAllowDocValuesFalseOnFieldTypeNested() { static class AnnotatedClass { @Nullable @Field private String field; - @Nullable @InnerField(suffix = "test", type = FieldType.Text) private String innerField; + @Nullable @MultiField(mainField = @Field, + otherFields = { @InnerField(suffix = "test", type = FieldType.Text) }) private String mainField; @Score private float score; @Nullable @Field(type = FieldType.Text, docValues = false) private String docValuesText; @Nullable @Field(type = FieldType.Nested, docValues = false) private String docValuesNested; diff --git a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java index 3d6dec9e0..186f3792b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/mapping/SimpleElasticsearchPersistentPropertyUnitTests.java @@ -28,6 +28,8 @@ import org.springframework.data.elasticsearch.annotations.DateFormat; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.data.elasticsearch.annotations.InnerField; +import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.MappingException; @@ -74,6 +76,16 @@ public void fieldAnnotationWithValueSetsFieldname() { assertThat(persistentProperty.getFieldName()).isEqualTo("by-value"); } + @Test // DATAES-896 + void shouldUseNameFromMultiFieldMainField() { + SimpleElasticsearchPersistentEntity persistentEntity = context + .getRequiredPersistentEntity(MultiFieldProperty.class); + ElasticsearchPersistentProperty persistentProperty = persistentEntity.getPersistentProperty("mainfieldProperty"); + + assertThat(persistentProperty).isNotNull(); + assertThat(persistentProperty.getFieldName()).isEqualTo("mainfield"); + } + @Test // DATAES-716, DATAES-792 void shouldSetPropertyConverters() { SimpleElasticsearchPersistentEntity persistentEntity = context.getRequiredPersistentEntity(DatesProperty.class); @@ -199,6 +211,11 @@ static class FieldValueProperty { @Nullable @Field(value = "by-value") String fieldProperty; } + static class MultiFieldProperty { + @Nullable @MultiField(mainField = @Field("mainfield"), + otherFields = { @InnerField(suffix = "suff", type = FieldType.Keyword) }) String mainfieldProperty; + } + static class DatesProperty { @Nullable @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "dd.MM.uuuu") LocalDate localDate; @Nullable @Field(type = FieldType.Date, format = DateFormat.basic_date_time) LocalDateTime localDateTime; From 73bf3dd9882b47e2705812ba7b0c00255034ff4d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 10 Aug 2020 21:58:57 +0200 Subject: [PATCH 0234/1191] DATAES-899 - Add documentation for join-type. original PR: #501 --- .../reference/elasticsearch-misc.adoc | 204 ++++++++++++++++++ .../elasticsearch/core/join/JoinField.java | 12 -- .../core/ElasticsearchTemplateTests.java | 15 +- 3 files changed, 214 insertions(+), 17 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-misc.adoc b/src/main/asciidoc/reference/elasticsearch-misc.adoc index 112d750c5..15b25ef85 100644 --- a/src/main/asciidoc/reference/elasticsearch-misc.adoc +++ b/src/main/asciidoc/reference/elasticsearch-misc.adoc @@ -99,4 +99,208 @@ If the class to be retrieved has a `GeoPoint` property named _location_, the fol Sort.by(new GeoDistanceOrder("location", new GeoPoint(48.137154, 11.5761247))) ---- +[[elasticsearch.misc.jointype]] +== Join-Type implementation + +Spring Data Elasticsearch supports the https://www.elastic.co/guide/en/elasticsearch/reference/current/parent-join.html[Join data type] for creating the corresponding index mappings and for storing the relevant information. + +=== Setting up the data + +For an entity to be used in a parent child join relationship, it must have a property of type `JoinField` which must be annotated. +Let's assume a `Statement` entity where a statement may be a _question_, an _answer_, a _comment_ or a _vote_ (a _Builder_ is also shown in this example, it's not necessary, but later used in the sample code): + +==== +[source,java] +---- +@Document(indexName = "statements") +public class Statement { + @Id + private String id; + + @Field(type = FieldType.Text) + private String text; + + @JoinTypeRelations( + relations = + { + @JoinTypeRelation(parent = "question", children = {"answer", "comment"}), <1> + @JoinTypeRelation(parent = "answer", children = "vote") <2> + } + ) + private JoinField relation; <3> + + private Statement() { + } + + public static StatementBuilder builder() { + return new StatementBuilder(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public JoinField getRelation() { + return relation; + } + + public void setRelation(JoinField relation) { + this.relation = relation; + } + + public static final class StatementBuilder { + private String id; + private String text; + private JoinField relation; + + private StatementBuilder() { + } + + public StatementBuilder withId(String id) { + this.id = id; + return this; + } + + public StatementBuilder withText(String text) { + this.text = text; + return this; + } + + public StatementBuilder withRelation(JoinField relation) { + this.relation = relation; + return this; + } + + public Statement build() { + Statement statement = new Statement(); + statement.setId(id); + statement.setText(text); + statement.setRelation(relation); + return statement; + } + } +} +---- +<1> a question can have answers and comments +<2> an answer can have votes +<3> the `JoinField` property is used to combine the name (_question_, _answer_, _comment_ or _vote_) of the relation with the parent id. The generic type must be the same as the `@Id` annotated property. +==== + +Spring Data Elasticsearch will build the following mapping for this class: + +==== +[source,json] +---- +{ + "statements": { + "mappings": { + "properties": { + "_class": { + "type": "text", + "fields": { + "keyword": { + "type": "keyword", + "ignore_above": 256 + } + } + }, + "relation": { + "type": "join", + "eager_global_ordinals": true, + "relations": { + "question": [ + "answer", + "comment" + ], + "answer": "vote" + } + }, + "text": { + "type": "text" + } + } + } + } +} +---- +==== + +=== Storing data + +Given a repository for this class the following code inserts a question, two answers, a comment and a vote: + +==== +[source,java] +---- +void init() { + repository.deleteAll(); + + Statement savedWeather = repository.save( + Statement.builder() + .withText("How is the weather?") + .withRelation(new JoinField<>("question")) <1> + .build()); + + Statement sunnyAnswer = repository.save( + Statement.builder() + .withText("sunny") + .withRelation(new JoinField<>("answer", savedWeather.getId())) <2> + .build()); + + repository.save( + Statement.builder() + .withText("rainy") + .withRelation(new JoinField<>("answer", savedWeather.getId())) <3> + .build()); + + repository.save( + Statement.builder() + .withText("I don't like the rain") + .withRelation(new JoinField<>("comment", savedWeather.getId())) <4> + .build()); + + repository.save( + Statement.builder() + .withText("+1 for the sun") + .withRelation(new JoinField<>("vote", sunnyAnswer.getId())) <5> + .build()); +} +---- +<1> create a question statement +<2> the first answer to the question +<3> the second answer +<4> a comment to the question +<5> a vote for the first answer +==== + +=== Retrieving data + +Currently native search queries must be used to query the data, so there is no support from standard repository methods. <> can be used instead. + +The following code shows as an example how to retrieve all entries that have a _vote_ (which must be _answers_, because only answers can have a vote) using an `ElasticsearchOperations` instance: + +==== +[source,java] +---- +SearchHits hasVotes() { + NativeSearchQuery query = new NativeSearchQueryBuilder() + .withQuery(hasChildQuery("vote", matchAllQuery(), ScoreMode.None)) + .build(); + + return operations.search(query, Statement.class); +} +---- +==== diff --git a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java index 9a08dbadd..70ce58ce3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/join/JoinField.java @@ -15,10 +15,6 @@ */ package org.springframework.data.elasticsearch.core.join; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - import org.springframework.lang.Nullable; /** @@ -56,12 +52,4 @@ public ID getParent() { public String getName() { return name; } - - public Map getAsMap() { - Map joinMap = new HashMap<>(); - joinMap.put("name", getName()); - joinMap.put("parent", getParent()); - - return Collections.unmodifiableMap(joinMap); - } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 7137b3b4f..7ffda4062 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -3379,7 +3379,7 @@ public String apply(SearchHit sampleJoinEntitySearchHit) { void shouldUpdateEntityWithJoinFields(String qId1, String qId2, String aId1, String aId2) throws Exception { org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document .create(); - document.put("myJoinField", new JoinField<>("answer", qId2).getAsMap()); + document.put("myJoinField", toDocument(new JoinField<>("answer", qId2))); UpdateQuery updateQuery = UpdateQuery.builder(aId2) // .withDocument(document) // .withRouting(qId2).build(); @@ -3389,8 +3389,7 @@ void shouldUpdateEntityWithJoinFields(String qId1, String qId2, String aId1, Str // when operations.bulkUpdate(queries, IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); - indexOperations.refresh(); - Thread.sleep(5000); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)).refresh(); SearchHits updatedHits = operations.search( new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).build(), @@ -3423,8 +3422,7 @@ void shouldDeleteEntityWithJoinFields(String qId2, String aId2) throws Exception Query query = new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).withRoute(qId2) .build(); operations.delete(query, SampleJoinEntity.class, IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)); - indexOperations.refresh(); - Thread.sleep(5000); + operations.indexOps(IndexCoordinates.of(INDEX_NAME_JOIN_SAMPLE_ENTITY)).refresh(); SearchHits deletedHits = operations.search( new NativeSearchQueryBuilder().withQuery(new ParentIdQueryBuilder("answer", qId2)).build(), @@ -3439,6 +3437,13 @@ public String apply(SearchHit sampleJoinEntitySearchHit) { assertThat(hitIds.size()).isEqualTo(0); } + private org.springframework.data.elasticsearch.core.document.Document toDocument(JoinField joinField) { + org.springframework.data.elasticsearch.core.document.Document document = create(); + document.put("name", joinField.getName()); + document.put("parent", joinField.getParent()); + return document; + } + protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } From 2b6e63995137f32a6f4c33970084e2ad93cacd0a Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 11 Aug 2020 22:24:23 +0200 Subject: [PATCH 0235/1191] DATAES-901 - Operations deleting an entity should use a routing deducted from the entity-the-entity. Original PR: #502 --- .../core/AbstractElasticsearchTemplate.java | 21 ++++++++++------- .../core/DocumentOperations.java | 18 +++++++++++++-- .../core/ElasticsearchOperations.java | 10 ++++++++ .../core/ElasticsearchRestTemplate.java | 4 ++-- .../core/ElasticsearchTemplate.java | 4 ++-- .../core/ReactiveElasticsearchTemplate.java | 2 +- .../elasticsearch/core/RequestFactory.java | 23 +++++++++++++++---- .../SimpleElasticsearchRepository.java | 8 +++---- 8 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 59702cb64..160102cb0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -535,15 +535,20 @@ private String getEntityId(Object entity) { } @Nullable - private String getEntityRouting(Object entity) { - ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); - ElasticsearchPersistentProperty joinProperty = persistentEntity.getJoinFieldProperty(); + public String getEntityRouting(Object entity) { + ElasticsearchPersistentEntity persistentEntity = elasticsearchConverter.getMappingContext() + .getPersistentEntity(entity.getClass()); + + if (persistentEntity != null) { + + ElasticsearchPersistentProperty joinProperty = persistentEntity.getJoinFieldProperty(); - if (joinProperty != null) { - Object joinField = persistentEntity.getPropertyAccessor(entity).getProperty(joinProperty); - if (joinField != null && JoinField.class.isAssignableFrom(joinField.getClass()) - && ((JoinField) joinField).getParent() != null) { - return elasticsearchConverter.convertId(((JoinField) joinField).getParent()); + if (joinProperty != null) { + Object joinField = persistentEntity.getPropertyAccessor(entity).getProperty(joinProperty); + if (joinField != null && JoinField.class.isAssignableFrom(joinField.getClass()) + && ((JoinField) joinField).getParent() != null) { + return elasticsearchConverter.convertId(((JoinField) joinField).getParent()); + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java index 47941263d..aa3e2f76d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/DocumentOperations.java @@ -205,6 +205,7 @@ default void bulkUpdate(List queries, IndexCoordinates index) { /** * Bulk update all objects. Will do update. + * * @param clazz the entity class * @param queries the queries to execute in bulk * @since 4.1 @@ -222,11 +223,24 @@ default void bulkUpdate(List queries, IndexCoordinates index) { /** * Delete the one object with provided id. * - * @param id the document ot delete + * @param id the document to delete + * @param index the index from which to delete + * @return documentId of the document deleted + */ + default String delete(String id, IndexCoordinates index) { + return delete(id, null, index); + } + + /** + * Delete the one object with provided id. + * + * @param id the document to delete + * @param routing the optional routing for the document to be deleted * @param index the index from which to delete * @return documentId of the document deleted + * @since 4.1 */ - String delete(String id, IndexCoordinates index); + String delete(String id, @Nullable String routing, IndexCoordinates index); /** * Delete the one object with provided id. diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java index 8866f2b7f..31afb2f4b 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchOperations.java @@ -59,6 +59,16 @@ public interface ElasticsearchOperations extends DocumentOperations, SearchOpera IndexCoordinates getIndexCoordinatesFor(Class clazz); + /** + * gets the routing for an entity which might be defined by a join-type relation + * + * @param entity the entity + * @return the routing, may be null if not set. + * @since 4.1 + */ + @Nullable + String getEntityRouting(Object entity); + // region IndexOperations /** * Create an index for given indexName . diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 0ac9be2cb..033cc9abb 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -207,12 +207,12 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index } @Override - public String delete(String id, IndexCoordinates index) { + public String delete(String id, @Nullable String routing, IndexCoordinates index) { Assert.notNull(id, "id must not be null"); Assert.notNull(index, "index must not be null"); - DeleteRequest request = requestFactory.deleteRequest(elasticsearchConverter.convertId(id), index); + DeleteRequest request = requestFactory.deleteRequest(elasticsearchConverter.convertId(id), routing, index); return execute(client -> client.delete(request, RequestOptions.DEFAULT).getId()); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index ce71d7480..86124a819 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -225,13 +225,13 @@ public void bulkUpdate(List queries, BulkOptions bulkOptions, Index } @Override - public String delete(String id, IndexCoordinates index) { + public String delete(String id, @Nullable String routing, IndexCoordinates index) { Assert.notNull(id, "id must not be null"); Assert.notNull(index, "index must not be null"); DeleteRequestBuilder deleteRequestBuilder = requestFactory.deleteRequestBuilder(client, - elasticsearchConverter.convertId(id), index); + elasticsearchConverter.convertId(id), routing, index); return deleteRequestBuilder.execute().actionGet().getId(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index b1b06ff0d..bc351b82b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -472,7 +472,7 @@ public Mono delete(String id, IndexCoordinates index) { private Mono doDeleteById(String id, IndexCoordinates index) { return Mono.defer(() -> { - DeleteRequest request = requestFactory.deleteRequest(id, index); + DeleteRequest request = requestFactory.deleteRequest(id, null, index); return doDelete(prepareDeleteRequest(request)); }); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 7497a1713..79505b54b 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -751,14 +751,29 @@ public DeleteByQueryRequest deleteByQueryRequest(Query query, Class clazz, In return deleteByQueryRequest; } - public DeleteRequest deleteRequest(String id, IndexCoordinates index) { + public DeleteRequest deleteRequest(String id, @Nullable String routing, IndexCoordinates index) { String indexName = index.getIndexName(); - return new DeleteRequest(indexName, id); + DeleteRequest deleteRequest = new DeleteRequest(indexName, id); + + if (routing != null) { + deleteRequest.routing(routing); + } + + return deleteRequest; } - public DeleteRequestBuilder deleteRequestBuilder(Client client, String id, IndexCoordinates index) { + public DeleteRequestBuilder deleteRequestBuilder(Client client, String id, @Nullable String routing, + IndexCoordinates index) { String indexName = index.getIndexName(); - return client.prepareDelete(indexName, IndexCoordinates.TYPE, id); + DeleteRequestBuilder deleteRequestBuilder = client.prepareDelete(); + deleteRequestBuilder.setIndex(indexName); + deleteRequestBuilder.setId(id); + + if (routing != null) { + deleteRequestBuilder.setRouting(routing); + } + + return deleteRequestBuilder; } @Deprecated diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java index 2d5bbd421..c2110e33e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/support/SimpleElasticsearchRepository.java @@ -271,7 +271,7 @@ public void deleteById(ID id) { Assert.notNull(id, "Cannot delete entity with id 'null'."); - doDelete(id, getIndexCoordinates()); + doDelete(id, null, getIndexCoordinates()); } @Override @@ -279,7 +279,7 @@ public void delete(T entity) { Assert.notNull(entity, "Cannot delete 'null' entity."); - doDelete(extractIdFromBean(entity), getIndexCoordinates()); + doDelete(extractIdFromBean(entity), operations.getEntityRouting(entity), getIndexCoordinates()); } @Override @@ -308,10 +308,10 @@ public void deleteAll(Iterable entities) { }); } - private void doDelete(@Nullable ID id, IndexCoordinates indexCoordinates) { + private void doDelete(@Nullable ID id, @Nullable String routing, IndexCoordinates indexCoordinates) { if (id != null) { - executeAndRefresh(operations -> operations.delete(stringIdRepresentation(id), indexCoordinates)); + executeAndRefresh(operations -> operations.delete(stringIdRepresentation(id), routing, indexCoordinates)); } } From 53762db51d2e4dd5266495f0751f9ecc71961355 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 11:51:37 +0200 Subject: [PATCH 0236/1191] DATAES-872 - Updated changelog. --- src/main/resources/changelog.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index 0beb68a36..b891595ab 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,36 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.1.0-M2 (2020-08-12) +---------------------------------------- +* DATAES-901 - Operations deleting an entity should use a routing deducted from the entity. +* DATAES-899 - Add documentation for join-type. +* DATAES-897 - Add documentation for Highlight annotation. +* DATAES-896 - Use mainField property of @MultiField annotation instead of additional @Field annotation. +* DATAES-894 - Adapt to changes in Reactor. +* DATAES-893 - Adopt to changed module layout of Reactor Netty. +* DATAES-891 - Returning a Stream from a Query annotated repository method crashes. +* DATAES-886 - Complete reactive auditing. +* DATAES-883 - Fix log level on resource load error. +* DATAES-878 - Wrong value for TermVector(woth_positions_offsets). +* DATAES-877 - Update test logging dependency. +* DATAES-876 - Add seqno and primary term to entity on initial save. +* DATAES-875 - MappingElasticsearchConverter.updateQuery not called at all places. +* DATAES-874 - Deprecate parent-id related methods and fields. +* DATAES-872 - Release 4.1 M2 (2020.0.0). +* DATAES-869 - Update to Elasticsearch 7.8. +* DATAES-864 - Rework alias management. +* DATAES-842 - Documentation fixes. +* DATAES-612 - Add support for index templates. +* DATAES-433 - Replace parent-child mappings to join field. +* DATAES-321 - Support time base rolling indices. +* DATAES-244 - Support alias renaming. +* DATAES-233 - Support for rolling index strategy. +* DATAES-207 - Allow fetching indices by alias. +* DATAES-192 - Define alias for document. +* DATAES-150 - mapping are not created when entity is saved in new dynamic name index (spel). + + Changes in version 4.0.2.RELEASE (2020-07-22) --------------------------------------------- * DATAES-883 - Fix log level on resource load error. @@ -1230,5 +1260,6 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From da2e49763f331be6906d7a0f5dc25cff0bab19e3 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 11:51:41 +0200 Subject: [PATCH 0237/1191] DATAES-872 - Prepare 4.1 M2 (2020.0.0). --- pom.xml | 8 ++++---- src/main/resources/notice.txt | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 51f6f6342..82e489051 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.4.0-SNAPSHOT + 2.4.0-M2 Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.8.0 2.13.2 - 2.4.0-SNAPSHOT + 2.4.0-M2 4.1.50.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-snapshot - https://repo.spring.io/libs-snapshot + spring-libs-milestone + https://repo.spring.io/libs-milestone diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt index 19bc47157..35309688d 100644 --- a/src/main/resources/notice.txt +++ b/src/main/resources/notice.txt @@ -1,4 +1,4 @@ -Spring Data Elasticsearch 4.1 M1 (2020.0.0) +Spring Data Elasticsearch 4.1 M2 (2020.0.0) Copyright (c) [2013-2019] Pivotal Software, Inc. This product is licensed to you under the Apache License, Version 2.0 (the "License"). @@ -16,3 +16,4 @@ conditions of the subcomponent's license, as noted in the LICENSE file. + From db78ef0ac6a7be251f4e4d864c2c4f11611691cc Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 11:52:07 +0200 Subject: [PATCH 0238/1191] DATAES-872 - Release version 4.1 M2 (2020.0.0). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 82e489051..d63f889ba 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.1.0-SNAPSHOT + 4.1.0-M2 org.springframework.data.build From 9459d1b8a1a59623d63df2c5a7ce07ba594ab42e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 12:00:21 +0200 Subject: [PATCH 0239/1191] DATAES-872 - Prepare next development iteration. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d63f889ba..82e489051 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-elasticsearch - 4.1.0-M2 + 4.1.0-SNAPSHOT org.springframework.data.build From 0825db2a0271c9b62f103a2daf5458069d4d922a Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 12:00:24 +0200 Subject: [PATCH 0240/1191] DATAES-872 - After release cleanups. --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 82e489051..51f6f6342 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.springframework.data.build spring-data-parent - 2.4.0-M2 + 2.4.0-SNAPSHOT Spring Data Elasticsearch @@ -21,7 +21,7 @@ 2.6 7.8.0 2.13.2 - 2.4.0-M2 + 2.4.0-SNAPSHOT 4.1.50.Final spring.data.elasticsearch @@ -373,8 +373,8 @@ - spring-libs-milestone - https://repo.spring.io/libs-milestone + spring-libs-snapshot + https://repo.spring.io/libs-snapshot From 0626a5736f4d247f673ef3b132fe706d851dbf12 Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Wed, 12 Aug 2020 13:07:18 +0200 Subject: [PATCH 0241/1191] DATAES-890 - Updated changelog. --- src/main/resources/changelog.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/resources/changelog.txt b/src/main/resources/changelog.txt index b891595ab..35d8c0fc5 100644 --- a/src/main/resources/changelog.txt +++ b/src/main/resources/changelog.txt @@ -1,6 +1,14 @@ Spring Data Elasticsearch Changelog =================================== +Changes in version 4.0.3.RELEASE (2020-08-12) +--------------------------------------------- +* DATAES-897 - Add documentation for Highlight annotation. +* DATAES-896 - Use mainField property of @MultiField annotation instead of additional @Field annotation. +* DATAES-891 - Returning a Stream from a Query annotated repository method crashes. +* DATAES-890 - Release 4.0.3 (Neumann SR3). + + Changes in version 4.1.0-M2 (2020-08-12) ---------------------------------------- * DATAES-901 - Operations deleting an entity should use a routing deducted from the entity. @@ -1261,5 +1269,6 @@ Release Notes - Spring Data Elasticsearch - Version 1.0 M1 (2014-02-07) + From 7b1e4cc126d3093ec7585e5d26a248dc17e67594 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 12 Aug 2020 20:37:08 +0200 Subject: [PATCH 0242/1191] DATAES-902 - Update to Elasticsearch 7.8.1. Original PR: #503 --- pom.xml | 2 +- src/main/asciidoc/preface.adoc | 9 +++------ .../asciidoc/reference/elasticsearch-new.adoc | 2 +- ...on-7.8.0.jar => analysis-common-7.8.1.jar} | Bin 199093 -> 199093 bytes .../plugin-descriptor.properties | 4 ++-- ....0.jar => elasticsearch-dissect-7.8.1.jar} | Bin 24686 -> 24686 bytes ...7.8.0.jar => elasticsearch-grok-7.8.1.jar} | Bin 34340 -> 34341 bytes ...mmon-7.8.0.jar => ingest-common-7.8.1.jar} | Bin 116176 -> 116332 bytes .../plugin-descriptor.properties | 4 ++-- ...on-7.8.0.jar => lang-expression-7.8.1.jar} | Bin 65528 -> 65528 bytes .../plugin-descriptor.properties | 4 ++-- ...icsearch-scripting-painless-spi-7.8.1.jar} | Bin 27848 -> 27849 bytes ...less-7.8.0.jar => lang-painless-7.8.1.jar} | Bin 561387 -> 561387 bytes .../plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- .../reindex/plugin-descriptor.properties | 4 ++-- .../plugin-descriptor.properties | 4 ++-- ...url-7.8.0.jar => repository-url-7.8.1.jar} | Bin 14772 -> 14773 bytes 18 files changed, 19 insertions(+), 22 deletions(-) rename src/test/resources/test-home-dir/modules/analysis-common/{analysis-common-7.8.0.jar => analysis-common-7.8.1.jar} (89%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-dissect-7.8.0.jar => elasticsearch-dissect-7.8.1.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{elasticsearch-grok-7.8.0.jar => elasticsearch-grok-7.8.1.jar} (87%) rename src/test/resources/test-home-dir/modules/ingest-common/{ingest-common-7.8.0.jar => ingest-common-7.8.1.jar} (84%) rename src/test/resources/test-home-dir/modules/lang-expression/{lang-expression-7.8.0.jar => lang-expression-7.8.1.jar} (88%) rename src/test/resources/test-home-dir/modules/lang-painless/{elasticsearch-scripting-painless-spi-7.8.0.jar => elasticsearch-scripting-painless-spi-7.8.1.jar} (87%) rename src/test/resources/test-home-dir/modules/lang-painless/{lang-painless-7.8.0.jar => lang-painless-7.8.1.jar} (93%) rename src/test/resources/test-home-dir/modules/repository-url/{repository-url-7.8.0.jar => repository-url-7.8.1.jar} (82%) diff --git a/pom.xml b/pom.xml index 51f6f6342..522f629f1 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 2.6 - 7.8.0 + 7.8.1 2.13.2 2.4.0-SNAPSHOT 4.1.50.Final diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 6d34045cb..5168c08fa 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -27,17 +27,14 @@ Requires an installation of https://www.elastic.co/products/elasticsearch[Elasti [[preface.versions]] === Versions -// NOTE: since Github does not support include directives, the content of -// this file is duplicated in the toplevel README -// Always change both files! -The following table shows the Elasticsearch versions that are used by Spring Data release trains and version of Spring Data Elasticsearch included in that, as well as the Spring Boot versions refering to that particular Spring Data release train: +The following table shows the Elasticsearch versions that are used by Spring Data release trains and version of Spring Data Elasticsearch included in that, as well as the Spring Boot versions referring to that particular Spring Data release train: [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot -| 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.8.0 |2.3.xfootnote:cdv[] +| 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.8.1 |2.3.xfootnote:cdv[] | Neumann | 4.0.x | 7.6.2 |2.3.x -| Moore | 3.2.x |6.8.10 | 2.2.x +| Moore | 3.2.x |6.8.12 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] | Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-new.adoc b/src/main/asciidoc/reference/elasticsearch-new.adoc index 68159d431..09f1d69ec 100644 --- a/src/main/asciidoc/reference/elasticsearch-new.adoc +++ b/src/main/asciidoc/reference/elasticsearch-new.adoc @@ -4,7 +4,7 @@ [[new-features.4-1-0]] == New in Spring Data Elasticsearch 4.1 -* Upgrade to Elasticsearch 7.8.0 +* Upgrade to Elasticsearch 7.8.1 * Improved API for alias management * Introduction of `ReactiveIndexOperations` for index management * Index templates support diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.0.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.1.jar similarity index 89% rename from src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.0.jar rename to src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.1.jar index 6d6696194791ba213cedb81b357b1601d2d35edd..aa0cf109749623c2930207b6a39a88fb4c4c9e3f 100644 GIT binary patch delta 8100 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 diff --git a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties index cc693279d..6ccdf0d2e 100644 --- a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Adds "built in" analyzers to Elasticsearch. # # 'version': plugin's version -version=7.8.0 +version=7.8.1 # # 'name': the plugin name name=analysis-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.8.0 +elasticsearch.version=7.8.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.0.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.1.jar similarity index 87% rename from src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.0.jar rename to src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.1.jar index f43a0b827bac44ff8ba3e742aa6f5d887f46eb57..a2c9d5ede815c7aec9e45b39fb2c4385683f83ec 100644 GIT binary patch delta 1142 zcmaENfbrb{M&1B#W)?061`ZAetJbd*dDS?8R6yVC-wG4073yPy4*DH7;Mp7g%0A=~ zlM`p=^|IU@3vxLaovm}6I%dz_6}!Z2WtoQ<_e4qC={kZ;ul;&#_!%f1n zjxL_D$)Mum*BgpAC2o54Z@qN)=Vp0rt&;N_nO`s2@pG?klVJ5L*2E2WnzJUlhpH_Q ziM$w6Igd+Y)v_Z~Qa`(?)O$vrO-qe4HP$#~P@(L7m;X}u?)l4p8=EX=?Ond>t46@X z`3n}@-1)%fV%Wii@3%g#XgrrBVe`$o-ByeJ-0{hCOXilZ@%270wacPvSt;bq3TDi<`T|zFd7r^8PO!-F05uM7STX?F^j>@sM9CCMHi$8ErF{j# zYCC*Qn0XnQM3~`;X7aBH6L_kbY!+$74D{9H;z)b2r?y7gf%HxO776i;MwBg>pAqE> zrVqqQPd*)`Iw?*C%x#R5W{MY`ywFB@vVarsY3F^XWtO;=Kjp0hD9#PBmPXrU-JQ2;CMcH`s^@J56b zC=fP8Ni!v@gQY)2K|CB8E6uc02P|~fN@B8QJP+6(|6`+{2LK-5$5H?Q delta 1170 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 KI}6<1VE+&7?w{}g delta 11541 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 diff --git a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties index fd7fea1bf..6db9d2333 100644 --- a/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties +++ b/src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties @@ -20,7 +20,7 @@ description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources # # 'version': plugin's version -version=7.8.0 +version=7.8.1 # # 'name': the plugin name name=ingest-common @@ -35,7 +35,7 @@ classname=org.elasticsearch.ingest.common.IngestCommonPlugin java.version=1.8 # # 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.8.0 +elasticsearch.version=7.8.1 ### optional elements for plugins: # # 'extended.plugins': other plugins this plugin extends through SPI diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.0.jar b/src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.1.jar similarity index 88% rename from src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.0.jar rename to src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.1.jar index fa1321e3d360b310f76747155a747565baa85004..44d83972a2f1ae5438a977da4f892108a4f30a80 100644 GIT binary patch delta 2517 zcmZWpdpOit7(Vm+8I3z*bo;SUiKs>@EF(h^&60X-7cEh1Q=6pwsxXymEuxcdqwPjf zOFX06&`md@bXQ4v>QOQ4ewQ(O=A6my)ckYKoZt6;-}`>=cTSIj?orTs{vujK8vqUm z2;)0b^~Q0~;-BdH^i`^hd2Gj?xh(`!dsVIu_d29CfSC zKV7ok)I`@WL890q%v&nDVy^pP@xzI2Sr6C&qxq6TYkO8$O~9f2tVDnv+oI zbKFr!|W;Eo8W0)0Gna z3-m`>S)g;BF;o5ci8y*%Up;^Su|2h$BBOfRi{zE-p4SPQ87owNjnPXB^}ce^4C00^D{01p7*>lxrKeZksoK$q_9giDPIX=Dr> z#kIie3@#t98@LX5&E>i)SE*_IQVMT;7aS!Utv}nz#?ISL6Mw4OwnzhSKJpsLCm*3$ zLm&HYt$m5F0YIk~3<*||YYL}GK0kg- zDhq%L3IH#hB3L$B>SHV+EE*T7w7vbinWXqNe}HU?>qNB9|0Y|S9`%yaQqnTLmj1(j z*vRve@`Ex-aMiF~MBg*#XXHe2d<>1LR4p+iCwdWyB&M8ycL@IUs3?IbIcxJB*@Pr6 zAu(x=t^^)@;}$ttRj@__OIlH#^IJOV%2j;;+^{5JKO-$UcbcS_vi$?8$2k~GkS|MX zO>w=r=m3(`GDC+1Z(h$PmNtZjlTVw&_Yu^OVdmuIkkt@ck45q5!AlN#^-~9LIrOi0 zrqTStqw zJidU?S|F|+i33wwco-Yh#Zbl;kYzj$9`CZmM|))q6={j1KFLVb%4UXIVvVC>g!-_k znXpS79C85M)vCOo0Ns1+;Msf~H1>qjdXLh)EHr_W(5-M*3yzwMg1vF=2fYjxH3j{( zg2yCgFtU>rDs!M+0#F;KAxY|Tj2z&N0e_5@H!;+0CrnbN@bNQynw_cVYL zyLIt#Uk^jwnhqbOIKer+q{5SnbF&9%07|vKZnU;1svv-otz3*v{LE0l_^489!EM>v zgJzjkPrCL24M#cyz*IGbnIb4YX9utU!^Q60-+4ba2FXc7a%QLn*38HJN6Lpmy&lqg z2H8=(2pxOFI2j?kHEC$*0faxN`E@(;7h~TR;zZ05+ z?0J`)*g0t8b|GKA)!IC3vkEW{dwRTsp#r1Pk#g!xU~dPhSlq}^^)X1N4WyffVL_!l zmpW_YS{!?!qYzi$}nmMncUO;f0Bav2yyfU}hufRU(?c&{S2gtT6#Ir0r%J z)>iAtfiWs=wgU`BA4ZYxF!zQoRCEwmB*KQ@dFU2Zp;=XT<=#=8cBFhfPAf;V>Ut6h za393V9yvtEBS)N&BVK9(9I~*0OW|B-)lC`@jBewobC}kpUgGH0+Gla`rU3LV{Q926 zokxM>L6V_qSXO~?<FVuk9 TYH8c+5H&u0Ze<4FDTe+FPRHCN delta 2654 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 aSH8dyG7}5%W@Q5@mjpph28Nl*ARYh;!{2uR diff --git a/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.8.0.jar b/src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.8.1.jar similarity index 93% rename from src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.8.0.jar rename to src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.8.1.jar index 8302459255fb2c48f95cf482451903b58518455f..b47b47d060df4ea09b8ef1662d7c1638aa07295a 100644 GIT binary patch delta 14507 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

2( zRL@0#Khe)DY+fz(x6hu^JE}YDWmw`-lRdERx2}(}obQZ3)^$hjpyx$lXYL&Gzo)n9 z{IZc@KT7rucV(*Ymg9^me4_t&{UR zCobN3&(+{YO?PKI!{Ap2S0*-FHs{9aYTJbDbFDrvaqIc6U{ka6xBPZ=KB??Ec9>`X zzA34bQ;K?R>{rk>Y4UilzCQko7Y#M*c%yLa#N+#;-6Eg<`Em66r;p-32zH)+a-aK8 zn*YSSfH|xJ9NAA27H_p0O>iY(c?*ty-zyHzPWCNLOn7d47B9qCY!up1^+ILGn z*MJRKQ@(t-(GfNY{@NNl7{T9Yz>qQcU+^4FX#K9~DW=#=l8@pzz`=fy41C8NGwxLITl zWf;mklBq+6@^3^z)gcf0Y&n@bk;MH+W%H@olt=qQr8i4}xg)q*Vu&g+k$nRvT6eBBCyv~*_#7%L zE`t{c6xA-|+)>;Ffk!>oDk-~WHr!S^8oE{)snExsT+AE2yrD0X8F(%?eCL4nOb`r^ z;YlTjVkZims&bq1K2cb;MURVD5(SEjluxMwS6sOd3NrWHlIuVf_`6hjIg-pB|6O^N zB{IfcsTmlhkjcL3Ao*mL2r)q(lYoEbG35Zt!OD!gNI4uiq)exy6`PbU)W5n-I9)nd zFo*Z1E}WmfULeV^wa1M&;~*JwXfpI@Ch+?fkDo%l>Xu`rPdxZNK;Dh8*cY+*3_}RZ zlE1ed1B6oup=w~D7z&j$EAOpGj2M^6mr!GO=kSkM%n3D*U<34VQibh3+F~5owOJe0 zHC4Ev;CR7Mb+*4^3U#epa_3Y1fqk9=gI&?DqXj+H@-jsnLloMXqd3%rjQC#4Zvq*O ziC}%T$S8Q3@&mQF##W)!BXi+h70DDYsEJ}DPv+MC$9Ct)NGpSl*CBdU_d$_8p(r!j zBTu=qIXV|7=&IVdD`HFt_}47ACpn<@X)Uy2lhWbfJ@!`x;qX_e@{^K`PDUt0dCKc; zW#BeJCUY?*$g1E3#c8U8|9RGw(yg4R>`q5#o-5KQU17nI!55V>S(P4+xeKz55lmIj z^4Y(sfN^PxAZ;Sb{vc~kP3BS+@f;DVz0rGYDpYC-LxdI%2EVS`&1TYCsJyQjN5z#S zC~r~PE!xVxlwW?Z;vjX6^#XR5g79;don6^hMAGRRD*R7Sx4G#toO2V%7q`KjH0xGZxm&8PXCj_gu17sSh2u>$bC9hsY9iy zq7@ftZ4Wk8Ua%q1W^(0dDkJ={Vj7iu^f%U?Cl&p$>p6QKvSO794bVMSiGoH8I;z04 z3L`4K+cCufII8I-m@{3_E3ewmX7k3 zN;68aJ%+tN=Mq*Z_ELTyFDp)v5$YZy42xmvrsdetGK9xFc z57VB}!sT4tu4kVW=xQb7uNu2tzL!>M$z3Lyl5~rZuco6PFPMdNG-0f~(m@Xs=l-{O z*)Aw{#}&O;Uo_K4;0t}B++DSpLk!8P1D~d}xeht~o<&QeUX|=r^h?6?;($j4l+I{F9d3m z+sAyPf`5dt3M$Ueg56C=TL&|}S>l|U)Q=-zy_Zc#ZzAQsXmgZcgw{mJwNyRySwo6! zegTk)U0a9BMNjS`#zD$qR`!*Y%O*2_09vHjsZcBwb025#upj- z2*#+mn$cEy%b77OvE-g^%lj(83D8DWg`6W=62q9F;FpY``g(-9%#!WG{13A}Ah0$a z+CV3~UGPTF0tI7LyA@0k)#KYRCX-4}-^l#XC7M@9%Gc1jH_42OjzW4erPK+L4fYe+i=Tb8I|_J1d6}#`mhFe`hYKdE{C}9U6t{y5 zEBfl+Rr1AD4nIO3MMq`FnRT@7%`fb0T?d@Xd19%m?oY;<;^e!sdUUjKtvr1w(SB(* zv)zb{Jf<_T)K?#-L=`Rt4x>3#GzgM*TStgo=5mOf$5dt+)uzUZ9Y}dC3X$j03_6p} zB+xm7CG{D(!JEBK=cf9ykLf5gp2?w-!s8!ITnkYds7)i+G7Q{(^9mz2zq!%!QIy1{ zP+mz#dstQssZsE2|0NC7^o0ad_19rnQw_uI*pHN?DbH5Z(W_XwIUR9ftS!~L#)R!o z=YpNskCe7>klaATJIHLKejTEde^~*#S_>%0m-Rsp`Un=P+CWw;*8koz?v!Ct8Dqj4 z;PzlwzRArvR3`gZTaLWsN_&-|F4H=cc-y**+>J^Y^D9$9N5hTSTsm_5#Jr`N*neSa z>5gE-M6QJ9`_pG#pY4Wi?I#&tsvOXj1%f#eR`Z9+;x>Mjay#9D%{Chx5eQ4ZKz1q) zs{DD}P`d9rp29sK{5S4bIbkZiaSS5lo{PA5bXjm&#wAkp3(NU9GTPU6{|u^4Mj{tV zw@7hQIBT-M+}G2qryVwKpXxS4x2@SZTr(nvZcIHRdA{)pK;;&|SJ2H`Mo)euwcqX$ zcYrPmPxo@7gFpH5UgF}hi~CMJF(ap_wH@p?3iWYJ994C;d_Rg)@`;1Z94Mpuw4a+z zm-xT8UH7Oml*x)c(VM-TC$ito>8oC@Ou%HW7@$W+J0^PS%Y;`N`VhIPLzUXo~*SKgyEGzxk4TOxOIoC%8p4 zMY=lk#bg(_#kvCaxLD0`XSiKPT6lB*`J{*M7?hgH2dXMV>o=!CUh=z2b`V4gjwJ4= zZZ&U+|4Y^KDi0f6Jlg!7?`=Uw`gX!z2!MEC23YiAHpTD-WP)tDQL3Y=s)$z-UaDuC zdDfE9d^Hmc1v1+6lz+^VQM)QWozutkI_p=Rv;_JZ9rR|Z(g8&;5%g96UE2P z0NFYmrOpGXS?qNG(i%(fdZs@{cjLJ{pmR!v(1=;#y-vPJz`3I@ahKlIK$*=q|S zij&E_B)WVNQJ)yfO;H9MGYEd-P}iIw*y`v*OKvH}FQBaDZbDO{OK}DW%qgV0yiDS( z&?Og<%iAVlR_$R8Yz1`+mkjFP{+yYsP);+!kH{+PvZ?~FaREOChbf|5i&F$kf?D!) zlmBKwvxaMnR%&+GrR_IS)a-c>n9>m(hdeVxE&dr0baN}5kF%X+GEWJS>kdkEf1cn# zY`NnCw%8pZv&%a!(?Yh*MYk@=1W4#z3c+ddD3hiI3ULO=@%!q$;Lv<$!I-FPV&=Kv z7hRd`ck9MppIfa~*O8z)oDFCe0S>^B)QI(rY;$7DwEywkjda5 z^>2U9>kpJQ*Ml=5X+ij3?s@W8d{9n?!uL~SW6!PCLA|^M8QvDO=X1daRz?JZAOw2IaK2zpIC&+!wmb$#B|`a04O?$Q@k{6M9O{%SSQC7# z8|X=Xj^baL%ux0%WV;!~hZ_;9hT#B8_} z^CRa2=+azEChI66LQa%F5Va!NU^o%1dfHq)tGQO8Rk(YSU?tZ_OWg!peCuL}{+%R{ zr4m(50Ln=nrIdQeCsk}1rBeVtB&Y#grzNM05)wouKixh&5+(a~Zb0Ne zMRc-!`}z%Ok$`))u_u;qy9P!k!Tl8IsoMx_Ej zyG;~CF2C|qMXwrRQC)v;Km`Wrp)r#MI})$?^8r3!D}_T=>7vW?#qvGg3_y7Y2?#RX z92vNXt@J-!z8)v)A$IQ3-8Cy0UOOh&y<2@l4>r*DjhooplT_3&7lE9(QLsDkGQ2`( zVIyaV7PyPcN*3-cL$6a%i4!!bGcHidSb+Kt>!;FmuAunAft(%cm?qj%f)}F4w~xSk9zZs)C}>ZAg(-@T7a7Kk22jNt0xHBe2rEZJ8RNz8K)WkrCN`1Dwzika z+$3S2_P!pSLl1Hk+7gFj(uY%Sm28EZiHl~9TU9#&4G$1(KoXDqdMPbX3am6l{SN&= zk#YW%PsE!0c}B&C1#Z2^aw^rHfEX(+2nhQv`F8MQ(AxYK$!f*=H$vWM`+) zLrHTWp)o&i$3x~0z{?q~=cElS#f=gX_hocd7@|RgL?Tn>X}2LzXFkS_m3ZLYfM{Q= zsPx^`(~sm(F;`*TlD79b{sbRE~Y?oOg0xTQ37Yotr`xd#ppE0BSo&t&#~!94wmnU?6~YEmDKD(9L|-2vx$i zfFuLk;^g18u#)f=5L=0fmzFgUwKff^Mjfb(!N631trX6q(!rwN{`@xnuqpWMBLrXS zw-%clXyTu$&?lM_O*9v-jSDWXm=M7gEG^B-?Xf+bpw}D#y``I|@Ld!W=a$X`h3-$K z+3Sw!w_G68GH<*t9r&YxW($(VE%2Ayd&?7Hlb&hSIPI4lqxhbQB5K@6oo-{HLb8k+ z8{PRYiV8u~M$LyqL&ZVM!jbt_P8A+3aOn6z!IpSJb5-0}=&b7$9oyG=m{{-I6M>QZ zfm#NKUL=Z%5sNG8pC|Q1O0;eOY(#Mr&|EM#);6lT9-TvT${<(Ni=)OBp&@YUQ}#L^<7U6>dnrj z@n$!jK@P(NCuGAa3^Ym|#Y$Z=#vn)ZC0?+#!{%L%pC35^;`|G=;MS6~?uNX23bv&C z1o*+?>(^hbl!*So2+k-(#{B+bDqB9@yZ;d+KpRLH={drt4VC%Zc)^U=GW|@6;N^#`fuvKxegN6w_HZ+SVhkHBSP+%+l3?~uGM&AY zB&xLUP*~y|*d+cA+hA!eyG^C2DQ{r$YM(5sT%zcWhcP8?U1ulR_j+#e2X-t;ZH3jHrMQA7HGT$wp3EG zoolED&!RyCd=e$gaWpQ^X}?j>;zZFKUSnZ4yp+mG9V?d6ixr+beLy8wXq>K+JlS)G zGGGz}Qxcnjqh`ll1=Js)eOn1?tBVx1<~P=aEZ|s;LcGz5zD6PNOhUI7f3>SQI02H) z36f2k-5YLG)XZZFZApM}cGZpqW&=(*q!))j@>fKOTEP(W6Xz2(jYTY=&nq<&zoL43aIy>$JtM`*)!-fHdsXlr$ z0u)<^8zdHFGzMl<&FE~eF>r*zvx{&9mf2!%E(q3rXEIxZ_hCDns0=r#Ei$_l8=US= zXW=c*ii7~&_l&@|^G_gJ(v6wBH%0w8S_~`>Q2n9MK^-l8D6H*(QEgC_JM8DNUY318 zmWLmiE!1L6(OQ3aGhFN;)_eCb04D@cqPo^_*SaQ5TsO4J^Idq@T&SSabXE%?N8}(i zyA`>R6)8bt4P0|LJ+~N0w!q6|xP*iYRg<6x?yR{+gY&_lfqA$Fd~^?Ej!v`}S&}C# zur&!h(@DazcLdcsxG!iuZn@kL<#!ORTGs`5hDTC(T{>fie%yuY9}Fk1{^9&#dm!j} z0FpIC!c^6h5_#%?j(HJs0}au+onwsMfan7$f2bQZiLuptx>9 z1Gr}!!I|*urFc>n4Dt5$p-XDjXor#q|(VG`@nM+2VFU9cyXP57J=p9bsDH7H%_g;?w#_2>dx-A-^Ki~>V|QR_nlf}n3$pd}&V z8k|%yeco26*lI|n5Q&enk5YVyYa1do`hzU8AGmWexKnx=GWWR1x(6-o4zo2%?7O$ZEFIp1zSp78g-Z1OdQPpc zIU01KVUA>bf)de}2%NOla!d|hZyhHxGlL~(-6(*0@vC&6SQ!S z*#0dNVfCz6LLX7r%G*g)Q zi_~lEw_0wji9;f8Q(9&k@L?};*O8B-7-OkX!{7vCr*T{sw(5%w0V7x)&C%shv3*ox zHG9B&K8U0dyyD8zg_Yu0&>;tQxG-vP|r zs>GR)ByS+CyGp!iQ><3O3?1@?t&6%_uEjOU?$I!==^$pw?alz1w@(9c4HN8$=ax;; ze~F(5t-*8BZZk(E3TiF1C#Z`HCp^po)D@tUG{UcrP*hSjafR?Opk9?3^!qCgh|GY$ zbQL{+oT`Isr(dMtK)zxk-$J0cj)E!UeM-&LMbjNO?DF2X3iy2kB|1qQ<9L?x!}XqP z2e*G}zhp#$^;YL8JF-O_!i$+s3ibp7{o#yz+nRpeyoL@D1)4k>KS~45`nYKP-|0&x>{1%<8HGGfoK6Nr_w~qzu7?h z@MtlU46)+#;Jj7eHDW!*>-b{4X0N)ZfqV@Sk3viEAtCIM1_IxI&;!h+2!QN9BtNc@-P{$;iYw6g@0A|$TA|6IdvXBlIualN%K@cd9idBOs2OrPa&!wC86 zIN}npiw1VmGe>VvR5TNAG~wGOQ#7ng!z#?ei|0&lHQWT11&LkybY;7_t`H_3GDFHQ z#+Twp_k_KRWe?F2A>Dx0KYkPx7YOE#{{+jvIv838RU?)GzY`F4>E5O?fD)Cq6-*J+ zU9cvfJ3R6!%t}DL(jav&grJbALOXP38a&rwTQy(0G`=%i&>5rJ;BQ}?$dkzVW@Y1I zLF^vL0qK+N{4k129t}6FQW}tJRYIisLZ&g1PXtPxE`DENI1Ma56-Bwgb9ECmbeh<` zzg@EmEpdd$#_^5664(@t@$J#&=7QP(^Gdm85@o$}hQLcMKk!q};Hqi8R=}py0FJz& zlI(e|Au~bIGhma7@vSP(E@%op`USXO`VROYLoLRI+>_kLZ#$7$bQT`8Ib^#4Zr1RH zQmf_w+WiXw!8h~Pl5;;s2*OYJ9&^>S1}HZ}e2%+~-8Cf_$uk63WS=Q=yzd0F1qJmS zO_neA;v~l6c%L2cvY84VNd|d0j>pq|R20P90JY2zU*bAs0@Ii0aH#Ci&K!6TeK1n2 zI_xT_67qupi9dY)Z*mc*VKe;(k9Hs%WzGR!{RqsRd>Vu%2k=c%P5mQIaBA*6T}ZGD z=*ZHi&393aSuKC7#@9zPW{V4Z z#XX%4b+D+XIW%6)EIwm=Z}j66XNK0y5=DQAJe)19$F&*Z8RV5W!#g#>PS<$^zbZW{P*LSLXu16%G_MVHVtJ zIQ8L8P`6)1wZ7sI_Hd_g_*Bc0IE!?WN}E?L$3knk23sxZdV1PJEy|aKXvZwzvcyN6 z#m2$MT&AdQrWmK}@D)qczbrpOT_Szzo!%xxs5j!|TCKIeiaP2Jq>d z5vp4#YV~6wXq9_h4bnn3TX+F=TLh8D{B8_6t8)sL*~Dft8FVD|Z&MEJD~LkyA)GTY zuqYo`6+NJ{@HLx0dhwK(-s56F1Y@*$)oNmWlv2e@-?On`&G&ZF8}CgyOl<>N_ySLm z6de{3vj{{azSW@pFIQ*j7!<@pIn0FDnueEdn{onwP)fC{J^x3f>M92QwI52LAFQ-e zN557I=;|W4-|ey(k_hW_FArMZDqK5PP9PQV+dxb^W}=OJeQc1g|6v23z2UFwR~%t& z5xTVQ?X3bwo|cA%vSx}$&idZf3z`;^X|%E4|Hq6M7B187Rd1UwyT4(YY+v7=MY2mT z+IVVqFBZRC)tZu;s?U7QyIlC*HS>@evhJ*lCqH^+-p3J^lPPfIViNZ*_jx9*4N)SY z*QccFEy&s>RUCH4dSZQQsqyTqsh7_#SoQctug;mg2@7xk-EwFCLd&%oR#$cRI`q~z zb%`x+y6lwAdw7RwpStV{!N)HO%{A^UEPLQ&chh5eQ*v^3mDPm>H8cL5d6eMxvd2~+ z|LWKEbL(CI?cVz}$Z`|k8u?14t%vW`Y4=}w+o)d6v7pR7W9ze%L0SJlGS_c;!WUyO zZDWt1nR?_dPw#og^PX?f(LVO-yG7N83#(4*c}2DOZ;&v${a!A!&QjZB)^r`q_(%b+ z$*mike-;)O=6q$To^i*)F7`QFPJf@xUEBItchjZUjzu>LYxUVNBEtT3%h!M{TOPIL z@-r~R=`b*eFfcIqx`u4N&e*}ve4^#+0ZY9l#Rbh3@l$1#T)RPZrQ;pL|b` z2h4w~=Ln_^^L>cVv+a}UXVSIefBdV_sdYc9>CAPwXiOunti&5!QNKA`tOIoXF@$iInKD=y iRei9jAjR625I5LaN;BmmgxBfIPM&8ez$Rn@(g*+tKx}0I delta 1041 zcmdm5yrq~oz?+$ci-CcIgJIg7a}#;hIDu3^?&gkP(GzXt>q~=ty_pRK_UgZ>kNB|2 z<58W;ZL_!~p+|0Aa_;WfURb`1cge{~zDNF5C)>Y>`XIpce(%ihX)`P{b{;!7(R|BX zlPDEQ-^UqwS?ee0tjS3^AoWu2(Cr`oQ8U*%u+E))_3p>_0y$e3ItsW?=6%8DYV@F4 zDfwx~^d7|?h1IKTdPC>dPcLO#Bk`$dLa|Pz%-+eJH@6w>u>E>_E;H|o59XI5%|DA~ z*>JZ_x%}q8n>TOnc0)gv>;Tzg7f){s-QoK7Kx@^eNq((Ij+uRV@38h$;xFy)wJ(<# zm$~l={eIj++*j{%-`wcj%GT_-N4 z)q3*CjcYQO?#x-U>;vmw>4d+f>kgQ`IPvA<*Y8$swON^a)^2b=dXXOy^iIGq-?HUV zTP{BXL!1r+g9rlygRg6dT zESZ6Ro;=G$nsM9YZ6?ZKKi&cILMQ()Q3C6bHI)_@5@KM;FG|-B@MdHZVTLEu$^NF& zOlCrp8HGhAH<&`)<7Y0-lmQW{H(w=9pM26x8t$y+dXpXXr6+e-VA`z$ uHxgv`1CT Date: Thu, 13 Aug 2020 18:05:49 +0200 Subject: [PATCH 0243/1191] DATAES-898 - Add join-type relevant parts to reactive calls. Original PR: #504 --- .../core/AbstractElasticsearchTemplate.java | 60 ++++-------- .../elasticsearch/core/EntityOperations.java | 93 ++++++++----------- .../core/ReactiveElasticsearchTemplate.java | 26 ++++-- 3 files changed, 72 insertions(+), 107 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 160102cb0..4a891ace3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -46,7 +46,6 @@ import org.springframework.data.elasticsearch.core.event.AfterConvertCallback; import org.springframework.data.elasticsearch.core.event.AfterSaveCallback; import org.springframework.data.elasticsearch.core.event.BeforeConvertCallback; -import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -79,10 +78,10 @@ */ public abstract class AbstractElasticsearchTemplate implements ElasticsearchOperations, ApplicationContextAware { - protected @Nullable ElasticsearchConverter elasticsearchConverter; - protected @Nullable RequestFactory requestFactory; - - private @Nullable EntityCallbacks entityCallbacks; + @Nullable protected ElasticsearchConverter elasticsearchConverter; + @Nullable protected RequestFactory requestFactory; + @Nullable private EntityOperations entityOperations; + @Nullable private EntityCallbacks entityCallbacks; // region Initialization protected void initialize(ElasticsearchConverter elasticsearchConverter) { @@ -90,6 +89,7 @@ protected void initialize(ElasticsearchConverter elasticsearchConverter) { Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null."); this.elasticsearchConverter = elasticsearchConverter; + this.entityOperations = new EntityOperations(this.elasticsearchConverter.getMappingContext()); requestFactory = new RequestFactory(elasticsearchConverter); VersionInfo.logVersions(getClusterVersion()); @@ -524,11 +524,11 @@ ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { @Nullable private String getEntityId(Object entity) { - ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); - ElasticsearchPersistentProperty idProperty = persistentEntity.getIdProperty(); - if (idProperty != null) { - return stringIdRepresentation(persistentEntity.getPropertyAccessor(entity).getProperty(idProperty)); + Object id = entityOperations.forEntity(entity, elasticsearchConverter.getConversionService()).getId(); + + if (id != null) { + return stringIdRepresentation(id); } return null; @@ -536,36 +536,16 @@ private String getEntityId(Object entity) { @Nullable public String getEntityRouting(Object entity) { - ElasticsearchPersistentEntity persistentEntity = elasticsearchConverter.getMappingContext() - .getPersistentEntity(entity.getClass()); - - if (persistentEntity != null) { - - ElasticsearchPersistentProperty joinProperty = persistentEntity.getJoinFieldProperty(); - - if (joinProperty != null) { - Object joinField = persistentEntity.getPropertyAccessor(entity).getProperty(joinProperty); - if (joinField != null && JoinField.class.isAssignableFrom(joinField.getClass()) - && ((JoinField) joinField).getParent() != null) { - return elasticsearchConverter.convertId(((JoinField) joinField).getParent()); - } - } - } - - return null; + return entityOperations.forEntity(entity, elasticsearchConverter.getConversionService()).getRouting(); } @Nullable private Long getEntityVersion(Object entity) { - ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); - ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); - if (versionProperty != null) { - Object version = persistentEntity.getPropertyAccessor(entity).getProperty(versionProperty); + Number version = entityOperations.forEntity(entity, elasticsearchConverter.getConversionService()).getVersion(); - if (version != null && Long.class.isAssignableFrom(version.getClass())) { - return ((Long) version); - } + if (version != null && Long.class.isAssignableFrom(version.getClass())) { + return ((Long) version); } return null; @@ -573,18 +553,10 @@ private Long getEntityVersion(Object entity) { @Nullable private SeqNoPrimaryTerm getEntitySeqNoPrimaryTerm(Object entity) { - ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); - ElasticsearchPersistentProperty property = persistentEntity.getSeqNoPrimaryTermProperty(); - if (property != null) { - Object seqNoPrimaryTerm = persistentEntity.getPropertyAccessor(entity).getProperty(property); - - if (seqNoPrimaryTerm != null && SeqNoPrimaryTerm.class.isAssignableFrom(seqNoPrimaryTerm.getClass())) { - return (SeqNoPrimaryTerm) seqNoPrimaryTerm; - } - } - - return null; + EntityOperations.AdaptibleEntity adaptibleEntity = entityOperations.forEntity(entity, + elasticsearchConverter.getConversionService()); + return adaptibleEntity.hasSeqNoPrimaryTerm() ? adaptibleEntity.getSeqNoPrimaryTerm() : null; } private IndexQuery getIndexQuery(T entity) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java index c5f0bd104..c30411ce3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/EntityOperations.java @@ -18,6 +18,7 @@ import java.util.Map; import org.springframework.core.convert.ConversionService; +import org.springframework.data.elasticsearch.core.join.JoinField; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -296,9 +297,19 @@ interface AdaptibleEntity extends Entity { * Returns SeqNoPropertyTerm for this entity. * * @return SeqNoPrimaryTerm, may be {@literal null} + * @since 4.0 */ @Nullable SeqNoPrimaryTerm getSeqNoPrimaryTerm(); + + /** + * returns the routing for the entity if it is available + * + * @return routing if available + * @since 4.1 + */ + @Nullable + String getRouting(); } /** @@ -421,6 +432,11 @@ public boolean isNew() { public ElasticsearchPersistentEntity getPersistentEntity() { return null; } + + @Override + public String getRouting() { + return null; + } } /** @@ -492,56 +508,32 @@ private static MappedEntity of(T bean, return new MappedEntity<>(entity, identifierAccessor, propertyAccessor); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getId() - */ @Override public Object getId() { return idAccessor.getIdentifier(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#isVersionedEntity() - */ @Override public boolean isVersionedEntity() { return entity.hasVersionProperty(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getVersion() - */ @Override @Nullable public Object getVersion() { - return propertyAccessor.getProperty(entity.getRequiredVersionProperty()); + return propertyAccessor.getProperty(entity.getVersionProperty()); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getBean() - */ @Override public T getBean() { return propertyAccessor.getBean(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#isNew() - */ @Override public boolean isNew() { return entity.isNew(propertyAccessor.getBean()); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.Entity#getPersistentEntity() - */ @Override public ElasticsearchPersistentEntity getPersistentEntity() { return entity; @@ -557,15 +549,17 @@ private static class AdaptibleMappedEntity extends MappedEntity implements private final ElasticsearchPersistentEntity entity; private final ConvertingPropertyAccessor propertyAccessor; private final IdentifierAccessor identifierAccessor; + private final ConversionService conversionService; private AdaptibleMappedEntity(ElasticsearchPersistentEntity entity, IdentifierAccessor identifierAccessor, - ConvertingPropertyAccessor propertyAccessor) { + ConvertingPropertyAccessor propertyAccessor, ConversionService conversionService) { super(entity, identifierAccessor, propertyAccessor); this.entity = entity; this.propertyAccessor = propertyAccessor; this.identifierAccessor = identifierAccessor; + this.conversionService = conversionService; } static AdaptibleEntity of(T bean, @@ -577,22 +571,14 @@ static AdaptibleEntity of(T bean, PersistentPropertyAccessor propertyAccessor = entity.getPropertyAccessor(bean); return new AdaptibleMappedEntity<>(entity, identifierAccessor, - new ConvertingPropertyAccessor<>(propertyAccessor, conversionService)); + new ConvertingPropertyAccessor<>(propertyAccessor, conversionService), conversionService); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#hasParent() - */ @Override public boolean hasParent() { return getRequiredPersistentEntity().getParentIdProperty() != null; } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#getParentId() - */ @Deprecated @Override public Object getParentId() { @@ -601,10 +587,6 @@ public Object getParentId() { return propertyAccessor.getProperty(parentProperty); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#populateIdIfNecessary(java.lang.Object) - */ @Nullable @Override public T populateIdIfNecessary(@Nullable Object id) { @@ -629,17 +611,12 @@ public T populateIdIfNecessary(@Nullable Object id) { return propertyAccessor.getBean(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.MappedEntity#getVersion() - */ @Override @Nullable public Number getVersion() { - ElasticsearchPersistentProperty versionProperty = entity.getRequiredVersionProperty(); - - return propertyAccessor.getProperty(versionProperty, Number.class); + ElasticsearchPersistentProperty versionProperty = entity.getVersionProperty(); + return versionProperty != null ? propertyAccessor.getProperty(versionProperty, Number.class) : null; } @Override @@ -655,10 +632,6 @@ public SeqNoPrimaryTerm getSeqNoPrimaryTerm() { return propertyAccessor.getProperty(seqNoPrimaryTermProperty, SeqNoPrimaryTerm.class); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#initializeVersionProperty() - */ @Override public T initializeVersionProperty() { @@ -673,10 +646,6 @@ public T initializeVersionProperty() { return propertyAccessor.getBean(); } - /* - * (non-Javadoc) - * @see org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity#incrementVersion() - */ @Override public T incrementVersion() { @@ -688,6 +657,22 @@ public T incrementVersion() { return propertyAccessor.getBean(); } + + @Override + public String getRouting() { + + ElasticsearchPersistentProperty joinFieldProperty = entity.getJoinFieldProperty(); + + if (joinFieldProperty != null) { + JoinField joinField = propertyAccessor.getProperty(joinFieldProperty, JoinField.class); + + if (joinField != null && joinField.getParent() != null) { + return conversionService.convert(joinField.getParent(), String.class); + } + } + + return null; + } } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index bc351b82b..a3c8b135f 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -55,7 +55,6 @@ import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.EntityOperations.AdaptibleEntity; -import org.springframework.data.elasticsearch.core.EntityOperations.Entity; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter; import org.springframework.data.elasticsearch.core.document.Document; @@ -399,6 +398,8 @@ private IndexQuery getIndexQuery(Object value) { } } + query.setRouting(entity.getRouting()); + return query; } @@ -414,11 +415,10 @@ public Mono get(String id, Class entityType, IndexCoordinates index) { DocumentCallback callback = new ReadDocumentCallback<>(converter, entityType, index); - return doGet(id, getPersistentEntityFor(entityType), index) - .flatMap(it -> callback.doWith(DocumentAdapters.from(it))); + return doGet(id, index).flatMap(it -> callback.doWith(DocumentAdapters.from(it))); } - private Mono doGet(String id, ElasticsearchPersistentEntity entity, IndexCoordinates index) { + private Mono doGet(String id, IndexCoordinates index) { return Mono.defer(() -> doGet(requestFactory.getRequest(id, index))); } @@ -441,9 +441,17 @@ protected Mono doGet(GetRequest request) { @Override public Mono delete(Object entity, IndexCoordinates index) { - Entity elasticsearchEntity = operations.forEntity(entity); + AdaptibleEntity elasticsearchEntity = operations.forEntity(entity, converter.getConversionService()); + + if (elasticsearchEntity.getId() == null) { + return Mono.error(new IllegalArgumentException("entity must have an id")); + } - return Mono.defer(() -> doDeleteById(converter.convertId(elasticsearchEntity.getId()), index)); + return Mono.defer(() -> { + String id = converter.convertId(elasticsearchEntity.getId()); + String routing = elasticsearchEntity.getRouting(); + return doDeleteById(id, routing, index); + }); } @Override @@ -466,13 +474,13 @@ public Mono delete(String id, IndexCoordinates index) { Assert.notNull(id, "id must not be null"); Assert.notNull(index, "index must not be null"); - return doDeleteById(id, index); + return doDeleteById(id, null, index); } - private Mono doDeleteById(String id, IndexCoordinates index) { + private Mono doDeleteById(String id, @Nullable String routing, IndexCoordinates index) { return Mono.defer(() -> { - DeleteRequest request = requestFactory.deleteRequest(id, null, index); + DeleteRequest request = requestFactory.deleteRequest(id, routing, index); return doDelete(prepareDeleteRequest(request)); }); } From 131f0318cc02298e389c916d26554dd397ef755c Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 18 Aug 2020 20:59:35 +0200 Subject: [PATCH 0244/1191] DATAES-706 - CriteriaQueryProcessor must handle nested Criteria definitions. Original PR: #505 --- src/main/asciidoc/preface.adoc | 6 +- .../reference/elasticsearch-operations.adoc | 119 ++- .../core/CriteriaFilterProcessor.java | 74 +- .../core/CriteriaQueryProcessor.java | 124 +-- .../elasticsearch/core/RequestFactory.java | 4 +- .../MappingElasticsearchConverter.java | 55 +- .../elasticsearch/core/query/Criteria.java | 814 ++++++++++++------ .../elasticsearch/core/query/SimpleField.java | 13 +- .../parser/ElasticsearchQueryCreator.java | 7 +- .../core/CriteriaQueryMappingTests.java | 64 +- .../core/CriteriaQueryProcessorTests.java | 341 ++++++++ .../core/query/CriteriaQueryTests.java | 134 ++- ...tiveElasticsearchStringQueryUnitTests.java | 8 +- 13 files changed, 1279 insertions(+), 484 deletions(-) create mode 100644 src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessorTests.java diff --git a/src/main/asciidoc/preface.adoc b/src/main/asciidoc/preface.adoc index 5168c08fa..48740c4be 100644 --- a/src/main/asciidoc/preface.adoc +++ b/src/main/asciidoc/preface.adoc @@ -1,7 +1,8 @@ [[preface]] = Preface -The Spring Data Elasticsearch project applies core Spring concepts to the development of solutions using the Elasticsearch Search Engine. It provides: +The Spring Data Elasticsearch project applies core Spring concepts to the development of solutions using the Elasticsearch Search Engine. +It provides: * _Templates_ as a high-level abstraction for storing, searching, sorting documents and building aggregations. * _Repositories_ which for example enable the user to express queries by defining interfaces having customized method names (for basic information about repositories see <>). @@ -29,12 +30,13 @@ Requires an installation of https://www.elastic.co/products/elasticsearch[Elasti === Versions The following table shows the Elasticsearch versions that are used by Spring Data release trains and version of Spring Data Elasticsearch included in that, as well as the Spring Boot versions referring to that particular Spring Data release train: + [cols="^,^,^,^",options="header"] |=== | Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot | 2020.0.0footnote:cdv[Currently in development] |4.1.xfootnote:cdv[]|7.8.1 |2.3.xfootnote:cdv[] | Neumann | 4.0.x | 7.6.2 |2.3.x -| Moore | 3.2.x |6.8.12 | 2.2.x +| Moore | 3.2.x |6.8.10 | 2.2.x | Lovelace | 3.1.x | 6.2.2 |2.1.x | Kayfootnote:oom[Out of maintenance] | 3.0.xfootnote:oom[] | 5.5.0 | 2.0.xfootnote:oom[] | Ingallsfootnote:oom[] | 2.1.xfootnote:oom[] | 2.4.0 | 1.5.xfootnote:oom[] diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index 69850323f..49580288b 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -45,7 +45,8 @@ public class TransportClientConfig extends ElasticsearchConfigurationSupport { } } ---- -<1> Setting up the <>. Deprecated as of version 4.0. +<1> Setting up the <>. +Deprecated as of version 4.0. <2> Creating the `ElasticsearchTemplate` bean, offering both names, _elasticsearchOperations_ and _elasticsearchTemplate_. ==== @@ -75,7 +76,9 @@ public class RestClientConfig extends AbstractElasticsearchConfiguration { [[elasticsearch.operations.usage]] == Usage examples -As both `ElasticsearchTemplate` and `ElasticsearchRestTemplate` implement the `ElasticsearchOperations` interface, the code to use them is not different. The example shows how to use an injected `ElasticsearchOperations` instance in a Spring REST controller. The decision, if this is using the `TransportClient` or the `RestClient` is made by providing the corresponding Bean with one of the configurations shown above. +As both `ElasticsearchTemplate` and `ElasticsearchRestTemplate` implement the `ElasticsearchOperations` interface, the code to use them is not different. +The example shows how to use an injected `ElasticsearchOperations` instance in a Spring REST controller. +The decision, if this is using the `TransportClient` or the `RestClient` is made by providing the corresponding Bean with one of the configurations shown above. .ElasticsearchOperations usage ==== @@ -123,9 +126,12 @@ include::reactive-elasticsearch-operations.adoc[leveloffset=+1] [[elasticsearch.operations.searchresulttypes]] == Search Result Types -When a document is retrieved with the methods of the `DocumentOperations` interface, just the found entity will be returned. When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity. +When a document is retrieved with the methods of the `DocumentOperations` interface, just the found entity will be returned. +When searching with the methods of the `SearchOperations` interface, additional information is available for each entity, for example the _score_ or the _sortValues_ of the found entity. -In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information. These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations. The following classes and interfaces are now available: +In order to return this information, each entity is wrapped in a `SearchHit` object that contains this entity-specific additional information. +These `SearchHit` objects themselves are returned within a `SearchHits` object which additionally contains informations about the whole search like the _maxScore_ or requested aggregations. +The following classes and interfaces are now available: .SearchHit Contains the following information: @@ -155,3 +161,108 @@ Returned by the low level scroll API functions in `ElasticsearchRestTemplate`, i .SearchHitsIterator An Iterator returned by the streaming functions of the `SearchOperations` interface. +== Queries + +Almost all of the methods defined in the `SearchOperations` and `ReactiveSearchOperations` interface take a `Query` parameter that defines the query to execute for searching. `Query` is an interface and Spring Data Elasticsearch provides three implementations: `CriteriaQuery`, `StringQuery` and `NativeSearchQuery`. + +=== CriteriaQuery + +`CriteriaQuery` based queries allow the creation of queries to search for data without knowing the syntax or basics of Elasticsearch queries. They allow the user to build queries by simply chaining and combining `Criteria` objects that specifiy the criteria the searched documents must fulfill. + +NOTE: when talking about AND or OR when combining criteria keep in mind, that in Elasticsearch AND are converted to a **must** condition and OR to a **should** + +`Criteria` and their usage are best explained by example +(let's assume we have a `Book` entity with a `price` property): + +.Get books with a given price +==== +[source,java] +---- +Criteria criteria = new Criteria("price").is(42.0); +Query query = new CriteriaQuery(criteria); +---- +==== + +Conditions for the same field can be chained, they will be combined with a logical AND: + +.Get books with a given price +==== +[source,java] +---- +Criteria criteria = new Criteria("price").greaterThan(42.0).lessThan(34.0L); +Query query = new CriteriaQuery(criteria); +---- +==== + +When chaining `Criteria`, by default a AND logic is used: + +.Get all persons with first name _James_ and last name _Miller_: +==== +[source,java] +---- +Criteria criteria = new Criteria("lastname").is("Miller") <1> + .and("firstname").is("James") <2> +Query query = new CriteriaQuery(criteria); +---- +<1> the first `Criteria` +<2> the and() creates a new `Criteria` and chaines it to the first one. +==== + +If you want to create nested queries, you need to use subqueries for this. Let's assume we want to find all persons with a last name of _Miller_ and a first name of either _Jack_ or _John_: + +.Nested subqueries +==== +[source,java] +---- +Criteria miller = new Criteria("lastName").is("Miller") <.> + .subCriteria( <.> + new Criteria().or("firstName").is("John") <.> + .or("firstName").is("Jack") <.> + ); +Query query = new CriteriaQuery(criteria); +---- +<.> create a first `Criteria` for the last name +<.> this is combined with AND to a subCriteria +<.> This sub Criteria is an OR combination for the first name _John_ +<.> and the first name Jack +==== + +Please refer to the API documentation of the `Criteria` class for a complete overview of the different available operations. + +=== StringQuery + +This class takes an Elasticsearch query as JSON String. +The following code shows a query that searches for persons having the first name "Jack": + +==== +[source,java] +---- + +Query query = new SearchQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } "); +SearchHits searchHits = operations.search(query, Person.class); + +---- +==== + +Using `StringQuery` may be appropriate if you already have an Elasticsearch query to use. + +=== NativeSearchQuery + +`NativeSearchQuery` is the class to use when you have a complex query, or a query that cannot be expressed by using the `Criteria` API, for example when building queries and using aggregates. +It allows to use all the different `QueryBuilder` implementations from the Elasticsearch library therefore named "native". + +The following code shows how to search for persons with a given firstname and for the found documents have a terms aggregation that counts the number of occurences of the lastnames for these persons: + +==== +[source,java] +---- +Query query = new NativeSearchQueryBuilder() + .addAggregation(terms("lastnames").field("lastname").size(10)) // + .withQuery(QueryBuilders.matchQuery("firstname", firstName)) + .build(); + +SearchHits searchHits = operations.search(query, Person.class); +---- +==== + + diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java index 911a38b39..3fd3a6fc9 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaFilterProcessor.java @@ -17,9 +17,11 @@ import static org.springframework.data.elasticsearch.core.query.Criteria.*; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; import org.elasticsearch.common.geo.GeoDistance; import org.elasticsearch.index.query.BoolQueryBuilder; @@ -47,66 +49,56 @@ */ class CriteriaFilterProcessor { - QueryBuilder createFilterFromCriteria(Criteria criteria) { - List fbList = new LinkedList<>(); - QueryBuilder filter = null; + @Nullable + QueryBuilder createFilter(Criteria criteria) { + + List filterBuilders = new ArrayList<>(); for (Criteria chainedCriteria : criteria.getCriteriaChain()) { - QueryBuilder fb = null; + if (chainedCriteria.isOr()) { - fb = QueryBuilders.boolQuery(); - for (QueryBuilder f : createFilterFragmentForCriteria(chainedCriteria)) { - ((BoolQueryBuilder) fb).should(f); - } - fbList.add(fb); + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); + queriesForEntries(chainedCriteria).forEach(boolQuery::should); + filterBuilders.add(boolQuery); } else if (chainedCriteria.isNegating()) { List negationFilters = buildNegationFilter(criteria.getField().getName(), criteria.getFilterCriteriaEntries().iterator()); - if (!negationFilters.isEmpty()) { - fbList.addAll(negationFilters); - } + filterBuilders.addAll(negationFilters); } else { - fbList.addAll(createFilterFragmentForCriteria(chainedCriteria)); + filterBuilders.addAll(queriesForEntries(chainedCriteria)); } } - if (!fbList.isEmpty()) { - if (fbList.size() == 1) { - filter = fbList.get(0); + QueryBuilder filter = null; + + if (!filterBuilders.isEmpty()) { + + if (filterBuilders.size() == 1) { + filter = filterBuilders.get(0); } else { - filter = QueryBuilders.boolQuery(); - for (QueryBuilder f : fbList) { - ((BoolQueryBuilder) filter).must(f); - } + BoolQueryBuilder boolQuery = QueryBuilders.boolQuery(); + filterBuilders.forEach(boolQuery::must); + filter = boolQuery; } } + return filter; } - private List createFilterFragmentForCriteria(Criteria chainedCriteria) { - Iterator it = chainedCriteria.getFilterCriteriaEntries().iterator(); - List filterList = new LinkedList<>(); + private List queriesForEntries(Criteria criteria) { - String fieldName = chainedCriteria.getField().getName(); + Assert.notNull(criteria.getField(), "criteria must have a field"); + String fieldName = criteria.getField().getName(); Assert.notNull(fieldName, "Unknown field"); - QueryBuilder filter = null; - while (it.hasNext()) { - Criteria.CriteriaEntry entry = it.next(); - filter = processCriteriaEntry(entry.getKey(), entry.getValue(), fieldName); - filterList.add(filter); - } - - return filterList; + return criteria.getFilterCriteriaEntries().stream() + .map(entry -> queryFor(entry.getKey(), entry.getValue(), fieldName)).collect(Collectors.toList()); } @Nullable - private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String fieldName) { + private QueryBuilder queryFor(OperationKey key, Object value, String fieldName) { - if (value == null) { - return null; - } QueryBuilder filter = null; switch (key) { @@ -169,8 +161,7 @@ private QueryBuilder processCriteriaEntry(OperationKey key, Object value, String // 2x text twoParameterBBox((GeoBoundingBoxQueryBuilder) filter, valArray); } else { - // error - Assert.isTrue(false, + throw new IllegalArgumentException( "Geo distance filter takes a 1-elements array(GeoBox) or 2-elements array(GeoPoints or Strings(format lat,lon or geohash))."); } break; @@ -208,8 +199,7 @@ private void oneParameterBBox(GeoBoundingBoxQueryBuilder filter, Object value) { GeoBox geoBBox; if (value instanceof Box) { - Box sdbox = (Box) value; - geoBBox = GeoBox.fromBox(sdbox); + geoBBox = GeoBox.fromBox((Box) value); } else { geoBBox = (GeoBox) value; } @@ -218,7 +208,7 @@ private void oneParameterBBox(GeoBoundingBoxQueryBuilder filter, Object value) { geoBBox.getBottomRight().getLon()); } - private static boolean isType(Object[] array, Class clazz) { + private static boolean isType(Object[] array, Class clazz) { for (Object o : array) { if (!clazz.isInstance(o)) { return false; @@ -247,7 +237,7 @@ private List buildNegationFilter(String fieldName, Iterator shouldQueryBuilderList = new LinkedList<>(); - List mustNotQueryBuilderList = new LinkedList<>(); - List mustQueryBuilderList = new LinkedList<>(); - - ListIterator chainIterator = criteria.getCriteriaChain().listIterator(); + List shouldQueryBuilders = new ArrayList<>(); + List mustNotQueryBuilders = new ArrayList<>(); + List mustQueryBuilders = new ArrayList<>(); QueryBuilder firstQuery = null; boolean negateFirstQuery = false; - while (chainIterator.hasNext()) { - Criteria chainedCriteria = chainIterator.next(); - QueryBuilder queryFragmentForCriteria = createQueryFragmentForCriteria(chainedCriteria); - if (queryFragmentForCriteria != null) { + for (Criteria chainedCriteria : criteria.getCriteriaChain()) { + QueryBuilder queryFragment = queryForEntries(chainedCriteria); + + if (queryFragment != null) { + if (firstQuery == null) { - firstQuery = queryFragmentForCriteria; + firstQuery = queryFragment; negateFirstQuery = chainedCriteria.isNegating(); continue; } + if (chainedCriteria.isOr()) { - shouldQueryBuilderList.add(queryFragmentForCriteria); + shouldQueryBuilders.add(queryFragment); } else if (chainedCriteria.isNegating()) { - mustNotQueryBuilderList.add(queryFragmentForCriteria); + mustNotQueryBuilders.add(queryFragment); + } else { + mustQueryBuilders.add(queryFragment); + } + } + } + + for (Criteria subCriteria : criteria.getSubCriteria()) { + + QueryBuilder subQuery = createQuery(subCriteria); + + if (subQuery != null) { + if (criteria.isOr()) { + shouldQueryBuilders.add(subQuery); + } else if (criteria.isNegating()) { + mustNotQueryBuilders.add(subQuery); } else { - mustQueryBuilderList.add(queryFragmentForCriteria); + mustQueryBuilders.add(subQuery); } } } if (firstQuery != null) { - if (!shouldQueryBuilderList.isEmpty() && mustNotQueryBuilderList.isEmpty() && mustQueryBuilderList.isEmpty()) { - shouldQueryBuilderList.add(0, firstQuery); + + if (!shouldQueryBuilders.isEmpty() && mustNotQueryBuilders.isEmpty() && mustQueryBuilders.isEmpty()) { + shouldQueryBuilders.add(0, firstQuery); } else { + if (negateFirstQuery) { - mustNotQueryBuilderList.add(0, firstQuery); + mustNotQueryBuilders.add(0, firstQuery); } else { - mustQueryBuilderList.add(0, firstQuery); + mustQueryBuilders.add(0, firstQuery); } } } BoolQueryBuilder query = null; - if (!shouldQueryBuilderList.isEmpty() || !mustNotQueryBuilderList.isEmpty() || !mustQueryBuilderList.isEmpty()) { + if (!shouldQueryBuilders.isEmpty() || !mustNotQueryBuilders.isEmpty() || !mustQueryBuilders.isEmpty()) { query = boolQuery(); - for (QueryBuilder qb : shouldQueryBuilderList) { + for (QueryBuilder qb : shouldQueryBuilders) { query.should(qb); } - for (QueryBuilder qb : mustNotQueryBuilderList) { + for (QueryBuilder qb : mustNotQueryBuilders) { query.mustNot(qb); } - for (QueryBuilder qb : mustQueryBuilderList) { + for (QueryBuilder qb : mustQueryBuilders) { query.must(qb); } } @@ -111,46 +126,41 @@ QueryBuilder createQueryFromCriteria(Criteria criteria) { } @Nullable - private QueryBuilder createQueryFragmentForCriteria(Criteria chainedCriteria) { - if (chainedCriteria.getQueryCriteriaEntries().isEmpty()) + private QueryBuilder queryForEntries(Criteria criteria) { + + if (criteria.getField() == null || criteria.getQueryCriteriaEntries().isEmpty()) return null; - Iterator it = chainedCriteria.getQueryCriteriaEntries().iterator(); - boolean singeEntryCriteria = (chainedCriteria.getQueryCriteriaEntries().size() == 1); + String fieldName = criteria.getField().getName(); - String fieldName = chainedCriteria.getField().getName(); Assert.notNull(fieldName, "Unknown field"); - QueryBuilder query = null; - if (singeEntryCriteria) { - Criteria.CriteriaEntry entry = it.next(); - query = processCriteriaEntry(entry, fieldName); + Iterator it = criteria.getQueryCriteriaEntries().iterator(); + QueryBuilder query; + + if (criteria.getQueryCriteriaEntries().size() == 1) { + query = queryFor(it.next(), fieldName); } else { query = boolQuery(); while (it.hasNext()) { Criteria.CriteriaEntry entry = it.next(); - ((BoolQueryBuilder) query).must(processCriteriaEntry(entry, fieldName)); + ((BoolQueryBuilder) query).must(queryFor(entry, fieldName)); } } - addBoost(query, chainedCriteria.getBoost()); + addBoost(query, criteria.getBoost()); return query; } @Nullable - private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String fieldName) { + private QueryBuilder queryFor(Criteria.CriteriaEntry entry, String fieldName) { OperationKey key = entry.getKey(); - Object value = entry.getValue(); - if (value == null) { - - if (key == OperationKey.EXISTS) { - return existsQuery(fieldName); - } else { - return null; - } + if (key == OperationKey.EXISTS) { + return existsQuery(fieldName); } + Object value = entry.getValue(); String searchText = QueryParserUtil.escape(value.toString()); QueryBuilder query = null; @@ -190,11 +200,23 @@ private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String f case FUZZY: query = fuzzyQuery(fieldName, searchText); break; + case MATCHES: + query = matchQuery(fieldName, value).operator(org.elasticsearch.index.query.Operator.OR); + break; + case MATCHES_ALL: + query = matchQuery(fieldName, value).operator(org.elasticsearch.index.query.Operator.AND); + break; case IN: - query = boolQuery().must(termsQuery(fieldName, toStringList((Iterable) value))); + if (value instanceof Iterable) { + Iterable iterable = (Iterable) value; + query = boolQuery().must(termsQuery(fieldName, toStringList(iterable))); + } break; case NOT_IN: - query = boolQuery().mustNot(termsQuery(fieldName, toStringList((Iterable) value))); + if (value instanceof Iterable) { + Iterable iterable = (Iterable) value; + query = boolQuery().mustNot(termsQuery(fieldName, toStringList(iterable))); + } break; } return query; @@ -203,15 +225,17 @@ private QueryBuilder processCriteriaEntry(Criteria.CriteriaEntry entry, String f private static List toStringList(Iterable iterable) { List list = new ArrayList<>(); for (Object item : iterable) { - list.add(StringUtils.toString(item)); + list.add(item != null ? item.toString() : null); } return list; } - private void addBoost(QueryBuilder query, float boost) { - if (Float.isNaN(boost)) { + private void addBoost(@Nullable QueryBuilder query, float boost) { + + if (query == null || Float.isNaN(boost)) { return; } + query.boost(boost); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 79505b54b..67e08c49e 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -1513,7 +1513,7 @@ private QueryBuilder getQuery(Query query) { elasticsearchQuery = searchQuery.getQuery(); } else if (query instanceof CriteriaQuery) { CriteriaQuery criteriaQuery = (CriteriaQuery) query; - elasticsearchQuery = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()); + elasticsearchQuery = new CriteriaQueryProcessor().createQuery(criteriaQuery.getCriteria()); } else if (query instanceof StringQuery) { StringQuery stringQuery = (StringQuery) query; elasticsearchQuery = wrapperQuery(stringQuery.getSource()); @@ -1533,7 +1533,7 @@ private QueryBuilder getFilter(Query query) { elasticsearchFilter = searchQuery.getFilter(); } else if (query instanceof CriteriaQuery) { CriteriaQuery criteriaQuery = (CriteriaQuery) query; - elasticsearchFilter = new CriteriaFilterProcessor().createFilterFromCriteria(criteriaQuery.getCriteria()); + elasticsearchFilter = new CriteriaFilterProcessor().createFilter(criteriaQuery.getCriteria()); } else if (query instanceof StringQuery) { elasticsearchFilter = null; } else { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index 910092a02..deda4c3fe 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -48,6 +48,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentEntity; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; +import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentPropertyAccessor; @@ -761,29 +762,39 @@ public void updateCriteriaQuery(CriteriaQuery criteriaQuery, Class domainClas ElasticsearchPersistentEntity persistentEntity = mappingContext.getPersistentEntity(domainClass); if (persistentEntity != null) { - criteriaQuery.getCriteria().getCriteriaChain().forEach(criteria -> { - String name = criteria.getField().getName(); - ElasticsearchPersistentProperty property = persistentEntity.getPersistentProperty(name); - - if (property != null && property.getName().equals(name)) { - criteria.getField().setName(property.getFieldName()); - - if (property.hasPropertyConverter()) { - ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); - criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> { - Object value = criteriaEntry.getValue(); - if (value.getClass().isArray()) { - Object[] objects = (Object[]) value; - for (int i = 0; i < objects.length; i++) { - objects[i] = propertyConverter.write(objects[i]); - } - } else { - criteriaEntry.setValue(propertyConverter.write(value)); - } - }); + for (Criteria chainedCriteria : criteriaQuery.getCriteria().getCriteriaChain()) { + updateCriteria(chainedCriteria, persistentEntity); + } + } + } + + private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity persistentEntity) { + String name = criteria.getField().getName(); + ElasticsearchPersistentProperty property = persistentEntity.getPersistentProperty(name); + + if (property != null && property.getName().equals(name)) { + criteria.getField().setName(property.getFieldName()); + + if (property.hasPropertyConverter()) { + ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); + criteria.getQueryCriteriaEntries().forEach(criteriaEntry -> { + Object value = criteriaEntry.getValue(); + if (value.getClass().isArray()) { + Object[] objects = (Object[]) value; + for (int i = 0; i < objects.length; i++) { + objects[i] = propertyConverter.write(objects[i]); + } + } else { + criteriaEntry.setValue(propertyConverter.write(value)); } - } - }); + }); + } + } + + for (Criteria subCriteria : criteria.getSubCriteria()) { + for (Criteria chainedCriteria : subCriteria.getCriteriaChain()) { + updateCriteria(chainedCriteria, persistentEntity); + } } } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java index 0a2ed5a86..6b7d0fdb3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Criteria.java @@ -15,12 +15,13 @@ */ package org.springframework.data.elasticsearch.core.query; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Objects; import java.util.Set; import org.springframework.dao.InvalidDataAccessApiUsageException; @@ -31,12 +32,19 @@ import org.springframework.data.geo.Point; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; import org.springframework.util.StringUtils; /** * Criteria is the central class when constructing queries. It follows more or less a fluent API style, which allows to - * easily chain together multiple criteria. + * easily chain together multiple criteria.
+ *
+ * A Criteria references a field and has {@link CriteriaEntry} sets for query and filter context. When building the + * query, the entries from the criteriaentries are combined in a bool must query (if more than one.
+ *
+ * A Criteria also has a {@link CriteriaChain} which is used to build a collection of Criteria with the fluent API. The + * value of {@link #isAnd()} and {@link #isOr()} describes whether the queries built from the criteria chain should be + * put in a must (and) or a should (or) clause when a query is built from it, it is not used to build some relationship + * between the elements of the criteria chain. * * @author Rizwan Idrees * @author Mohsin Husen @@ -45,564 +53,800 @@ */ public class Criteria { - @Override - public String toString() { - return "Criteria{" + "field=" + field.getName() + ", boost=" + boost + ", negating=" + negating + ", queryCriteria=" - + ObjectUtils.nullSafeToString(queryCriteria) + ", filterCriteria=" - + ObjectUtils.nullSafeToString(filterCriteria) + '}'; - } - - public static final String WILDCARD = "*"; - public static final String CRITERIA_VALUE_SEPERATOR = " "; - - private static final String OR_OPERATOR = " OR "; - private static final String AND_OPERATOR = " AND "; + public static final String CRITERIA_VALUE_SEPARATOR = " "; + /** @deprecated since 4.1, use {@link #CRITERIA_VALUE_SEPARATOR} */ + public static final String CRITERIA_VALUE_SEPERATOR = CRITERIA_VALUE_SEPARATOR; private @Nullable Field field; private float boost = Float.NaN; private boolean negating = false; - private List criteriaChain = new ArrayList<>(1); + private final CriteriaChain criteriaChain = new CriteriaChain(); + private final Set queryCriteriaEntries = new LinkedHashSet<>(); + private final Set filterCriteriaEntries = new LinkedHashSet<>(); + private final Set subCriteria = new LinkedHashSet<>(); + + // region criteria creation - private Set queryCriteria = new LinkedHashSet<>(); + /** + * @return factory method to create an and-Criteria that is not bound to a field + * @since 4.1 + */ + public static Criteria and() { + return new Criteria(); + } - private Set filterCriteria = new LinkedHashSet<>(); + /** + * @return factory method to create an or-Criteria that is not bound to a field + * @since 4.1 + */ + public static Criteria or() { + return new OrCriteria(); + } public Criteria() {} /** * Creates a new Criteria with provided field name * - * @param fieldname + * @param fieldName the field name */ - public Criteria(String fieldname) { - this(new SimpleField(fieldname)); + public Criteria(String fieldName) { + this(new SimpleField(fieldName)); } /** * Creates a new Criteria for the given field * - * @param field + * @param field field to create the Criteria for */ public Criteria(Field field) { Assert.notNull(field, "Field for criteria must not be null"); Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty"); - this.criteriaChain.add(this); this.field = field; + this.criteriaChain.add(this); } - protected Criteria(List criteriaChain, String fieldname) { - this(criteriaChain, new SimpleField(fieldname)); + /** + * Creates a Criteria for the given field, sets it's criteriaChain to the given value and adds itself to the end of + * the chain. + * + * @param criteriaChain the chain to add to + * @param fieldName field to create the Criteria for + */ + protected Criteria(List criteriaChain, String fieldName) { + this(criteriaChain, new SimpleField(fieldName)); } + /** + * Creates a Criteria for the given field, sets it's criteriaChain to the given value and adds itself to the end of + * the chain. + * + * @param criteriaChain the chain to add to + * @param field field to create the Criteria for + */ protected Criteria(List criteriaChain, Field field) { Assert.notNull(criteriaChain, "CriteriaChain must not be null"); Assert.notNull(field, "Field for criteria must not be null"); Assert.hasText(field.getName(), "Field.name for criteria must not be null/empty"); + this.field = field; this.criteriaChain.addAll(criteriaChain); this.criteriaChain.add(this); - this.field = field; } /** * Static factory method to create a new Criteria for field with given name * - * @param field - * @return + * @param fieldName field to create the Criteria for */ - public static Criteria where(String field) { - return where(new SimpleField(field)); + public static Criteria where(String fieldName) { + return new Criteria(fieldName); } /** * Static factory method to create a new Criteria for provided field * - * @param field - * @return + * @param field field to create the Criteria for */ public static Criteria where(Field field) { return new Criteria(field); } + // endregion + + // region criteria attributes + /** + * @return the Field targeted by this Criteria + */ + @Nullable + public Field getField() { + return this.field; + } + + public Set getQueryCriteriaEntries() { + return Collections.unmodifiableSet(this.queryCriteriaEntries); + } + + public Set getFilterCriteriaEntries() { + return Collections.unmodifiableSet(this.filterCriteriaEntries); + } + + /** + * Conjunction to be used with this criteria (AND | OR) + * + * @deprecated since 4.1, use {@link #getOperator()} + */ + @Deprecated + public String getConjunctionOperator() { + return Operator.AND.name(); + } + + public Operator getOperator() { + return Operator.AND; + } + + public List getCriteriaChain() { + return Collections.unmodifiableList(this.criteriaChain); + } + + /** + * Sets the negating flag + * + * @return this object + */ + public Criteria not() { + this.negating = true; + return this; + } + + public boolean isNegating() { + return this.negating; + } + + /** + * Sets the boost factor. + * + * @param boost boost factor + * @return this object + */ + public Criteria boost(float boost) { + + Assert.isTrue(boost >= 0, "boost must not be negative"); + + this.boost = boost; + return this; + } + + public float getBoost() { + return this.boost; + } + + public boolean isAnd() { + return getOperator() == Operator.AND; + } + public boolean isOr() { + return getOperator() == Operator.OR; + } + + /** + * @return the set ob subCriteria + * @since 4.1 + */ + public Set getSubCriteria() { + return subCriteria; + } + + // endregion + + // region criteria chaining /** - * Chain using {@code AND} + * Chain a new and-Criteria * - * @param field - * @return + * @param field the field for the new Criteria + * @return the new chained Criteria */ public Criteria and(Field field) { - return new Criteria(this.criteriaChain, field); + return new Criteria(criteriaChain, field); } /** - * Chain using {@code AND} + * Chain a new and- Criteria * - * @param fieldName - * @return + * @param fieldName the field for the new Criteria + * @return the new chained Criteria */ public Criteria and(String fieldName) { - return new Criteria(this.criteriaChain, fieldName); + return new Criteria(criteriaChain, fieldName); } /** - * Chain using {@code AND} + * Chain a Criteria to this object. * - * @param criteria - * @return + * @param criteria the Criteria to add + * @return this object */ public Criteria and(Criteria criteria) { + + Assert.notNull(criteria, "Cannot chain 'null' criteria."); + this.criteriaChain.add(criteria); return this; } /** - * Chain using {@code AND} + * Chain an array of Criteria to this object. * - * @param criterias - * @return + * @param criterias the Criteria to add + * @return this object */ public Criteria and(Criteria... criterias) { + + Assert.notNull(criterias, "Cannot chain 'null' criterias."); + this.criteriaChain.addAll(Arrays.asList(criterias)); return this; } /** - * Chain using {@code OR} + * Chain a new or-Criteria * - * @param field - * @return + * @param field the field for the new Criteria + * @return the new chained Criteria */ public Criteria or(Field field) { return new OrCriteria(this.criteriaChain, field); } /** - * Chain using {@code OR} + * Chain a new or-Criteria + * + * @param fieldName the field for the new Criteria + * @return the new chained Criteria + */ + public Criteria or(String fieldName) { + return or(new SimpleField(fieldName)); + } + + /** + * Chain a new or-Criteria. The new Criteria uses the {@link #getField()}, {@link #getQueryCriteriaEntries()} and + * {@link #getFilterCriteriaEntries()} of the passed in parameter. the new created criteria is added to the criteria + * chain. * - * @param criteria - * @return + * @param criteria contains the information for the new Criteria + * @return the new chained criteria */ public Criteria or(Criteria criteria) { + Assert.notNull(criteria, "Cannot chain 'null' criteria."); + Assert.notNull(criteria.getField(), "Cannot chain Criteria with no field"); - Criteria orConnectedCritiera = new OrCriteria(this.criteriaChain, criteria.getField()); - orConnectedCritiera.queryCriteria.addAll(criteria.queryCriteria); - return orConnectedCritiera; + Criteria orCriteria = new OrCriteria(this.criteriaChain, criteria.getField()); + orCriteria.queryCriteriaEntries.addAll(criteria.queryCriteriaEntries); + orCriteria.filterCriteriaEntries.addAll(criteria.filterCriteriaEntries); + return orCriteria; } /** - * Chain using {@code OR} - * - * @param fieldName - * @return + * adds a Criteria as subCriteria + * + * @param criteria the criteria to add, must not be {@literal null} + * @return this object + * @since 4.1 */ - public Criteria or(String fieldName) { - return or(new SimpleField(fieldName)); + public Criteria subCriteria(Criteria criteria) { + + Assert.notNull(criteria, "criteria must not be null"); + + subCriteria.add(criteria); + return this; } + // endregion + + // region criteria entries - query /** - * Crates new CriteriaEntry without any wildcards + * Add a {@link OperationKey#EQUALS} entry to the {@link #queryCriteriaEntries} * - * @param o - * @return + * @param o the argument to the operation + * @return this object */ public Criteria is(Object o) { - queryCriteria.add(new CriteriaEntry(OperationKey.EQUALS, o)); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EQUALS, o)); return this; } /** - * Creates a new CriteriaEntry for existence check. - * + * Add a {@link OperationKey#EXISTS} entry to the {@link #queryCriteriaEntries} + * * @return this object * @since 4.0 */ public Criteria exists() { - queryCriteria.add(new CriteriaEntry(OperationKey.EXISTS, null)); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXISTS)); return this; } /** - * Crates new CriteriaEntry with leading and trailing wildcards
- * NOTE: mind your schema as leading wildcards may not be supported and/or execution might be slow. + * Adds a OperationKey.BETWEEN entry to the {@link #queryCriteriaEntries}. Only one of the parameters may be null to + * define an unbounded end of the range. * - * @param s - * @return + * @param lowerBound the lower bound of the range, null for unbounded + * @param upperBound the upper bound of the range, null for unbounded + * @return this object */ - public Criteria contains(String s) { - assertNoBlankInWildcardedQuery(s, true, true); - queryCriteria.add(new CriteriaEntry(OperationKey.CONTAINS, s)); + public Criteria between(@Nullable Object lowerBound, @Nullable Object upperBound) { + + if (lowerBound == null && upperBound == null) { + throw new InvalidDataAccessApiUsageException("Range [* TO *] is not allowed"); + } + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound })); return this; } /** - * Crates new CriteriaEntry with trailing wildcard + * Add a {@link OperationKey#STARTS_WITH} entry to the {@link #queryCriteriaEntries} * - * @param s - * @return + * @param s the argument to the operation + * @return this object */ public Criteria startsWith(String s) { - assertNoBlankInWildcardedQuery(s, true, false); - queryCriteria.add(new CriteriaEntry(OperationKey.STARTS_WITH, s)); + + Assert.notNull(s, "s may not be null"); + + assertNoBlankInWildcardQuery(s, true, false); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.STARTS_WITH, s)); return this; } /** - * Crates new CriteriaEntry with leading wildcard
- * NOTE: mind your schema and execution times as leading wildcards may not be supported. + * Add a {@link OperationKey#CONTAINS} entry to the {@link #queryCriteriaEntries}
+ * NOTE: mind your schema as leading wildcards may not be supported and/or execution might be slow. * - * @param s - * @return + * @param s the argument to the operation + * @return this object */ - public Criteria endsWith(String s) { - assertNoBlankInWildcardedQuery(s, false, true); - queryCriteria.add(new CriteriaEntry(OperationKey.ENDS_WITH, s)); + public Criteria contains(String s) { + + Assert.notNull(s, "s may not be null"); + + assertNoBlankInWildcardQuery(s, true, true); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.CONTAINS, s)); return this; } /** - * Crates new CriteriaEntry with trailing - + * Add a {@link OperationKey#ENDS_WITH} entry to the {@link #queryCriteriaEntries}
+ * NOTE: mind your schema as leading wildcards may not be supported and/or execution might be slow. * - * @return + * @param s the argument to the operation + * @return this object */ - public Criteria not() { - this.negating = true; + public Criteria endsWith(String s) { + + Assert.notNull(s, "s may not be null"); + + assertNoBlankInWildcardQuery(s, false, true); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.ENDS_WITH, s)); return this; } /** - * Crates new CriteriaEntry with trailing ~ + * Add a {@link OperationKey#IN} entry to the {@link #queryCriteriaEntries}. This will create a terms query, so don't + * use it with text fields as these are analyzed and changed by Elasticsearch (converted to lowercase with the default + * analyzer). If used for Strings, these should be marked a sfield type Keyword. * - * @param s - * @return + * @param values the argument to the operation + * @return this object */ - public Criteria fuzzy(String s) { - queryCriteria.add(new CriteriaEntry(OperationKey.FUZZY, s)); - return this; + public Criteria in(Object... values) { + return in(toCollection(values)); } /** - * Crates new CriteriaEntry allowing native elasticsearch expressions + * Add a {@link OperationKey#IN} entry to the {@link #queryCriteriaEntries}. See the comment at + * {@link Criteria#in(Object...)}. * - * @param s - * @return + * @param values the argument to the operation + * @return this object */ - public Criteria expression(String s) { - queryCriteria.add(new CriteriaEntry(OperationKey.EXPRESSION, s)); + public Criteria in(Iterable values) { + + Assert.notNull(values, "Collection of 'in' values must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.IN, values)); return this; } /** - * Boost positive hit with given factor. eg. ^2.3 + * Add a {@link OperationKey#NOT_IN} entry to the {@link #queryCriteriaEntries}. See the comment at + * {@link Criteria#in(Object...)}. * - * @param boost - * @return + * @param values the argument to the operation + * @return this object */ - public Criteria boost(float boost) { - if (boost < 0) { - throw new InvalidDataAccessApiUsageException("Boost must not be negative."); - } - this.boost = boost; - return this; + public Criteria notIn(Object... values) { + return notIn(toCollection(values)); } /** - * Crates new CriteriaEntry for {@code RANGE [lowerBound TO upperBound]} + * Add a {@link OperationKey#NOT_IN} entry to the {@link #queryCriteriaEntries}. See the comment at + * {@link Criteria#in(Object...)}. * - * @param lowerBound - * @param upperBound - * @return + * @param values the argument to the operation + * @return this object */ - public Criteria between(Object lowerBound, Object upperBound) { - if (lowerBound == null && upperBound == null) { - throw new InvalidDataAccessApiUsageException("Range [* TO *] is not allowed"); - } + public Criteria notIn(Iterable values) { - queryCriteria.add(new CriteriaEntry(OperationKey.BETWEEN, new Object[] { lowerBound, upperBound })); + Assert.notNull(values, "Collection of 'NotIn' values must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.NOT_IN, values)); return this; } /** - * Crates new CriteriaEntry for {@code RANGE [* TO upperBound]} + * Add a {@link OperationKey#EXPRESSION} entry to the {@link #queryCriteriaEntries} allowing native elasticsearch + * expressions * - * @param upperBound - * @return + * @param s the argument to the operation + * @return this object */ - public Criteria lessThanEqual(Object upperBound) { - if (upperBound == null) { - throw new InvalidDataAccessApiUsageException("UpperBound can't be null"); - } - queryCriteria.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound)); + public Criteria expression(String s) { + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.EXPRESSION, s)); return this; } - public Criteria lessThan(Object upperBound) { - if (upperBound == null) { - throw new InvalidDataAccessApiUsageException("UpperBound can't be null"); - } - queryCriteria.add(new CriteriaEntry(OperationKey.LESS, upperBound)); + /** + * Add a {@link OperationKey#FUZZY} entry to the {@link #queryCriteriaEntries} + * + * @param s the argument to the operation + * @return this object + */ + public Criteria fuzzy(String s) { + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.FUZZY, s)); return this; } /** - * Crates new CriteriaEntry for {@code RANGE [lowerBound TO *]} + * Add a {@link OperationKey#LESS_EQUAL} entry to the {@link #queryCriteriaEntries} * - * @param lowerBound - * @return + * @param upperBound the argument to the operation + * @return this object */ - public Criteria greaterThanEqual(Object lowerBound) { - if (lowerBound == null) { - throw new InvalidDataAccessApiUsageException("LowerBound can't be null"); - } - queryCriteria.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound)); - return this; - } + public Criteria lessThanEqual(Object upperBound) { - public Criteria greaterThan(Object lowerBound) { - if (lowerBound == null) { - throw new InvalidDataAccessApiUsageException("LowerBound can't be null"); - } - queryCriteria.add(new CriteriaEntry(OperationKey.GREATER, lowerBound)); + Assert.notNull(upperBound, "upperBound must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS_EQUAL, upperBound)); return this; } /** - * Crates new CriteriaEntry for multiple values {@code (arg0 arg1 arg2 ...)} + * Add a {@link OperationKey#LESS} entry to the {@link #queryCriteriaEntries} * - * @param values - * @return + * @param upperBound the argument to the operation + * @return this object */ - public Criteria in(Object... values) { - return in(toCollection(values)); + public Criteria lessThan(Object upperBound) { + + Assert.notNull(upperBound, "upperBound must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.LESS, upperBound)); + return this; } /** - * Crates new CriteriaEntry for multiple values {@code (arg0 arg1 arg2 ...)} + * Add a {@link OperationKey#GREATER_EQUAL} entry to the {@link #queryCriteriaEntries} * - * @param values the collection containing the values to match against - * @return + * @param lowerBound the argument to the operation + * @return this object */ - public Criteria in(Iterable values) { - Assert.notNull(values, "Collection of 'in' values must not be null"); - queryCriteria.add(new CriteriaEntry(OperationKey.IN, values)); - return this; - } - - private List toCollection(Object... values) { - if (values.length == 0 || (values.length > 1 && values[1] instanceof Collection)) { - throw new InvalidDataAccessApiUsageException( - "At least one element " + (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "") - + " has to be present."); - } - return Arrays.asList(values); - } + public Criteria greaterThanEqual(Object lowerBound) { - public Criteria notIn(Object... values) { - return notIn(toCollection(values)); - } + Assert.notNull(lowerBound, "lowerBound must not be null"); - public Criteria notIn(Iterable values) { - Assert.notNull(values, "Collection of 'NotIn' values must not be null"); - queryCriteria.add(new CriteriaEntry(OperationKey.NOT_IN, values)); + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER_EQUAL, lowerBound)); return this; } /** - * Creates new CriteriaEntry for {@code location WITHIN distance} + * Add a {@link OperationKey#GREATER} entry to the {@link #queryCriteriaEntries} * - * @param location {@link org.springframework.data.elasticsearch.core.geo.GeoPoint} center coordinates - * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be - * set - * @return Criteria the chaind criteria with the new 'within' criteria included. + * @param lowerBound the argument to the operation + * @return this object */ - public Criteria within(GeoPoint location, String distance) { - Assert.notNull(location, "Location value for near criteria must not be null"); - Assert.notNull(location, "Distance value for near criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); + public Criteria greaterThan(Object lowerBound) { + + Assert.notNull(lowerBound, "lowerBound must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.GREATER, lowerBound)); return this; } /** - * Creates new CriteriaEntry for {@code location WITHIN distance} - * - * @param location {@link org.springframework.data.geo.Point} center coordinates - * @param distance {@link org.springframework.data.geo.Distance} radius . - * @return Criteria the chaind criteria with the new 'within' criteria included. + * Add a {@link OperationKey#MATCHES} entry to the {@link #queryCriteriaEntries}. This will build a match query with + * the OR operator. + * + * @param value the value to match + * @return this object + * @since 4.1 */ - public Criteria within(Point location, Distance distance) { - Assert.notNull(location, "Location value for near criteria must not be null"); - Assert.notNull(location, "Distance value for near criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); + public Criteria matches(Object value) { + + Assert.notNull(value, "value must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES, value)); return this; } /** - * Creates new CriteriaEntry for {@code geoLocation WITHIN distance} + * Add a {@link OperationKey#MATCHES} entry to the {@link #queryCriteriaEntries}. This will build a match query with + * the AND operator. * - * @param geoLocation {@link String} center point supported formats: lat on = > "41.2,45.1", geohash = > "asd9as0d" - * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be - * set - * @return + * @param value the value to match + * @return this object + * @since 4.1 */ - public Criteria within(String geoLocation, String distance) { - Assert.isTrue(!StringUtils.isEmpty(geoLocation), "geoLocation value must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance })); + public Criteria matchesAll(Object value) { + + Assert.notNull(value, "value must not be null"); + + queryCriteriaEntries.add(new CriteriaEntry(OperationKey.MATCHES_ALL, value)); return this; } + // endregion + // region criteria entries - filter /** - * Creates new CriteriaEntry for {@code location GeoBox bounding box} + * Adds a new filter CriteriaEntry for {@code location GeoBox bounding box} * * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + * right bottom corner) - * @return Criteria the chaind criteria with the new 'boundingBox' criteria included. + * @return this object */ public Criteria boundedBy(GeoBox boundingBox) { + Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox })); + + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox })); return this; } /** - * Creates new CriteriaEntry for {@code location Box bounding box} + * Adds a new filter CriteriaEntry for {@code location Box bounding box} * * @param boundingBox {@link org.springframework.data.elasticsearch.core.geo.GeoBox} bounding box(left top corner + * right bottom corner) - * @return Criteria the chaind criteria with the new 'boundingBox' criteria included. + * @return this object */ public Criteria boundedBy(Box boundingBox) { + Assert.notNull(boundingBox, "boundingBox value for boundedBy criteria must not be null"); - filterCriteria + + filterCriteriaEntries .add(new CriteriaEntry(OperationKey.BBOX, new Object[] { boundingBox.getFirst(), boundingBox.getSecond() })); return this; } /** - * Creates new CriteriaEntry for bounding box created from points + * Adds a new filter CriteriaEntry for bounding box created from points * * @param topLeftGeohash left top corner of bounding box as geohash * @param bottomRightGeohash right bottom corner of bounding box as geohash - * @return Criteria the chaind criteria with the new 'boundedBy' criteria included. + * @return this object */ public Criteria boundedBy(String topLeftGeohash, String bottomRightGeohash) { + Assert.isTrue(!StringUtils.isEmpty(topLeftGeohash), "topLeftGeohash must not be empty"); Assert.isTrue(!StringUtils.isEmpty(bottomRightGeohash), "bottomRightGeohash must not be empty"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash })); + + filterCriteriaEntries + .add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftGeohash, bottomRightGeohash })); return this; } /** - * Creates new CriteriaEntry for bounding box created from points + * Adds a new filter CriteriaEntry for bounding box created from points * * @param topLeftPoint left top corner of bounding box * @param bottomRightPoint right bottom corner of bounding box - * @return Criteria the chaind criteria with the new 'boundedBy' criteria included. + * @return this object */ public Criteria boundedBy(GeoPoint topLeftPoint, GeoPoint bottomRightPoint) { + Assert.notNull(topLeftPoint, "topLeftPoint must not be null"); Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint })); + + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { topLeftPoint, bottomRightPoint })); return this; } + /** + * Adds a new filter CriteriaEntry for bounding box created from points + * + * @param topLeftPoint left top corner of bounding box + * @param bottomRightPoint right bottom corner of bounding box + * @return this object + */ public Criteria boundedBy(Point topLeftPoint, Point bottomRightPoint) { + Assert.notNull(topLeftPoint, "topLeftPoint must not be null"); Assert.notNull(bottomRightPoint, "bottomRightPoint must not be null"); - filterCriteria.add(new CriteriaEntry(OperationKey.BBOX, + + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.BBOX, new Object[] { GeoPoint.fromPoint(topLeftPoint), GeoPoint.fromPoint(bottomRightPoint) })); return this; } - private void assertNoBlankInWildcardedQuery(String searchString, boolean leadingWildcard, boolean trailingWildcard) { - if (searchString != null && searchString.contains(CRITERIA_VALUE_SEPERATOR)) { - throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + '"' - + searchString + '"' + (trailingWildcard ? "*" : "") + "'. Use expression or multiple clauses instead."); - } - } - /** - * Field targeted by this Criteria + * Adds a new filter CriteriaEntry for {@code location WITHIN distance} * - * @return + * @param location {@link org.springframework.data.elasticsearch.core.geo.GeoPoint} center coordinates + * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be + * set + * @return this object */ - @Nullable - public Field getField() { - return this.field; - } + public Criteria within(GeoPoint location, String distance) { - public Set getQueryCriteriaEntries() { - return Collections.unmodifiableSet(this.queryCriteria); - } + Assert.notNull(location, "Location value for near criteria must not be null"); + Assert.notNull(location, "Distance value for near criteria must not be null"); - public Set getFilterCriteriaEntries() { - return Collections.unmodifiableSet(this.filterCriteria); + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); + return this; } - public Set getFilterCriteria() { - return filterCriteria; + /** + * Adds a new filter CriteriaEntry for {@code location WITHIN distance} + * + * @param location {@link org.springframework.data.geo.Point} center coordinates + * @param distance {@link org.springframework.data.geo.Distance} radius . + * @return this object + */ + public Criteria within(Point location, Distance distance) { + + Assert.notNull(location, "Location value for near criteria must not be null"); + Assert.notNull(location, "Distance value for near criteria must not be null"); + + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { location, distance })); + return this; } /** - * Conjunction to be used with this criteria (AND | OR) + * Adds a new filter CriteriaEntry for {@code geoLocation WITHIN distance} * - * @return + * @param geoLocation {@link String} center point supported formats: lat on = > "41.2,45.1", geohash = > "asd9as0d" + * @param distance {@link String} radius as a string (e.g. : '100km'). Distance unit : either mi/miles or km can be + * set + * @return this object */ - public String getConjunctionOperator() { - return AND_OPERATOR; + public Criteria within(String geoLocation, String distance) { + + Assert.isTrue(!StringUtils.isEmpty(geoLocation), "geoLocation value must not be null"); + + filterCriteriaEntries.add(new CriteriaEntry(OperationKey.WITHIN, new Object[] { geoLocation, distance })); + return this; } - public List getCriteriaChain() { - return Collections.unmodifiableList(this.criteriaChain); + // endregion + + // region helper functions + private void assertNoBlankInWildcardQuery(String searchString, boolean leadingWildcard, boolean trailingWildcard) { + + if (searchString.contains(CRITERIA_VALUE_SEPARATOR)) { + throw new InvalidDataAccessApiUsageException("Cannot constructQuery '" + (leadingWildcard ? "*" : "") + '"' + + searchString + '"' + (trailingWildcard ? "*" : "") + "'. Use expression or multiple clauses instead."); + } } - public boolean isNegating() { - return this.negating; + private List toCollection(Object... values) { + if (values.length == 0 || (values.length > 1 && values[1] instanceof Collection)) { + throw new InvalidDataAccessApiUsageException( + "At least one element " + (values.length > 0 ? ("of argument of type " + values[1].getClass().getName()) : "") + + " has to be present."); + } + return Arrays.asList(values); } - public boolean isAnd() { - return AND_OPERATOR == getConjunctionOperator(); + // endregion + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + Criteria criteria = (Criteria) o; + + if (Float.compare(criteria.boost, boost) != 0) + return false; + if (negating != criteria.negating) + return false; + if (!Objects.equals(field, criteria.field)) + return false; + if (!queryCriteriaEntries.equals(criteria.queryCriteriaEntries)) + return false; + if (!filterCriteriaEntries.equals(criteria.filterCriteriaEntries)) + return false; + return subCriteria.equals(criteria.subCriteria); } - public boolean isOr() { - return OR_OPERATOR == getConjunctionOperator(); + @Override + public int hashCode() { + int result = field != null ? field.hashCode() : 0; + result = 31 * result + (boost != +0.0f ? Float.floatToIntBits(boost) : 0); + result = 31 * result + (negating ? 1 : 0); + result = 31 * result + queryCriteriaEntries.hashCode(); + result = 31 * result + filterCriteriaEntries.hashCode(); + result = 31 * result + subCriteria.hashCode(); + return result; } - public float getBoost() { - return this.boost; + @Override + public String toString() { + return "Criteria{" + // + "field=" + field + // + ", boost=" + boost + // + ", negating=" + negating + // + ", queryCriteriaEntries=" + queryCriteriaEntries + // + ", filterCriteriaEntries=" + filterCriteriaEntries + // + ", subCriteria=" + subCriteria + // + '}'; // } + @SuppressWarnings("unused") static class OrCriteria extends Criteria { public OrCriteria() { super(); } + public OrCriteria(String fieldName) { + super(fieldName); + } + public OrCriteria(Field field) { super(field); } - public OrCriteria(List criteriaChain, Field field) { - super(criteriaChain, field); + public OrCriteria(List criteriaChain, String fieldName) { + super(criteriaChain, fieldName); } - public OrCriteria(List criteriaChain, String fieldname) { - super(criteriaChain, fieldname); + public OrCriteria(List criteriaChain, Field field) { + super(criteriaChain, field); } - public OrCriteria(String fieldname) { - super(fieldname); + @Override + public String getConjunctionOperator() { + return Operator.OR.name(); } @Override - public String getConjunctionOperator() { - return OR_OPERATOR; + public Operator getOperator() { + return Operator.OR; } } + /** + * a list of {@link Criteria} objects that belong to one query. + * + * @since 4.1 + */ + public static class CriteriaChain extends LinkedList {} + + /** + * Operator to join the entries of the criteria chain + */ + public enum Operator { + AND, // + OR // + } + public enum OperationKey { // EQUALS, // CONTAINS, // @@ -611,11 +855,18 @@ public enum OperationKey { // EXPRESSION, // BETWEEN, // FUZZY, // + /** + * @since 4.1 + */ + MATCHES, // + /** + * @since 4.1 + */ + MATCHES_ALL, // IN, // NOT_IN, // WITHIN, // BBOX, // - NEAR, // LESS, // LESS_EQUAL, // GREATER, // @@ -623,16 +874,29 @@ public enum OperationKey { // /** * @since 4.0 */ - EXISTS + EXISTS // } + /** + * A class defining a single operation and it's argument value for the field of a {@link Criteria}. + */ public static class CriteriaEntry { - private OperationKey key; + private final OperationKey key; + @Nullable private Object value; + + protected CriteriaEntry(OperationKey key) { - private Object value; + Assert.isTrue(key == OperationKey.EXISTS, "key must be OperationKey.EXISTS for this call"); + + this.key = key; + } CriteriaEntry(OperationKey key, Object value) { + + Assert.notNull(key, "key must not be null"); + Assert.notNull(value, "value must not be null"); + this.key = key; this.value = value; } @@ -642,13 +906,41 @@ public OperationKey getKey() { } public void setValue(Object value) { + + Assert.notNull(value, "value must not be null"); + this.value = value; } public Object getValue() { + + Assert.isTrue(key != OperationKey.EXISTS, key.name() + " has no value"); + Assert.notNull(value, "unexpected null value"); + return value; } + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + CriteriaEntry that = (CriteriaEntry) o; + + if (key != that.key) + return false; + return Objects.equals(value, that.value); + } + + @Override + public int hashCode() { + int result = key.hashCode(); + result = 31 * result + (value != null ? value.hashCode() : 0); + return result; + } + @Override public String toString() { return "CriteriaEntry{" + "key=" + key + ", value=" + value + '}'; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index bf4503492..f9fed6a69 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -18,7 +18,8 @@ import org.springframework.util.Assert; /** - * The most trivial implementation of a Field + * The most trivial implementation of a Field. The {@link #name} is updateable, so it may be changed during query + * preparation by the {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. * * @author Rizwan Idrees * @author Mohsin Husen @@ -29,25 +30,27 @@ public class SimpleField implements Field { private String name; public SimpleField(String name) { - Assert.notNull(name, "name must not be null"); + + Assert.hasText(name, "name must not be null"); this.name = name; } @Override public void setName(String name) { - Assert.notNull(name, "name must not be null"); + + Assert.hasText(name, "name must not be null"); this.name = name; } @Override public String getName() { - return this.name; + return name; } @Override public String toString() { - return this.name; + return getName(); } } diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java index 8eac98132..97567dec3 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/parser/ElasticsearchQueryCreator.java @@ -96,13 +96,10 @@ protected CriteriaQuery complete(@Nullable CriteriaQuery query, Sort sort) { return query.addSort(sort); } - private Criteria from(Part part, Criteria instance, Iterator parameters) { + private Criteria from(Part part, Criteria criteria, Iterator parameters) { + Part.Type type = part.getType(); - Criteria criteria = instance; - if (criteria == null) { - criteria = new Criteria(); - } switch (type) { case TRUE: return criteria.is(true); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java index d7a6c913f..00d49da8c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryMappingTests.java @@ -56,12 +56,15 @@ void setUp() { } - @Test + @Test // DATAES-716 void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException { // use POJO properties and types in the query building - CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("birthDate") - .between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)).or("birthDate").is(LocalDate.of(2019, 12, 28))); + CriteriaQuery criteriaQuery = new CriteriaQuery( // + new Criteria("birthDate") // + .between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)) // + .or("birthDate").is(LocalDate.of(2019, 12, 28)) // + ); // mapped field name and converted parameter String expected = '{' + // @@ -90,7 +93,60 @@ void shouldMapNamesAndConvertValuesInCriteriaQuery() throws JSONException { '}'; // mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class); - String queryString = new CriteriaQueryProcessor().createQueryFromCriteria(criteriaQuery.getCriteria()).toString(); + String queryString = new CriteriaQueryProcessor().createQuery(criteriaQuery.getCriteria()).toString(); + + assertEquals(expected, queryString, false); + } + + @Test // DATAES-706 + void shouldMapNamesAndValuesInSubCriteriaQuery() throws JSONException { + + CriteriaQuery criteriaQuery = new CriteriaQuery( // + new Criteria("firstName").matches("John") // + .subCriteria(new Criteria("birthDate") // + .between(LocalDate.of(1989, 11, 9), LocalDate.of(1990, 11, 9)) // + .or("birthDate").is(LocalDate.of(2019, 12, 28)))); + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"match\": {\n" + // + " \"first-name\": {\n" + // + " \"query\": \"John\"\n" + // + " }\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"range\": {\n" + // + " \"birth-date\": {\n" + // + " \"from\": \"09.11.1989\",\n" + // + " \"to\": \"09.11.1990\",\n" + // + " \"include_lower\": true,\n" + // + " \"include_upper\": true\n" + // + " }\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"28.12.2019\",\n" + // + " \"fields\": [\n" + // + " \"birth-date^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}\n"; // + + mappingElasticsearchConverter.updateQuery(criteriaQuery, Person.class); + String queryString = new CriteriaQueryProcessor().createQuery(criteriaQuery.getCriteria()).toString(); assertEquals(expected, queryString, false); } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessorTests.java b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessorTests.java new file mode 100644 index 000000000..ccf07c596 --- /dev/null +++ b/src/test/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessorTests.java @@ -0,0 +1,341 @@ +/* + * Copyright 2020 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; + +import static org.skyscreamer.jsonassert.JSONAssert.*; + +import org.json.JSONException; +import org.junit.jupiter.api.Test; +import org.springframework.data.elasticsearch.core.query.Criteria; + +/** + * @author Peter-Josef Meisch + */ +class CriteriaQueryProcessorTests { + + private final CriteriaQueryProcessor queryProcessor = new CriteriaQueryProcessor(); + + @Test // DATAES-706 + void shouldProcessTwoCriteriaWithAnd() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value1\",\n" + // + " \"fields\": [\n" + // + " \"field1^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value2\",\n" + // + " \"fields\": [\n" + // + " \"field2^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}"; // + + Criteria criteria = new Criteria("field1").is("value1").and("field2").is("value2"); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldProcessTwoCriteriaWithOr() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value1\",\n" + // + " \"fields\": [\n" + // + " \"field1^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value2\",\n" + // + " \"fields\": [\n" + // + " \"field2^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}"; // + + Criteria criteria = new Criteria("field1").is("value1").or("field2").is("value2"); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldProcessMixedCriteriaWithOrAnd() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value1\",\n" + // + " \"fields\": [\n" + // + " \"field1^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value3\",\n" + // + " \"fields\": [\n" + // + " \"field3^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ],\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value2\",\n" + // + " \"fields\": [\n" + // + " \"field2^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"value4\",\n" + // + " \"fields\": [\n" + // + " \"field4^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}\n"; // + + Criteria criteria = new Criteria("field1").is("value1") // + .or("field2").is("value2") // + .and("field3").is("value3") // + .or("field4").is("value4"); // + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldAddSubQuery() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Miller\",\n" + // + " \"fields\": [\n" + // + " \"lastName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"John\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Jack\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}"; // + + Criteria criteria = new Criteria("lastName").is("Miller") + .subCriteria(new Criteria().or("firstName").is("John").or("firstName").is("Jack")); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldProcessNestedSubCriteria() throws JSONException { + + String expected = "{\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Miller\",\n" + // + " \"fields\": [\n" + // + " \"lastName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Jack\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"John\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Smith\",\n" + // + " \"fields\": [\n" + // + " \"lastName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"bool\": {\n" + // + " \"should\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Emma\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " },\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"Lucy\",\n" + // + " \"fields\": [\n" + // + " \"firstName^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}"; // + + Criteria criteria = Criteria.or() + .subCriteria(new Criteria("lastName").is("Miller") + .subCriteria(new Criteria().or("firstName").is("John").or("firstName").is("Jack"))) + .subCriteria(new Criteria("lastName").is("Smith") + .subCriteria(new Criteria().or("firstName").is("Emma").or("firstName").is("Lucy"))); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldBuildMatchQuery() throws JSONException { + + String expected = "{\n" + // + " \"bool\" : {\n" + // + " \"must\" : [\n" + // + " {\n" + // + " \"match\" : {\n" + // + " \"field1\" : {\n" + // + " \"query\" : \"value1 value2\",\n" + // + " \"operator\" : \"OR\"\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}\n"; // + + Criteria criteria = new Criteria("field1").matches("value1 value2"); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } + + @Test // DATAES-706 + void shouldBuildMatchAllQuery() throws JSONException { + + String expected = "{\n" + // + " \"bool\" : {\n" + // + " \"must\" : [\n" + // + " {\n" + // + " \"match\" : {\n" + // + " \"field1\" : {\n" + // + " \"query\" : \"value1 value2\",\n" + // + " \"operator\" : \"AND\"\n" + // + " }\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + "}\n"; // + + Criteria criteria = new Criteria("field1").matchesAll("value1 value2"); + + String query = queryProcessor.createQuery(criteria).toString(); + + assertEquals(expected, query, false); + } +} diff --git a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java index 516c64b5f..149a01f1b 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/query/CriteriaQueryTests.java @@ -83,99 +83,72 @@ void after() { indexOperations.delete(); } - @Test - public void shouldPerformAndOperation() { + @Test // ,DATAES-706 + public void shouldPerformAndOperationOnCriteriaEntries() { // given - String documentId = nextIdAsString(); - SampleEntity sampleEntity = new SampleEntity(); - sampleEntity.setId(documentId); - sampleEntity.setMessage("some test message"); - sampleEntity.setVersion(System.currentTimeMillis()); - - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(documentId); - indexQuery.setObject(sampleEntity); - operations.index(indexQuery, index); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(nextIdAsString()); + sampleEntity1.setMessage("some test message"); + operations.save(sampleEntity1); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(nextIdAsString()); + sampleEntity2.setMessage("some other message"); + operations.save(sampleEntity2); indexOperations.refresh(); - CriteriaQuery criteriaQuery = new CriteriaQuery( - new Criteria("message").contains("test").and("message").contains("some")); // when - SearchHit sampleEntity1 = operations.searchOne(criteriaQuery, SampleEntity.class, index); + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("message").contains("test").and("message").contains("some")); + SearchHit searchHit = operations.searchOne(criteriaQuery, SampleEntity.class, index); // then - assertThat(sampleEntity1).isNotNull(); + assertThat(searchHit).isNotNull(); + assertThat(searchHit.getId()).isEqualTo(sampleEntity1.id); } - // @Ignore("DATAES-30") - @Test - public void shouldPerformOrOperation() { + @Test // ,DATAES-706 + public void shouldPerformOrOperationOnCriteriaEntries() { // given - List indexQueries = new ArrayList<>(); - - // first document - String documentId = nextIdAsString(); SampleEntity sampleEntity1 = new SampleEntity(); - sampleEntity1.setId(documentId); - sampleEntity1.setMessage("some message"); - sampleEntity1.setVersion(System.currentTimeMillis()); - - IndexQuery indexQuery1 = new IndexQuery(); - indexQuery1.setId(documentId); - indexQuery1.setObject(sampleEntity1); - indexQueries.add(indexQuery1); - - // second document - String documentId2 = nextIdAsString(); + sampleEntity1.setId(nextIdAsString()); + sampleEntity1.setMessage("some test message"); + operations.save(sampleEntity1); SampleEntity sampleEntity2 = new SampleEntity(); - sampleEntity2.setId(documentId2); - sampleEntity2.setMessage("test message"); - sampleEntity2.setVersion(System.currentTimeMillis()); - - IndexQuery indexQuery2 = new IndexQuery(); - indexQuery2.setId(documentId2); - indexQuery2.setObject(sampleEntity2); - - indexQueries.add(indexQuery2); - operations.bulkIndex(indexQueries, index); + sampleEntity2.setId(nextIdAsString()); + sampleEntity2.setMessage("some other message"); + operations.save(sampleEntity2); indexOperations.refresh(); - CriteriaQuery criteriaQuery = new CriteriaQuery( - new Criteria("message").contains("some").or("message").contains("test")); // when + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("message").contains("test").or("message").contains("other")); SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then assertThat(searchHits).isNotNull(); - assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getSearchHits().stream().map(SearchHit::getId)).containsExactlyInAnyOrder(sampleEntity1.id, + sampleEntity2.id); } - @Test + @Test // ,DATAES-706 public void shouldPerformAndOperationWithinCriteria() { // given - List indexQueries = new ArrayList<>(); - - // first document - String documentId = nextIdAsString(); - SampleEntity sampleEntity = new SampleEntity(); - sampleEntity.setId(documentId); - sampleEntity.setMessage("some message"); - sampleEntity.setVersion(System.currentTimeMillis()); - - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(documentId); - indexQuery.setObject(sampleEntity); - indexQueries.add(indexQuery); - - operations.bulkIndex(indexQueries, index); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(nextIdAsString()); + sampleEntity1.setMessage("some test message"); + operations.save(sampleEntity1); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(nextIdAsString()); + sampleEntity2.setMessage("some other message"); + operations.save(sampleEntity2); indexOperations.refresh(); - CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().and(new Criteria("message").contains("some"))); // when - + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("message").contains("test").and(new Criteria("message").contains("some"))); SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then @@ -183,34 +156,29 @@ public void shouldPerformAndOperationWithinCriteria() { assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); } - @Test + @Test // ,DATAES-706 public void shouldPerformOrOperationWithinCriteria() { // given - List indexQueries = new ArrayList<>(); - - // first document - String documentId = nextIdAsString(); - SampleEntity sampleEntity = new SampleEntity(); - sampleEntity.setId(documentId); - sampleEntity.setMessage("some message"); - sampleEntity.setVersion(System.currentTimeMillis()); - - IndexQuery indexQuery = new IndexQuery(); - indexQuery.setId(documentId); - indexQuery.setObject(sampleEntity); - indexQueries.add(indexQuery); - - operations.bulkIndex(indexQueries, index); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(nextIdAsString()); + sampleEntity1.setMessage("some test message"); + operations.save(sampleEntity1); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(nextIdAsString()); + sampleEntity2.setMessage("some other message"); + operations.save(sampleEntity2); indexOperations.refresh(); - CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria().or(new Criteria("message").contains("some"))); // when + CriteriaQuery criteriaQuery = new CriteriaQuery( + new Criteria("message").contains("test").or(new Criteria("message").contains("other"))); SearchHits searchHits = operations.search(criteriaQuery, SampleEntity.class, index); // then assertThat(searchHits).isNotNull(); - assertThat(searchHits.getTotalHits()).isGreaterThanOrEqualTo(1); + assertThat(searchHits.getSearchHits().stream().map(SearchHit::getId)).containsExactlyInAnyOrder(sampleEntity1.id, + sampleEntity2.id); } @Test diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java index df787404e..dd55e4088 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/query/ReactiveElasticsearchStringQueryUnitTests.java @@ -78,9 +78,9 @@ public void setUp() { public void bindsSimplePropertyCorrectly() throws Exception { ReactiveElasticsearchStringQuery elasticsearchStringQuery = createQueryForMethod("findByName", String.class); - StubParameterAccessor accesor = new StubParameterAccessor("Luke"); + StubParameterAccessor accessor = new StubParameterAccessor("Luke"); - org.springframework.data.elasticsearch.core.query.Query query = elasticsearchStringQuery.createQuery(accesor); + org.springframework.data.elasticsearch.core.query.Query query = elasticsearchStringQuery.createQuery(accessor); StringQuery reference = new StringQuery("{ 'bool' : { 'must' : { 'term' : { 'name' : 'Luke' } } } }"); assertThat(query).isInstanceOf(StringQuery.class); @@ -93,9 +93,9 @@ public void bindsExpressionPropertyCorrectly() throws Exception { ReactiveElasticsearchStringQuery elasticsearchStringQuery = createQueryForMethod("findByNameWithExpression", String.class); - StubParameterAccessor accesor = new StubParameterAccessor("Luke"); + StubParameterAccessor accessor = new StubParameterAccessor("Luke"); - org.springframework.data.elasticsearch.core.query.Query query = elasticsearchStringQuery.createQuery(accesor); + org.springframework.data.elasticsearch.core.query.Query query = elasticsearchStringQuery.createQuery(accessor); StringQuery reference = new StringQuery("{ 'bool' : { 'must' : { 'term' : { 'name' : 'Luke' } } } }"); assertThat(query).isInstanceOf(StringQuery.class); From c82792b34d09e26d1cbb7f46d2b848684e55aaed Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Wed, 19 Aug 2020 23:18:44 +0400 Subject: [PATCH 0245/1191] DATAES-908 - Fill version on an indexed entity. Original PR: #506 --- .../core/AbstractElasticsearchTemplate.java | 27 ++++++- .../core/ElasticsearchRestTemplate.java | 4 +- .../core/ElasticsearchTemplate.java | 5 +- .../core/IndexedObjectInformation.java | 22 ++++-- .../core/ReactiveElasticsearchTemplate.java | 41 +++++++++-- .../core/ElasticsearchTemplateTests.java | 70 +++++++++++++++++++ .../ReactiveElasticsearchTemplateTests.java | 41 ++++++++++- 7 files changed, 193 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java index 4a891ace3..2e5b29519 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/AbstractElasticsearchTemplate.java @@ -493,9 +493,10 @@ protected List checkForBulkOperationFailure(BulkRespon return Stream.of(bulkResponse.getItems()).map(bulkItemResponse -> { DocWriteResponse response = bulkItemResponse.getResponse(); if (response != null) { - return IndexedObjectInformation.of(response.getId(), response.getSeqNo(), response.getPrimaryTerm()); + return IndexedObjectInformation.of(response.getId(), response.getSeqNo(), response.getPrimaryTerm(), + response.getVersion()); } else { - return IndexedObjectInformation.of(bulkItemResponse.getId(), null, null); + return IndexedObjectInformation.of(bulkItemResponse.getId(), null, null, null); } }).collect(Collectors.toList()); @@ -511,11 +512,17 @@ protected void updateIndexedObject(Object entity, IndexedObjectInformation index propertyAccessor.setProperty(idProperty, indexedObjectInformation.getId()); } - if (persistentEntity.hasSeqNoPrimaryTermProperty()) { + if (indexedObjectInformation.getSeqNo() != null && indexedObjectInformation.getPrimaryTerm() != null + && persistentEntity.hasSeqNoPrimaryTermProperty()) { ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty(); propertyAccessor.setProperty(seqNoPrimaryTermProperty, new SeqNoPrimaryTerm(indexedObjectInformation.getSeqNo(), indexedObjectInformation.getPrimaryTerm())); } + + if (indexedObjectInformation.getVersion() != null && persistentEntity.hasVersionProperty()) { + ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); + propertyAccessor.setProperty(versionProperty, indexedObjectInformation.getVersion()); + } } ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { @@ -662,6 +669,20 @@ protected T maybeCallbackAfterConvert(T entity, Document document, IndexCoor // endregion + protected void updateIndexedObjectsWithQueries(List queries, + List indexedObjectInformations) { + for (int i = 0; i < queries.size(); i++) { + Object query = queries.get(i); + if (query instanceof IndexQuery) { + IndexQuery indexQuery = (IndexQuery) query; + Object queryObject = indexQuery.getObject(); + if (queryObject != null) { + updateIndexedObject(queryObject, indexedObjectInformations.get(i)); + } + } + } + } + // region Document callbacks protected interface DocumentCallback { @Nullable diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 033cc9abb..6a3b0db60 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -149,7 +149,8 @@ public String index(IndexQuery query, IndexCoordinates index) { Object queryObject = query.getObject(); if (queryObject != null) { updateIndexedObject(queryObject, - IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), indexResponse.getPrimaryTerm())); + IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), + indexResponse.getPrimaryTerm(), indexResponse.getVersion())); } maybeCallbackAfterSaveWithQuery(query, index); @@ -243,6 +244,7 @@ private List doBulkOperation(List queries, BulkOpti BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); List indexedObjectInformations = checkForBulkOperationFailure( execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); + updateIndexedObjectsWithQueries(queries, indexedObjectInformations); maybeCallbackAfterSaveWithQueries(queries, index); return indexedObjectInformations; } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 86124a819..493496c7e 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -163,7 +163,8 @@ public String index(IndexQuery query, IndexCoordinates index) { Object queryObject = query.getObject(); if (queryObject != null) { updateIndexedObject(queryObject, - IndexedObjectInformation.of(documentId, response.getSeqNo(), response.getPrimaryTerm())); + IndexedObjectInformation.of(documentId, response.getSeqNo(), response.getPrimaryTerm(), + response.getVersion())); } maybeCallbackAfterSaveWithQuery(query, index); @@ -210,6 +211,8 @@ public List bulkIndex(List queries, BulkOp List indexedObjectInformations = doBulkOperation(queries, bulkOptions, index); + updateIndexedObjectsWithQueries(queries, indexedObjectInformations); + maybeCallbackAfterSaveWithQueries(queries, index); return indexedObjectInformations; diff --git a/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java b/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java index 436f58e23..f3340e297 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/IndexedObjectInformation.java @@ -21,32 +21,44 @@ * Value class capturing information about a newly indexed document in Elasticsearch. * * @author Peter-Josef Meisch + * @author Roman Puchkovskiy * @since 4.1 */ public class IndexedObjectInformation { private final String id; @Nullable private final Long seqNo; @Nullable private final Long primaryTerm; + @Nullable private final Long version; - private IndexedObjectInformation(String id, @Nullable Long seqNo, @Nullable Long primaryTerm) { + private IndexedObjectInformation(String id, @Nullable Long seqNo, @Nullable Long primaryTerm, + @Nullable Long version) { this.id = id; this.seqNo = seqNo; this.primaryTerm = primaryTerm; + this.version = version; } - public static IndexedObjectInformation of(String id, @Nullable Long seqNo, @Nullable Long primaryTerm) { - return new IndexedObjectInformation(id, seqNo, primaryTerm); + public static IndexedObjectInformation of(String id, @Nullable Long seqNo, @Nullable Long primaryTerm, + @Nullable Long version) { + return new IndexedObjectInformation(id, seqNo, primaryTerm, version); } public String getId() { return id; } - public long getSeqNo() { + @Nullable + public Long getSeqNo() { return seqNo; } - public long getPrimaryTerm() { + @Nullable + public Long getPrimaryTerm() { return primaryTerm; } + + @Nullable + public Long getVersion() { + return version; + } } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index a3c8b135f..e0a4e56a8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -15,6 +15,8 @@ */ package org.springframework.data.elasticsearch.core; +import org.elasticsearch.action.DocWriteResponse; +import org.springframework.data.mapping.PersistentPropertyAccessor; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -204,9 +206,9 @@ public Mono save(T entity, IndexCoordinates index) { .map(it -> { T savedEntity = it.getT1(); IndexResponse indexResponse = it.getT2(); - AdaptibleEntity adaptableEntity = operations.forEntity(savedEntity, converter.getConversionService()); - // noinspection ReactiveStreamsNullableInLambdaInTransform - return adaptableEntity.populateIdIfNecessary(indexResponse.getId()); + return updateIndexedObject(savedEntity, + IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), + indexResponse.getPrimaryTerm(), indexResponse.getVersion())); }).flatMap(saved -> maybeCallAfterSave(saved, index)); } @@ -241,15 +243,42 @@ public Flux saveAll(Mono> entitiesPubli T savedEntity = entities.entityAt(indexAndResponse.getT1()); BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); - AdaptibleEntity adaptibleEntity = operations.forEntity(savedEntity, - converter.getConversionService()); - adaptibleEntity.populateIdIfNecessary(bulkItemResponse.getResponse().getId()); + DocWriteResponse response = bulkItemResponse.getResponse(); + updateIndexedObject(savedEntity, + IndexedObjectInformation.of(response.getId(), response.getSeqNo(), + response.getPrimaryTerm(), response.getVersion())); return maybeCallAfterSave(savedEntity, index); }); }); } + private T updateIndexedObject(T entity, IndexedObjectInformation indexedObjectInformation) { + AdaptibleEntity adaptibleEntity = operations.forEntity(entity, converter.getConversionService()); + adaptibleEntity.populateIdIfNecessary(indexedObjectInformation.getId()); + + ElasticsearchPersistentEntity persistentEntity = getRequiredPersistentEntity(entity.getClass()); + PersistentPropertyAccessor propertyAccessor = persistentEntity.getPropertyAccessor(entity); + + if (indexedObjectInformation.getSeqNo() != null && indexedObjectInformation.getPrimaryTerm() != null + && persistentEntity.hasSeqNoPrimaryTermProperty()) { + ElasticsearchPersistentProperty seqNoPrimaryTermProperty = persistentEntity.getSeqNoPrimaryTermProperty(); + propertyAccessor.setProperty(seqNoPrimaryTermProperty, + new SeqNoPrimaryTerm(indexedObjectInformation.getSeqNo(), indexedObjectInformation.getPrimaryTerm())); + } + + if (indexedObjectInformation.getVersion() != null && persistentEntity.hasVersionProperty()) { + ElasticsearchPersistentProperty versionProperty = persistentEntity.getVersionProperty(); + propertyAccessor.setProperty(versionProperty, indexedObjectInformation.getVersion()); + } + + return entity; + } + + private ElasticsearchPersistentEntity getRequiredPersistentEntity(Class clazz) { + return converter.getMappingContext().getRequiredPersistentEntity(clazz); + } + @Override public Flux multiGet(Query query, Class clazz) { return multiGet(query, clazz, getIndexCoordinatesFor(clazz)); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index 7ffda4062..c6b4d4cdb 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -37,6 +37,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -3448,6 +3449,68 @@ protected RequestFactory getRequestFactory() { return ((AbstractElasticsearchTemplate) operations).getRequestFactory(); } + @Test // DATAES-908 + void shouldFillVersionOnSaveOne() { + VersionedEntity saved = operations.save(new VersionedEntity()); + + assertThat(saved.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillVersionOnSaveIterable() { + List iterable = Arrays.asList(new VersionedEntity(), new VersionedEntity()); + Iterator results = operations.save(iterable).iterator(); + VersionedEntity saved1 = results.next(); + VersionedEntity saved2 = results.next(); + + assertThat(saved1.getVersion()).isNotNull(); + assertThat(saved2.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillVersionOnSaveArray() { + VersionedEntity[] array = {new VersionedEntity(), new VersionedEntity()}; + Iterator results = operations.save(array).iterator(); + VersionedEntity saved1 = results.next(); + VersionedEntity saved2= results.next(); + + assertThat(saved1.getVersion()).isNotNull(); + assertThat(saved2.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillVersionOnIndexOne() { + VersionedEntity entity = new VersionedEntity(); + IndexQuery query = new IndexQueryBuilder().withObject(entity).build(); + operations.index(query, operations.getIndexCoordinatesFor(VersionedEntity.class)); + + assertThat(entity.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillVersionOnBulkIndex() { + VersionedEntity entity1 = new VersionedEntity(); + VersionedEntity entity2= new VersionedEntity(); + IndexQuery query1 = new IndexQueryBuilder().withObject(entity1).build(); + IndexQuery query2 = new IndexQueryBuilder().withObject(entity2).build(); + operations.bulkIndex(Arrays.asList(query1, query2), VersionedEntity.class); + + assertThat(entity1.getVersion()).isNotNull(); + assertThat(entity2.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillSeqNoPrimaryKeyOnBulkIndex() { + OptimisticEntity entity1 = new OptimisticEntity(); + OptimisticEntity entity2 = new OptimisticEntity(); + IndexQuery query1 = new IndexQueryBuilder().withObject(entity1).build(); + IndexQuery query2 = new IndexQueryBuilder().withObject(entity2).build(); + operations.bulkIndex(Arrays.asList(query1, query2), OptimisticEntity.class); + + assertThatSeqNoPrimaryTermIsFilled(entity1); + assertThatSeqNoPrimaryTermIsFilled(entity2); + } + @Data @NoArgsConstructor @AllArgsConstructor @@ -3625,6 +3688,13 @@ static class OptimisticAndVersionedEntity { @Version private Long version; } + @Data + @Document(indexName = "test-index-versioned-entity-template") + static class VersionedEntity { + @Id private String id; + @Version private Long version; + } + @Data @NoArgsConstructor @AllArgsConstructor diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 4488ea42a..7e67883df 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -390,7 +390,9 @@ public void shouldExecuteGivenCriteriaQuery() { template.search(query, SampleEntity.class) // .map(SearchHit::getContent) // .as(StepVerifier::create) // - .expectNext(shouldMatch) // + .assertNext(next -> { + assertThat(next.getMessage()).isEqualTo("test message"); + }) // .verifyComplete(); } @@ -963,6 +965,36 @@ void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { template.save(forEdit).as(StepVerifier::create).expectNextCount(1).verifyComplete(); } + @Test // DATAES-908 + void shouldFillVersionOnSaveOne() { + VersionedEntity saved = template.save(new VersionedEntity()).block(); + + assertThat(saved.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillVersionOnSaveAll() { + VersionedEntity saved = template.saveAll(singletonList(new VersionedEntity()), VersionedEntity.class) + .blockLast(); + + assertThat(saved.getVersion()).isNotNull(); + } + + @Test // DATAES-908 + void shouldFillSeqNoPrimaryTermOnSaveOne() { + OptimisticEntity saved = template.save(new OptimisticEntity()).block(); + + assertThatSeqNoPrimaryTermIsFilled(saved); + } + + @Test // DATAES-908 + void shouldFillSeqNoPrimaryTermOnSaveAll() { + OptimisticEntity saved = template.saveAll(singletonList(new OptimisticEntity()), OptimisticEntity.class) + .blockLast(); + + assertThatSeqNoPrimaryTermIsFilled(saved); + } + @Data @Document(indexName = "marvel") static class Person { @@ -1051,4 +1083,11 @@ static class OptimisticAndVersionedEntity { private SeqNoPrimaryTerm seqNoPrimaryTerm; @Version private Long version; } + + @Data + @Document(indexName = "test-index-reactive-versioned-entity-template") + static class VersionedEntity { + @Id private String id; + @Version private Long version; + } } From 26ab5f6db4bc91c91a447858324b1c29635e1cd8 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Wed, 19 Aug 2020 21:30:36 +0200 Subject: [PATCH 0246/1191] DATAES-908 - Polishing. --- .../core/ElasticsearchRestTemplate.java | 5 ++--- .../elasticsearch/core/ElasticsearchTemplate.java | 5 ++--- .../core/ReactiveElasticsearchTemplate.java | 14 ++++++-------- .../core/ElasticsearchTemplateTests.java | 6 +++--- .../core/ReactiveElasticsearchTemplateTests.java | 3 +-- 5 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index 6a3b0db60..ebd98a497 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -148,9 +148,8 @@ public String index(IndexQuery query, IndexCoordinates index) { // We should call this because we are not going through a mapper. Object queryObject = query.getObject(); if (queryObject != null) { - updateIndexedObject(queryObject, - IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), - indexResponse.getPrimaryTerm(), indexResponse.getVersion())); + updateIndexedObject(queryObject, IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), + indexResponse.getPrimaryTerm(), indexResponse.getVersion())); } maybeCallbackAfterSaveWithQuery(query, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java index 493496c7e..e385fb341 100755 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java @@ -162,9 +162,8 @@ public String index(IndexQuery query, IndexCoordinates index) { // We should call this because we are not going through a mapper. Object queryObject = query.getObject(); if (queryObject != null) { - updateIndexedObject(queryObject, - IndexedObjectInformation.of(documentId, response.getSeqNo(), response.getPrimaryTerm(), - response.getVersion())); + updateIndexedObject(queryObject, IndexedObjectInformation.of(documentId, response.getSeqNo(), + response.getPrimaryTerm(), response.getVersion())); } maybeCallbackAfterSaveWithQuery(query, index); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index e0a4e56a8..bccdbacc8 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -15,8 +15,6 @@ */ package org.springframework.data.elasticsearch.core; -import org.elasticsearch.action.DocWriteResponse; -import org.springframework.data.mapping.PersistentPropertyAccessor; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.util.function.Tuple2; @@ -27,6 +25,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.elasticsearch.action.DocWriteResponse; import org.elasticsearch.action.bulk.BulkItemResponse; import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; @@ -75,6 +74,7 @@ import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.core.query.UpdateQuery; import org.springframework.data.elasticsearch.support.VersionInfo; +import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; import org.springframework.data.mapping.context.MappingContext; import org.springframework.http.HttpStatus; @@ -206,9 +206,8 @@ public Mono save(T entity, IndexCoordinates index) { .map(it -> { T savedEntity = it.getT1(); IndexResponse indexResponse = it.getT2(); - return updateIndexedObject(savedEntity, - IndexedObjectInformation.of(indexResponse.getId(), indexResponse.getSeqNo(), - indexResponse.getPrimaryTerm(), indexResponse.getVersion())); + return updateIndexedObject(savedEntity, IndexedObjectInformation.of(indexResponse.getId(), + indexResponse.getSeqNo(), indexResponse.getPrimaryTerm(), indexResponse.getVersion())); }).flatMap(saved -> maybeCallAfterSave(saved, index)); } @@ -244,9 +243,8 @@ public Flux saveAll(Mono> entitiesPubli BulkItemResponse bulkItemResponse = indexAndResponse.getT2(); DocWriteResponse response = bulkItemResponse.getResponse(); - updateIndexedObject(savedEntity, - IndexedObjectInformation.of(response.getId(), response.getSeqNo(), - response.getPrimaryTerm(), response.getVersion())); + updateIndexedObject(savedEntity, IndexedObjectInformation.of(response.getId(), response.getSeqNo(), + response.getPrimaryTerm(), response.getVersion())); return maybeCallAfterSave(savedEntity, index); }); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java index c6b4d4cdb..7e7aefd6e 100755 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplateTests.java @@ -3469,10 +3469,10 @@ void shouldFillVersionOnSaveIterable() { @Test // DATAES-908 void shouldFillVersionOnSaveArray() { - VersionedEntity[] array = {new VersionedEntity(), new VersionedEntity()}; + VersionedEntity[] array = { new VersionedEntity(), new VersionedEntity() }; Iterator results = operations.save(array).iterator(); VersionedEntity saved1 = results.next(); - VersionedEntity saved2= results.next(); + VersionedEntity saved2 = results.next(); assertThat(saved1.getVersion()).isNotNull(); assertThat(saved2.getVersion()).isNotNull(); @@ -3490,7 +3490,7 @@ void shouldFillVersionOnIndexOne() { @Test // DATAES-908 void shouldFillVersionOnBulkIndex() { VersionedEntity entity1 = new VersionedEntity(); - VersionedEntity entity2= new VersionedEntity(); + VersionedEntity entity2 = new VersionedEntity(); IndexQuery query1 = new IndexQueryBuilder().withObject(entity1).build(); IndexQuery query2 = new IndexQueryBuilder().withObject(entity2).build(); operations.bulkIndex(Arrays.asList(query1, query2), VersionedEntity.class); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index 7e67883df..b2dbbbda0 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -974,8 +974,7 @@ void shouldFillVersionOnSaveOne() { @Test // DATAES-908 void shouldFillVersionOnSaveAll() { - VersionedEntity saved = template.saveAll(singletonList(new VersionedEntity()), VersionedEntity.class) - .blockLast(); + VersionedEntity saved = template.saveAll(singletonList(new VersionedEntity()), VersionedEntity.class).blockLast(); assertThat(saved.getVersion()).isNotNull(); } From 0208bffc0addcfe886d7f28d481138fcdb853d1c Mon Sep 17 00:00:00 2001 From: Roman Puchkovskiy Date: Thu, 20 Aug 2020 08:13:59 +0400 Subject: [PATCH 0247/1191] DATAES-909 - Add singular update() methods to ReactiveDocumentOperations. Original PR: #507 Co-authored-by: Peter-Josef Meisch --- .../core/ReactiveDocumentOperations.java | 12 +++++++ .../core/ReactiveElasticsearchTemplate.java | 14 ++++++++ .../ReactiveElasticsearchTemplateTests.java | 34 +++++++++++++------ 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 37109773b..8bc4e006c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -15,6 +15,7 @@ */ package org.springframework.data.elasticsearch.core; +import org.springframework.data.elasticsearch.core.query.UpdateResponse; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -34,6 +35,7 @@ * * @author Peter-Josef Meisch * @author Aleksei Arsenev + * @author Roman Puchkovskiy * @since 4.0 */ public interface ReactiveDocumentOperations { @@ -324,4 +326,14 @@ default Mono delete(String id, Class entityType, IndexCoordinates ind * @return a {@link Mono} emitting the number of the removed documents. */ Mono delete(Query query, Class entityType, IndexCoordinates index); + + /** + * Partial update of the document. + * + * @param updateQuery query defining the update + * @param index the index where to update the records + * @return a {@link Mono} emitting the update response + * @since 4.1 + */ + Mono update(UpdateQuery updateQuery, IndexCoordinates index); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index bccdbacc8..86d541f7c 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -38,6 +38,7 @@ import org.elasticsearch.action.support.IndicesOptions; import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; +import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.DeleteByQueryRequest; @@ -73,6 +74,7 @@ import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.elasticsearch.core.query.UpdateResponse; import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.callback.ReactiveEntityCallbacks; @@ -524,6 +526,18 @@ public Mono delete(Query query, Class entityType, IndexCoordinates inde return doDeleteBy(query, entityType, index).map(BulkByScrollResponse::getDeleted).publishNext(); } + @Override + public Mono update(UpdateQuery updateQuery, IndexCoordinates index) { + Assert.notNull(updateQuery, "UpdateQuery must not be null"); + Assert.notNull(index, "Index must not be null"); + + return Mono.defer(() -> { + UpdateRequest request = requestFactory.updateRequest(updateQuery, index); + return Mono.from(execute(client -> client.update(request))) + .map(response -> new UpdateResponse(UpdateResponse.Result.valueOf(response.getResult().name()))); + }); + } + @Override public Mono delete(Query query, Class entityType) { return delete(query, entityType, getIndexCoordinatesFor(entityType)); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index b2dbbbda0..c66b5f511 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -63,16 +63,7 @@ import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; 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.IndexQuery; -import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder; -import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; -import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; -import org.springframework.data.elasticsearch.core.query.Query; -import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; -import org.springframework.data.elasticsearch.core.query.StringQuery; -import org.springframework.data.elasticsearch.core.query.UpdateQuery; +import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; @@ -965,6 +956,29 @@ void shouldAllowFullReplaceOfEntityWithBothSeqNoPrimaryTermAndVersion() { template.save(forEdit).as(StepVerifier::create).expectNextCount(1).verifyComplete(); } + @Test // DATAES-909 + void shouldDoUpdate() { + SampleEntity entity = randomEntity("test message"); + entity.rate = 1; + index(entity); + + org.springframework.data.elasticsearch.core.document.Document document = org.springframework.data.elasticsearch.core.document.Document + .create(); + document.put("message", "updated"); + UpdateQuery updateQuery = UpdateQuery.builder(entity.getId()) // + .withDocument(document) // + .build(); + + UpdateResponse updateResponse = template.update(updateQuery, IndexCoordinates.of(DEFAULT_INDEX)).block(); + assertThat(updateResponse).isNotNull(); + assertThat(updateResponse.getResult()).isEqualTo(UpdateResponse.Result.UPDATED); + + template.get(entity.getId(), SampleEntity.class, IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNextMatches(foundEntity -> foundEntity.getMessage().equals("updated")) // + .verifyComplete(); + } + @Test // DATAES-908 void shouldFillVersionOnSaveOne() { VersionedEntity saved = template.save(new VersionedEntity()).block(); From a62e8af14ff9f0356fd46682608f178070163462 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Thu, 20 Aug 2020 06:27:50 +0200 Subject: [PATCH 0248/1191] DATAES-909 - Polishing. --- .../elasticsearch/core/ReactiveDocumentOperations.java | 10 +++++----- .../core/ReactiveElasticsearchTemplate.java | 1 + .../core/ReactiveElasticsearchTemplateTests.java | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java index 8bc4e006c..4e4789825 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveDocumentOperations.java @@ -15,7 +15,6 @@ */ package org.springframework.data.elasticsearch.core; -import org.springframework.data.elasticsearch.core.query.UpdateResponse; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -27,6 +26,7 @@ import org.springframework.data.elasticsearch.core.query.BulkOptions; 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.util.Assert; /** @@ -103,8 +103,8 @@ default Flux saveAll(Iterable entities, Class clazz) { } /** - * Index entities in the given {@literal index}. If the {@literal index} is - * {@literal null} or empty the index name provided via entity metadata is used. + * Index entities in the given {@literal index}. If the {@literal index} is {@literal null} or empty the index name + * provided via entity metadata is used. * * @param entities must not be {@literal null}. * @param index the target index, must not be {@literal null} @@ -129,8 +129,8 @@ default Flux saveAll(Iterable entities, IndexCoordinates index) { Flux saveAll(Mono> entities, Class clazz); /** - * Index entities in the given {@literal index}. If the {@literal index} is - * {@literal null} or empty the index name provided via entity metadata is used. + * Index entities in the given {@literal index}. If the {@literal index} is {@literal null} or empty the index name + * provided via entity metadata is used. * * @param entities must not be {@literal null}. * @param index the target index, must not be {@literal null} diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java index 86d541f7c..0064f03ef 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplate.java @@ -528,6 +528,7 @@ public Mono delete(Query query, Class entityType, IndexCoordinates inde @Override public Mono update(UpdateQuery updateQuery, IndexCoordinates index) { + Assert.notNull(updateQuery, "UpdateQuery must not be null"); Assert.notNull(index, "Index must not be null"); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index c66b5f511..a757c0844 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -977,8 +977,8 @@ void shouldDoUpdate() { .as(StepVerifier::create) // .expectNextMatches(foundEntity -> foundEntity.getMessage().equals("updated")) // .verifyComplete(); - } - + } + @Test // DATAES-908 void shouldFillVersionOnSaveOne() { VersionedEntity saved = template.save(new VersionedEntity()).block(); From 368957f735601d71f4fae741dd184bfe3f94ef5b Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sat, 22 Aug 2020 16:53:52 +0200 Subject: [PATCH 0249/1191] DATAES-911 - Add documentation for automatic index creation. Original PR: #508 --- .../reference/elasticsearch-object-mapping.adoc | 2 +- .../asciidoc/reference/elasticsearch-operations.adoc | 12 ++++++++++++ .../reference/elasticsearch-repositories.adoc | 7 +++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc index 43d1b3bb6..de252e2c7 100644 --- a/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc +++ b/src/main/asciidoc/reference/elasticsearch-object-mapping.adoc @@ -34,7 +34,7 @@ The following annotations are available: ** `replicas`: the number of replicas for the index. ** `refreshIntervall`: Refresh interval for the index. Used for index creation. Default value is _"1s"_. ** `indexStoreType`: Index storage type for the index. Used for index creation. Default value is _"fs"_. -** `createIndex`: Configuration whether to create an index on repository bootstrapping. Default value is _true_. +** `createIndex`: flag whether to create an index on repository bootstrapping. Default value is _true_. See <> ** `versionType`: Configuration of version management. Default value is _EXTERNAL_. * `@Id`: Applied at the field level to mark the field used for identity purpose. diff --git a/src/main/asciidoc/reference/elasticsearch-operations.adoc b/src/main/asciidoc/reference/elasticsearch-operations.adoc index 49580288b..34a752c2b 100644 --- a/src/main/asciidoc/reference/elasticsearch-operations.adoc +++ b/src/main/asciidoc/reference/elasticsearch-operations.adoc @@ -17,6 +17,18 @@ The default implementations of the interfaces offer: * A rich query and criteria api. * Resource management and Exception translation. +[NOTE] +==== +.Index management and automatic creation of indices and mappings. + +The `IndexOperations` interface and the provided implementation which can be obtained from an `ElasticsearchOperations` instance - for example with a call to `operations.indexOps(clazz)`- give the user the ability to create indices, put mappings or store template and alias information in the Elasticsearch cluster. + +**None of these operations are done automatically** by the implementations of `IndexOperations` or `ElasticsearchOperations`. It is the user's responsibility to call the methods. + +There is support for automatic creation of indices and writing the mappings when using Spring Data Elasticsearch repositories, see <> + +==== + [[elasticsearch.operations.template]] == ElasticsearchTemplate diff --git a/src/main/asciidoc/reference/elasticsearch-repositories.adoc b/src/main/asciidoc/reference/elasticsearch-repositories.adoc index 60c186967..6fba3fd3a 100644 --- a/src/main/asciidoc/reference/elasticsearch-repositories.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repositories.adoc @@ -26,6 +26,13 @@ class Book { ---- ==== +[[elasticsearch.repositories.autocreation]] +== Automatic creation of indices with the corresponding mapping + +The `@Document` annotation has an argument `createIndex`. If this argument is set to true - which is the default value - Spring Data Elasticsearch will during bootstrapping the repository support on application startup check if the index defined by the `@Document` annotation exists. + +If it does not exist, the index will be created and the mappings derived from the entity's annotations (see <>) will be written to the newly created index. + include::elasticsearch-repository-queries.adoc[leveloffset=+1] include::reactive-elasticsearch-repositories.adoc[leveloffset=+1] From 4ef442966f1905299417ea718f933ae3ee5733ac Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Sun, 23 Aug 2020 15:28:50 +0200 Subject: [PATCH 0250/1191] DATAES-913 - Minor optimization on collection-returning derived queries. Original PR: #509 --- .../elasticsearch/core/SearchHitSupport.java | 3 ++- .../query/ElasticsearchPartQuery.java | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java index bc6298889..02f8547c1 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/SearchHitSupport.java @@ -48,7 +48,8 @@ private SearchHitSupport() {} * @return a corresponding object where the SearchHits are replaced by their content if possible, otherwise the * original object */ - public static Object unwrapSearchHits(Object result) { + @Nullable + public static Object unwrapSearchHits(@Nullable Object result) { if (result == null) { return result; diff --git a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java index 647941885..e1c9f31f0 100644 --- a/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java +++ b/src/main/java/org/springframework/data/elasticsearch/repository/query/ElasticsearchPartQuery.java @@ -15,10 +15,14 @@ */ 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; import org.springframework.data.elasticsearch.core.SearchHits; +import org.springframework.data.elasticsearch.core.SearchHitsImpl; +import org.springframework.data.elasticsearch.core.TotalHitsRelation; import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; @@ -28,6 +32,7 @@ import org.springframework.data.repository.query.ParametersParameterAccessor; import org.springframework.data.repository.query.parser.PartTree; import org.springframework.data.util.StreamUtils; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; @@ -74,6 +79,7 @@ public Object execute(Object[] parameters) { Object result = null; if (tree.isLimiting()) { + // noinspection ConstantConditions query.setMaxResults(tree.getMaxResults()); } @@ -100,12 +106,19 @@ public Object execute(Object[] parameters) { if (accessor.getPageable().isUnpaged()) { int itemCount = (int) elasticsearchOperations.count(query, clazz, index); - query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); + + if (itemCount == 0) { + result = new SearchHitsImpl<>(0, TotalHitsRelation.EQUAL_TO, Float.NaN, null, Collections.emptyList(), null); + } else { + query.setPageable(PageRequest.of(0, Math.max(1, itemCount))); + } } else { query.setPageable(accessor.getPageable()); } - result = elasticsearchOperations.search(query, clazz, index); + if (result == null) { + result = elasticsearchOperations.search(query, clazz, index); + } } else if (tree.isCountProjection()) { result = elasticsearchOperations.count(query, clazz, index); @@ -116,6 +129,7 @@ public Object execute(Object[] parameters) { return queryMethod.isNotSearchHitMethod() ? SearchHitSupport.unwrapSearchHits(result) : result; } + @Nullable private Object countOrGetDocumentsForDelete(CriteriaQuery query, ParametersParameterAccessor accessor) { Object result = null; From 79fdc449b873b317cc6d9544285e870c11a4d240 Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Mon, 24 Aug 2020 07:02:43 +0200 Subject: [PATCH 0251/1191] DATAES-912 - Derived Query with "In" Keyword does not work on Text field. Original PR: #510 --- .../elasticsearch-repository-queries.adoc | 17 ++++-- .../core/CriteriaQueryProcessor.java | 50 ++++++++++++++--- .../core/ElasticsearchRestTemplate.java | 10 ++-- .../MappingElasticsearchConverter.java | 23 ++++++-- .../data/elasticsearch/core/query/Field.java | 14 +++++ .../elasticsearch/core/query/SimpleField.java | 16 +++++- .../core/ElasticsearchPartQueryTests.java | 48 +++++++++++------ .../CustomMethodRepositoryBaseTests.java | 54 +++++++++++++++++-- 8 files changed, 190 insertions(+), 42 deletions(-) diff --git a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc index c17844fb3..7b35a79a0 100644 --- a/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc +++ b/src/main/asciidoc/reference/elasticsearch-repository-queries.adoc @@ -48,7 +48,9 @@ A list of supported keywords for Elasticsearch is shown below. |=== | Keyword | Sample -| Elasticsearch Query String| `And` +| Elasticsearch Query String + +| `And` | `findByNameAndPrice` | `{ "query" : { "bool" : { @@ -201,7 +203,7 @@ A list of supported keywords for Elasticsearch is shown below. } }}` -| `In` +| `In` (when annotated as FieldType.Keyword) | `findByNameIn(Collectionnames)` | `{ "query" : { "bool" : { @@ -215,7 +217,12 @@ A list of supported keywords for Elasticsearch is shown below. } }}` -| `NotIn` + +| `In` +| `findByNameIn(Collectionnames)` +| `{ "query": {"bool": {"must": [{"query_string":{"query": "\"?\" \"?\"", "fields": ["name"]}}]}}}` + +| `NotIn` (when annotated as FieldType.Keyword) | `findByNameNotIn(Collectionnames)` | `{ "query" : { "bool" : { @@ -229,6 +236,10 @@ A list of supported keywords for Elasticsearch is shown below. } }}` +| `NotIn` +| `findByNameNotIn(Collectionnames)` +| `{"query": {"bool": {"must": [{"query_string": {"query": "NOT(\"?\" \"?\")", "fields": ["name"]}}]}}}` + | `Near` | `findByStoreNear` | `Not Supported Yet !` diff --git a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java index f465f2201..958caddde 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/CriteriaQueryProcessor.java @@ -26,7 +26,9 @@ import org.apache.lucene.queryparser.flexible.standard.QueryParserUtil; import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.QueryBuilder; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.core.query.Criteria; +import org.springframework.data.elasticsearch.core.query.Field; import org.springframework.lang.Nullable; import org.springframework.util.Assert; @@ -128,23 +130,24 @@ QueryBuilder createQuery(Criteria criteria) { @Nullable private QueryBuilder queryForEntries(Criteria criteria) { - if (criteria.getField() == null || criteria.getQueryCriteriaEntries().isEmpty()) - return null; + Field field = criteria.getField(); - String fieldName = criteria.getField().getName(); + if (field == null || criteria.getQueryCriteriaEntries().isEmpty()) + return null; + String fieldName = field.getName(); Assert.notNull(fieldName, "Unknown field"); Iterator it = criteria.getQueryCriteriaEntries().iterator(); QueryBuilder query; if (criteria.getQueryCriteriaEntries().size() == 1) { - query = queryFor(it.next(), fieldName); + query = queryFor(it.next(), field); } else { query = boolQuery(); while (it.hasNext()) { Criteria.CriteriaEntry entry = it.next(); - ((BoolQueryBuilder) query).must(queryFor(entry, fieldName)); + ((BoolQueryBuilder) query).must(queryFor(entry, field)); } } @@ -153,7 +156,11 @@ private QueryBuilder queryForEntries(Criteria criteria) { } @Nullable - private QueryBuilder queryFor(Criteria.CriteriaEntry entry, String fieldName) { + private QueryBuilder queryFor(Criteria.CriteriaEntry entry, Field field) { + + String fieldName = field.getName(); + boolean isKeywordField = FieldType.Keyword == field.getFieldType(); + OperationKey key = entry.getKey(); if (key == OperationKey.EXISTS) { @@ -209,13 +216,21 @@ private QueryBuilder queryFor(Criteria.CriteriaEntry entry, String fieldName) { case IN: if (value instanceof Iterable) { Iterable iterable = (Iterable) value; - query = boolQuery().must(termsQuery(fieldName, toStringList(iterable))); + if (isKeywordField) { + query = boolQuery().must(termsQuery(fieldName, toStringList(iterable))); + } else { + query = queryStringQuery(orQueryString(iterable)).field(fieldName); + } } break; case NOT_IN: if (value instanceof Iterable) { Iterable iterable = (Iterable) value; - query = boolQuery().mustNot(termsQuery(fieldName, toStringList(iterable))); + if (isKeywordField) { + query = boolQuery().mustNot(termsQuery(fieldName, toStringList(iterable))); + } else { + query = queryStringQuery("NOT(" + orQueryString(iterable) + ')').field(fieldName); + } } break; } @@ -230,6 +245,25 @@ private static List toStringList(Iterable iterable) { return list; } + private static String orQueryString(Iterable iterable) { + StringBuilder sb = new StringBuilder(); + + for (Object item : iterable) { + + if (item != null) { + + if (sb.length() > 0) { + sb.append(' '); + } + sb.append('"'); + sb.append(QueryParserUtil.escape(item.toString())); + sb.append('"'); + } + } + + return sb.toString(); + } + private void addBoost(@Nullable QueryBuilder query, float boost) { if (query == null || Float.isNaN(boost)) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java index ebd98a497..cd3358761 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchRestTemplate.java @@ -92,8 +92,8 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate { private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchRestTemplate.class); - private RestHighLevelClient client; - private ElasticsearchExceptionTranslator exceptionTranslator; + private final RestHighLevelClient client; + private final ElasticsearchExceptionTranslator exceptionTranslator; // region Initialization public ElasticsearchRestTemplate(RestHighLevelClient client) { @@ -241,11 +241,11 @@ private List doBulkOperation(List queries, BulkOpti IndexCoordinates index) { maybeCallbackBeforeConvertWithQueries(queries, index); BulkRequest bulkRequest = requestFactory.bulkRequest(queries, bulkOptions, index); - List indexedObjectInformations = checkForBulkOperationFailure( + List indexedObjectInformationList = checkForBulkOperationFailure( execute(client -> client.bulk(bulkRequest, RequestOptions.DEFAULT))); - updateIndexedObjectsWithQueries(queries, indexedObjectInformations); + updateIndexedObjectsWithQueries(queries, indexedObjectInformationList); maybeCallbackAfterSaveWithQueries(queries, index); - return indexedObjectInformations; + return indexedObjectInformationList; } // endregion diff --git a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java index deda4c3fe..5de116b78 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/convert/MappingElasticsearchConverter.java @@ -50,6 +50,7 @@ import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentPropertyConverter; import org.springframework.data.elasticsearch.core.query.Criteria; import org.springframework.data.elasticsearch.core.query.CriteriaQuery; +import org.springframework.data.elasticsearch.core.query.Field; import org.springframework.data.elasticsearch.core.query.SeqNoPrimaryTerm; import org.springframework.data.mapping.PersistentPropertyAccessor; import org.springframework.data.mapping.context.MappingContext; @@ -94,7 +95,7 @@ public class MappingElasticsearchConverter private final ElasticsearchTypeMapper typeMapper; - private ConcurrentHashMap propertyWarnings = new ConcurrentHashMap<>(); + private final ConcurrentHashMap propertyWarnings = new ConcurrentHashMap<>(); public MappingElasticsearchConverter( MappingContext, ElasticsearchPersistentProperty> mappingContext) { @@ -579,13 +580,13 @@ protected Object getWriteComplexValue(ElasticsearchPersistentProperty property, } if (property.isEntity() || !isSimpleType(value)) { - return writeEntity(value, property, typeHint); + return writeEntity(value, property); } return value; } - private Object writeEntity(Object value, ElasticsearchPersistentProperty property, TypeInformation typeHint) { + private Object writeEntity(Object value, ElasticsearchPersistentProperty property) { Document target = Document.create(); writeEntity(mappingContext.getRequiredPersistentEntity(value.getClass()), value, target, @@ -769,11 +770,17 @@ public void updateCriteriaQuery(CriteriaQuery criteriaQuery, Class domainClas } private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity persistentEntity) { - String name = criteria.getField().getName(); + Field field = criteria.getField(); + + if (field == null) { + return; + } + + String name = field.getName(); ElasticsearchPersistentProperty property = persistentEntity.getPersistentProperty(name); if (property != null && property.getName().equals(name)) { - criteria.getField().setName(property.getFieldName()); + field.setName(property.getFieldName()); if (property.hasPropertyConverter()) { ElasticsearchPersistentPropertyConverter propertyConverter = property.getPropertyConverter(); @@ -789,6 +796,12 @@ private void updateCriteria(Criteria criteria, ElasticsearchPersistentEntity } }); } + + org.springframework.data.elasticsearch.annotations.Field fieldAnnotation = property.findAnnotation(org.springframework.data.elasticsearch.annotations.Field.class); + + if (fieldAnnotation != null) { + field.setFieldType(fieldAnnotation.type()); + } } for (Criteria subCriteria : criteria.getSubCriteria()) { diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java index aa80c12dc..92969a11d 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/Field.java @@ -15,6 +15,9 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.lang.Nullable; + /** * Defines a Field that can be used within a Criteria. * @@ -27,4 +30,15 @@ public interface Field { void setName(String name); String getName(); + + /** + * @param fieldType sets the field's type + */ + void setFieldType(FieldType fieldType); + + /** + * @return The annotated FieldType of the field + */ + @Nullable + FieldType getFieldType(); } diff --git a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java index f9fed6a69..1091bdb78 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/query/SimpleField.java @@ -15,10 +15,12 @@ */ package org.springframework.data.elasticsearch.core.query; +import org.springframework.data.elasticsearch.annotations.FieldType; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** - * The most trivial implementation of a Field. The {@link #name} is updateable, so it may be changed during query + * The most trivial implementation of a Field. The {@link #name} is updatable, so it may be changed during query * preparation by the {@link org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter}. * * @author Rizwan Idrees @@ -28,6 +30,7 @@ public class SimpleField implements Field { private String name; + @Nullable private FieldType fieldType; public SimpleField(String name) { @@ -49,6 +52,17 @@ public String getName() { return name; } + @Override + public void setFieldType(FieldType fieldType) { + this.fieldType = fieldType; + } + + @Nullable + @Override + public FieldType getFieldType() { + return fieldType; + } + @Override public String toString() { return getName(); diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java index 70691f434..7fde9d1fc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ElasticsearchPartQueryTests.java @@ -197,14 +197,22 @@ void findByNameIn() throws NoSuchMethodException, JSONException { String query = getQueryBuilder(methodName, parameterClasses, parameters); - String expected = "{\"query\": {" + // - " \"bool\" : {" + // - " \"must\" : [" + // - " {\"bool\" : {\"must\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) - + "\"]}}]}}" + // - " ]" + // - " }" + // - "}}"; // + String expected = "{\n" + // + " \"query\": {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"\\\"Title\\\" \\\"Title2\\\"\",\n" + // + " \"fields\": [\n" + // + " \"name^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + "}\n"; // assertEquals(expected, query, false); } @@ -220,14 +228,22 @@ void findByNameNotIn() throws NoSuchMethodException, JSONException { String query = getQueryBuilder(methodName, parameterClasses, parameters); - String expected = "{\"query\": {" + // - " \"bool\" : {" + // - " \"must\" : [" + // - " {\"bool\" : {\"must_not\" : [{\"terms\" : {\"name\" : [\"" + names.get(0) + "\", \"" + names.get(1) - + "\"]}}]}}" + // - " ]" + // - " }" + // - "}}"; // + String expected = "{\n" + // + " \"query\": {\n" + // + " \"bool\": {\n" + // + " \"must\": [\n" + // + " {\n" + // + " \"query_string\": {\n" + // + " \"query\": \"NOT(\\\"Title\\\" \\\"Title2\\\")\",\n" + // + " \"fields\": [\n" + // + " \"name^1.0\"\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + " ]\n" + // + " }\n" + // + " }\n" + // + "}\n"; // assertEquals(expected, query, false); } diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java index d2c2b3f71..780626d78 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/custommethod/CustomMethodRepositoryBaseTests.java @@ -360,7 +360,7 @@ public void shouldExecuteCustomMethodForNotIn() { } @Test // DATAES-647 - public void shouldHandleManyValuesQueryingIn() { + public void shouldHandleManyKeywordValuesQueryingIn() { // given String documentId1 = nextIdAsString(); @@ -378,7 +378,8 @@ public void shouldHandleManyValuesQueryingIn() { List keywords = new ArrayList<>(); keywords.add("foo"); - for (int i = 0; i < 1025; i++) { + // limit for normal query clauses is 1024, for keywords we change to terms queries + for (int i = 0; i < 1200; i++) { keywords.add(nextIdAsString()); } @@ -391,7 +392,7 @@ public void shouldHandleManyValuesQueryingIn() { } @Test // DATAES-647 - public void shouldHandleManyValuesQueryingNotIn() { + public void shouldHandleManyKeywordValuesQueryingNotIn() { // given String documentId1 = nextIdAsString(); @@ -409,7 +410,8 @@ public void shouldHandleManyValuesQueryingNotIn() { List keywords = new ArrayList<>(); keywords.add("foo"); - for (int i = 0; i < 1025; i++) { + // limit for normal query clauses is 1024, for keywords we change to terms queries + for (int i = 0; i < 1200; i++) { keywords.add(nextIdAsString()); } @@ -421,6 +423,46 @@ public void shouldHandleManyValuesQueryingNotIn() { assertThat(list.get(0).getId()).isEqualTo(documentId2); } + @Test // DATAES-912 + void shouldHandleTextFieldQueryingIn() { + String documentId1 = nextIdAsString(); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId1); + sampleEntity1.setMessage("foo"); + repository.save(sampleEntity1); + + String documentId2 = nextIdAsString(); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setMessage("bar"); + repository.save(sampleEntity2); + + List list = repository.findByMessageIn(Arrays.asList("Foo", "Bar")); + + assertThat(list).hasSize(2); + assertThat(list.stream().map(SampleEntity::getId)).containsExactlyInAnyOrder(documentId1, documentId2); + } + + @Test // DATAES-912 + void shouldHandleTextFieldQueryingNotIn() { + String documentId1 = nextIdAsString(); + SampleEntity sampleEntity1 = new SampleEntity(); + sampleEntity1.setId(documentId1); + sampleEntity1.setMessage("foo"); + repository.save(sampleEntity1); + + String documentId2 = nextIdAsString(); + SampleEntity sampleEntity2 = new SampleEntity(); + sampleEntity2.setId(documentId2); + sampleEntity2.setMessage("bar"); + repository.save(sampleEntity2); + + List list = repository.findByMessageNotIn(Arrays.asList("Boo", "Bar")); + + assertThat(list).hasSize(1); + assertThat(list.get(0).getId()).isEqualTo(documentId1); + } + @Test public void shouldExecuteCustomMethodForTrue() { @@ -1622,6 +1664,10 @@ public interface SampleCustomMethodRepository extends ElasticsearchRepository findByKeywordNotIn(List keywords); + List findByMessageIn(List keywords); + + List findByMessageNotIn(List keywords); + Page findByIdNotIn(List ids, Pageable pageable); Page findByAvailableTrue(Pageable pageable); From 6361a1eefe49f31f5023d305b6494d8d1d23bb7d Mon Sep 17 00:00:00 2001 From: Peter-Josef Meisch Date: Tue, 25 Aug 2020 16:35:42 +0200 Subject: [PATCH 0252/1191] DATAES-914 - Use TestContainers. --- Jenkinsfile | 12 + pom.xml | 774 +++++++++--------- .../client/NodeClientFactoryBean.java | 2 + .../elasticsearch/core/RequestFactory.java | 7 +- .../elasticsearch/support/VersionInfo.java | 25 +- .../ElasticsearchTestConfiguration.java | 49 -- .../RestElasticsearchTestConfiguration.java | 34 - .../data/elasticsearch/TestUtils.java | 137 ---- .../data/elasticsearch/Utils.java | 64 -- .../ReactiveElasticsearchClientTests.java | 216 +++-- .../ReactiveElasticsearchTemplateTests.java | 108 +-- .../junit/junit4/ElasticsearchVersion.java | 45 - .../junit4/ElasticsearchVersionRule.java | 132 --- .../junit/junit4/TestNodeResource.java | 54 -- .../junit/junit4/package-info.java | 5 - .../junit/jupiter/ClusterConnection.java | 63 +- .../junit/jupiter/ClusterConnectionInfo.java | 52 +- .../ElasticsearchTemplateConfiguration.java | 17 +- .../repositories/cdi/CdiRepositoryTests.java | 3 + ...a => ElasticsearchOperationsProducer.java} | 37 +- ...asticsearchRepositoriesRegistrarTests.java | 17 +- ...eReactiveElasticsearchRepositoryTests.java | 256 +++--- src/test/resources/logback.xml | 3 + .../analysis-common/analysis-common-7.8.1.jar | Bin 199093 -> 0 bytes .../plugin-descriptor.properties | 45 - .../elasticsearch-dissect-7.8.1.jar | Bin 24686 -> 0 bytes .../elasticsearch-grok-7.8.1.jar | Bin 34341 -> 0 bytes .../ingest-common/ingest-common-7.8.1.jar | Bin 116332 -> 0 bytes .../modules/ingest-common/jcodings-1.0.44.jar | Bin 1682608 -> 0 bytes .../modules/ingest-common/joni-2.1.29.jar | Bin 214815 -> 0 bytes .../plugin-descriptor.properties | 45 - .../antlr4-runtime-4.5.1-1.jar | Bin 302034 -> 0 bytes .../modules/lang-expression/asm-5.0.4.jar | Bin 53297 -> 0 bytes .../lang-expression/asm-commons-5.0.4.jar | Bin 41796 -> 0 bytes .../lang-expression/asm-tree-5.0.4.jar | Bin 29050 -> 0 bytes .../lang-expression/lang-expression-7.8.1.jar | Bin 65528 -> 0 bytes .../lucene-expressions-8.5.1.jar | Bin 73343 -> 0 bytes .../plugin-descriptor.properties | 45 - .../lang-expression/plugin-security.policy | 32 - .../lang-painless/antlr4-runtime-4.5.3.jar | Bin 302248 -> 0 bytes .../modules/lang-painless/asm-7.2.jar | Bin 114873 -> 0 bytes .../lang-painless/asm-analysis-7.2.jar | Bin 33444 -> 0 bytes .../modules/lang-painless/asm-commons-7.2.jar | Bin 70051 -> 0 bytes .../modules/lang-painless/asm-tree-7.2.jar | Bin 50283 -> 0 bytes .../modules/lang-painless/asm-util-7.2.jar | Bin 80707 -> 0 bytes ...ticsearch-scripting-painless-spi-7.8.1.jar | Bin 27849 -> 0 bytes .../lang-painless/lang-painless-7.8.1.jar | Bin 561387 -> 0 bytes .../plugin-descriptor.properties | 45 - .../lang-painless/plugin-security.policy | 26 - .../plugin-descriptor.properties | 45 - .../reindex/plugin-descriptor.properties | 45 - .../modules/reindex/plugin-security.policy | 33 - .../plugin-descriptor.properties | 45 - .../repository-url/plugin-security.policy | 22 - .../repository-url/repository-url-7.8.1.jar | Bin 14773 -> 0 bytes 55 files changed, 835 insertions(+), 1705 deletions(-) delete mode 100644 src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/TestUtils.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/Utils.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java delete mode 100644 src/test/java/org/springframework/data/elasticsearch/junit/junit4/package-info.java rename src/test/java/org/springframework/data/elasticsearch/repositories/cdi/{ElasticsearchTemplateProducer.java => ElasticsearchOperationsProducer.java} (51%) delete mode 100644 src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-grok-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/jcodings-1.0.44.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/joni-2.1.29.jar delete mode 100644 src/test/resources/test-home-dir/modules/ingest-common/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/antlr4-runtime-4.5.1-1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/asm-5.0.4.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/asm-commons-5.0.4.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/asm-tree-5.0.4.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lang-expression-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.5.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/antlr4-runtime-4.5.3.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-analysis-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-commons-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/lang-painless-7.8.1.jar delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/lang-painless/plugin-security.policy delete mode 100644 src/test/resources/test-home-dir/modules/mapper-extras/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/reindex/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/reindex/plugin-security.policy delete mode 100644 src/test/resources/test-home-dir/modules/repository-url/plugin-descriptor.properties delete mode 100644 src/test/resources/test-home-dir/modules/repository-url/plugin-security.policy delete mode 100644 src/test/resources/test-home-dir/modules/repository-url/repository-url-7.8.1.jar diff --git a/Jenkinsfile b/Jenkinsfile index a1f7efeb9..d04309cb6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -24,12 +24,16 @@ pipeline { image 'adoptopenjdk/openjdk8:latest' label 'data' args '-v $HOME:/tmp/jenkins-home' + args '-u root -v /var/run/docker.sock:/var/run/docker.sock' } } options { timeout(time: 30, unit: 'MINUTES') } steps { + sh 'mkdir -p /tmp/jenkins-home' + sh 'chown -R 1001:1001 .' sh 'rm -rf ?' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B' + sh 'chown -R 1001:1001 .' } } @@ -47,12 +51,16 @@ pipeline { image 'adoptopenjdk/openjdk11:latest' label 'data' args '-v $HOME:/tmp/jenkins-home' + args '-u root -v /var/run/docker.sock:/var/run/docker.sock' } } options { timeout(time: 30, unit: 'MINUTES') } steps { + sh 'mkdir -p /tmp/jenkins-home' + sh 'chown -R 1001:1001 .' sh 'rm -rf ?' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' + sh 'chown -R 1001:1001 .' } } @@ -62,12 +70,16 @@ pipeline { image 'adoptopenjdk/openjdk12:latest' label 'data' args '-v $HOME:/tmp/jenkins-home' + args '-u root -v /var/run/docker.sock:/var/run/docker.sock' } } options { timeout(time: 30, unit: 'MINUTES') } steps { + sh 'mkdir -p /tmp/jenkins-home' + sh 'chown -R 1001:1001 .' sh 'rm -rf ?' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' + sh 'chown -R 1001:1001 .' } } } diff --git a/pom.xml b/pom.xml index 522f629f1..577bf0da5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,388 +1,396 @@ - 4.0.0 - - org.springframework.data - spring-data-elasticsearch - 4.1.0-SNAPSHOT - - - org.springframework.data.build - spring-data-parent - 2.4.0-SNAPSHOT - - - Spring Data Elasticsearch - Spring Data Implementation for Elasticsearch - https://github.com/spring-projects/spring-data-elasticsearch - - - 2.6 - 7.8.1 - 2.13.2 - 2.4.0-SNAPSHOT - 4.1.50.Final - spring.data.elasticsearch - - - - - biomedcentral - BioMed Central Development Team - +0 - - - cstrobl - Christoph Strobl - cstrobl at pivotal.io - Pivotal - https://www.pivotal.io - - Developer - - +1 - - - mpaluch - Mark Paluch - mpaluch at pivotal.io - Pivotal - https://www.pivotal.io - - Developer - - +1 - - - - - https://github.com/spring-projects/spring-data-elasticsearch - scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git - scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git - - - - - Bamboo - https://build.spring.io/browse/SPRINGDATAES - - - - JIRA - https://jira.spring.io/browse/DATAES - - - - - - - io.netty - netty-bom - ${netty} - pom - import - - - - - - - - - org.springframework - spring-context - - - commons-logging - commons-logging - - - - - - org.springframework - spring-tx - - - - - org.springframework.data - spring-data-commons - ${springdata.commons} - - - - - org.springframework - spring-webflux - true - - - - io.projectreactor.netty - reactor-netty-http - true - - - - io.projectreactor - reactor-test - test - - - - - commons-lang - commons-lang - ${commonslang} - test - - - - - joda-time - joda-time - ${jodatime} - true - - - - - org.elasticsearch.client - transport - ${elasticsearch} - - - commons-logging - commons-logging - - - - - - - org.elasticsearch.plugin - transport-netty4-client - ${elasticsearch} - - - - org.elasticsearch.client - elasticsearch-rest-high-level-client - ${elasticsearch} - - - commons-logging - commons-logging - - - - - - org.slf4j - log4j-over-slf4j - ${slf4j} - test - - - - org.apache.logging.log4j - log4j-core - ${log4j} - test - - - - - com.fasterxml.jackson.core - jackson-core - - - com.fasterxml.jackson.core - jackson-databind - - - - - javax.enterprise - cdi-api - ${cdi} - provided - true - - - - - org.springframework - spring-test - test - - - ch.qos.logback - logback-classic - - - - - - org.apache.openwebbeans.test - cditest-owb - 1.2.8 - test - - - org.apache.geronimo.specs - geronimo-jcdi_1.0_spec - - - org.apache.geronimo.specs - geronimo-atinject_1.0_spec - - - - - - org.skyscreamer - jsonassert - 1.5.0 - test - - - - com.github.tomakehurst - wiremock-jre8 - 2.26.3 - test - - - - commons-logging - commons-logging - - - org.ow2.asm - asm - - - - - - - org.apache.xbean - xbean-asm5-shaded - 4.5 - test - - - - javax.servlet - javax.servlet-api - 3.1.0 - test - - - - org.mockito - mockito-junit-jupiter - ${mockito} - test - - - - - - - - src/main/resources - true - - **/versions.properties - - - - src/main/resources - false - - **/versions.properties - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - true - false - - **/*Tests.java - **/*Test.java - - - false - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - org.asciidoctor - asciidoctor-maven-plugin - - - - - - - - ci - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - - - - - - **/* - .git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy - ./ - - - - - - - - - - - - spring-libs-snapshot - https://repo.spring.io/libs-snapshot - - - - - - spring-plugins-release - https://repo.spring.io/plugins-release - - + 4.0.0 + + org.springframework.data + spring-data-elasticsearch + 4.1.0-DATAES-914-SNAPSHOT + + + org.springframework.data.build + spring-data-parent + 2.4.0-SNAPSHOT + + + Spring Data Elasticsearch + Spring Data Implementation for Elasticsearch + https://github.com/spring-projects/spring-data-elasticsearch + + + 2.6 + 7.8.1 + 2.13.3 + 4.1.50.Final + 2.4.0-SNAPSHOT + 1.14.3 + spring.data.elasticsearch + + + + + biomedcentral + BioMed Central Development Team + +0 + + + cstrobl + Christoph Strobl + cstrobl at pivotal.io + Pivotal + https://www.pivotal.io + + Developer + + +1 + + + mpaluch + Mark Paluch + mpaluch at pivotal.io + Pivotal + https://www.pivotal.io + + Developer + + +1 + + + + + https://github.com/spring-projects/spring-data-elasticsearch + scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git + scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git + + + + + Bamboo + https://build.spring.io/browse/SPRINGDATAES + + + + JIRA + https://jira.spring.io/browse/DATAES + + + + + + + io.netty + netty-bom + ${netty} + pom + import + + + + + + + + + org.springframework + spring-context + + + commons-logging + commons-logging + + + + + + org.springframework + spring-tx + + + + + org.springframework.data + spring-data-commons + ${springdata.commons} + + + + + org.springframework + spring-webflux + true + + + + io.projectreactor.netty + reactor-netty-http + true + + + + io.projectreactor + reactor-test + test + + + + + commons-lang + commons-lang + ${commonslang} + test + + + + + joda-time + joda-time + ${jodatime} + true + + + + + org.elasticsearch.client + transport + ${elasticsearch} + + + commons-logging + commons-logging + + + + + + + org.elasticsearch.plugin + transport-netty4-client + ${elasticsearch} + + + + org.elasticsearch.client + elasticsearch-rest-high-level-client + ${elasticsearch} + + + commons-logging + commons-logging + + + + + + org.slf4j + log4j-over-slf4j + ${slf4j} + test + + + + org.apache.logging.log4j + log4j-core + ${log4j} + test + + + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + + + javax.enterprise + cdi-api + ${cdi} + provided + true + + + + + org.springframework + spring-test + test + + + ch.qos.logback + logback-classic + + + + + + org.apache.openwebbeans.test + cditest-owb + 1.2.8 + test + + + org.apache.geronimo.specs + geronimo-jcdi_1.0_spec + + + org.apache.geronimo.specs + geronimo-atinject_1.0_spec + + + + + + org.skyscreamer + jsonassert + 1.5.0 + test + + + + com.github.tomakehurst + wiremock-jre8 + 2.26.3 + test + + + + commons-logging + commons-logging + + + org.ow2.asm + asm + + + + + + + org.apache.xbean + xbean-asm5-shaded + 4.5 + test + + + + javax.servlet + javax.servlet-api + 3.1.0 + test + + + + org.mockito + mockito-junit-jupiter + ${mockito} + test + + + + org.testcontainers + elasticsearch + ${testcontainers} + test + + + + + + + + src/main/resources + true + + **/versions.properties + + + + src/main/resources + false + + **/versions.properties + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + false + + **/*Tests.java + **/*Test.java + + + false + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + org.asciidoctor + asciidoctor-maven-plugin + + + + + + + + ci + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + + + + + + + + **/* + .git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy + ./ + + + + + + + + + + + + spring-libs-snapshot + https://repo.spring.io/libs-snapshot + + + + + + spring-plugins-release + https://repo.spring.io/plugins-release + + diff --git a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java index 37a7cc7e5..1c047fb31 100644 --- a/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java +++ b/src/main/java/org/springframework/data/elasticsearch/client/NodeClientFactoryBean.java @@ -44,7 +44,9 @@ * @author Mohsin Husen * @author Ilkang Na * @author Peter-Josef Meisch + * @deprecated since 4.1, we're not supporting embedded Node clients anymore, use the REST client */ +@Deprecated public class NodeClientFactoryBean implements FactoryBean, InitializingBean, DisposableBean { private static final Logger logger = LoggerFactory.getLogger(NodeClientFactoryBean.class); diff --git a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java index 67e08c49e..9d90d5272 100644 --- a/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java +++ b/src/main/java/org/springframework/data/elasticsearch/core/RequestFactory.java @@ -173,7 +173,12 @@ public GetAliasesRequest getAliasesRequest(IndexCoordinates index) { } public GetAliasesRequest getAliasesRequest(@Nullable String[] aliasNames, @Nullable String[] indexNames) { - return new GetAliasesRequest(aliasNames).indices(indexNames); + GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliasNames); + + if (indexNames != null) { + getAliasesRequest.indices(indexNames); + } + return getAliasesRequest; } public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { diff --git a/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java b/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java index ed92341a2..d7c3b0e05 100644 --- a/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java +++ b/src/main/java/org/springframework/data/elasticsearch/support/VersionInfo.java @@ -36,7 +36,10 @@ public final class VersionInfo { private static final Logger LOG = LoggerFactory.getLogger(VersionInfo.class); private static final AtomicBoolean initialized = new AtomicBoolean(false); - private static String VERSION_PROPERTIES = "versions.properties"; + + private static final String VERSION_PROPERTIES = "versions.properties"; + public static final String VERSION_SPRING_DATA_ELASTICSEARCH = "version.spring-data-elasticsearch"; + public static final String VERSION_ELASTICSEARCH_CLIENT = "version.elasticsearch-client"; /** * logs the relevant version info the first time it is called. Does nothing after the first call @@ -51,8 +54,8 @@ public static void logVersions(@Nullable String clusterVersion) { Properties properties = new Properties(); properties.load(resource); - String versionSpringDataElasticsearch = properties.getProperty("version.spring-data-elasticsearch"); - Version versionESBuilt = Version.fromString(properties.getProperty("version.elasticsearch-client")); + String versionSpringDataElasticsearch = properties.getProperty(VERSION_SPRING_DATA_ELASTICSEARCH); + Version versionESBuilt = Version.fromString(properties.getProperty(VERSION_ELASTICSEARCH_CLIENT)); Version versionESUsed = Version.CURRENT; Version versionESCluster = clusterVersion != null ? Version.fromString(clusterVersion) : null; @@ -83,6 +86,22 @@ public static void logVersions(@Nullable String clusterVersion) { } } + public static Properties versionProperties() throws Exception { + try { + InputStream resource = VersionInfo.class.getClassLoader().getResourceAsStream(VERSION_PROPERTIES); + if (resource != null) { + Properties properties = new Properties(); + properties.load(resource); + return properties; + } else { + throw new IllegalStateException("Resource not found"); + } + } catch (Exception e) { + LOG.error("Could not load {}", VERSION_PROPERTIES, e); + throw e; + } + } + private static boolean differInMajorOrMinor(Version version1, Version version2) { return version1.major != version2.major || version1.minor != version2.minor; } diff --git a/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java deleted file mode 100644 index f0bf2b856..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/ElasticsearchTestConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019-2020 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; - -import org.elasticsearch.client.Client; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; -import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter; -import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource; - -/** - * configuration class for the classic ElasticsearchTemplate. Needs a {@link TestNodeResource} bean that should be set - * up in the test as ClassRule and exported as bean. - * - * @author Peter-Josef Meisch - */ -@Configuration -public class ElasticsearchTestConfiguration extends ElasticsearchConfigurationSupport { - - @Autowired private TestNodeResource testNodeResource; - - @Bean - public Client elasticsearchClient() { - return testNodeResource.client(); - } - - @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) - public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient, - ElasticsearchConverter elasticsearchConverter) { - return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter); - } - -} diff --git a/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java deleted file mode 100644 index 6bcee8f79..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/RestElasticsearchTestConfiguration.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2019-2020 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; - -import org.elasticsearch.client.RestHighLevelClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration; - -/** - * @author Peter-Josef Meisch - */ -@Configuration -public class RestElasticsearchTestConfiguration extends AbstractElasticsearchConfiguration { - - @Override - @Bean - public RestHighLevelClient elasticsearchClient() { - return TestUtils.restHighLevelClient(); - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java b/src/test/java/org/springframework/data/elasticsearch/TestUtils.java deleted file mode 100644 index 5f3bd2094..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/TestUtils.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2018-2020 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; - -import lombok.SneakyThrows; - -import java.time.Duration; - -import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; -import org.elasticsearch.action.get.GetRequest; -import org.elasticsearch.action.search.SearchRequest; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.index.query.QueryBuilders; -import org.elasticsearch.search.builder.SearchSourceBuilder; -import org.springframework.data.elasticsearch.client.ClientConfiguration; -import org.springframework.data.elasticsearch.client.RestClients; -import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; -import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients; -import org.springframework.data.elasticsearch.support.SearchHitsUtil; -import org.springframework.data.util.Version; -import org.springframework.util.ObjectUtils; - -/** - * @author Christoph Strobl - * @author Mark Paluch - * @currentRead Fool's Fate - Robin Hobb - */ -public final class TestUtils { - - private TestUtils() {} - - private static final ClientConfiguration CONFIG = ClientConfiguration.builder().connectedToLocalhost() - .withConnectTimeout(Duration.ofSeconds(5)).withSocketTimeout(Duration.ofSeconds(3)).build(); - - public static RestHighLevelClient restHighLevelClient() { - return RestClients.create(CONFIG).rest(); - } - - public static ReactiveElasticsearchClient reactiveClient() { - return ReactiveRestClients.create(CONFIG); - } - - public static Version serverVersion() { - - try (RestHighLevelClient client = restHighLevelClient()) { - - org.elasticsearch.Version version = org.elasticsearch.Version - .fromString(client.info(RequestOptions.DEFAULT).getVersion().getNumber()); - return new Version(version.major, version.minor, version.revision); - - } catch (Exception e) { - return new Version(0, 0, 0); - } - } - - @SneakyThrows - public static void deleteIndex(String... indexes) { - - if (ObjectUtils.isEmpty(indexes)) { - return; - } - - try (RestHighLevelClient client = restHighLevelClient()) { - for (String index : indexes) { - - try { - client.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT); - } catch (ElasticsearchStatusException ex) { - // just ignore it - } - } - } - } - - @SneakyThrows - public static boolean isEmptyIndex(String indexName) { - - try (RestHighLevelClient client = restHighLevelClient()) { - - return 0L == SearchHitsUtil.getTotalCount(client - .search(new SearchRequest(indexName) - .source(SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery())), RequestOptions.DEFAULT) - .getHits()); - } - } - - public static OfType documentWithId(String id) { - return new DocumentLookup(id); - } - - public interface ExistsIn { - boolean existsIn(String index); - } - - public interface OfType extends ExistsIn { - ExistsIn ofType(String type); - } - - private static class DocumentLookup implements OfType { - - private String id; - - public DocumentLookup(String id) { - this.id = id; - } - - @Override - @SneakyThrows - public boolean existsIn(String index) { - - GetRequest request = new GetRequest(index).id(id); - try (RestHighLevelClient client = restHighLevelClient()) { - return client.get(request, RequestOptions.DEFAULT).isExists(); - } - } - - @Override - public ExistsIn ofType(String type) { - return this; - } - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/Utils.java b/src/test/java/org/springframework/data/elasticsearch/Utils.java deleted file mode 100644 index 3aedcabb9..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/Utils.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2015-2020 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; - -import java.util.Arrays; -import java.util.UUID; - -import org.elasticsearch.client.Client; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.join.ParentJoinPlugin; -import org.elasticsearch.node.Node; -import org.elasticsearch.node.NodeValidationException; -import org.elasticsearch.transport.Netty4Plugin; -import org.springframework.data.elasticsearch.client.NodeClientFactoryBean; - -/** - * @author Mohsin Husen - * @author Artur Konczak - * @author Ilkang Na - * @author Peter-Josef Meisch - * @author Roman Puchkovskiy - * @author Subhobrata Dey - */ -public class Utils { - - public static Node getNode() { - String pathHome = "src/test/resources/test-home-dir"; - String pathData = "target/elasticsearchTestData"; - String clusterName = UUID.randomUUID().toString(); - - return new NodeClientFactoryBean.TestNode( // - Settings.builder() // - .put("transport.type", "netty4") // - .put("http.type", "netty4") // - .put("path.home", pathHome) // - .put("path.data", pathData) // - .put("cluster.name", clusterName) // - .put("node.max_local_storage_nodes", 100)// - // the following 3 settings are needed to avoid problems on big, but - // almost full filesystems, see DATAES-741 - .put("cluster.routing.allocation.disk.watermark.low", "1gb")// - .put("cluster.routing.allocation.disk.watermark.high", "1gb")// - .put("cluster.routing.allocation.disk.watermark.flood_stage", "1gb")// - .build(), // - Arrays.asList(Netty4Plugin.class, ParentJoinPlugin.class)); - } - - public static Client getNodeClient() throws NodeValidationException { - return getNode().start().client(); - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java index b5bc533a6..e5d14c96c 100644 --- a/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClientTests.java @@ -18,9 +18,9 @@ import static org.assertj.core.api.Assertions.*; import lombok.SneakyThrows; +import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import java.io.IOException; import java.time.Duration; import java.util.Arrays; import java.util.Collections; @@ -39,11 +39,6 @@ import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.action.update.UpdateRequest; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; -import org.elasticsearch.client.indices.CreateIndexRequest; -import org.elasticsearch.client.indices.GetIndexRequest; -import org.elasticsearch.client.indices.PutMappingRequest; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.query.QueryBuilders; @@ -58,13 +53,17 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.data.elasticsearch.TestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.client.ClientConfiguration; -import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; +import org.springframework.data.elasticsearch.core.ReactiveIndexOperations; +import org.springframework.data.elasticsearch.core.document.Document; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.http.HttpHeaders; -import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; /** @@ -76,21 +75,27 @@ * @author Thomas Geese */ @SpringIntegrationTest -@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) +@ContextConfiguration(classes = { ReactiveElasticsearchClientTests.Config.class }) public class ReactiveElasticsearchClientTests { + @Configuration + static class Config extends ReactiveElasticsearchRestTemplateConfiguration { + @Override + @Bean + public ReactiveElasticsearchClient reactiveElasticsearchClient() { + return super.reactiveElasticsearchClient(); + } + } + static final String INDEX_I = "idx-1-reactive-client-tests"; static final String INDEX_II = "idx-2-reactive-client-tests"; - static final String TYPE_I = "doc-type-1"; - static final String TYPE_II = "doc-type-2"; - // must be and not , otherwise UpdateRequest.doc() will use the overload with // (Object...) static final Map DOC_SOURCE; - RestHighLevelClient syncClient; - ReactiveElasticsearchClient client; + @Autowired ReactiveElasticsearchClient client; + @Autowired ReactiveElasticsearchOperations operations; static { @@ -103,19 +108,14 @@ public class ReactiveElasticsearchClientTests { @BeforeEach public void setUp() { - - syncClient = TestUtils.restHighLevelClient(); - client = TestUtils.reactiveClient(); - - TestUtils.deleteIndex(INDEX_I, INDEX_II); + operations.indexOps(IndexCoordinates.of(INDEX_I)).delete().block(); + operations.indexOps(IndexCoordinates.of(INDEX_II)).delete().block(); } @AfterEach - public void after() throws IOException { - - TestUtils.deleteIndex(INDEX_I, INDEX_II); - - syncClient.close(); + public void after() { + operations.indexOps(IndexCoordinates.of(INDEX_I)).delete().block(); + operations.indexOps(IndexCoordinates.of(INDEX_II)).delete().block(); } @Test // DATAES-488 @@ -157,7 +157,7 @@ public void getOnNonExistingIndexShouldThrowException() { @Test // DATAES-488 public void getShouldFetchDocumentById() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); client.get(new GetRequest(INDEX_I, id)) // .as(StepVerifier::create) // @@ -172,7 +172,7 @@ public void getShouldFetchDocumentById() { @Test // DATAES-488 public void getShouldCompleteForNonExistingDocuments() { - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); String id = "this-one-does-not-exist"; client.get(new GetRequest(INDEX_I, id)) // @@ -183,8 +183,8 @@ public void getShouldCompleteForNonExistingDocuments() { @Test // DATAES-488 public void multiGetShouldReturnAllDocumentsFromSameCollection() { - String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id1 = addSourceDocument().to(INDEX_I); + String id2 = addSourceDocument().to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // .add(INDEX_I, id1) // @@ -200,8 +200,8 @@ public void multiGetShouldReturnAllDocumentsFromSameCollection() { @Test // DATAES-488 public void multiGetShouldReturnAllExistingDocumentsFromSameCollection() { - String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id1 = addSourceDocument().to(INDEX_I); + addSourceDocument().to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // .add(INDEX_I, id1) // @@ -216,8 +216,8 @@ public void multiGetShouldReturnAllExistingDocumentsFromSameCollection() { @Test // DATAES-488 public void multiGetShouldSkipNonExistingDocuments() { - String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id1 = addSourceDocument().to(INDEX_I); + String id2 = addSourceDocument().to(INDEX_I); MultiGetRequest request = new MultiGetRequest() // .add(INDEX_I, id1) // @@ -234,8 +234,8 @@ public void multiGetShouldSkipNonExistingDocuments() { @Test // DATAES-488 public void multiGetShouldCompleteIfNothingFound() { - String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id1 = addSourceDocument().to(INDEX_I); + String id2 = addSourceDocument().to(INDEX_I); client.multiGet(new MultiGetRequest() // .add(INDEX_II, id1).add(INDEX_II, id2)) // @@ -246,8 +246,8 @@ public void multiGetShouldCompleteIfNothingFound() { @Test // DATAES-488 public void multiGetShouldReturnAllExistingDocumentsFromDifferentCollection() { - String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - String id2 = addSourceDocument().ofType(TYPE_II).to(INDEX_II); + String id1 = addSourceDocument().to(INDEX_I); + String id2 = addSourceDocument().to(INDEX_II); MultiGetRequest request = new MultiGetRequest() // .add(INDEX_I, id1) // @@ -263,7 +263,7 @@ public void multiGetShouldReturnAllExistingDocumentsFromDifferentCollection() { @Test // DATAES-488 public void existsReturnsTrueForExistingDocuments() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); client.exists(new GetRequest(INDEX_I, id)) // .as(StepVerifier::create) // @@ -274,7 +274,7 @@ public void existsReturnsTrueForExistingDocuments() { @Test // DATAES-488 public void existsReturnsFalseForNonExistingDocuments() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); client.exists(new GetRequest(INDEX_II, id)) // .as(StepVerifier::create) // @@ -285,7 +285,7 @@ public void existsReturnsFalseForNonExistingDocuments() { @Test // DATAES-488 public void indexShouldAddDocument() { - IndexRequest request = indexRequest(DOC_SOURCE, INDEX_I, TYPE_I); + IndexRequest request = indexRequest(); client.index(request) // .as(StepVerifier::create) // @@ -300,9 +300,9 @@ public void indexShouldAddDocument() { @Test // DATAES-488 public void indexShouldErrorForExistingDocuments() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); - IndexRequest request = indexRequest(DOC_SOURCE, INDEX_I, TYPE_I)// + IndexRequest request = indexRequest()// .id(id); client.index(request) // @@ -331,7 +331,7 @@ public void updateShouldUpsertNonExistingDocumentWhenUsedWithUpsert() { @Test // DATAES-488 public void updateShouldUpdateExistingDocument() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); UpdateRequest request = new UpdateRequest(INDEX_I, id) // .doc(Collections.singletonMap("dutiful", "farseer")); @@ -362,7 +362,7 @@ public void updateShouldErrorNonExistingDocumentWhenNotUpserted() { @Test // DATAES-488 public void deleteShouldRemoveExistingDocument() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); DeleteRequest request = new DeleteRequest(INDEX_I, id); @@ -375,7 +375,7 @@ public void deleteShouldRemoveExistingDocument() { @Test // DATAES-488 public void deleteShouldReturnNotFoundForNonExistingDocument() { - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); DeleteRequest request = new DeleteRequest(INDEX_I, "this-one-does-not-exist"); @@ -388,8 +388,8 @@ public void deleteShouldReturnNotFoundForNonExistingDocument() { @Test // DATAES-488 public void searchShouldFindExistingDocuments() { - addSourceDocument().ofType(TYPE_I).to(INDEX_I); - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); + addSourceDocument().to(INDEX_I); SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); @@ -401,9 +401,9 @@ public void searchShouldFindExistingDocuments() { } @Test // DATAES-488 - public void searchShouldCompleteIfNothingFound() throws IOException { + public void searchShouldCompleteIfNothingFound() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); @@ -414,10 +414,9 @@ public void searchShouldCompleteIfNothingFound() throws IOException { } @Test // DATAES-488 - @ElasticsearchVersion(asOf = "6.5.0") public void deleteByShouldRemoveExistingDocument() { - String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String id = addSourceDocument().to(INDEX_I); DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", id))); @@ -430,10 +429,9 @@ public void deleteByShouldRemoveExistingDocument() { } @Test // DATAES-488 - @ElasticsearchVersion(asOf = "6.5.0") public void deleteByEmitResultWhenNothingRemoved() { - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", "it-was-not-me"))); @@ -448,7 +446,7 @@ public void deleteByEmitResultWhenNothingRemoved() { @Test // DATAES-510 public void scrollShouldReadWhileEndNotReached() { - IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); + IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).to(INDEX_I)); SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); @@ -464,7 +462,7 @@ public void scrollShouldReadWhileEndNotReached() { @Test // DATAES-510 public void scrollShouldReadWhileTakeNotReached() { - IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); + IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).to(INDEX_I)); SearchRequest request = new SearchRequest(INDEX_I) // .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); @@ -479,9 +477,9 @@ public void scrollShouldReadWhileTakeNotReached() { } @Test // DATAES-569 - public void indexExistsShouldReturnTrueIfSo() throws IOException { + public void indexExistsShouldReturnTrueIfSo() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().existsIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // @@ -490,9 +488,9 @@ public void indexExistsShouldReturnTrueIfSo() throws IOException { } @Test // DATAES-569 - public void indexExistsShouldReturnFalseIfNot() throws IOException { + public void indexExistsShouldReturnFalseIfNot() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().existsIndex(request -> request.indices(INDEX_II)) // .as(StepVerifier::create) // @@ -501,20 +499,23 @@ public void indexExistsShouldReturnFalseIfNot() throws IOException { } @Test // DATAES-569, DATAES-678 - public void createIndex() throws IOException { + public void createIndex() { client.indices().createIndex(request -> request.index(INDEX_I)) // .as(StepVerifier::create) // .expectNext(true) // .verifyComplete(); - assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isTrue(); + operations.indexOps(IndexCoordinates.of(INDEX_I)).exists() // + .as(StepVerifier::create) // + .expectNext(true) // + .verifyComplete(); } @Test // DATAES-569 - public void createExistingIndexErrors() throws IOException { + public void createExistingIndexErrors() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().createIndex(request -> request.index(INDEX_I)) // .as(StepVerifier::create) // @@ -522,16 +523,20 @@ public void createExistingIndexErrors() throws IOException { } @Test // DATAES-569, DATAES-678 - public void deleteExistingIndex() throws IOException { + public void deleteExistingIndex() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().deleteIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // .expectNext(true) // .verifyComplete(); - assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse(); + operations.indexOps(IndexCoordinates.of(INDEX_I)) // + .exists() // + .as(StepVerifier::create) // + .expectNext(false) // + .verifyComplete(); } @Test // DATAES-569, DATAES-767 @@ -543,9 +548,9 @@ public void deleteNonExistingIndexErrors() { } @Test // DATAES-569 - public void openExistingIndex() throws IOException { + public void openExistingIndex() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().openIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // @@ -561,9 +566,9 @@ public void openNonExistingIndex() { } @Test // DATAES-569 - public void closeExistingIndex() throws IOException { + public void closeExistingIndex() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().openIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // @@ -579,9 +584,9 @@ public void closeNonExistingIndex() { } @Test // DATAES-569 - public void refreshIndex() throws IOException { + public void refreshIndex() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().refreshIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // @@ -597,14 +602,14 @@ public void refreshNonExistingIndex() { } @Test // DATAES-569 - public void updateMapping() throws IOException { + public void updateMapping() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); Map jsonMap = Collections.singletonMap("properties", Collections.singletonMap("message", Collections.singletonMap("type", "text"))); - client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // + client.indices().updateMapping(request -> request.indices(INDEX_I).source(jsonMap)) // .as(StepVerifier::create) // .expectNext(true) // .verifyComplete(); @@ -616,15 +621,15 @@ public void updateMappingNonExistingIndex() { Map jsonMap = Collections.singletonMap("properties", Collections.singletonMap("message", Collections.singletonMap("type", "text"))); - client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // + client.indices().updateMapping(request -> request.indices(INDEX_I).source(jsonMap)) // .as(StepVerifier::create) // .verifyError(ElasticsearchStatusException.class); } @Test // DATAES-569 - public void flushIndex() throws IOException { + public void flushIndex() { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block(); client.indices().flushIndex(request -> request.indices(INDEX_I)) // .as(StepVerifier::create) // @@ -641,8 +646,8 @@ public void flushNonExistingIndex() { @Test // DATAES-684 public void bulkShouldUpdateExistingDocument() { - String idFirstDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); - String idSecondDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); + String idFirstDoc = addSourceDocument().to(INDEX_I); + String idSecondDoc = addSourceDocument().to(INDEX_I); UpdateRequest requestFirstDoc = new UpdateRequest(INDEX_I, idFirstDoc) // .doc(Collections.singletonMap("dutiful", "farseer")); @@ -666,13 +671,15 @@ public void bulkShouldUpdateExistingDocument() { } @Test // DATAES-567 - public void aggregateReturnsAggregationResults() throws IOException { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + public void aggregateReturnsAggregationResults() { + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(INDEX_I)); + indexOps.create().block(); + Map jsonMap = Collections.singletonMap("properties", Collections.singletonMap("firstname", Collections.singletonMap("type", "keyword"))); - syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); + indexOps.putMapping(Mono.just(Document.from(jsonMap))).block(); - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); searchSourceBuilder.aggregation(AggregationBuilders.terms("terms").field("firstname")); @@ -685,13 +692,14 @@ public void aggregateReturnsAggregationResults() throws IOException { } @Test // DATAES-866 - public void suggestReturnsSuggestionResults() throws IOException { - syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); + public void suggestReturnsSuggestionResults() { + ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(INDEX_I)); + indexOps.create().block(); Map jsonMap = Collections.singletonMap("properties", Collections.singletonMap("firstname", Collections.singletonMap("type", "completion"))); - syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); + indexOps.putMapping(Mono.just(Document.from(jsonMap))).block(); - addSourceDocument().ofType(TYPE_I).to(INDEX_I); + addSourceDocument().to(INDEX_I); SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("firstname", new CompletionSuggestionBuilder("firstname").prefix("ch")); @@ -708,55 +716,43 @@ public void suggestReturnsSuggestionResults() throws IOException { .verifyComplete(); } - private AddToIndexOfType addSourceDocument() { + private AddToIndex addSourceDocument() { return add(DOC_SOURCE); } - private AddToIndexOfType add(Map source) { + private AddToIndex add(Map source) { return new AddDocument(source); } - private IndexRequest indexRequest(Map source, String index, String type) { + private IndexRequest indexRequest() { - return new IndexRequest(index) // + return new IndexRequest(ReactiveElasticsearchClientTests.INDEX_I) // .id(UUID.randomUUID().toString()) // - .source(source) // + .source(ReactiveElasticsearchClientTests.DOC_SOURCE) // .setRefreshPolicy(RefreshPolicy.IMMEDIATE) // .create(true); } @SneakyThrows - private String doIndex(Map source, String index, String type) { - return syncClient.index(indexRequest(source, index, type), RequestOptions.DEFAULT).getId(); - } - - interface AddToIndexOfType extends AddToIndex { - AddToIndex ofType(String type); + private String doIndex(Map source, String index) { + return operations.save(source, IndexCoordinates.of(index)).block().get("id").toString(); } interface AddToIndex { String to(String index); } - class AddDocument implements AddToIndexOfType { + class AddDocument implements AddToIndex { Map source; - @Nullable String type; AddDocument(Map source) { this.source = source; } - @Override - public AddToIndex ofType(String type) { - - this.type = type; - return this; - } - @Override public String to(String index) { - return doIndex(new LinkedHashMap<>(source), index, type); + return doIndex(new LinkedHashMap<>(source), index); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java index a757c0844..e51bd43bc 100644 --- a/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/core/ReactiveElasticsearchTemplateTests.java @@ -28,6 +28,7 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import java.lang.Boolean; import java.lang.Long; import java.lang.Object; import java.net.ConnectException; @@ -49,6 +50,9 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.data.annotation.Id; @@ -56,7 +60,6 @@ import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; -import org.springframework.data.elasticsearch.TestUtils; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; @@ -64,7 +67,7 @@ import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.query.*; -import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.util.StringUtils; @@ -83,25 +86,26 @@ @SpringIntegrationTest public class ReactiveElasticsearchTemplateTests { + @Configuration + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class }) + static class Config {} + static final String DEFAULT_INDEX = "reactive-template-test-index"; static final String ALTERNATE_INDEX = "reactive-template-tests-alternate-index"; - private ElasticsearchRestTemplate restTemplate; - private ReactiveElasticsearchTemplate template; - private IndexOperations indexOperations; + @Autowired private ReactiveElasticsearchTemplate template; + private ReactiveIndexOperations indexOperations; @BeforeEach public void setUp() { - restTemplate = new ElasticsearchRestTemplate(TestUtils.restHighLevelClient()); - indexOperations = restTemplate.indexOps(SampleEntity.class); + indexOperations = template.indexOps(SampleEntity.class); deleteIndices(); - indexOperations.create(); - indexOperations.putMapping(SampleEntity.class); - indexOperations.refresh(); - - template = new ReactiveElasticsearchTemplate(TestUtils.reactiveClient(), restTemplate.getElasticsearchConverter()); + indexOperations.create() // + .then(indexOperations.putMapping(SampleEntity.class)) // + .then(indexOperations.refresh()) // + .block(); // } @AfterEach @@ -110,9 +114,13 @@ public void after() { } private void deleteIndices() { - TestUtils.deleteIndex(DEFAULT_INDEX, ALTERNATE_INDEX, "rx-template-test-index-this", "rx-template-test-index-that", - "test-index-reactive-optimistic-entity-template", - "test-index-reactive-optimistic-and-versioned-entity-template"); + template.indexOps(IndexCoordinates.of(DEFAULT_INDEX)).delete().block(); + template.indexOps(IndexCoordinates.of(ALTERNATE_INDEX)).delete().block(); + template.indexOps(IndexCoordinates.of("rx-template-test-index-this")).delete().block(); + template.indexOps(IndexCoordinates.of("rx-template-test-index-that")).delete().block(); + template.indexOps(IndexCoordinates.of("test-index-reactive-optimistic-entity-template")).delete().block(); + template.indexOps(IndexCoordinates.of("test-index-reactive-optimistic-and-versioned-entity-template")).delete() + .block(); } @Test // DATAES-504 @@ -147,10 +155,12 @@ public void insertWithIdShouldWork() { indexOperations.refresh(); - SearchHits result = restTemplate.search( - new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, - IndexCoordinates.of(DEFAULT_INDEX)); - assertThat(result).hasSize(1); + template + .search(new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, + IndexCoordinates.of(DEFAULT_INDEX)) // + .as(StepVerifier::create) // + .expectNextCount(1) // + .verifyComplete(); } @Test // DATAES-504 @@ -159,17 +169,17 @@ public void insertWithAutogeneratedIdShouldUpdateEntityId() { SampleEntity sampleEntity = SampleEntity.builder().message("wohoo").build(); template.save(sampleEntity) // - .as(StepVerifier::create) // - .consumeNextWith(it -> { - - assertThat(it.getId()).isNotNull(); - - indexOperations.refresh(); - assertThat(TestUtils.documentWithId(it.getId()).existsIn(DEFAULT_INDEX)).isTrue(); - }) // + .map(SampleEntity::getId) // + .flatMap(id -> indexOperations.refresh().thenReturn(id)) // + .flatMap(id -> documentWithIdExistsInIndex(id, DEFAULT_INDEX)).as(StepVerifier::create) // + .expectNext(true) // .verifyComplete(); } + private Mono documentWithIdExistsInIndex(String id, String index) { + return template.exists(id, IndexCoordinates.of(index)); + } + @Test // DATAES-504 public void insertWithExplicitIndexNameShouldOverwriteMetadata() { @@ -181,11 +191,11 @@ public void insertWithExplicitIndexNameShouldOverwriteMetadata() { .expectNextCount(1)// .verifyComplete(); - restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); - restTemplate.refresh(alternateIndex); + template.indexOps(IndexCoordinates.of(DEFAULT_INDEX)).refresh().block(); + template.indexOps(alternateIndex).refresh().block(); - assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse(); - assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue(); + assertThat(documentWithIdExistsInIndex(sampleEntity.getId(), DEFAULT_INDEX).block()).isFalse(); + assertThat(documentWithIdExistsInIndex(sampleEntity.getId(), ALTERNATE_INDEX).block()).isTrue(); } @Test // DATAES-504 @@ -266,16 +276,14 @@ public void getByIdWithExplicitIndexNameShouldOverwriteMetadata() { SampleEntity sampleEntity = randomEntity("some message"); - IndexQuery indexQuery = getIndexQuery(sampleEntity); - IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX); IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX); - restTemplate.index(indexQuery, alternateIndex); - indexOperations.refresh(); - - restTemplate.indexOps(defaultIndex).refresh(); - restTemplate.indexOps(alternateIndex).refresh(); + template.save(sampleEntity, alternateIndex) // + .then(indexOperations.refresh()) // + .then(template.indexOps(defaultIndex).refresh()) // + .then(template.indexOps(alternateIndex).refresh()) // + .block(); template.get(sampleEntity.getId(), SampleEntity.class, defaultIndex) // .as(StepVerifier::create) // @@ -612,7 +620,6 @@ public void deleteShouldCompleteWhenNothingDeleted() { } @Test // DATAES-519 - @ElasticsearchVersion(asOf = "6.5.0") public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() { CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test")); @@ -624,7 +631,6 @@ public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() { } @Test // DATAES-547 - @ElasticsearchVersion(asOf = "6.5.0") public void shouldDeleteAcrossIndex() { String indexPrefix = "rx-template-test-index"; @@ -637,8 +643,7 @@ public void shouldDeleteAcrossIndex() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(thisIndex); - restTemplate.refresh(thatIndex); + template.indexOps(thisIndex).refresh().then(template.indexOps(thatIndex).refresh()).block(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "test")) // @@ -649,11 +654,10 @@ public void shouldDeleteAcrossIndex() { .expectNext(2L) // .verifyComplete(); - TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); + template.indexOps(thisIndex).delete().then(template.indexOps(thatIndex).delete()).block(); } @Test // DATAES-547 - @ElasticsearchVersion(asOf = "6.5.0") public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { String indexPrefix = "rx-template-test-index"; @@ -666,8 +670,7 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .as(StepVerifier::create)// .verifyComplete(); - restTemplate.refresh(thisIndex); - restTemplate.refresh(thatIndex); + template.indexOps(thisIndex).refresh().then(template.indexOps(thatIndex).refresh()).block(); NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // .withQuery(termQuery("message", "negative")) // @@ -678,11 +681,10 @@ public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { .expectNext(0L) // .verifyComplete(); - TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); + template.indexOps(thisIndex).delete().then(template.indexOps(thatIndex).delete()).block(); } @Test // DATAES-504 - @ElasticsearchVersion(asOf = "6.5.0") public void deleteByQueryShouldReturnNumberOfDeletedDocuments() { index(randomEntity("test message"), randomEntity("test test"), randomEntity("some message")); @@ -696,7 +698,6 @@ public void deleteByQueryShouldReturnNumberOfDeletedDocuments() { } @Test // DATAES-504 - @ElasticsearchVersion(asOf = "6.5.0") public void deleteByQueryShouldReturnZeroIfNothingDeleted() { index(randomEntity("test message")); @@ -896,7 +897,8 @@ void searchShouldReturnSeqNoPrimaryTerm() { OptimisticEntity original = new OptimisticEntity(); original.setMessage("It's fine"); OptimisticEntity saved = template.save(original).block(); - restTemplate.refresh(OptimisticEntity.class); + + template.indexOps(OptimisticEntity.class).refresh().block(); template .search(searchQueryForOne(saved.getId()), OptimisticEntity.class, @@ -1050,12 +1052,10 @@ private void index(SampleEntity... entities) { IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX); if (entities.length == 1) { - restTemplate.index(getIndexQuery(entities[0]), indexCoordinates); + template.save(entities[0], indexCoordinates).then(indexOperations.refresh()).block(); } else { - restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates); + template.saveAll(Mono.just(Arrays.asList(entities)), indexCoordinates).then(indexOperations.refresh()).block(); } - - indexOperations.refresh(); } @Data diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java deleted file mode 100644 index 8d936c268..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersion.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2018-2020 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.junit.junit4; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * @author Christoph Strobl - */ -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.METHOD) -@Documented -public @interface ElasticsearchVersion { - - /** - * Inclusive lower bound of Elasticsearch server range. - * - * @return {@code 0.0.0} by default. - */ - String asOf() default "0.0.0"; - - /** - * Exclusive upper bound of Elasticsearch server range. - * - * @return {@code 9999.9999.9999} by default. - */ - String until() default "9999.9999.9999"; -} diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java deleted file mode 100644 index d71c1f8b7..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/ElasticsearchVersionRule.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2018-2020 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.junit.junit4; - -import java.util.concurrent.atomic.AtomicReference; - -import org.junit.AssumptionViolatedException; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.elasticsearch.TestUtils; -import org.springframework.data.util.Version; - -/** - * @author Christoph Strobl - */ -public class ElasticsearchVersionRule implements TestRule { - - private static final Logger logger = LoggerFactory.getLogger(ElasticsearchVersionRule.class); - - private static final Version ANY = new Version(9999, 9999, 9999); - private static final Version DEFAULT_HIGH = ANY; - private static final Version DEFAULT_LOW = new Version(0, 0, 0); - - private final static AtomicReference currentVersion = new AtomicReference<>(null); - private final Version minVersion; - private final Version maxVersion; - - public ElasticsearchVersionRule(Version min, Version max) { - - this.minVersion = min; - this.maxVersion = max; - } - - public static ElasticsearchVersionRule any() { - return new ElasticsearchVersionRule(ANY, ANY); - } - - public static ElasticsearchVersionRule atLeast(Version minVersion) { - return new ElasticsearchVersionRule(minVersion, DEFAULT_HIGH); - } - - public static ElasticsearchVersionRule atMost(Version maxVersion) { - return new ElasticsearchVersionRule(DEFAULT_LOW, maxVersion); - } - - @Override - public Statement apply(Statement base, Description description) { - - return new Statement() { - - @Override - public void evaluate() throws Throwable { - - if (!getCurrentVersion().equals(ANY)) { - - Version minVersion = ElasticsearchVersionRule.this.minVersion.equals(ANY) ? DEFAULT_LOW - : ElasticsearchVersionRule.this.minVersion; - Version maxVersion = ElasticsearchVersionRule.this.maxVersion.equals(ANY) ? DEFAULT_HIGH - : ElasticsearchVersionRule.this.maxVersion; - - if (description.getAnnotation(ElasticsearchVersion.class) != null) { - ElasticsearchVersion version = description.getAnnotation(ElasticsearchVersion.class); - if (version != null) { - - Version expectedMinVersion = Version.parse(version.asOf()); - if (!expectedMinVersion.equals(ANY) && !expectedMinVersion.equals(DEFAULT_LOW)) { - minVersion = expectedMinVersion; - } - - Version expectedMaxVersion = Version.parse(version.until()); - if (!expectedMaxVersion.equals(ANY) && !expectedMaxVersion.equals(DEFAULT_HIGH)) { - maxVersion = expectedMaxVersion; - } - } - } - - validateVersion(minVersion, maxVersion); - } - - base.evaluate(); - } - }; - } - - private void validateVersion(Version min, Version max) { - - if (getCurrentVersion().isLessThan(min) || getCurrentVersion().isGreaterThanOrEqualTo(max)) { - - throw new AssumptionViolatedException(String - .format("Expected Elasticsearch server to be in range (%s, %s] but found %s", min, max, currentVersion)); - } - - } - - private Version getCurrentVersion() { - - if (currentVersion.get() == null) { - - Version current = fetchCurrentVersion(); - if (currentVersion.compareAndSet(null, current)) { - logger.info("Running Elasticsearch " + current); - } - } - - return currentVersion.get(); - } - - private Version fetchCurrentVersion() { - return TestUtils.serverVersion(); - } - - @Override - public String toString() { - return getCurrentVersion().toString(); - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java deleted file mode 100644 index 007704d6c..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/TestNodeResource.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2019-2020 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.junit.junit4; - -import java.io.IOException; - -import org.elasticsearch.client.Client; -import org.elasticsearch.node.Node; -import org.junit.rules.ExternalResource; -import org.springframework.data.elasticsearch.Utils; -import org.springframework.util.Assert; - -/** - * JUnit4 Rule that sets up and tears down a local Elasticsearch node. - * - * @author Peter-Josef Meisch - */ -public class TestNodeResource extends ExternalResource { - - private Node node; - - @Override - protected void before() throws Throwable { - node = Utils.getNode(); - node.start(); - } - - @Override - protected void after() { - if (node != null) { - try { - node.close(); - } catch (IOException ignored) {} - } - } - - public Client client() { - Assert.notNull(node, "node is not initialized"); - return node.client(); - } -} diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/package-info.java b/src/test/java/org/springframework/data/elasticsearch/junit/junit4/package-info.java deleted file mode 100644 index aacd0ea7f..000000000 --- a/src/test/java/org/springframework/data/elasticsearch/junit/junit4/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * interfaces, annotations and classes related to JUnit 4 test handling. - */ -@org.springframework.lang.NonNullApi -package org.springframework.data.elasticsearch.junit.junit4; diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java index eb5d624b6..9721836bd 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnection.java @@ -15,42 +15,44 @@ */ package org.springframework.data.elasticsearch.junit.jupiter; -import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import org.elasticsearch.node.Node; -import org.elasticsearch.node.NodeValidationException; import org.junit.jupiter.api.extension.ExtensionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.elasticsearch.Utils; +import org.springframework.data.elasticsearch.support.VersionInfo; import org.springframework.lang.Nullable; import org.springframework.util.StringUtils; +import org.testcontainers.elasticsearch.ElasticsearchContainer; /** - * This class manages the connection to an Elasticsearch Cluster, starting a local one if necessary. The information - * about the ClusterConnection is stored both as a variable in the instance for direct access from JUnit 5 and in a - * static ThreadLocal accessible with the {@link ClusterConnection#clusterConnectionInfo()} - * method to be integrated in the Spring setup + * This class manages the connection to an Elasticsearch Cluster, starting a containerized one if necessary. The + * information about the ClusterConnection is stored both as a variable in the instance for direct access from JUnit 5 + * and in a static ThreadLocal accessible with the + * {@link ClusterConnection#clusterConnectionInfo()} method to be integrated in the Spring setup * * @author Peter-Josef Meisch */ -class ClusterConnection implements ExtensionContext.Store.CloseableResource { +public class ClusterConnection implements ExtensionContext.Store.CloseableResource { + private static final Logger LOGGER = LoggerFactory.getLogger(ClusterConnection.class); + private static final int ELASTICSEARCH_DEFAULT_PORT = 9200; + private static final int ELASTICSEARCH_DEFAULT_TRANSPORT_PORT = 9300; + private static final String ELASTICSEARCH_DEFAULT_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch"; + private static final ThreadLocal clusterConnectionInfoThreadLocal = new ThreadLocal<>(); - private Node node; - private final ClusterConnectionInfo clusterConnectionInfo; + @Nullable private final ClusterConnectionInfo clusterConnectionInfo; /** - * creates the ClusterConnection, starting a local node if necessary. + * creates the ClusterConnection, starting a container if necessary. * * @param clusterUrl if null or empty a local cluster is tarted */ public ClusterConnection(@Nullable String clusterUrl) { - clusterConnectionInfo = StringUtils.isEmpty(clusterUrl) ? startLocalNode() : parseUrl(clusterUrl); + clusterConnectionInfo = StringUtils.isEmpty(clusterUrl) ? startElasticsearchContainer() : parseUrl(clusterUrl); if (clusterConnectionInfo != null) { LOGGER.debug(clusterConnectionInfo.toString()); @@ -68,6 +70,7 @@ public static ClusterConnectionInfo clusterConnectionInfo() { return clusterConnectionInfoThreadLocal.get(); } + @Nullable public ClusterConnectionInfo getClusterConnectionInfo() { return clusterConnectionInfo; } @@ -94,18 +97,27 @@ private ClusterConnectionInfo parseUrl(String clusterUrl) { } - private @Nullable ClusterConnectionInfo startLocalNode() { - LOGGER.debug("starting local node"); + @Nullable + private ClusterConnectionInfo startElasticsearchContainer() { + + LOGGER.debug("Starting Elasticsearch Container"); try { - node = Utils.getNode(); - node.start(); + String elasticsearchVersion = VersionInfo.versionProperties() + .getProperty(VersionInfo.VERSION_ELASTICSEARCH_CLIENT); + + String dockerImageName = ELASTICSEARCH_DEFAULT_IMAGE + ':' + elasticsearchVersion; + LOGGER.debug("Docker image: {}", dockerImageName); + ElasticsearchContainer elasticsearchContainer = new ElasticsearchContainer(dockerImageName); + elasticsearchContainer.start(); return ClusterConnectionInfo.builder() // - .withHostAndPort("localhost", 9200) // - .withClient(node.client()) // + .withHostAndPort(elasticsearchContainer.getHost(), + elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_PORT)) // + .withTransportPort(elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_TRANSPORT_PORT)) // + .withElasticsearchContainer(elasticsearchContainer) // .build(); - } catch (NodeValidationException e) { - LOGGER.error("could not start local node", e); + } catch (Exception e) { + LOGGER.error("Could not start Elasticsearch container", e); } return null; @@ -114,12 +126,11 @@ private ClusterConnectionInfo parseUrl(String clusterUrl) { @Override public void close() { - if (node != null) { - LOGGER.debug("closing node"); - try { - node.close(); - } catch (IOException ignored) {} + if (clusterConnectionInfo != null && clusterConnectionInfo.getElasticsearchContainer() != null) { + LOGGER.debug("Stopping container"); + clusterConnectionInfo.getElasticsearchContainer().stop(); } + LOGGER.debug("closed"); } } diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java index 33884dbc6..bd45bffd7 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ClusterConnectionInfo.java @@ -15,16 +15,15 @@ */ package org.springframework.data.elasticsearch.junit.jupiter; -import org.elasticsearch.client.Client; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.testcontainers.elasticsearch.ElasticsearchContainer; /** - * The information about the ClusterConnection. the {@link #client} field is only set if a local node is started, - * otherwise it is null.
+ * The information about the ClusterConnection.
* The {@link #host}, {@link #httpPort} and {@link #useSsl} values specify the values needed to connect to the cluster * with a rest client for both a local started cluster and for one defined by the cluster URL when creating the - * {@link ClusterConnection}.
+ * {@link ClusterConnection}.
* The object must be created by using a {@link ClusterConnectionInfo.Builder}. * * @author Peter-Josef Meisch @@ -33,23 +32,32 @@ public final class ClusterConnectionInfo { private final boolean useSsl; private final String host; private final int httpPort; - private final Client client; + private final int transportPort; + private final String clusterName; + @Nullable private final ElasticsearchContainer elasticsearchContainer; public static Builder builder() { return new Builder(); } - private ClusterConnectionInfo(String host, int httpPort, boolean useSsl, Client client) { + private ClusterConnectionInfo(String host, int httpPort, boolean useSsl, int transportPort, + @Nullable ElasticsearchContainer elasticsearchContainer) { this.host = host; this.httpPort = httpPort; this.useSsl = useSsl; - this.client = client; + this.transportPort = transportPort; + this.elasticsearchContainer = elasticsearchContainer; + this.clusterName = "docker-cluster"; } @Override public String toString() { - return "ClusterConnectionInfo{" + "useSsl=" + useSsl + ", host='" + host + '\'' + ", httpPort=" + httpPort - + ", client=" + client + '}'; + return "ClusterConnectionInfo{" + // + "useSsl=" + useSsl + // + ", host='" + host + '\'' + // + ", httpPort=" + httpPort + // + ", transportPort=" + transportPort + // + '}'; // } public String getHost() { @@ -60,20 +68,29 @@ public int getHttpPort() { return httpPort; } + public int getTransportPort() { + return transportPort; + } + + public String getClusterName() { + return clusterName; + } + public boolean isUseSsl() { return useSsl; } @Nullable - public Client getClient() { - return client; + public ElasticsearchContainer getElasticsearchContainer() { + return elasticsearchContainer; } public static class Builder { boolean useSsl = false; private String host; private int httpPort; - private Client client = null; + private int transportPort; + @Nullable private ElasticsearchContainer elasticsearchContainer; public Builder withHostAndPort(String host, int httpPort) { Assert.hasLength(host, "host must not be empty"); @@ -87,13 +104,18 @@ public Builder useSsl(boolean useSsl) { return this; } - public Builder withClient(Client client) { - this.client = client; + public Builder withTransportPort(int transportPort) { + this.transportPort = transportPort; + return this; + } + + public Builder withElasticsearchContainer(ElasticsearchContainer elasticsearchContainer) { + this.elasticsearchContainer = elasticsearchContainer; return this; } public ClusterConnectionInfo build() { - return new ClusterConnectionInfo(host, httpPort, useSsl, client); + return new ClusterConnectionInfo(host, httpPort, useSsl, transportPort, elasticsearchContainer); } } } diff --git a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java index 8795f3c81..03a42f2cf 100644 --- a/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java +++ b/src/test/java/org/springframework/data/elasticsearch/junit/jupiter/ElasticsearchTemplateConfiguration.java @@ -15,7 +15,14 @@ */ package org.springframework.data.elasticsearch.junit.jupiter; +import java.net.InetAddress; +import java.net.UnknownHostException; + import org.elasticsearch.client.Client; +import org.elasticsearch.client.transport.TransportClient; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.transport.TransportAddress; +import org.elasticsearch.transport.client.PreBuiltTransportClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; @@ -32,8 +39,14 @@ public class ElasticsearchTemplateConfiguration extends ElasticsearchConfigurationSupport { @Bean - public Client elasticsearchClient(ClusterConnectionInfo clusterConnectionInfo) { - return clusterConnectionInfo.getClient(); + public Client elasticsearchClient(ClusterConnectionInfo clusterConnectionInfo) throws UnknownHostException { + + Settings settings = Settings.builder().put("cluster.name", clusterConnectionInfo.getClusterName()).build(); + TransportClient client = new PreBuiltTransportClient(settings); + client.addTransportAddress(new TransportAddress(InetAddress.getByName(clusterConnectionInfo.getHost()), + clusterConnectionInfo.getTransportPort())); + + return client; } @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java index 6eafb7cc4..b4e12beff 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/CdiRepositoryTests.java @@ -35,12 +35,14 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.data.annotation.Id; 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.InnerField; import org.springframework.data.elasticsearch.annotations.MultiField; +import org.springframework.data.elasticsearch.junit.jupiter.SpringDataElasticsearchExtension; import org.springframework.lang.Nullable; /** @@ -49,6 +51,7 @@ * @author Christoph Strobl * @author Peter-Josef Meisch */ +@ExtendWith(SpringDataElasticsearchExtension.class) public class CdiRepositoryTests { @Nullable private static CdiTestContainer cdiContainer; diff --git a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchOperationsProducer.java similarity index 51% rename from src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java rename to src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchOperationsProducer.java index 2a4a07b16..4c5a6ae34 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchTemplateProducer.java +++ b/src/test/java/org/springframework/data/elasticsearch/repositories/cdi/ElasticsearchOperationsProducer.java @@ -19,33 +19,31 @@ import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; -import org.elasticsearch.client.Client; -import org.elasticsearch.node.NodeValidationException; -import org.springframework.data.elasticsearch.Utils; +import org.elasticsearch.client.RestHighLevelClient; +import org.springframework.data.elasticsearch.client.ClientConfiguration; +import org.springframework.data.elasticsearch.client.RestClients; import org.springframework.data.elasticsearch.core.ElasticsearchOperations; -import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; +import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnection; +import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnectionInfo; /** * @author Mohsin Husen + * @author Peter-Josef Meisch */ @ApplicationScoped -class ElasticsearchTemplateProducer { +class ElasticsearchOperationsProducer { @Produces - public Client createNodeClient() throws NodeValidationException { - return Utils.getNodeClient(); - } - - @Produces - public ElasticsearchOperations createElasticsearchTemplate(Client client) { - return new ElasticsearchTemplate(client); + public ElasticsearchOperations createElasticsearchTemplate(RestHighLevelClient restHighLevelClient) { + return new ElasticsearchRestTemplate(restHighLevelClient); } @Produces @OtherQualifier @PersonDB - public ElasticsearchOperations createQualifiedElasticsearchTemplate(Client client) { - return new ElasticsearchTemplate(client); + public ElasticsearchOperations createQualifiedElasticsearchTemplate(RestHighLevelClient restHighLevelClient) { + return new ElasticsearchRestTemplate(restHighLevelClient); } @PreDestroy @@ -53,4 +51,15 @@ public void shutdown() { // remove everything to avoid conflicts with other tests in case server not shut down properly } + @Produces + public RestHighLevelClient elasticsearchClient() { + // we rely on the tests being run with the SpringDataElasticsearchExtension class that sets up a containerized ES. + ClusterConnectionInfo connectionInfo = ClusterConnection.clusterConnectionInfo(); + + ClientConfiguration clientConfiguration = ClientConfiguration.builder() // + .connectedTo(connectionInfo.getHost() + ':' + connectionInfo.getHttpPort()) // + .build(); + + return RestClients.create(clientConfiguration).rest(); + } } diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java index 3745c3efb..228c74d66 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/config/ReactiveElasticsearchRepositoriesRegistrarTests.java @@ -26,13 +26,12 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; import org.springframework.data.annotation.Id; -import org.springframework.data.elasticsearch.TestUtils; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.test.context.ContextConfiguration; @@ -46,14 +45,9 @@ public class ReactiveElasticsearchRepositoriesRegistrarTests { @Configuration + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class }) @EnableReactiveElasticsearchRepositories(considerNestedRepositories = true) - static class Config { - - @Bean - public ReactiveElasticsearchTemplate reactiveElasticsearchTemplate() { - return new ReactiveElasticsearchTemplate(TestUtils.reactiveClient()); - } - } + static class Config {} @Autowired ReactiveSampleEntityRepository repository; @Autowired ApplicationContext context; @@ -72,8 +66,7 @@ interface ReactiveSampleEntityRepository extends ReactiveElasticsearchRepository @NoArgsConstructor @AllArgsConstructor @Builder - @Document(indexName = "test-index-sample-reactive-repositories-registrar", - replicas = 0, refreshInterval = "-1") + @Document(indexName = "test-index-sample-reactive-repositories-registrar", replicas = 0, refreshInterval = "-1") static class SampleEntity { @Id private String id; diff --git a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java index 05c2bed0f..1203bea49 100644 --- a/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java +++ b/src/test/java/org/springframework/data/elasticsearch/repository/support/SimpleReactiveElasticsearchRepositoryTests.java @@ -27,23 +27,13 @@ import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import java.io.IOException; import java.lang.Boolean; import java.lang.Long; -import java.lang.Object; import java.util.Arrays; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; -import java.util.UUID; import java.util.stream.IntStream; import org.elasticsearch.ElasticsearchStatusException; -import org.elasticsearch.action.bulk.BulkRequest; -import org.elasticsearch.action.index.IndexRequest; -import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; -import org.elasticsearch.client.RequestOptions; -import org.elasticsearch.client.RestHighLevelClient; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -57,22 +47,19 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Order; -import org.springframework.data.elasticsearch.TestUtils; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Highlight; import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.Query; -import org.springframework.data.elasticsearch.annotations.Score; -import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; -import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration; +import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations; import org.springframework.data.elasticsearch.core.SearchHit; -import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; +import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; +import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.test.context.ContextConfiguration; -import org.springframework.util.StringUtils; /** * @author Christoph Strobl @@ -83,38 +70,37 @@ public class SimpleReactiveElasticsearchRepositoryTests { @Configuration - @Import({ ElasticsearchRestTemplateConfiguration.class }) + @Import({ ReactiveElasticsearchRestTemplateConfiguration.class }) @EnableReactiveElasticsearchRepositories(considerNestedRepositories = true) - static class Config extends AbstractReactiveElasticsearchConfiguration { - - @Override - public ReactiveElasticsearchClient reactiveElasticsearchClient() { - return TestUtils.reactiveClient(); - } - } + static class Config {} static final String INDEX = "test-index-sample-simple-reactive"; - static final String TYPE = "test-type"; - @Autowired ReactiveSampleEntityRepository repository; + @Autowired ReactiveElasticsearchOperations operations; + @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Autowired ReactiveSampleEntityRepository repository; @BeforeEach public void setUp() { - TestUtils.deleteIndex(INDEX); + operations.indexOps(IndexCoordinates.of(INDEX)).delete().block(); } @AfterEach void after() { - TestUtils.deleteIndex(INDEX); + operations.indexOps(IndexCoordinates.of(INDEX)).delete().block(); } @Test // DATAES-519 public void saveShouldSaveSingleEntity() { repository.save(SampleEntity.builder().build()) // + .map(SampleEntity::getId) // + .flatMap(this::documentWithIdExistsInIndex) // .as(StepVerifier::create) // - .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // - .verifyComplete(); + .expectNext(true).verifyComplete(); + } + + private Mono documentWithIdExistsInIndex(String id) { + return operations.exists(id, IndexCoordinates.of(INDEX)); } @Test // DATAES-519 @@ -123,10 +109,12 @@ public void saveShouldComputeMultipleEntities() { repository .saveAll(Arrays.asList(SampleEntity.builder().build(), SampleEntity.builder().build(), SampleEntity.builder().build())) // + .map(SampleEntity::getId) // + .flatMap(this::documentWithIdExistsInIndex) // .as(StepVerifier::create) // - .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // - .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // - .consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // + .expectNext(true) // + .expectNext(true) // + .expectNext(true) // .verifyComplete(); } @@ -138,11 +126,12 @@ public void findByIdShouldErrorIfIndexDoesNotExist() { } @Test // DATAES-519 - public void findShouldRetrieveSingleEntityById() throws IOException { + public void findShouldRetrieveSingleEntityById() { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // - SampleEntity.builder().id("id-three").build()); + SampleEntity.builder().id("id-three").build()) // + .block(); repository.findById("id-two").as(StepVerifier::create)// .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-two")) // @@ -150,23 +139,25 @@ public void findShouldRetrieveSingleEntityById() throws IOException { } @Test // DATAES-519 - public void findByIdShouldCompleteIfNothingFound() throws IOException { + public void findByIdShouldCompleteIfNothingFound() { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // - SampleEntity.builder().id("id-three").build()); + SampleEntity.builder().id("id-three").build()) // + .block(); repository.findById("does-not-exist").as(StepVerifier::create) // .verifyComplete(); } @Test // DATAES-720 - public void findAllShouldReturnAllElements() throws IOException { + public void findAllShouldReturnAllElements() { // make sure to be above the default page size of the Query interface int count = DEFAULT_PAGE_SIZE * 2; bulkIndex(IntStream.range(1, count + 1) // .mapToObj(it -> SampleEntity.builder().id(String.valueOf(it)).build()) // - .toArray(SampleEntity[]::new)); + .toArray(SampleEntity[]::new)) // + .block(); repository.findAll() // .as(StepVerifier::create) // @@ -180,11 +171,12 @@ public void findAllByIdByIdShouldCompleteIfIndexDoesNotExist() { } @Test // DATAES-519 - public void findAllByIdShouldRetrieveMatchingDocuments() throws IOException { + public void findAllByIdShouldRetrieveMatchingDocuments() { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // - SampleEntity.builder().id("id-three").build()); + SampleEntity.builder().id("id-three").build()) // + .block(); repository.findAllById(Arrays.asList("id-one", "id-two")) // .as(StepVerifier::create)// @@ -194,11 +186,12 @@ public void findAllByIdShouldRetrieveMatchingDocuments() throws IOException { } @Test // DATAES-519 - public void findAllByIdShouldCompleteWhenNothingFound() throws IOException { + public void findAllByIdShouldCompleteWhenNothingFound() { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // - SampleEntity.builder().id("id-three").build()); + SampleEntity.builder().id("id-three").build()) // + .block(); repository.findAllById(Arrays.asList("can't", "touch", "this")) // .as(StepVerifier::create)// @@ -206,11 +199,12 @@ public void findAllByIdShouldCompleteWhenNothingFound() throws IOException { } @Test // DATAES-717 - void shouldReturnFluxOfSearchHit() throws IOException { + void shouldReturnFluxOfSearchHit() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), // - SampleEntity.builder().id("id-three").message("message").build()); + SampleEntity.builder().id("id-three").message("message").build()) // + .block(); repository.queryAllByMessage("message") // .as(StepVerifier::create) // @@ -220,11 +214,12 @@ void shouldReturnFluxOfSearchHit() throws IOException { } @Test // DATAES-717 - void shouldReturnFluxOfSearchHitForStringQuery() throws IOException { + void shouldReturnFluxOfSearchHitForStringQuery() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), // - SampleEntity.builder().id("id-three").message("message").build()); + SampleEntity.builder().id("id-three").message("message").build()) // + .block(); repository.queryByMessageWithString("message") // .as(StepVerifier::create) // @@ -234,11 +229,12 @@ void shouldReturnFluxOfSearchHitForStringQuery() throws IOException { } @Test // DATAES-372 - void shouldReturnHighlightsOnAnnotatedMethod() throws IOException { + void shouldReturnHighlightsOnAnnotatedMethod() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), // - SampleEntity.builder().id("id-three").message("message").build()); + SampleEntity.builder().id("id-three").message("message").build()) // + .block(); repository.queryAllByMessage("message") // .as(StepVerifier::create) // @@ -251,11 +247,12 @@ void shouldReturnHighlightsOnAnnotatedMethod() throws IOException { } @Test // DATAES-372 - void shouldReturnHighlightsOnAnnotatedStringQueryMethod() throws IOException { + void shouldReturnHighlightsOnAnnotatedStringQueryMethod() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), // - SampleEntity.builder().id("id-three").message("message").build()); + SampleEntity.builder().id("id-three").message("message").build()) // + .block(); repository.queryByMessageWithString("message") // .as(StepVerifier::create) // @@ -275,20 +272,22 @@ public void countShouldErrorWhenIndexDoesNotExist() { } @Test // DATAES-519 - public void countShouldCountDocuments() throws IOException { + public void countShouldCountDocuments() { bulkIndex(SampleEntity.builder().id("id-one").build(), // - SampleEntity.builder().id("id-two").build()); + SampleEntity.builder().id("id-two").build()) // + .block(); repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete(); } @Test // DATAES-519 - public void existsByIdShouldReturnTrueIfExists() throws IOException { + public void existsByIdShouldReturnTrueIfExists() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.existsById("id-two") // .as(StepVerifier::create) // @@ -297,11 +296,12 @@ public void existsByIdShouldReturnTrueIfExists() throws IOException { } @Test // DATAES-519 - public void existsByIdShouldReturnFalseIfNotExists() throws IOException { + public void existsByIdShouldReturnFalseIfNotExists() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.existsById("wrecking ball") // .as(StepVerifier::create) // @@ -310,11 +310,12 @@ public void existsByIdShouldReturnFalseIfNotExists() throws IOException { } @Test // DATAES-519 - public void countShouldCountMatchingDocuments() throws IOException { + public void countShouldCountMatchingDocuments() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.countAllByMessage("test") // .as(StepVerifier::create) // @@ -323,11 +324,12 @@ public void countShouldCountMatchingDocuments() throws IOException { } @Test // DATAES-519 - public void existsShouldReturnTrueIfExists() throws IOException { + public void existsShouldReturnTrueIfExists() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.existsAllByMessage("message") // .as(StepVerifier::create) // @@ -336,11 +338,12 @@ public void existsShouldReturnTrueIfExists() throws IOException { } @Test // DATAES-519 - public void existsShouldReturnFalseIfNotExists() throws IOException { + public void existsShouldReturnFalseIfNotExists() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.existsAllByMessage("these days") // .as(StepVerifier::create) // @@ -349,10 +352,11 @@ public void existsShouldReturnFalseIfNotExists() throws IOException { } @Test // DATAES-519 - public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { + public void deleteByIdShouldCompleteIfNothingDeleted() { bulkIndex(SampleEntity.builder().id("id-one").build(), // - SampleEntity.builder().id("id-two").build()); + SampleEntity.builder().id("id-two").build()) // + .block(); repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); } @@ -365,61 +369,69 @@ public void deleteByIdShouldCompleteWhenIndexDoesNotExist() { } @Test // DATAES-519 - public void deleteByIdShouldDeleteEntry() throws IOException { + public void deleteByIdShouldDeleteEntry() { SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); - bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); + bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted) // + .block(); repository.deleteById(toBeDeleted.getId()).as(StepVerifier::create).verifyComplete(); - assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); + assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); } @Test // DATAES-519 - public void deleteShouldDeleteEntry() throws IOException { + public void deleteShouldDeleteEntry() { SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); - bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); + bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted) // + .block(); repository.delete(toBeDeleted).as(StepVerifier::create).verifyComplete(); - assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); + assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); } @Test // DATAES-519 - public void deleteAllShouldDeleteGivenEntries() throws IOException { + public void deleteAllShouldDeleteGivenEntries() { SampleEntity toBeDeleted = SampleEntity.builder().id("id-one").build(); SampleEntity hangInThere = SampleEntity.builder().id("id-two").build(); SampleEntity toBeDeleted2 = SampleEntity.builder().id("id-three").build(); - bulkIndex(toBeDeleted, hangInThere, toBeDeleted2); + bulkIndex(toBeDeleted, hangInThere, toBeDeleted2) // + .block(); repository.deleteAll(Arrays.asList(toBeDeleted, toBeDeleted2)).as(StepVerifier::create).verifyComplete(); - assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); - assertThat(TestUtils.documentWithId(toBeDeleted2.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); - assertThat(TestUtils.documentWithId(hangInThere.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); + assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse(); + assertThat(documentWithIdExistsInIndex(toBeDeleted2.getId()).block()).isFalse(); + assertThat(documentWithIdExistsInIndex(hangInThere.getId()).block()).isTrue(); } @Test // DATAES-519 - public void deleteAllShouldDeleteAllEntries() throws IOException { + public void deleteAllShouldDeleteAllEntries() { bulkIndex(SampleEntity.builder().id("id-one").build(), // SampleEntity.builder().id("id-two").build(), // - SampleEntity.builder().id("id-three").build()); + SampleEntity.builder().id("id-three").build()) // + .block(); repository.deleteAll().as(StepVerifier::create).verifyComplete(); - assertThat(TestUtils.isEmptyIndex(INDEX)).isTrue(); + repository.count() // + .as(StepVerifier::create) // + .expectNext(0L) // + .verifyComplete(); } @Test // DATAES-519 - public void derivedFinderMethodShouldBeExecutedCorrectly() throws IOException { + public void derivedFinderMethodShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.findAllByMessageLike("test") // .as(StepVerifier::create) // @@ -428,11 +440,12 @@ public void derivedFinderMethodShouldBeExecutedCorrectly() throws IOException { } @Test // DATAES-519 - public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() throws IOException { + public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.findAllByMessage(Mono.just("test")) // .as(StepVerifier::create) // @@ -441,11 +454,12 @@ public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() thr } @Test // DATAES-519 - public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() throws IOException { + public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // - SampleEntity.builder().id("id-three").message("test test").rate(2).build()); + SampleEntity.builder().id("id-three").message("test test").rate(2).build()) // + .block(); repository.findAllByMessageLikeOrderByRate("test") // .as(StepVerifier::create) // @@ -456,11 +470,12 @@ public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() throws } @Test // DATAES-519 - public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() throws IOException { + public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // - SampleEntity.builder().id("id-three").message("test test").rate(2).build()); + SampleEntity.builder().id("id-three").message("test test").rate(2).build()) // + .block(); repository.findAllByMessage("test", Sort.by(Order.asc("rate"))) // .as(StepVerifier::create) // @@ -471,11 +486,12 @@ public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() thro } @Test // DATAES-519 - public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() throws IOException { + public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // - SampleEntity.builder().id("id-three").message("test test").rate(2).build()); + SampleEntity.builder().id("id-three").message("test test").rate(2).build()) // + .block(); repository.findAllByMessage("test", PageRequest.of(0, 2, Sort.by(Order.asc("rate")))) // .as(StepVerifier::create) // @@ -485,11 +501,12 @@ public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() } @Test // DATAES-519 - public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() throws IOException { + public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.findFirstByMessageLike("test") // .as(StepVerifier::create) // @@ -498,11 +515,12 @@ public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() throws I } @Test // DATAES-519 - public void annotatedFinderMethodShouldBeExecutedCorrectly() throws IOException { + public void annotatedFinderMethodShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.findAllViaAnnotatedQueryByMessageLike("test") // .as(StepVerifier::create) // @@ -511,60 +529,25 @@ public void annotatedFinderMethodShouldBeExecutedCorrectly() throws IOException } @Test // DATAES-519 - public void derivedDeleteMethodShouldBeExecutedCorrectly() throws IOException { + public void derivedDeleteMethodShouldBeExecutedCorrectly() { bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), // - SampleEntity.builder().id("id-three").message("test test").build()); + SampleEntity.builder().id("id-three").message("test test").build()) // + .block(); repository.deleteAllByMessage("message") // .as(StepVerifier::create) // .expectNext(2L) // .verifyComplete(); - assertThat(TestUtils.documentWithId("id-one").ofType(TYPE).existsIn(INDEX)).isFalse(); - assertThat(TestUtils.documentWithId("id-two").ofType(TYPE).existsIn(INDEX)).isFalse(); - assertThat(TestUtils.documentWithId("id-three").ofType(TYPE).existsIn(INDEX)).isTrue(); - } - - private IndexRequest indexRequest(Map source, String index) { - - return new IndexRequest(index) // - .id(source.containsKey("id") ? source.get("id").toString() : UUID.randomUUID().toString()) // - .source(source) // - .create(true); - } - - private IndexRequest indexRequestFrom(SampleEntity entity) { - - Map target = new LinkedHashMap<>(); - - if (StringUtils.hasText(entity.getId())) { - target.put("id", entity.getId()); - } - - if (StringUtils.hasText(entity.getType())) { - target.put("type", entity.getType()); - } - - if (StringUtils.hasText(entity.getMessage())) { - target.put("message", entity.getMessage()); - } - - target.put("rate", entity.getRate()); - target.put("available", entity.isAvailable()); - - return indexRequest(target, INDEX); + assertThat(documentWithIdExistsInIndex("id-one").block()).isFalse(); + assertThat(documentWithIdExistsInIndex("id-two").block()).isFalse(); + assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue(); } - void bulkIndex(SampleEntity... entities) throws IOException { - - BulkRequest request = new BulkRequest(); - Arrays.stream(entities).forEach(it -> request.add(indexRequestFrom(it))); - - try (RestHighLevelClient client = TestUtils.restHighLevelClient()) { - client.bulk(request.setRefreshPolicy(RefreshPolicy.IMMEDIATE), RequestOptions.DEFAULT); - } + Mono bulkIndex(SampleEntity... entities) { + return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then(); } interface ReactiveSampleEntityRepository extends ReactiveCrudRepository { @@ -617,7 +600,6 @@ static class SampleEntity { private int rate; private boolean available; @Version private Long version; - @Score private float score; } } diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index b6c1f4d3f..7a6440457 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -16,4 +16,7 @@ + + + diff --git a/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.1.jar b/src/test/resources/test-home-dir/modules/analysis-common/analysis-common-7.8.1.jar deleted file mode 100644 index aa0cf109749623c2930207b6a39a88fb4c4c9e3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 199093 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�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 z

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�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 Qr^fK#C={{zd)e3iA8WS`YXATM diff --git a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties b/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties deleted file mode 100644 index 6ccdf0d2e..000000000 --- a/src/test/resources/test-home-dir/modules/analysis-common/plugin-descriptor.properties +++ /dev/null @@ -1,45 +0,0 @@ -# Elasticsearch plugin descriptor file -# This file must exist as 'plugin-descriptor.properties' inside a plugin. -# -### example plugin for "foo" -# -# foo.zip <-- zip file for the plugin, with this structure: -# |____ .jar <-- classes, resources, dependencies -# |____ .jar <-- any number of jars -# |____ plugin-descriptor.properties <-- example contents below: -# -# classname=foo.bar.BazPlugin -# description=My cool plugin -# version=6.0 -# elasticsearch.version=6.0 -# java.version=1.8 -# -### mandatory elements for all plugins: -# -# 'description': simple summary of the plugin -description=Adds "built in" analyzers to Elasticsearch. -# -# 'version': plugin's version -version=7.8.1 -# -# 'name': the plugin name -name=analysis-common -# -# 'classname': the name of the class to load, fully-qualified. -classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin -# -# 'java.version': version of java the code is built against -# use the system property java.specification.version -# version string must be a sequence of nonnegative decimal integers -# separated by "."'s and may have leading zeros -java.version=1.8 -# -# 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.8.1 -### optional elements for plugins: -# -# 'extended.plugins': other plugins this plugin extends through SPI -extended.plugins=lang-painless -# -# 'has.native.controller': whether or not the plugin has a native controller -has.native.controller=false diff --git a/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/elasticsearch-dissect-7.8.1.jar deleted file mode 100644 index a2c9d5ede815c7aec9e45b39fb2c4385683f83ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24686 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�Thqe;|b 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 MFK4Jb`ajVM>$y&62NRh#e=} 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 S0D$oQYyEv7&EWC-um2Bp`=>ep diff --git a/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.8.1.jar b/src/test/resources/test-home-dir/modules/ingest-common/ingest-common-7.8.1.jar deleted file mode 100644 index fb010841dedcf410043fdc2da9866efc0755160c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116332 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 Sp)7}gj#LU|a5mhHQ~n3{_te|~ diff --git a/src/test/resources/test-home-dir/modules/ingest-common/jcodings-1.0.44.jar b/src/test/resources/test-home-dir/modules/ingest-common/jcodings-1.0.44.jar deleted file mode 100644 index ba13f142eeda5c911ce9ebc621b7ebe08ff57de9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1682608 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⁡4L7t`eO{?Ex?uMkXiz54f&2i_=Krf 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

    M84pA_^hWP& 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 z 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

    YGaKbH*|Ul@Q8^NAiX8KB+RGFU7!I25 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ĊXjRl(E&_OWQQ=rlZvoI5{Ilxbm3eEissKtQRd+iWIjKw1ji zP_%4x906wJhz+K!)eJgs=p$DYHME6Pu&m<>GmL@>F5sY3>wq_w=tlF#h1Ratf$T`Gfx>xhuyY{4Oj|5rl+{qVb~?zG&~96~Bocon zm{mud`S<8P@187F<7xf2c3s>$lkEegEpD+BiFV0E(vDP#Yt#ai^OlxO+mI)2qfCC8ALN$VP}y@ zRY=w=v*tqEa7{K%|4sjO>KQc?r9>`e>EbFIOuYEo3y#1PG0>ZNfn{1+e)?s4h2r;z z9zO<6Q#M#C1fMs8H>+YP6l*2Qol&KQrjE!3;nMFR#{#>h-C`s;i&tiFJB@`3htoOf zR_}f@i4Lmrv6Y@Q%UZZqTkcMFxbk1!i*V0aowfyKOB>a3*57LCoBN{ymAPvm8+07c z_hxw7>&<8APD=&2A^KXZ5oU85_G+k8wOA^l1K#^MM9#jai*ExS?59Y>R=lS!v4kRP zc+sF4;ckT%I8R!-4o7~NGMXW#JK{&{hgXr)z4Y28XrYz~;n-#^lMX8<$c+4y8?tp^ z#jnoBhtkgU@D?7nSG5AivAM)ep0wG1lc57xeCLAeMECpuX6)>XIyyq*#>;p9S=20@ zYo`q?otXN5`O~8gAxgYG1n%VNEBNBy<#u=)GrMsGC34)(c8YuCz-ncd0w1@K8bj)J za}hfNKRnt!r`PZb+b&l(uf=?8eRXvCjLUqu2%lo&Zmvzdn0s3qL%J2_ytPVjGKSm{ zRk$VYwjtW@Ll^_GsP66kYusKd2=(vW{_UL+Ze2gy#-{RhbM;;M*?-pu^RFCW3!l%{ z9uluFk;i+yxi4_emv^Q{q1Tn_nb6HNKmejfzBU_Zj`sdT=V{mb@@4?$jj=bj)2sXb zyeFgf3-^5j+!yZCE}#d>_{Kr6x#K8Df%i*+&*zZ&ZkL1C`xvm#EHLoLI&;3i0pTBP z&ZGSfhFn+4UCnX7b^CMZTOG>dSQM@3nR7flv8F2n`zO@@?($MCXNsrrKYm!_{)f0( z*xlJw#NNbI(b3Y*`M(j!RT}Qjss|Wf8!wwF|Hx%gAwkgm1tmw~g4iTM|AK3hqM(x^ z7w(d$2f-w!GpFa(*;%arXfhHL6&f^E%=r>3^5SP0bO(~51?UTXH8UR^y!q3GK3 zw5LRaMzJ-Y{Mhu~+PHGH*~-?fw|i*)dSqGMbk$m;XEPD8AN7wL=@TD*8 zK?ZDcm&oGR4$wg-|A4tB&f&6tiCDQar`J>BGvDdVcsZ|< z<%GH@JEA1BoClqu_$(WTTY_n+^7$hUCsE+fbfz5mx$sFG+gwvu7yb7Ff#fe~zsRn& zb@fTq$Su66bC%o)|LR4zNJU7c)gg^3&m_f8Of%%yx}WU(cA<2s#_)&`c~%wyA{#`8 zE++<_%lb|~xU91wDrE-~go-Zp5G&UEHn?&+T&4q6>iUdjLVu?FAABlr<#PtC%M@u* zO}TWFt^U_jXB(FtLK~+YJz4U73NI_@(AC0j#m26|d#-)BlyNKTON$35EUMy4zhYn; z6JBXYEpnu@jq48odMoQ&dt%b(7_YgFEmr`qob zN|Vz5l?(UXEa@^sSm9}8TFy3>DMUQ!o=5pwiobudnPI6S44R3eVH7n4u{}6K;RcJD zYr<)s7KDjnzG|6nm@hoE)D~&;HdJbvu`BdMQib9)rs}Q1^dZjVCIIrXzs|60^woc<`_ zW&gy0-(CD#1qy&8d(<4YrM0sy5chi-K_cH3YtWAR_U~l~W$vpT_HBAS-Xt)6#^2E{ zRAi4mbs{nil`1Xb0`T8;x! zDn(-o>emlLEvX|a87FpW#X+1*!&O!`$}EOq{Bbru>S5l=;(@_K7D`3a!`1vFz!i>$ zf#(CACk0vqF^{?F-_gld>yCIskF+kRbjo@t%~`zI)#7?!;hV>~QhO3VL(kHgW68;; zi98T}@?Di(+p1mHFkQB_i+JZTAZQIv(YBqQ8ON_*>u^_AMLSs&J?1K2=4E_*EP-Ic zsZ!&}yf{i+MwF$s$D)xTx)8_iI~R-Zi=Rb^#TYb~fMU*`NC6-p=peF;6CY})pbDu{ z29(KyE2TphpqlU4sHjk2W(tkq#_w4C+sXQ-mMAs!KXu6aVHjNJqb%{b2* z@BdY1uUm(z4cDH5zbroeECtv9C9@6GJpAMwJ0>y&4BnGAq_#y8)hPo8vvLH%j?B>p zz~Fgsatz&qcL*puutS)mOw;p#V(~*pL5_9wS8?%P^R-{-z9lVl(dTI%run}o%w!R>SJjUf zDzQ*hK7#c&Jd})1Z-r|NyULhd{MjxsDhK+dv%4(HMZ36QdvFPl$Q7(O9F0z=O<4X) zWh9dY>$TXbM*jTb1X-{mS{R+9A})Bq(6m;WLyJ=81}1jbtDfjf%~(9by*atmH(&6{ml!G506#EH)b-Gqq3+G>((& zU3B~k`|WY*fanC*(hOCq>LB>baD@wNGAjH-z@2HZ-5a~FFN#ivc_pOyyq|i9JxB1e zHi-{gx7?X4ivMoC@P6_pt?YAaa4rV092b9|%#^@_kLA({08LR4?Lb}f!RMiGF3aG( zrR>QVXJ5Ql+4v8m>DPUu>=u>A_KgF{{UOU zxDg8n0N|<67}@>3#iSUik+M1@ysgUcLkmXW)hKPpsP3(LQ9y(OaO)w~N;FdqMjAk3 zT43f7SF0QyP`nP*HO#{X)n}a|pjA7lPOQ-|vlaa*VysSACm3q*!A-GpNW=(?5VPfb z?gzm$$j(bcIIy?dvP|)4)Z&J_u?xXVqSv3e>vE1^ZZRvZY*Pl?*zF~8*qQC6?V&sunJLG;vy`~o|w=F);9@{&O}%wu?IUgIpS8SO=H^<9#}?NR5qvG zHo=t%-Z^d2(98>~7FCrPRV7L{BCrar$)YvUvr4UrBsP^=Mm+M$E$9^~U$|tH5EQ92 zJz2CrQY2f3wq99h)WG!mB26R>K#&YpPSPRx8$Nxgq%=cmqrb_J9_+#Sny`D32S zHA*5)8}SLt-2W+`S(@Q`ooLkAl5Bd-cCPM@KD~cC=Kc7QUDG4Y|3P2Ag!H{#U}ihb zP1uqwrX>_T8hditv)1~?4?caaHb=MeHH5%T5}`oN^eOtuDwI_+r-6C6SfQGz{-0HXn&iYGtG%z$1xYI|ar773%e2baDN zJzanb9ltkTjR9se%ACz95T?7uO|B!3c>^1D$vi6JERmz`*(H|wtsR&))p?15qgG}< z9t<mQwC?CmzqF z0c~ZRaxrk`gZ9+0A^ihcQi9CYEA-u-*-KeWY{if@_CiQKAU&a}cRndww5Tw=I>`If zdJDh{JY{P2)i%+_TkmOd)6fLQ6ZTrX%rj$z0<_#2Sf2NC?Kv@S$v_?a*MIC~8ss;@ zWUN&#t(tW(cds(5sE%AJQveHXB&yd98lp$cu+ulORo_hZ4x+ouNEh$&my&dcRN94fPF#y?^9AN z9NRGWcmCr4fBB+V{wsoUQQK0%Q$zo}oS@9KVP65)u*^fJQB4$vkz7e3QYWFnCHDij zOoq~6U#qoUc4m+K#s7T#ydAkG!!rl91_*)TiJ4?tP?9)U@E!2&52eZJFtiZcNcWs_ zo#H!Mcj|V!I=A=zxMuNVt{h8K&)Zp`t{!s0sTnfZb_t%25^OM{2|H;|J4Bbwr=G@x zt=^Wyp}@I=kGBN6yj#QP+t@`5(Xf`Y2R3iFKJH#lrd(8IXuHfd(zDVvbenm^Xb{m- z_^w(0Dx+9x>Jr|tVYk)#L&w^w_4#MO(Mc$)Cq zaQ@!=Uvb$*!;?<*X5`bp(Fw2ISJ|#*YUR==OShqd*(-yK3tDXgE>Z7)-ph~CNZvJ; zO3rPP(RTBXA!E9w>jY&vRlqa*t5c&z;60vabOGZ$FwMj)s3k}K(1%PehAfmRPfomN ztqB|XT0dbfY-bWK{M>~y&>TckbV%9Hl-DI!YT1|}ru>NmNGW?RaVfRgL`X}nBQDez z*BmAdRJJ_#NYQl$Ke)jx9taRPMWax(XZ;yie__v2{wqb&J;5`7XVcM&Mp=@@d1@o; zXQkbE3I}GYI*0n0^ms*0pNNFA0&HAX3Ju!Oz?C41#{k^UjG@tLrij~ zQh&jzyo2Z8*L_ZN-6Ir;gnGyC-tBr0f7-z!l}3J{&8|g6GoKM*-5mHai6XrR!q%J` zcRakqJOTQ!<0be(q9-cACY}dU4+n7!O7c^X5d~Id%m*DQ$^;Z@H(99Uu6vmHMf|Vj z8#XC=VVb_;lxJStg*QA}#N0cVZULdy11J9wbUrxc^|zUdLMbHnH?-xw$d77a{(fFo z94VYs(?Nyqvioq~nY&Qgv1 z(T(;}Gd=&2_paJ@&HelqX_kL4g8!NKs+bx&8e5Qy+dH}%I-30dqNCU+Js^ney;dS8 zS6J1gg#nI4h>LW%UANmOOoDtyG8NwOb*}spjU=aT($t;h z8PvElgRluI#a$QK6MQsb|veocI@zt zvQgOLUvz!bThZRIDk#bKw*p3cs0gn$r>c@Uc?;Bz;W&V^SFrQ!07%*XKf0ZQq0^ht zwGt>UMnq6-Pt!FIp=^lL6wQ)ry~rsuFaJ@~S(J6gaKH2PIHdoueu>!II#}BLcjV>$ z+twLh4adjKHE|_de%8x2;SdaLF~e?F+#*U#nnV)}JTZyVvd%JDHsPPy?1T+>hg2da zGKhAb20DsVF)_rtmTDQfwnbf@W6Y7;`xy}*(AOiT=UmCxqH6wVGkZghUAw;Rsmp0= z>TUDL+x*FuNWT-_0FPh!Mh@Y^jjlHo2<8U5g-Rp}u|;*G_} z-62f5EING+PGn@YZqxuF#&ay{s>6R{ikB+7aBf7k1-y&8xau^Fl6_L-K5&3p%=o9CnZXV> z;DNCUG}JB#uHtAPzgF9M-@4R!;~$g`q>(7`56ycyvlcB!=A;@Lv~pUj3+hVRQTb{3g{@Gb6xT<(Q?CNT`;vSxD)J+$7> zZF>2ah3?uAY@<;(H`mgPu%Huf9UdMYAz~xx(EU4QD6v@lrZH3snkh;+T4~I4xDPM5 zI4P=SBSo8f&1INTjWFL_<=Rj51f@x|c!1FZlowW=zL!q$FgP6DY z1k6TdsiE1Q{qq;OeLO!a|W@8R&Z-O4olAZuP zf~P_beWu?A+~U1XYFO2j1clgh%rTx}7kDK465xq1DCSmDq2VyXZ)mkOd&DKT7d1a3 zW46K?M477whMhk(9TgW)z}D1MQf$ranyS_SM)LZ&h~QdX2b-Q~+8p{cawXdwY_XH# z>}PJ^5*X{sz0!oYg9j>(#vuPdTWR#~9u3XM`W%;zlekheelDha52RH4h}}|rUv!m{ z9d$)~Yqt6}5YT5%4Ww6$_?{@sKN{vMb(c(zM5n<3Zs@kT$hc|svqCTq3Neo0!mqq& zbL{xLDSg;1LIc#@lqjaBYWUSa9}?8rHsoWNktOv^rR*U|SrEEw3v+>Yz zDJ}BzS%m&4cQ_nQiLs*m212UAPsb<~()`X|L1kfDL$|JJ!~%lVG!~tFe&@hcuy0YIiiF^K zcAs|zL}MQ2eGh080EMDYP!aD0ntTSiKu~F#2%hzpTu5I+NwKh-azbe^wX?fZn%s4{ z3)=D0=-tp_{K&(sE(NDEoNIjq-fr)2^Ia{E`@CHa0J`Ib7}5a17Rtvd3>Ui%!aMx= zg8rRzJsP7xnarA{1(R%U+KpP160O{4_vgvxLNShtdK^E2n?5m>YpojL9e(`2!+QnO z!C=k^6=gKjuUgS zKyxUqe+7BX7fUL++@Cax z<{ncVi!d5O_DOfp@9VCkHj2r1ibhR>)e<3Cen+^xqiX62v2DDkuib&8{SMoxtB*}O zy+`~b?5jqWdm9)Z^l=X;#Nbi-G}=$$&Zsn29B{?}*;V@oluoN=JE3L4OvU?bel zT4R>UTE)xV;h88~pN?Z@J_lYLL`wYqk&@n`B7-yuYPr+U@GGjSiVA)&Rnd2T0sb#! z-lNHL%9AXi)hnK-$+jcct2Xn=b^Q;E+m@Oov#k75`GxT=aj#DYYVM6*Qc!^Kf2$V-&+aLQ0nl~4hwP2{*ztcijw zdFlG3H+ZOw!0i?Qr$pEB#S!HE8c^O{sq0<+p&0v}0kWqigzXv@=fl7Al`LFf$dIb3 zW>~27aSAX}hLMV|CxuiqL=uVg0CsxMIw*OU%DF#(Oc4&^;l_t3tY#;*UTlQz$LbqB z5LezANvp603nzKk!UY@g`C^7o4{6a}N@CzUrDA|!uV>RzoQh2>%A58y%XtCMUn||D)?IfZ}+D2x~6*0^!e(X zWNBemTc6!35Yf+Nt%_Q;hJsVXdD6?D&bti~yP=T+IA6Yqx0VmOGZQ&Fs%fpHsFvea zUA3c(Ti2R$v~-mO*cEz2WMc~=GJTu)#d29Wf_diIH^TBe#)2~@r`5%F^8tmvQG%9t zmsG&WzonKo-xIhkds!W6-&M)%a`(-gLi6GD-J!}JMo->QaOY2n>Ily6*lj$6tn|;e z7QY|~Z=m1rbPexOir@sPk1xa~xu3sLN{f8;SL*fis#EF=TmiH8B4p~WwKlk5=xt!> zT5UOIY+I@>VF1=zj8FueaK^omCKR)!QCONUeoOHceQM!1V|mDu5@Sozb?5zH@H>NT zHyPo_@v$A3S(H9=PdI|Ac(GL$uf1nT3(DhCjWDaP9$P%%M9#RPRnI#-o6Tml%*4=U zpkaM`vOdR#VXF^-6SO-herm)}6C4v^T!9;tp?W}RT;zMeou4r+tv6Z93CKYJ9I zbkX6M0e;rHu0QqadSIdd%$e?!5ZjhOoOWMQQ$I(**H^EBlJ+`O z?;G>8o`pW?;Ae-jvTkxN(u8KPq8COtJJN$9ki zr|s4v_n9Wl3<*R;#6F(r%V%TMfy1ijV|cC;WrchByO=WBv-~5m-?7|PplItt;27|w zA6Up}bTe%!RVxSLX@b5ABG0omQ zzvAU%ki2^DyO4;NX*1;5Ei321h0<`MJcW?mx=r)lNU-SFePoYI^Z*;7-SS6ZmtV!} zYND&C>GyWy9hP}DDb3&0b}QRIJz0zduF~)$w9;;yK4-k)f>b7>gaFkxYm{M+8TMM~tG3scwv@}A&i1yl(WFwrPt9sL zXEXY`^YG8RN4e94X$~kPnnbrI=lQwxT&?`mAx;l1E5dj9nT4kXzt%n#w+BR2XCsTa z{A}%V=RB|A2p@Z=Y!a+~VY!6>)-97A%Sy;W!S zqqhH4^^2YoVE+hVyei~Td0pje^o72l3$q)54h{gh#QEMN99C&v2}&qF1&~VpGGJfu zpM723QLjsi^T54tu&^p)qLbaK)P@KL+hIK{wCy-GGdnL%?XyOD zDoP2_Wua(*7!R(OKg`5Z=N@E{_3}P z!PhBhNf2=^3M!n$<@})HfuO~&C!~B>X>A{8p*l9R4MmQ=AUtl&%NbCc?#I7sMpa{8s80zcAH0tLk{BG_G_SrV zeBE#%W^J=K0!etzmhjAd4c^_ zwygS4HLgpu8EkUIoPLuuCf#dyqO^M$Gxkzo6LjG2t)EfLZJKCdxKK0H1ZVFmJ~D2RW8dFTc(V>Wt=`IX%E+5T&y+v_t+Fz3XC;K1aazraAoQKkMH)>r4_ zCsczsE0X=$Tm077a^)90USJSou2`n)lN4YuY>fT%22AkEg!e8G#cp}?#o!eM{Zwq{ zr@<>WiRlECzvU^Nq=EBkj^#}O-E0=x+5DtKG7t{Aw!W??p=TikvT2w(*7FB}#g z-hhAunPZJ7H(x(#$v_yS(DH^MJs*RG zf@v5v+IBA())n4NqE2M7)pkqi)ja?fv#8MOocI}zN@8$mx$q++1>Dojg>W}xSqKue zvFQn43MCrmjVW%QL{kFcX2ak$&H_;;BpBQu;)Kjh0rzUe68uFU78CkDch?z#ivjy4 z&JyhZe>cqBd57a-e7K7pzB5DlH#7ioW}i@30^x}%W03j3*-^J1x`qF{@nm^BNrIya z*=T(drNothaW=ng4A+K%4WNzNC)R{TxEaxZ9Y{i<2qA|YK1TiP=!+Q}B>JzzO8@oC ze@~b#9GZRX9*28EW*OlBZ%X>sCwNLk85r?|F>>I)n0!#<#Bu(MzzeSs`M-K>Jnxuj{j5Mh?L`u|F`rl(ZObQPGvkg-8h z-7SQt-HW-W{HAHTp=*oh>qs3w*f*|>V5Va)6sTUy_PgoiCC*Tz#qD*}jw=U4Dn3wBvL+6{Nn@n9z}0r!Z`G!8(SiD|=DfXU zOw-E}Gj=#@bfdJmTFIFwHtZ*g8#*F6_1V$*?1*)AgbUgQBn|Vb0@Z6Z+Q)XN=oR8p z+dm$VRJs5v6~QZQD@#z|e31cB+dlzM&9!eoa*pCvdfNoC!CRrNt8R3;WeO-N^P25* zbqbX{=fmke%x!%0nFak^glCS0NT|*J_;tDkQQ>!R)@hmMiFbHAm@y+-$vQWN#~!p~ zTg5!G4&}^l?Ur&^It_6m;O;x@Y)zhMP2jk5 zC!1E+d6o~e0QkXtoc@KY~ZV1jS@{2c;B${pfX{``;%2Ea7H{ddd08D!I2kn743_Xgu$uO znj0UYUr<}_z|TvT-UfD;@?$@v2*-_P)O(u|XW#W$TLX~yN)Pp-sH1R)ICT*y&Z-vY z{sHwN-C=^Mv%pDzFSc8wl3v5@i%sC#gM)pP>KuKF#4AQg`PsW^PINkYA85GG z{i&E_`cnE>vsc}%TJMEzwPVo~!9W};D9^$XHO|6mb7uRM#yuXvTN2%Pf&s&h9FRw& z$tUAR(5PtxN25Yz-}u1GtCMUOn$wUMDj+rbQ-)*=rqvWA7L#Rv`h&uT1CK({F)K$Z ze+J9)eOfu?U>LS%-7Q#ROU^q+Q|JCJ>Dy0n%;MEDxl}UN2bp&%XVYoXQ7_Cnaa*!q zNP{B4fYE{YBY?LDdIUA80n#&J*BpPTHMc4=$}PYh^Al?K8s$W0o!0upG0e+1F+auU z@a8Dg#I@e@kbUQ@nJB#&Q`54?#muuxD(4mK<=9TvdPiEj%Y%~HTV>3_LD9(-A?rel zg4aZhF`5?_>@Qtw=ME$v^;Nj44ixmIacXyZ)P{+G4DXa=p=@tsnn|`?b)^`y`MHe# zzx%jnuZ9G1B?vA*Z!SN^u{q%1t$2;7ST^Q^^u0QcLkJbq%Q{J4FC_vrs~ z;~?AA_SE`E8yusQoVJ2D_Bm+Ic@hlHYcv14aMfXg5mvde7&w2$&uu zrRKYVA4D54NXW&j)weTe65I3VeX~2>;y14Ie!BPPqhuVFFL(Dz1-J&Amoyo<`}b=J zPKVz$q$)o8td^iN%WzqlvR!)#r#6HM`VBx;nGn8uXc(;j8b`5@uzQqve@iZSOK#W& ziynSrg7i8JFLofhM^#X(p>QAzIg3Cw|4V+%p)Ys3C+Xg@{0ZGWbKPgtPsu(u z-%;!{TXdOD%k#p9zn_!^dNFx(9VMuA{PGbiPp?|>h;VW7=+~aQue4?qECwO$0IP?e z!V}z4EcRc_LksHc#g^B${hyR(4Yn*v!hEC7G2L1sg80S9b322(?@=9`g;E!Mj~etA zU(OcWr2e*WwF#Wt?BXmTFXJ7F_ZvjAqIfa!iya)>3%!-ue;S#{im4gLwN$!_#nX#) zC63p&=HO3P>-Oiy8v8N9-gMi>eJQgPsWO{g=`I{=dxIO%Q{E~RYujAF#)7PZqtGU^ z6kEYiFj2w4S0osFYW)nimv#`A&{^_C#}>P~t#L72&M-g=w?FRfFe}qcY@+dS5GH>e zf7t6oAM1VF&oGckm(lpNm*Lsh+!4C8LNvaa0@2ZLMvzyo{9Zn7K-Jmf+bxx`I|2My zP{`5+l-`^=&A$&ap~?O8w%?lHuhirxn_1tgS<>xjkUMi5hz5F|)$f_K+3mKi$h&Cq zw$f=drXw}D#_pa{rcAx}I5LtssJ2{sTgTJ#Q2Uevnr0=dFvGJe6KJLKF=5qp)yA4}vYxXKfSXqc| z%41PV@F(*pvM_J+BpwArZ*%(E!(ilH$)^t8rU)xE;Q14YUMUtDPjjR*KE^K{3+4{{ z4?<1-b~Yc?rcFV2)G{@P{1(LS9AV@sxT{R{hfA`&>9V}SPu!Rc!3J3inIz(dtDEu( z<0fgYE!R{zW%nmjL!{bBxCRftxGG56e2^LnZDu5`JPBH)m6E0Llyv~M|;tJ){8D6%7K_^15s)1cI`NKtaE*>mJrsNkh(M4ecOtMFzvMxv?*L0Di^ zb~It@nIrC_{GO~z6fU>bdQ8oev-w;x>!!uTMHX+Ir(ug^0|vLPa=F?pg3ccZq0!u2 zun>PRJ0Z943Jqd#J-acRBrV?9u`i^i6EBI&?lU6(i5_M{CxbS#@Gm^fK9lJ%_^LI@ z4&-1o_#|jM@h#TAzwm5 zllMhGmp4E|1~A#^jM*;fICt>S(C7nIW=)ZFm71t=P{%F|cw$}pzozqARcAzIhafPG zO8oVAdJE#R!L5aS@aykzkER%$e<8IL1>O@yozHMkiYPXHbv^Y#?$hNXgJqXFXC)Gu zIw;2Sk$w{TqF}E`fok{ppCDhA9&&LpW9T}K-3Oj{F&|zIatIaG&)A{*^!vaw_QN~m z1;r*ZMJh9kVb`8m^*c7pPW-qQr_ix@{1^jkkM9e^n8sL_LZRE@7*K$r_^{#}t^#C@ zLr8fYmOH5a`@}5v8!Y8RHpdrpr#G_!j17?TAMAYh`@y8q!7$u!n<_1VN0fuOv{!b) zg)EEdQYKc{1Z;ReXzfYL3$Px4$~^K^r;T+bwAjL;3vV)LC^g6BTUwDHX(ibxx5~KZ zCEpOVa_>wXQJoShAIN3d92SiI5l9q2go`_34Vb--4OTz=XaA@6EP6|>_?AhIaoMx4 zzuIgf_iYI2=ru*vZ@dWSKB_#-cQTLAd^WebR&F97>Z&Up_tP9TL;G*{pv>A&+^>We zLZwc!qTY|0FZ!sg(cfpnj4DGmEk@&O9ZZma$6C*rtnRC3buJQe3tZW)iMIC>-Q!*o4{4z}aVEh5l^9wlM@I0ksSaJ7w}kd$1b@AVv1>|4ba7^1=!= z>C8g8UPEfhOLFYSZ>;vN=>y(_6nFNmq@M+y-^84MDUm>QEQ8TfyXI5*c?yjF5@$5^ z&Z68m_ZmC!(Itx)H8Wd@0C=y$ECnwXH0rf|zR+MLB)eklGl(g7GEm93C-B>Kp>y9@ zr1PxF8#?)q1Y6EMG<<$FL1;m}){`Qd`Y~3y5j^MIJRLk^^GA3fd2mCFKJbLLu(R2$ zPjw|he@ZBWXn#nAgl()B4|4NGvByNBvuA__6cmE}(f9f5+sFTjMeH33Kwj7|Ff;Tp zFnIqb7E!VAu(JE#84Tru$UfR@Yo~p_+|D+4NLys#vosepKyw&ZZLC#{FoY2*Nk06n zS>Tj;N(?vlP`QLo-J7msZ9SGYMNu`;MoLkM?qA$j+4^rU%!BJajV2DPo~5b_-PiLo z*3y52p56Al9}E2FyKM)LTKC0X31CPPK|~ksBLO~(h}}0ysAQ3UfiVY|WMn4?oMb_@ zkfYbYe|Chs(8zb2Ge)w4?*}2dkzgW`Qph{UQyp;-Y!rdtS7h;p6?~s3QZ+M=5v3b0 z>A}->agGO+)MqpNsrwp0;}#!%s=}V|?9BTFQe*D{+7oqS|I~_j_W`R;;M?JE)apJ<;8*ltqcrn|w;Lk3j zDyhNUFbAk;10K?dB9kL}s!utC`vM15*l%;tPA7RPyJ)1Z-MDMKI_?-vL>BU(Ho*cU z9{LPKBBK$$9-?B9HoLK5yY-YoT&C{aLAf*LMYBtw54Du83XiT?58F2qMw4M?5K@PW zJBCG9H)eb!)!eV!vSDJ9BL+ppo*rEDx5EW=ihD><4 zq{~ux^a=uHFTS`T6L+$0)KN^1ORGXSeLG{5m{ct~Ty0iVJ!cQBq+|3de-cfyxyet% zZ>)(ta#)oVX=xArs^VU@3k?kgUGehTpQJ6qi+Pj3-wdx;^td?K7d0g7x_vHzNF23D zunfC*SJ4qsxi)7~by6fD@r7H_3{cZuN3vQc)0s9>;M&oyt*zD4rKs%a5Q7iWxZEa% zVq8Gd0zPjS>+N4^6E+K11!~PBO?o=dk?H!A-dVvDTn)Xgpqp)c? z3IsZ#FD@(*eBsL2BEgbHvZhlCNSeJeg`*xf$m`9Yruj}5Ye~`3x>j zbzq%U0fUH`%C?1;4a6&)rrL6XurlMGKdn z?!2CX-dbhdd^!Xg`}+( z4O@LphVt>|eEcZ>DkAeCMBdt$=Tlv*B0vF!sw#T*M!l<{J?IL?E9GJ`GZp};c0>b= zxN>PlN>rtPp2lz8g3qQLq?z0QjLn%L!=;f6uR@jahcYPw`ye4^j0P(>0>uPa?qEdh zn1DFqPCZP-HJxb1mBv!XQOeTGr`aftbSRXEti;oHu8ykYDS(=B-bC`*Lmx7-<)Zo` z$W7p>Kj;6&2MLnsp+B~$NH%|RKrd0jF670c@#88t&Z8?lx;WO0G^fZw?gOSYTE0-v zV!ai>=5tp02;b~FXVjw`r&;n>9-=!%R>(6P$+z=Il#{MMR$Q@E*IiM1Fvox0 zEt0LLqlM~I$X_68iJ&Wa=Ebf|+WzU8yjVv%g(Iyzy2ZicmTUH&B^kRXJjO~L3*a4F zn$^Iec4Oj#q0SEpLQ`A4r4b>t*c`G4KnOU#MjKz>$zBK$H(%Tj!=ig}-@EkH6eH&K z{*v#@_{tY)tEGciop-pnMBvn*#^bUXvqh+S;9b_AU-SLUG5P~ zIB5SX(5u4bp0g=jhs^Bbz@9&5Gz^*i_RqVpq@$&$X96*Q4fRW=E=ygV6oJ{jsA`%k zSP$Qrh?lq~UOq2W5uJNWq7KWEIGJzOgCr({twKUcy(OJ$ik+VH-Vx9IR>;SdSyKD+|nl(+a$1j7s`?G>}trPb+$%1%|j_z>=* zNTDZ09xZdqIsEcDd}*=`)Uf+5(`fc|;B9#gl-CrZMb<)3 z3M)~$0{7SmerWYj)K0VrO1;}Ior7q8xe+L4nCFzvx@XX~ny22_Me<>nB_$a_CsGz@ zJ@!=hl?x|~?6yB_<#VsqISV5Wq>9kVF|li@i$>|rM*#0Y-+92QHj6LiF4;-6D~H+0 znMwuOO*%K$(I-vFpj7l4-jaMYy(F60q+{ihacyIknCX-U4Fh$KU)l0_%$Z};pk_A( z-3;z!@gK`HrL{4b!v4*Tiz{fp)}$Rt;5VL+X!A}SuU>^4R-0(;#F4+EEq)Xgpz~|J zj;;byCb_SyvsS>#FGhYY)gJek+)x41wDnjcVa>jR<<{@v8zT!c zrERq5ZHfu``i5I!;UXT#A6$8nwWNKKtxcqnF=&5iay&+m##IKsSmHhTEK#_T4X(H_ z3EyxE**Q-H;?*Y=cSwgG&@jGe_^yuLI)V9+cWHTUxQp5E7pPy8-Et2eu0paDq_n(3 zRu+XMexbNU?t`4V>@+v|2nG>JIT9*_Axo0Ji{D6ILpE?~tI+0e2FioN_oJC?^O4AnGKRFb7E$)^%tps&7@IzW=+k5A8A zAUW7XEltbkXe7t(l~KFR9(pSMkVK0%vtd=nMo{VXO{iYx5k|S@~}<>-od{9iLu-AJt#n}d)j8Vx`Y z8uegkje-KlP`P9SKwR!c4g4HkWOsvVDDM_@-fPSK=+bgX!Y`_TLXKqh#)(w5&Syh& zZaE>6I3XfVqk#DK4%rt?)5PrGo7E0)Oop9Aa2ahfLXLc0Ys_xFO_RBZEL|)T8LPI2 zlcf^AkYpBiI8P^?Joj4$>s3VgMt(ZC=yvgLERM;8Uf>=&q2GQzZqI{nGZmCb6&%VF zJhsQPv~_E*=VrC6`~zeawbbIql;Cm@JRZl4I2_~85u+BTtmO<8r+Nuy>=q?h*-kz77PP9alEdhiJgQb+l zc?HZfP_mcfmkcL*8(_0%Iu6;bgIA0gn8>p^C$u%Dz#Pp9J$)Vt(VwHKV~*_z6xjc2 z%Sp(vY{_W>IBO5=C@ZOoYRfK4LA*N*c39N~mRTyu_Dy(W-gS70l_98!rRr>d=kY-I zj}98&0FD{~frdDFobquk&;IQU+ghx#Ul6vGE61CLk2d;(D(#fKqyfS0UQNu)_4JM- zw|%4Am--a=?JC<83qQBuof3O&bUzea6>>m<$$aUr}4jb|21n^|rL9z2UkDYM2tUzZ?kPS6IxR}cL^gbutGtV;jrbX!(koMZNsNKTg0r*4Ptz_a;U5Q$PU`U^9r z$|@>3WIiqHsCc_zj>q%GFq9E(sa}70dGd7&+o!~vxC9I?5S%SXnv`UHN_i~lnBGek zvD@tLP1(qndH}`S$CvB0sKIm1fW*@@et3vEd@?mUIwpi$%WU{XEm==rGTsiZRpq)anIr_4(;)

    K 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.jar <-- classes, resources, dependencies -# |____ .jar <-- any number of jars -# |____ plugin-descriptor.properties <-- example contents below: -# -# classname=foo.bar.BazPlugin -# description=My cool plugin -# version=6.0 -# elasticsearch.version=6.0 -# java.version=1.8 -# -### mandatory elements for all plugins: -# -# 'description': simple summary of the plugin -description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources -# -# 'version': plugin's version -version=7.8.1 -# -# 'name': the plugin name -name=ingest-common -# -# 'classname': the name of the class to load, fully-qualified. -classname=org.elasticsearch.ingest.common.IngestCommonPlugin -# -# 'java.version': version of java the code is built against -# use the system property java.specification.version -# version string must be a sequence of nonnegative decimal integers -# separated by "."'s and may have leading zeros -java.version=1.8 -# -# 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.8.1 -### optional elements for plugins: -# -# 'extended.plugins': other plugins this plugin extends through SPI -extended.plugins=lang-painless -# -# 'has.native.controller': whether or not the plugin has a native controller -has.native.controller=false diff --git a/src/test/resources/test-home-dir/modules/lang-expression/antlr4-runtime-4.5.1-1.jar b/src/test/resources/test-home-dir/modules/lang-expression/antlr4-runtime-4.5.1-1.jar deleted file mode 100644 index 387129d648f1fe3b9c6cbc4e6eb459eb1e5a20ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 302034 zcmbTd1C(TKvNl@PW!rX_Z5vs(Z5v(cvTb(Rwv8^^wr$^@`R1JU&)jvsd+wiW=g!Q% zB68;&e%^?b2Y`S=1O4OCV}L6D&o}=%LH&7^5mgqXm6R2um;V%~)6I@2Yd8S;Gq|FRPk>Y_YW9Kr8Vf!Xl8Ath&?$BH zF-Q%3Z+dqX2K88@YT7gp_?&xm0;C~gI-02QgbS!{eZ{VpJ%LC#SngsNJMN_`_h?`= zYLX>)q*P)sSM+J}Q}wej@$IPLd4FBm&b3Pz6$N6Nt%tD8#YmysJW;g8coM-a?mYWF zdM_WKl0<&|AdVbCFFT2$kOe>VCyjbp3ez?YJh0e)TN7_Rg$P0< z3DN8T6pAeaz}J%HOty@UGLte?#t`(UsWz~OG1S{O($e?#Q2%ez?8hL9>}Lrkb2-0Ku+8A{5Wsoo)B#u?syogiI;Ycd7waq0%&z45Yw#G2!NuOhN#u6pU&d?o z+@m_08&fO*B2h{kOcTv@iMg898vTA-%?!irR~yJ%patlh&PoCEJ{EG4A9F^qo&6vu zSxtmfX?+0rRq>?RxMJat!5cG{LF@fiTOLc>jOogw_SEbnt$6^sBOpRKCsSeFPJ&U^l}6tw4C29{=aQcmknnG| z*$f13@9_tO6?Gs>MokBK>*2s2P<#;t1H6r2kv8APS)}&}{>zep{%J}7r@?{#`C#X0 z_TRSl|EBndq5gxyz}DH?@o(th{*BI+L0&183X+8#ZH8 zgTG#*|Nhl~MU&=Q z(0&=aT9qk;YEu5T9Y)u^LjI0fuoEqaNWWO<@2H7DA3WBMn zKLb(0WMH}(Nr(jn8v6$m(XA)d&d2AHWodomNrxfm31M;tM;Gh;h1hOkcXcwclyLX@ z`2G#(s75bP3aJcqbVQjbgC%k%_$Mz^15zSoBpjZeyb;-JDo?kI2Xg4Cqle}Eyiq8p62 zL{gJM`M3%EU%vU5UJ9zGl5zg%MeW3(lDg?IM;VH=+kC2H#HvlT1~iNVZ*?!=p^jt*i`>FL!Sc z`*3f9cE0q$I{VRNd-ru_WH6~U5&snpLM59$GkDv?0-B3O+FUx^bgZ!;S;L9I$8d>S zZYH^kwLr@!vi-2AC|U1wq<63^`xo}+W!x6$g1yLQ(4*?d*;aU{33WHoNZ78j@wY=i zH8*eZ5-7RI<*vG&z1zfmZ3JQFq}Zvwfm(Pjwfs#&w_w%819KlHRc28Rs*0O8uG}~< zf02{#EnNgo$9zQ(SFY5cLQpH$ynWa_J(VWPnU~xPPG@aOZ1Nwu^S2vrCMXX)osBux z?Xa0k_D)dTzy4jyW!gNmh<_yf_Q(3E{?_`%EUZob2-(EI=3gR?U$dPPKn(tpQRHT{ z#ojGCSV#XMktr`61R9zkFIp&}5Nlovs%>M0g8m}UDLZK7C-Qwa51~hx$aHDw0I^^* z@@pmQqdP6G`|H{Dn?6jmA5#@($+l(CJZl;qmikb*boH3M@Nii)Yw)esj;A-iJM6=z zr_TW1uMlA~_ApTnubv!U)LaRCW|s6X-R4IuskJyj%+U|x``5kgo`|Pszv}Zm;HM`K z8sludpxe6Nbt^J zag^FpH`P{PAmRX6f*+ynu=T?9D^Wu?gc)vKE9q>taf`p%N)D@&*$zNZ$g!EMQyJ_h z2Z*t`(#bVzWEy4|9Z)i0%gwOj4KBV+Hm>b6-^=Qi>xmuPrtT^kP%|7?3rq3+FyS&& z!mce2Oqd+za?{PUb~9`=v&K*+gXC&#U6Hy4{mVXM;3Gt-s32W z-es}GZC{oRHrThb_wyG)7tFS62ht$;{%MW@U%2f4U{Oz4F1O!DnSuxjh{0uF@SX==9-Wa5vob zF1Mq}+}eP>lMi9�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�q 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

    %5rB!W?-gvj`= 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 F{67(LwlDwy diff --git a/src/test/resources/test-home-dir/modules/lang-expression/asm-5.0.4.jar b/src/test/resources/test-home-dir/modules/lang-expression/asm-5.0.4.jar deleted file mode 100644 index cdb283dd7f6d7d420ba0fca8ec23e1f38fc3b7c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53297 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 diff --git a/src/test/resources/test-home-dir/modules/lang-expression/asm-commons-5.0.4.jar b/src/test/resources/test-home-dir/modules/lang-expression/asm-commons-5.0.4.jar deleted file mode 100644 index e89265f1e6c315689b63f11eed9397bb2e7ab9ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41796 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 Ilpo*z54W;yKmY&$ diff --git a/src/test/resources/test-home-dir/modules/lang-expression/asm-tree-5.0.4.jar b/src/test/resources/test-home-dir/modules/lang-expression/asm-tree-5.0.4.jar deleted file mode 100644 index ac68a32ec1957f2ae489cf2ae6392fd8e7b163a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29050 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 z 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 TNCH;qz`x0>2na|kNB{djLKZfY diff --git a/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.5.1.jar b/src/test/resources/test-home-dir/modules/lang-expression/lucene-expressions-8.5.1.jar deleted file mode 100644 index ca7697601721b9f211e6ffdd5d80bde086953055..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73343 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.jar <-- classes, resources, dependencies -# |____ .jar <-- any number of jars -# |____ plugin-descriptor.properties <-- example contents below: -# -# classname=foo.bar.BazPlugin -# description=My cool plugin -# version=6.0 -# elasticsearch.version=6.0 -# java.version=1.8 -# -### mandatory elements for all plugins: -# -# 'description': simple summary of the plugin -description=Lucene expressions integration for Elasticsearch -# -# 'version': plugin's version -version=7.8.1 -# -# 'name': the plugin name -name=lang-expression -# -# 'classname': the name of the class to load, fully-qualified. -classname=org.elasticsearch.script.expression.ExpressionPlugin -# -# 'java.version': version of java the code is built against -# use the system property java.specification.version -# version string must be a sequence of nonnegative decimal integers -# separated by "."'s and may have leading zeros -java.version=1.8 -# -# 'elasticsearch.version': version of elasticsearch compiled against -elasticsearch.version=7.8.1 -### optional elements for plugins: -# -# 'extended.plugins': other plugins this plugin extends through SPI -extended.plugins= -# -# 'has.native.controller': whether or not the plugin has a native controller -has.native.controller=false diff --git a/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy b/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy deleted file mode 100644 index 4835ab053..000000000 --- a/src/test/resources/test-home-dir/modules/lang-expression/plugin-security.policy +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -grant { - // needed to generate runtime classes - permission java.lang.RuntimePermission "createClassLoader"; - - // expression runtime - permission org.elasticsearch.script.ClassPermission "java.lang.String"; - permission org.elasticsearch.script.ClassPermission "org.apache.lucene.expressions.Expression"; - permission org.elasticsearch.script.ClassPermission "org.apache.lucene.search.DoubleValues"; - // available functions - permission org.elasticsearch.script.ClassPermission "java.lang.Math"; - permission org.elasticsearch.script.ClassPermission "org.apache.lucene.util.MathUtil"; - permission org.elasticsearch.script.ClassPermission "org.apache.lucene.util.SloppyMath"; -}; diff --git a/src/test/resources/test-home-dir/modules/lang-painless/antlr4-runtime-4.5.3.jar b/src/test/resources/test-home-dir/modules/lang-painless/antlr4-runtime-4.5.3.jar deleted file mode 100644 index 44353757ebdad9d7f594045118143536e8e5691a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 302248 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%0DVWoD_7^ zF^qnQJ?4f=Sh142KHBL+K|$a4JUin;Q}$Jy+zSs)DeqZ4Zd(_Jo(pw9Nc5x{JY3H9 zuNr~+!?eprUh(4ON}Xgh7sHD%Q1o{m5*f$?jf65aC&N+E7XcrNZ>*FiLkjCdez-*8 zd6Q^CC3!5NcRXp+PNGDx;RPOQqVUOh%o`+Z!jR=d5qED)K8<+E~osfktS_jqh;PSgY>9=vJ=* zPtM*G8pi{<%^9txbC1E6tw~ttcYm|-nudz*J}uuwf?N5{efsRj>iO5Y${_aCaDiRb zZC^03m)K64jN=)j60fY0m_Kw6kTvM$KGau@jLcaZY0jMYH<;IXLs@hAw;T(|=5%7y zb}DBtz&gAkz&1CRxPaJ5hdvGO2gdc<%Xw5gZ zq)%CorEYW%_zK27?roSc4m}* zDnnB5gpQ8PNe7->-TR`m$~@-B$h;russ)I<2`ofuaB@+$4e zv2J|#4BG=Wj&t{VHMQ7BhUHpdNXpL2f+Y||o>4kx9Pr@*;RLrcMk?)|%N%M70%rDJ z4Zo>B5kg?QGqFm`-Aez36z0P6y$nlcF)t&Q(Jfk^qsxmcpD%Qb9zzp8bq>ga+Y``hR zoY@S6VWld#T1OCHO!p2a+<5CJ;yw2|%TZ}dqp<>fMDnzeTfK)e@WLr}dMAP$F0r|o z!EV+!;_Wsv|HLg(#Iz$NKuW}morC6;C%q-X*yl4knbYu*IknC#p#EoR)fI zcSjFQ?6kHz$8lYZT#O^KaNUF(o80@k@9TdojrB(E@4SEmss>O&2g;CD;AR_Lt(1a+ zxpQ!IS*Zdjd)Ff?hn{LlmnN)c$0^ty@CFZ++wl>{=b1+Mx5sZ zPIXwXvO3=69is4f_$@|dkvYCxx?rRSP|lR~(PB1g-+1eg1jroB|CmJ`j+Dyc|Lces z7#VPMSHX%Mau`OGNhm|3@BOrp8`E{XpHv{!7`Y&V;-nWLUMfh%++)%T{b*~OXtA1`vbZ|+6my>J@ts1 zKYv@&Tf}BkM)4nNiKYvBODV#z4?DXQ-joJ>rR%0aN@uEZEafzrf^31yj_v%5guVW*?_V9EUU!eqSJV!63Lr3N_e+Fq+Zm2?9w!-!2Q}FjEZ-%+l#@*EH_LoDKM<&W2*`f!ZaQ}HEjj=_N zrtFKSMNjzuP1`ED+L#L4f8}mHT>c|%TcrW#qr8OkFNb4Hc0n691k*~J8i`z13-}vp zd_V{Sfp#=Eu)Z#>I1hZDthfcvzuay?3XVfKXk+q+JT6=a1U(h79(P(ICgxvhaZ^rB6%* z0g$(U{+`jj4%DAwA6XsAE;zwrrO4v0As+iz<>9>eholeGvF2M%zvksZP~#PSKo9Ape^ z&Wm?J2F9@{5gg58?a`h;L@P+M>T>52;o&lqp1l05dDqskqj2U-4nW+|W7(-Fr?8y3 zV-Bs3rc7%Db_X`wLROA$czuP$3R$}O^xfR}2OQ!pDDtyr9@bQuOeBu&e`Xl!Xz(N5 zhe@1f68ff8cGHRW_Jsn3?6+{wtRviKujiK~=sNRDD)=&O;F`tTl$LRkAPTGl$HG5s z=>bvE@pj+s-GFDm##H&{9He>8f?K2z^{_DUVPnx_6o2XIW2`r?go^Cgurvj;YT)izLu~gpFL=X(^q_p!WB5>|R z8+@4Tm9{C zda9OQlHyWmt1BR01`!3F zl}3mVGxeMuh532gDz)knM&h*{_>Or+y1ooyJzP9j~xaG{dK&lXr&ScDq}ExoD} z;pNM4+L}#g=NjW9oZ=drr%l4}6w8_xjEAi)MG}-m#mw+2<%^8JW1evlSiAB@m;&U6 zbqHjgG=A%!rv{-(KnQ!#Nl^rCkWtYY5y?T0hbRn`_mV!&#B?~Y;&NuMktHx zh$;7)|4lRgwjn1#->I##2BI?OP0Q0;|K|?D{4K+FVjM&f6mh`%91F<(ZqiR8pFj`w zhxj3bk)9#M2vh6eQ#aD7?s0=)l#5gL<0lBXzLHkExxXKYL0qXw_T04_o&vaHh>*x#`_H> zRL?eo_FD0c(oqccSVw|Tea16&=2$T^{*pVpUq9LhmOrbT54nYU&MbzZX*EI=-_;om zvp}?r8$+6IkI5bDhI{CECpwTHebn5L2=;Jc4l2wC@V<+$q$4Q$3u`mnkPbC9*jW)+ z$f9CM(*QrVrZgRV_slk7@-5^8%7Wkjk+3xs-8;zviEk%AX(@ff#uOJ%1_+1{BcEv1 z-X*nYTFlOU_=y&Huf&Vi%o1>@k;ltp?1FI|n;*C}qckU&b67pry)}zy5M@uaX?`uJ zNEADP@$VZigvR;xAxOy7APVp&gz8Iy5(HF&mu*In9j2))4&WdsA5R)${l^JRncXjH z^w2~ETGzU@4mDf^^GGw?YLY$*{Fb~U{)d#CI=RaHEeq0Ky5U(B^3u9=7=s!{(|E0+ zQl-K<%T|+nL@F`Tmx_C%2g(@qe)g`|-n_jMR`=ND7Cf%O)w@L1kC?QNE7RLVy{2qP zRQBUsLxfB{33)oU?BbPc*<1^cvMRYq124z$(#vX1(wcL2J(|1Hmt<(2GMSyjeqx=j z!eonX4dz{uzi?-=B}4g_(}wCqxBZxXbNRBln1R<4;-cCb@oL1alOFr;$R8IYgSrmk zc{drDcCs)XGf(RyHd!?So+nR2=b-d0d-5wd*^%TT@Y|n zJBg!OF;XMnXdtSEf-(un3wdPa{EHfhRMqo7_JtIceF>x%h1hoTw?YDS)H^u%mP+}CnPToB_!x%pMw0M_8e)^?ZF{_&bCi|gs`4koj43Q# zuOmll$(jL$4HH`7nJH{-FoIbIL~*d44y?;{{$X5ski20eRsk{=~M({)edkWrY?NJ5ff<_h1ysG2n#Ji9i3;yA28b)3_qJqqJA$IU@x z7h}!jV$Y!VAMcLb+l(^So_3EKcMsBer+w=Z`t(TN?HV@n$okbOc(bjtnl?L(Y+A4k3W+7*SkdB~GKrNZ_D&J4dRS1bhy@}!bmG71ifP&2q;#s z8#V=c$6OjU(T&<1jK~+NWm_FVRBGl~!bpEpt)NV+36fl&URN}a84aC#RuLm5lg=ye zGp-rx`jyjgv!8cOJrD)uVJ3^v+u%3ouk_3u{o5qbi#WvNis9^W2uT&w=b^`y+l$a3 z4l;_e8Fzu8?TV^u9|{aW_}XRa`b61+%`9D@4(CV|r)m-F=JA0lr- z0o-?H)=L`l4~GaZ4-sK0LG}%prAh0VmD2zqzT;3W4X1i{Kwus4&yEmF%xdhx0wW}l zHMTUk=W#D&r)kpPjYO?M+9e9c_0IQpnRg2s4FwEsg0@k1Eihuv*$p3S0 zDWw0)SY`4hQm6lKJ2jl_Jv>F7oa~+cGZLu@WdA>fRl_+UyxYueta&Gt9^ytR}NThucqQc`{Xvr!AIGN5{i_xZbRZ3_6c;RM@5ggi?7I zhmM5?4IgN(&{DvQuj(0{d-c=u^sh6aoo))b`K{mUFj^-EpQdiFf@9ebwBSq2ScD_8 zZ##P^3LA{;?u8O)PB1$kMw>2ZGl6WMTuiqD4H$#?!v|JG<2W!lsj$vjqTem;-u zd|zJM-qfw&V~pw_&>k-KQqOBIFl?_|R?d^IcCg$)5fg1=OA5o4&*6l#o2w&q)cP{K zIYdUR9lBltKx2!Khau+NLv^Gn@j@lE5Y7#lTe+7N05&s(Z)|LuLAdSbKjKk}&7sxb z);rV95Wq%^n47N7%1U)1>_yDVK|7y2_1rJ%YEkJ;Ev0tj6}nmIWJB5#A@SV5<^-y zz-O$(w8mgsalk-_htzXZFdyDidU@_c6YJp>qchxdkX%Vvu&MP`9<~C)V;)7yk>WQo36h+l-bqo))kHO=W35L z`3L=$BwrOkr3aRzx^<6#37xZ)&Dy9}B5Nwo-6bjB6LWu2D&-wyM=^%=#OX2)l~6}C zTOXu`P~fGq6HvXUtrMrFFklZI4O!6la`>73tC4)YJ&1!~hwrboyen2tuec6}>{cS( zZ|WkC2q2Qe0z{{1I#VcfIB+uoZ<#8=11}}%jVzQaUs98K5Qo)Lw-`fVnWr^BKT#wQ z#j5H6WUceqHem6FWk|5{x#y&M^n79@Tc12BPgN8>vq;E#>T@J$`8t_rA;J6{rx{9u zPxgo=xuqkXMY>1Vl4=aHqdik)5cpM7h^Q#9qX=~fVn0L2h^4xu_S;rpr1sfWE@3+R zTA_}jS^Z(DKbsoun3mrf8kreJgpZX!UwzV|7g@AtJYspJqi%ddZ~Mwvc=nIYQr~eNmAF zyKQdrPgO>jW<$Icii}CKf!qU+y&_J%lP>>WIG5mQk2xHBuf15M9A~$_I2-7LMPTNA zw)6IJ=k>i`=2VXV-%t2n>lZEt$!UsQ8?#*PVXSP4= zm9S*G6&m#1PwF6A2Wov+Y0ZV(aXYtnt7TiRY~8y0^Dvqf2rpQ-G3GCdDU6Kkf<9A} zs8PPCy|_VskXwNby*k0n`fVw0OP1CES}S&SrgLZD@z?3E+;?dtmfn2AO$u*`5=6>` z8KYPt{s5PKI_DdYCPB9vb4d@Iq^vvU?o9ph5pcRp-;!qPrTnv5XDc7h{I1!!ik&8w z&V9f~j8Uu zq2(_oOO<6!H0kUJ&+NR&rLNJbQvZNa>zrjDSVzri^ciy0(!9=V-~R~|$yR7QwreVR zTHT8bK>gVHgu>GI$b^&vx%U*U7nHG``{r)@p-LYj{-Wh!uQ<`vE;rY3JXHZ~+6`4> z6*+@CY(a1!x_t24iTXK8o`4ukU7|`Aw^wPELy$BiI|15p{ns!-%%^otzTXz616KK1wOK4!tOeoDW2f7k49%RPoJ)C;L zn7hIo#C4Sx{PrxX%{vgbvGOQAfaRZO4mLEq9-Im3J?T;HxT57Ch;b(#M90tJ3OG$n zuKDF}{a!l%b$Mnc5FA1bVM|kqCvR=68=es_Axq6pEP^Z$aNBJA#h-kxH%MuVsI$+h ze%u0x5lj=lIXtEb^s7#j91mitvWhKJW<{IkmfS*#a`Mft(B~fElE;xJjv6H-5i>(l zG=E9YmvD#%wy|lc21^!@Bzjw;1=F+A!GRhzzhV~xsk1(jmi_p zyr?<{c>|@|U;hgljHfOMW$w$icwkMKf&E23n|;{tWnl)X!w>VsmA~VIN$yd1#l>0~k)0 z#D9UwbQq9K9`8~x3$dOF&_d0?Kz4m4r*n1R>6w48^lbjwX&t0E)OO0kn2Ebd`VIn3 zEKkB!{fpRnl{+iP_h7Cjg&2IsFT8OPTe=sWocK^-V8)GON#LprTLnLx;^kziwkPOn zlBID>ZlQ5XnU*6|=AaDaA13=iP*4+uI=pVRmw6GCgxUKzQx&z8@R$D>f(#3KiGnn1R|5&Av&8&1Rt?UyJyG4yvbj^Lz0gV|`<=6Q?DPcJ_B^4Kw66~9 zSGCLez0^Y_`=c4WXW&};7K#_M7oL~FFgtF7@~;L#ukuSl@LOVF$=?^}Zwoh3B9AuT zX7)Ti?*apRMuGm12ljV=uD^eP{i7QKdPw?x7VYkQSJ^`m&;uRN-rW-keA14n|Migl z(ZwL}@BSd1$o|D~F_!bM2kmd;AAZCi{Rdd0etVB_IV6#Pg~ui{6ODFYtGr(|9BPIozGGMt-Xp?fMDN{qLp z1|+ZvH~?rJ_1r>M!*Rb{KfSeRwi_!;8hB6(j+9`6+$o+M3bs1UPClHZw`6FGAEsSw zfOgR6Eh78zDzx;v${V!1w$cx298rU|afG(gNj!as>168_I4Et+oLyyo(4tw%IXSLg zT+GO^Iz|au>ApFH#s?PsbBCbpD}p-u2n*+GIwk4@$Oo0!hdw!aioZ>j#T>DcmgyJ( z`w(i6oL{d1poBdc4l&Zi{w=sFYM#F|KWhuCd*QakSJ`%)f(*vIQ^i0|_7X-n&5OWr z1rY~8eSJ7AZOJC|+E_|P&YmMq$ZmN?hT3c(5)5K{Faf0JS8nL|VARTDssp#vCX`{e zsOdYC)n&BPHOWRrNLWi!E5oUOm>)%Qy8S`335gY9x(|<^`}c>}OwFOqlu~?Xo>**P zi6tw!P^?p|H$^I~Hu2t}zjBI+WZEvP8m~zBX$}FRI0_nMoAQ%*hPhEghE+|J&dd_W zE*r9a4gys})i`L2;+3Nfc^b3=p!Y+qTwftn1Q=X5ErB`n)0m0mK<0|4y zAyDiEwDD{+8wUhOM@cC9ENwa{l8B=0!;2q3Y|?WfUW|0q2(K{(P3C6b-s)L;ehGg! z@+=QtEE71}q%%0?#j^Y<982DO%H3Gc zG(CSCR<*V>Y;8&#*(m_S5o1VdG}2Xy*vgIxwGszT zM>g1(S^=<0At zXw+b{L=NG+5DQ8u>R)1JW)eMI${i&_=OVlE)w!5>IR zAS$LXu_8j>O<5W1J|vCt#tj6CpAcW@?a)X4d+C$nWs>4zi;= zwRvj^aw2nk&rdap`SRFWCCT>Av!^+SG0!GEJ~TCoWo%;Fk4@d!MEB_9s`42)p}LMb zS4!BdZ;Up7tC7z*Z_ke_dknMmhc`t`Am^_6qbo#*3R5yPWBTB-&IN8g=CioAHM|drxH}sK8myx!x_UFnHFXEEc%8EEw$EDDa4LP;Cy|aB|~G*3g3u% zOQMUI+axyykz-f%QHBObZKDlWx%DL7q22RXEAHO`9yr=s)L+cwb-0(vTq(3j+aa); z|5~ruR;=5uoT_%Fh^$K*t^(B6AkDk71wg9P=1#HfX*;qywq%*RTupY^`B&d~@wlkh z!R)ilk$gHlm4feI31(0%$R0>!22ndxXqVa}o()+?;OgDjdTC7%D7W}W1-6o;a(8$Q zheAGb_%Yow5;5=(ZT+|O(658)C-QV{u4nc`m@^l^Nlg)nDd*x zkKXHQHr>DzF(-UXwtdnX@%jj>*x<4xv5=obPrJ6aItKmW$)OvqTl3~DJa<1 zFG50HX;d+BDb-*TmK489_+!UYtwY#dC9@}lqc^0_t(3*53l#b!!GMCcYRRr4s5jFtxh3)?d%!r+ ztqSfzHQ_HH!9J2^FI`EaXdNb9q4$UGDjymxHUwx zBZUpX)PzoG=H!r2Sh^IGv+n-pn3_XfRs_saP)do6Gh_^^))}rTC52I~9WO?umViaY z57>bp#K%Z9%2rLCAlT2=r=S)sgoG>vq(=YHgVj4Yyh~!L`AIlB@zLMWI5{f*bbfw z4>z2FDYwSKyW71G#$|rFwavbX=0C0dRQK%6@nYLOV7;hj)r=h-;<)TT!w6nDC`!Y+ zgUB3;#^(9stMh>y#CXQ2f6dF!i_7dF+mwfWgm#c<>e!8cA?-B1%oYAdI&J$+7u&Ym zk4ZfUc;m8IBW6GnzIfWl>7 zE@_D4{6(d|bPX`G=dsw+{u2LhKWnH9O&)*9fWzwEWRE@*8CuqZZpjbj6qpg43)XWB)7FYCMz_U5EzNMD` z#>dYe+alYw`{=^i#TSa(BBCG!+9vuwji z&xFx^N<`Wvth_L+Jm#fmzY*zVy$&Ug`EMZHkT#@Pn%NGzl;v(#O)GbKZzfjr$hIhD zYoeFl2%EL5+J=TSk6$rXn(7Sha6R^A!Dz4!PB2elklnr(>+(H^B$Q_-my>;RYr)h( z*>Yg^b91)gHDjU7bax_>P5MJaq+}C$^?`a)>O6a@UI)e2m3;e1Q4-u&*Q(LMj`1t; zlj})d?jfQu`)M#ym^}zWAqWC%zC_fML1x@Wcel1iNz_<(VlCX8jkAudCND*0B#VxG z&@NH~RMFAfWDZwg*J`=auUj3bcid~Xk-(~MB8k@@0K7q=>DOOX8GOzGhW-+u$VaqvGH ziT=O1QQ2x*?#gN?pHJybPREXj3H*wJf>1#z#-s~ppn{n};^6q@5`Ls$1l2B#=^?<0 z>FnP(>=j*QtLw{_T3XfmL55bHd0>#h6io#?WWKM*nRMOHv%mBfZ|);Rw7q7g$FyY= z{6jg+c9wfST{x_+Ubeor-++33o|DlsZySH9xQFoNJnlk07o>{nIUb~i(0S$WS@8az z4n4U;;q~$7(|y<@@m`8dy<_=&ZVyp=E>~me9NyWv)hE(DDP-$>Cha~N%6x9d8hIIq zp#8$(&G?)DbLS{F5mVOV4pp|}j)!ggIP>Oq1S8-ViR+V5gwTu5JW3Cb$E?NqA5V)SjWOeD?79Vn-agm#9}KQ zoD+ghE>vjXiA=)FxmD(&s5UL!n*8NQh*#>n>4tUUV0x4&Vj;9uD)P}< zMzUZ3@*8{sn>LhpVu}Cv=%BA_~w4= z-Jv0^Mo$&`K=wqo#nW3G2^{T&0CwY%gTBY-1RA`SF^dUl*xIzwqZ6=5Y>N&=X8%L(Ja8!6GIGY;uxq%c%K+p-FccIxDpf+YyDy zpPc>(yW~z7sq+M&>%ZdCu3C1@nOCgtE|sGUN4Bs4q98A45Qml+pbVCG@sU^u(Gg#3 z6QBW`NM~dmuR6H_Ip@nkS{%Ni8E4^Ise!7P2KLfD9h^}696nlkqsb>8y$|Mr_M^@z z0wm6i-IKxrOh!)H{e%z>oSQwyrXB*EtJUGho|*#!>!mxV&u5?>d?ToGtJZ!8UkS&H z)2Ff+oYTd*VA=D#;;o=R@(m36an!hQwCiNFoPR_A*upQ)w7-FId9}O!q12p@F3b;V zJfLy&=Ef{-#<8ZB-Pw=I>0zdSma@}SRu*PLtDCnhkh9rdEYb3K3uz|G=SjhRK^C*ikY)07?;5 za6GrA8eGYle|COG>iZu3Oln|OI;}yGmnHZ6fl_!o`{tW*wzjZJ%^U419VrD)-fDG`D%#lEpjaNjnEm8=9P~=Q6Y}BMwG5`3XD3UKgf?LD_ zTHUXI#Hn18U!C>0>{tR(XWr-N^IkqlX?78#EC%$7w(d@U@8Idj=vEk z=<@(S*lX3%(Z(4bhkd{oU8#6>QS2^q@rzaxZ>jjqhH93Y0gY>!}}@-!-VHywyo zedhA7fmt%7Fxy{<1;N|zN&S$8P9(pC>gbX82x97bK!AO1ta=AdOEFR}zZF8=e!V-9 zE7ig`RK43dvA5E|+CuLpHu9Mp+$RGwzb4H(#fgT}6R$N%;?VxyMI48!e)ow1OD*mT z7P~F0jQ|KHSjo{&M+lbuRtGs@@FtC=(1XyD4h;@@@$S)6g^JD95fA}O4mSQuJCKb% znhpc4O(wtVV*J71Qvt1t8t_i>t4KOP8F4hM(TUEVJV0a@Th&Bf$NW5$qr{V1iRZB1 zJg40I$YEkpA>VjAy-P9t7><67L2W44N!dIFvU)UAGoI~?kWyt5ki~gz!GPSb%3eym;PfQLoT7qi7KSFpJl2z1Bx2weD=;FSmqOW49 zb8)Fc?G72^7B&a`9jwx73EDEYkV?H$v0+Sq${(ZgcBmcItmz))yfWLLW05IK)Ff}6 zBeV(9=b&Y#SLdoTh)YwaPg4ywCE{IW5z({_9ZKD<)-tpX8yv-DMh0S;!PhObYC0YW&|g zE6PHYI&7c8vDRc^j#*l*v~e*4oJGi7dcq5?Q~N^tYtG{Luf_Vkh8~G}UKbTI>r-g~ zn2DXkh_YxU*5b@bqK3b6Iz^yH({mdDelP(zyB$%{N&ar#ksZ?!?F~SEQb#ACmrDO` zBsYtmm=*PnV!(c*81(;%TJrxmE2&vHn}7Ss$-3D56V6cBkR0HL=h-MJA2x4#^cB)8 z5@o>WEe9tA4<;-qnAvD=th6B9u(>PrMo0>P^Yz0cnYN8!dzBYtH6t~f&RTnU_V)T! z8>s@vK^@iKS0EteL48u!zxzi#*F_V$O0X|Ks+iYsG=;4OBP;Pxl^(f*5p}Q}!ez(` z!6ag-Xu8k}P!#?qA;xBsY0!~TCOT?_Q(oJFRv}wuA{B&|EuKYOhZ_4TdVXAY<;nl> zNB@&U%_iSh1xGoGcv^Zjpbky5iv z*F;g_`Mz=n1KKaydZ&?&%@J@>pVm<|dBJ+OYxD|#`m;^cJIAZ)?KblKPf z9%Jwyy0gGg^);j1N=bd_*?NyJN+9JEuU>fXOzqR2 zsH#cJp?MK6i^#ZQGL{6WO({*br|#g+c*%&Z!sO^d-Y}vaS5Zhy`gV?s5bNya*mb}P z>AAM*WVfpvEFX6-6<;b879xh@>m0#8NejH!Uo1Zn6;Zd;nJAt8O2oU*sW{dq&ZDhf zv5|Uiu~z7CASVRw7_jfo-jk*hF<;X`C~4AQZ3zgmNF(T646JY4^EBCT==vB;X9e0| z72WXNPf%~+(VJ`!prmAUe%*A;Zt}Zad)bRAq_S&p-59d-5NH89<@kGsSIf8!6 z!CXk2EI$BwMc+R#QX2utuW_0(loAC>VII3|_Fh2W=<2D{(qJH#AuJhdKSY*NB*~|Y1jLAJF5afZkc=tUPTKGFT)q*2?>(P79JpngX73im zO>=>;b9kTB&iLrvg7Ktp-j5PAwrsu2K$4K-vtc#Dk*$YO%%mJHW0b64E^*l?en~k` zxh_9LCgq4l_BA|YESx@$ z%*N_smvV_{NBL6DHHJEuNF8Uw&h|9-TR?_99mIeZo(A>@ zlUJ+@6#%4MkYd0Zk~16Y5Jx9I_)@B>LXHPzydjv0IdRGJ3VS-ES;l<+C@semP=PEY zqS+cX*b3r&_#yi{+`WS66Q^-Q65yzXQ+V1qJ6Upo1g>?H!F1L_xcIj4sLU) z33y_pfLx^V5ybKK12l5BM%tbW^232T%StFk#_(*4rRP)k&NTk)nO($HO72OxWIMd& z@>%%o1^FyG`*Z=?;&$OLSU4SElXi7opSV6|_{?PAULHSx0G-II?5g`C{nW68&g8Vw`q;=3^^^bEmNG-ue{5*(rIaGd z2QS~4Bk>4`&zUmS1BqB!tOYA^HG1q&%Rq1ml@-LVcHzpm63v@k=A821ZqZDY8JKnc z`69J$Tlm#d`-nv>g&M;YR%uPX zfUE;0pS`kn3R)Q*nkD^FKMn)Sp5>rVQfz4&3cZ(b-m9J-yMuLqvo!XsLzn$E`5)@d zAO7QCp@`~l8%j^t;aia;?|``eXiE7IW@>zzkhfqGW0Jm!Q7VXO{2EgB$gIqZnVARd<6!S9WT8b^j*Wxr%)#6*hUE)uB_^&8%g_nhP|B7Gd-Vy3Nf9H|r zJD>lN)$oseiW(R>+c|ptS6aCq?N)ffz`%&WcwND8UBPrk!I}>X76%iQMMLOea^DM_ zKL$G!vIsvIkvxDnE20NWUb`uJ|dybVH{Ollr zftZhrWhNuupNXA`hpw)u5!_sYi$KcyHVq|9PctdYGFm6tNz@QwR-rt+ZTY)bVp-BX41zQFW z6W$9XdEzWZ!9+Gm1yL9o!Sk>thevxydk2AjN>fKcPeN1k^HPP4^nx8X47_0TLmN0S z+WTAB{+ptjMl{6>#rI;6`wrfJym?)*%2Z-EZUngx8g_j#a{<%#SMM^vV3mc>~0trKYJXQ&~0qCS?AUMk^!1V zi4_7B7~UZr>#t!h=M9&ZZMJ`{)LG?^?)UFXCHnskwzH#&!9UNdKJioE=T+q3nZ~BV z$C}TorQk^C1HUkE9Y{d}{MGJWbXo!zMt=vyS8G~tAUw&=DUeO+hBU9;=?~aVr{BIk z-9I)D1Pv)2NF8YD#npbUj2Wh=(yFa{9w^`EY1{ZHBxtJO8K3+d$m;BcSZQvkvP_Nd zwV59YrYJc|DTLwTCb@g5f1X_I_jHVAz1L`8j#d@j(5C64vYsYQm1z8E9k{DzebBBu z7#{hU$I(}ByP>mWgV^Xs4sl8k`RF3j*|rG02; zh**PKBPEimAWGdXTW~D~Gj2$?gx&07l`&X$-VcK?xbFc!%MX8>M3)uMrpcIg?=YEl z^K|U|{^r%_R=5R)z zafBH6si;f9-y-vvo3sSU@+v`p4oy6mLTS>Nf{ zuC!LITNTqN{GAVn36Y`W3ovh19LPtrTjSbo?McW%QKQys(wp13#|%qcBzR4}6-%pqsvA!M=r zh$nLwQ*DqbRn3EjVRk z@JkD4$YQJ2-zT-jP-k|)k|GtQx7>{hXJ!Pu&QKqY2v^x$FwqDZ`pQCxZn>CFsZ&LZ z@QR_rFucm&gH0sJzw^`?g&c@-3G$3dFI%D!`hYkk4>vs*o`bi4FT(WPQ4z>UZ~PN( z1O#DO<&?50f`2h{@$ea#f*ODGW{6$CPM7m(CRlBL0zn}A8!Yh?ml}0}k&p_gq)GU~ z;!gzl9I$X=`HcS9;`1aL2=9wYVB=pR@e8SkU6j7gVT?cfzSI!}(7@dyKZ`tV;&~~g zav@1Ie|6&Poj8^s@&^0@=PAj)DhzGj7DE4ly^k!k3qz`Sl}u(m8+AItX5JV0lI&m0 z8z}Fz3F`Z$wipZui2eVjycJFCt-pPx|GTo2zpc`h1mHiLX}TQZG$}zr`y$pO8^g-@ zsZb-#o8&zFr zZ{76p`hw9%d7yE^I}L;qSy$+B&I z1hUO0I$B1x=o#ewY%p{DLIcp>;Q-n>_iZIeqs2lQ{_{EPrAn8>$% z!xS8-DBLzZ`*)C3(cZhl2}!LY<-Bj7iH7C(gr#>kP$fbm#4&}r-Pm{^DyXZ2SwC=N z)41!^1rlTL8+G$^;@@eAx%%UEYVC_kH=5z3THVl=ZIHHwDpLde+>oDfZB`3DSUtxO zS+8(f!=(JmLCcbc7HJbrSy(dcBaB)jteOhw$VG);2DoZ{f{_s%;b>;WHErm2GIS#P z%_fn#?Df%bFEd3dLEj$>d_fQj2KOl0;L4d_nX49AFL8s7e=)i=^xu@_De@*0pclmGougSFLqxSa#!~ect;QPN@VE@=i!9TRcp75+$lxr>c3sjOt3(St zBrz?YI}gLFO<~;1QSvRJZ>%{N?y-`kaEq(Mu=sv>@-MEsy z#t>X&Lroj`h%P0h>8IZIyolA{S;y~2b%q9Sd9-3{&0y)$TUGdBT2LBs3UkrK0G!qG zUB(cSA{1?b(4b04QThsf=oRFs1I~fJEc2y(7Yg+LSi}!ft>wF@wo&sR4|~r?-a7DgfK8)yn(B#6lzE2oit?^{lW{Q7Pi>hFQey zW*4yxKermU&}Rh=bj|QbJ)lIEtWWMJ77hbAA5g5bx6}L`SLQXvhK2>8pZf1)Cx8nD2N9oYFyjpkUsv$JB1bU}}cJI}(CR%sMC~k*{Z~Z#6B{NeuzVQxq;~IjtfqSFB36Pxa9>%B!;qkrbWkA=u|fRQK(6ZWA4XB~*g@0P;Uj8MhVgwvqDT zq|D{mHO3#BPK5*ND?=lMTz_b@TNh&Y@veUx&x`&xL#W;P*PW3iyy>+883+i#2n0m? zf3a}?Yn}c>`B|;)>-Wj@;j}a@L6Ee*;7|X0;`AVA1B(IJViQT!6lBS!Sqa7<|1s$- zX>#Ri6%W1fMOD3~s{Q3sxSZ~G?#DK|nRYd;l~-hq?Wb(76I0T3e)4X; zv2>@IKVQrDK06#A^KEjzV7*HZ@<3beYq7NNLxW#n`m1=qANTA?Wq;}K-wd$_HZZ!= z_D*?x5~m3dp$kQbjm8ZVMYp6yj3(vCVfIM)0|h8kknoqO|dv>;Fl8z1j#G^^xF_}*SG3Tg`JND$O zF2eG5Hu6(d7!+fBF>mT^elA-QvmtGIGnWBsQAk!lJOZjNcA2kYD<3Gzg!pu+>lSXL zTHY3`B^)!R?jl6Ex`};6k|Z4aROf8qZe~edzAwHobSpZ*xE`6Gljcq)PSWf76Jo;F z;%u$a0QeYonb2%$q_NVGAh%k>-NLYu6i(!kxnMeTuQ&T)Fd3m-&xa&q$|{Tm%+TL@ znIo=MWHj+QTHP5>2!#IU(G^bl~dLdQnIX|bX%eQ=Nj*leA+$8$uKHtN;ofu^bHa{t; z_j%dBcX>i>9{yy8s+-hVSo!dfFR4|V_C+ME&tjIv(M6MR8FPi$HG@UMk25zdEPa`J9zn_~yx{QS`h7e3 zJ^xYTyI8;^MZ!}jJq>N(X|q*EohnO$m^}x;k#1%s>`WP6^Oy(LDG;ot6co9#Upj3X zirLyI=$dRn1W1LV$5|*JLbY|!QJG)xEv{ZZUocTaWGWswfgI*vs}rV#SJ%A|qc`=t z)%x*k=CtyLPc$<^^sAuN+XCzw-E3oBOqhR~fUBUblO9K3jUVFa{NiWEp@_PO-Y8L5 z@Vl2fsc()GfTC;K=jaQ!$=ZK*CWt_5NNmmG8J;#Qxyl-9!kiL`x2+QooHrA?zSSM%FXc{PORI z+!l^eq6z+4&zljC5JMUpO9vm>mZv}XiGV;M3r;Wa^dLtE!pp7ik-(WFB3Ae6D74Hz zMto;Z=zF3c#YmEJfv%vdrAFR2gPmUY9=sB>i_&%XNn1ViFl}CNtE#t|Zdx4;7G%Fr zrelJ9sN&5TnOk@%F1nbKpnY<*Pdc@J_h3ehiIEMg1(9z+KJjZm+%_Bg!*x|$!ludO zuqfB1a)Oa!Wt7xrw_>R%nslq*j1A`k_tdaQdxo0?Yy}WrjKh|#$+ZZ2@h9CFA*waZ zbL&)NqK0B9Z|m;!ilUh^H&RQ)V|`?*+u8brvoFVq!jP-DiasS}swA6)y+{jlR(JMh zSIk(V?%E_3;mu=WwgK69Xn#zh{f==Lj06!%^`d}Bf1b2|Bn0#1kF59BSHoLfgPRD` zm5=LtYqP6+07aZ5Bo2SXA3d@!3GA(E6$1xt%_*^RA1g1sO#5m2mZ`qER4iIVD3BE# z=sthDRl{koY}sUkq9Fba6O2YbOUjUW?bW$_vH&3pj)Ppy)j4kt=FpevBMJGm4+BYE zbk|k5Dmj><4nwxV;?*2=zftQoa|5>PmRn5wF)mwp3zf#-SYBnpzO`iOTXofQ{vc1o zaI_jJvSMyfBL417p*)d96P4c=iMSp}pJN4T3pU@?M{k+_SQ(oZrdIt3RreVRJV4>9K$fG=`O=XeoG~5wnMK5_0RdE&^Vs!CgkHSb3 z^E|*^b;hPg0DyX~&rJ@!psIlnXOoqaOoo{e%N;RUgS(qkw1`%@ScXm3u<49x3*hSH zp*w6wAzQ=&8_kA?zx8##FfpuotG{QLXr9|*kHVYUs&NzDa1ItV3vtnEj~q5VsgYcy z^8=mNXwR$)?p-_S52obADg@Nb-b9wJZk?0nqFhUO+gdwt!MzbR=~WRIbqpRh&voNz z(*x&pC~8-Z#k|e~7}O0aFYYj3B;Yz_%C7O&s#AY1^K=SCeK3S6yz7+4Iab83*h|_o zQ{-uWgCm{9$ZgU7xSZh(2X%|=9Gc^A+1}jrB7c46O=jI^#^N$&v!RTo8FhBp-*3Ow z8SBb;X=FK=hZS{qT)rbGLo>Ryu@}vnaI#RpRLI%vTY&0#8bo)-huT|hP0S@@4!X+lX(oj*W?)hUAc)_DlbMFakU4bM2b=fI| z7Q0=PBdDiiOM6Fj#dKZswl%(4iavhJP4RqY2GX~@J!A&8 zN?-jlDtRY+=1%uw+Lo{CKkoQoSWC&hQBO6OR}+`Zsa&eI3Y^OmWD2y6L;}X&hM^?p zZn^Y$8z>i;aToSW_C97!WNL$iG$d%SNLEfbmLd^_Ua9xb^19~Q&PTX05uH;UE3i&l zjXg4{Dmljf8|fG8(P$jNLQ}YtY-79O=c!06mAjGh`H#LHr_QocW4qo~%md-0r_p5D zPeEbcB5p^a{#zgEY22~J#L(}AsSPyvB3vW&=-igJ&0qSy=50j;Z+|9AE-2T z+&Q$S@Je&Rwm>4_1Tk0mm%DVuJxHf6J&Etx<1g1jZHwfabg2nJBflP=Wk0)#PQ1`e z9e=Z3AO3CP{^RNHft;rG8(A5T7h2`_&*757TkMdQPxwv~5i)&S$}3*T9fxNaYwRpI zZ*8IOm<>r&_-9P+XS(M*7t&Xl#l0SeUpt0~{J}CHZhJ6)0;YKkQWBZ2hp})}GoDkC zGD$0QT)*x3cHLN_Oz7(8p0i6ruVNx-;>uJ?-@I~2-a=h}Au_QW zK}~sLO%-z>+08X4=g6yd8WCRiX=y~Xa5%0LJ^dNoU`cfbW0LL+G`k-7fX#LCD9uZw zeng1Ep?t8@@Sr;;pLRwWVetp98&t^Bz+;6xy@G?j8^P{M2SAs6&rJot#sN2H93_2; z?3?-a!-&aqB43-J9@1d~hILQ-U+!ctm$YAt&*uVo!rV}Rat3=3LVkWl`^&`wz1!OC zc<(;3_hzE2TQimLZrWp;VCO>m<(hnCPcR&!qj^VJjWT5XF7^@}o;AjG7`3(^1vwv3 z$=OIBekNcR?~@aSjrNlw+MNeCS4g@xvAD!icsUZ1K<*PeE=%sQ6F!1F;OXrhDpdXK zhNAq9?hcXKZlve`=c#S{3qIErLJqqvAoIKuGq#{$O$m=T0Agx8j_i;pCOl{WJox#7 zoif>{0A@-E^aeDU0q%eyXPhB8psWybYQ_+2>8N!3`@^E#H4qy-=1#Xgf*3Ud(wQsQ zzQS|%ceIOJ(EDTDvMaa;=8Cb(Md7U|KLes}LixCiXT_x660X(qH!_}m_S^+K5s?}T zDnG#VaEyrkz!&YM&S3hv>>{ddGjs^6GGsn&oVg^r_v6P1mQ&mBPN1i~kl~-BOz0lR zVVgHDZ9801Z)Db(#AlO-Z5@>rcq4-qPX(Q?UF6j%gU;AXgI;Lay@xVn^ubI9GHZ)O zX{s(DYDqFDvQ5sW_9Hqpz)T*y;HEetS7vf~Fse=vhxaIgCzu8)5D zLXDp-V^@c2PYc1GkdT`Ozf&RETeUeN$uW(OY-Kp%+$3)mXLv6$XmhCR9G_b-4bP`w zTNcwcDXPg8KL@b}i*3I=tKB}a@2eayH4@@x9+CqrZQL+Pd*hY%0IgqJz zB9gHI)-TjLT@_j9OY=)sF@s3Oo=tWHV$U~a6B@ZhFTzhHa}^%ewJ3Qn^^dxQ7v@|) z8-Y=hM)xcVCKiN4OMz;pPsVT&a_Y6?ItSa>z-yLuK)qu3hHd4Z7_@yrR-oHr<$uR8 zskE9rGI-AmM6y3s;HNI3fp##F{RGhw2(b0{fhNOV4dz(Mvj0)!CEB|04Vmj2$7@7X z&J(3P$#s0J=YR=oFwG6u;&kE>xQ#uXI~$Y!u`e<6CT~1>f15qJU&a^Px=9(2V%_ut zDaX}T*H)IJ^w2bAI?FVJ_5j)yYb5qPG=kG>L%?*pFb&{n1+3k`GCP4KB@1+W(8`;` z2ECWkvmmp_1cN;ONOCMVj1@^RD7D!{DjZ_7`pfVHN%%R^5t6vnLbh%w7M$= zAwB#Xdm`w9s<-w}KTuWvm1`~PIO4PbJTWN%ofSKf--eG0q0 z(=%{}ygY->e+zD95J^8Ll0r986?n!?SBs`(z77m`_Jb&sL9QVlJ z4L_Y4x%>0Vk~~0I=9!g+!&)U??~VT@*vw;U$_=y(1h@lh<7}*P`Slp`@=gdo50z;w zeBb>-Y$B2EW|Dr(#ck{RmhNlBAmJW+B7R1D>26M^{+&61x|HR4hWy0&rsZBndiO?JYniL%r;eUBBjpQPv|F% zPRuc_1FWI_VaOWxj!NH)ZGt_1uJx{VV&J=x{WGrUwy{p8?+M#)G z;1|`D+iyyhrn-n&nuIn{ zTtlG0PuT=bhTRx|YJ-?3w@V1}F!02;L2RzC!3+$?zXZ++Boc?93`d~NsV|bfKOrCn zel3DmtJjz;_7ow5uZnKO@ zW~||a*%n3HFRAk_quIXunL}hSI)fjf31}~z?}((cH}vVgv6`>I$FsTYhaVW3XC|;t zzlUgFv3Mnak5KTw?iAfWHxqK#AjdPBC;U;YrYxxaqZCP5qRW!9T{JugToHwLjF?6M3S)o}3kgr^HUMe&#i>gq0D)W4-wUob6 zZCLuTRFtElR#9_1o?BMA1a*%2Sdd|rW|=cr24DdwFAZ}y^{Q8)VzQNs41+bTu2!X> zQ#38ER;OS+{do?wEQakeYmM57%EmtJ9yhQ>!JRc|4%2M)d&%f@Q=|*suW_Q|54wK_ z>mJMh!^W&o!=xeCvqZ42Pvet3aKWaLDs>9=oZ<`Oo)dW6@>ncIu|T__42OA#lV7sz zIJ&a9*dTt|#rsH{8ilE`Bwrp~g}Nt~!56C;thd(@PzAf|i&Dv#CIs%7rx7_cjiOtOKc%z24S{27@PmFQhuM+C#q?_+z*RxkGaj1$KCB~ZTH2Ma#BcR)VQF|X#J(} zOfq)X_;+Z0f&7S}bnqQwcEVbH#N^9W~A~z_uvbDK6B=Pnhrm&hL z(;qYYo_C6Z)e*N)Iq1p-| zdv&fZm2a&Iu@viGk!dF=>t0>2`$@?j*;ifdPgw7&YJC^C1%Dm+QV;3ws>Hk+eJtW0 zdz@Cja#l7fKX=VZ!Dlqo4b49Oehw{^p)+6Mz1+yPKbcuCxe)-noC-?YUG9&Ax5oT# z@&Eic-HxtjY-HGPUL@7Ge$ame2EP$+6FLDyCuhfRmW#ZBqmzm9_b;jzP8Q#sm;VMV zq?|UC(RtKT-ov(vWHR{u`1QbgG#BDhSY5Y@hAkF2Z6%~l_0{v(D+>2lF*K%obN0k) zFH5jcYax(O-+@@)@lb=ENVJ-8Mi3@f+tqTry{2DqUms2`cD{gW!_Gkn)x!-@;7H*` z86sxn6FOMhyvW^R1=Zp99Khv30z4Wl)Rtv%zQ< zj#OprtS?e1ZaPGlwwX45N*$%B%$&<~7?{AN)~l9UWWI?mH$xM3v@d)Eo2GmV)y)dU zCL7k7t`p-BlQ4q5zh?ux-uQ0+ELj5h<*($ok%$<;2D!4NQuIzkJ)85{F4ju9=%O;R z6AkX-`8Ux5_>Cv3*jze{?xe@bXqF(eoElM|CWiqg%%Im%T%Btc=qRXWjm8Q{Vavqx zC3Dxz)*7`6wxnMdQMG4DFBy2ef5VoBkdZO$i|y7tuQp&ldMPk6CGgMWeDn@g2G-d! zJ%#Z3uB~UT9!`C7QCqKb#}qiv$Z0fGCo0%Eur}0lcFeO6IM1i%nA*!?2fiIP?zGK3 zJcE1E(8sDtw4W%tbX%g@ZLzw5tvirD$!LfKh;Y+-g%_Tukq~6!qWDtp4ZUiXEG{`~ zEQ57rCvxK@Ym7w2Um_G%I8pU5W9_ZSxv9&;LVG6FQsw$lMT`1ICb*gXNSifrDov}> z9TRA>SOK=;73c+F!SXQ%z{%*gh73Wa4BP`J44Xra(3z_d1`sVEs9$fw$n1RBa0`cg z`2Ll=SsXYInp5ofeTx@B4z?)O`c$Mo!0xEnen|hpbdE}87_ypl>Gjaw<>b*%-y829p+^1% z=vRp+K3il!2JL|+D8U}&SSgJpcXM)&oY~P2?O3(DuhGwGcDn^k5D*GO&*@6y5Y)!= zhEU3bZ>pLt1*f*AOPa;xeFW`N4K6gCGXy}UG{On;&IysU6LVCK&QzpQ}$$<4pww0$OcK2{F6L=T8fr-=!s z70BO6j6fH)dt@ncEFeh!F)0@|mOek^EgS3CXcofo+nJuOO^#;>(zZd8_PkWKtK?Uw zDR)il2}$Ll;|>8EnO5rC1#ZjhJ^a&zQtOs(d`H&E)p27k*UCuRlj~C&U)%N<+P^|9 z!PF)Jf#1+d<@cB3KS3=2=rR8gY?QS#{wEjAC6WQMpC4Z2OL$5Y>JB!b7&w8-ygXP} zKU!$Db}iT-aX`Zz2#&-Qi;J&Quj}cPTMr0U9Wx1RIFGOj;4mvHI}K&vqa5uS1Gnbp z+8AWBm|`QY>rtf<8mCQ{r5yB|(jd{~FKeTBo7+5b|MhQoq${0T-WC#ndFjbGu{1e7 z{X5WqeG=z#afya+O54>p()%B!C;#=UxXfePLdy;w6|MtP{hBD^hl!4L->zaO^F!pem(LTZb zz5zn6OBaUDExE&}L|vx#uDeYp&`s%HL7vP7Sq&yj<5;`!W4yINFna2ELTQ`}9d>*9FXl`qC*DqT%EwR0%hnJ*Tv7 z1@{9hZ2l&XOk9sdkO>DO8ls-kSj;@;1gb@!jg(i!Xx<&F(J+-c?##>plcKi_V-hit z7y6h2wcZj~wIJ>*P#k2Xs4xVzlw02}EXkdaq}Gpl2u-3?TKDut+;U7gk)X+Xah&L1 zv#;FevxohieT8qH*#BI||7VZK`m=655?6!yD^AT1c3$yj)h zS}~#EcJslvWM+f?H5Y3t-c$AXIOCr@cyT@|iVeea#L(iJ zI`uNKH`%OH2M(YuKi?&k-CvxP8I*y96nhUkP@3(|TNUfe1p? z)koR;Q$q)_a!NQkC+dpAOzWP~XkY!?P;xHxByu}S-wwE7Z!nNwnR@FoK(fi-15COScYSMn`NVm^g}Jd96aM0 z_+4Rmtpiw5GjV{9tD}KwhG}N<>f`hN0L@RPQ<5n7duF8wVL%bGMSfHtL!_(f)Z`mo zCtk*2+;q?$O1|Rc2^l+wxN(|La^3Kp=^zPN^xtx9{ZpjBiqTD@rn6SxTDU%cZl^Kt zl(dDAk|3zgLhDr^+o9N{PysJnV9nKBL607M1Sa%e?M2L-dld$!TS{S^&9-rvUeO-f zxwSjLd@_rnHo~gXf*M>)x&?@{S?3t@hgcc$mN1@L2VS2v}o?Hz-3ZI*4(o^9KlZQGu0+qP|Y&$eybwr$(C-Ls9;-&%X` zv%huEUgzGp5ziCx#{1)msH&{YtjZi?z_6xp3tYK-L9gbj^wcP#&rjR6H4Os`OG*J( z4ghi=B6HilrZn)>k!0$R%%z?t&7={^z<^%<*1UzTct)zFHKFSw^cLp0o4t^ z(>4fmHinOGZxL~JABlg$FtN?HXL=>AY;|%2a+VivH~B9%;Hxng$0*8(N1SyTv_(1eno9MT#X4 z>T-VoHG)R=dCJR7BEo$2UOWWVXX1LbKG^;DJ?u8kppN{#f6u?|^M3@<{Ub>J*B<`c zQ6e&SQyP#SK2XL^4+P{k*aZN|O1}dhe+#{nz}#@(E6|vleADpcs^4uF=tg$nsthZy z#yY;pA&vcB$~dX~2@U}5(4X zI>QMDOEis=kg30Bi1vGX5X|9|0C(^-)C6myDi~A<;p9Sv=kIn zkhMr#cY|yp;xK2uReFx*%YWs9gy{npM$U@&n0d7gaJnAGIntnsZ@-bgt|jv@X7-A4 z&gWKtkbVa8lvrd3m^$(IOESiLO{raYEv>y>;Cy<2zGVZD-2C)qB9W4W*@5{FVuMoE{g(R`ZxGGa`xtHYU=3wS#SE;Eq zl8n_`bh#kFTk}+Oq1%k>zFvg`T4k~A;D^&Zwh1)6ZST(>*yUDz6$k}6E9tD&OU8`b z3MpVzeWmQ&%({_tX89~Ae<(b8yPVk*?|{YBH@pR#jOUu(r(T41RM(8u=4Ai0$3>c! zFnk@xzhM(hfh;pPa3ibNLCXJn_gRbNd42tA9jJu3+}5{aezMSX#kPH(cEgAAy6Jub zx>qdwu^l$Io0ukOvD?L;-2SIAt$QIS?juHi|EdeEiD>ZH!uxF&sXTHs=ZMC`FWW1h zlZMys5gY2*j!&74e|xn3EHCLd8W|Q9V$&<~g&(X49U|++z4RS27LC|9zOX8D(UrP=pxnN}f!**g z7^9xM;ISlm2-xuS-&9nBk}-r2O7<^%_!Ig_c7bMu95@ogb3?RjB3w8YdAxoCMBZVg zIyzkQRX_yfWyF&NV(Gr2R6(%@+91Yq17tJ`Cn$L;sguCQbfH3$xqXdcW}YH~bE-KD zYGa=%%%Pzt&ir-lBN_=?k$M@#BX?O6&j}NZf(#LKAwLA@DlX-% z>1TF0HoZF*-onZGtw+jnUj?{N?vLAyK%<|(_bl)Dx-AuDK+yKj^Bd^?diV)uV)<#9^f#rX zJ+xiQE?Iv{%$B-IKaQR&ixy&>+8a@TomnQA`{IzS-)y6#xzD`4C_2HJV&({2S zsLF&}{1E%jcCNqaL|OiAX851e^k30MO3%^2^q=!Js66h1q=fxR5-p8LB0m?5DofB1 zQv|^$h}-m2_7~-;fC5zGPw99w^c2ZGL-`+CEw{X~(JfCqeL~#oxbCvb_EDV4*6);> z_5;__Bwj>7pqj4IQ<)w-i+(f8lybUQ~h6{zVqW?^u ztqH9eN-yfK5>c}fGjCBJKW47XK~W_Lt{5F3U^jUcflb!V;GWU zI7nhI1sR*)vY}_m4rCQW8f4WjA%sVkqoe%>k6T%4v=8mI6Ae>Xt_98d#d3{;KejTr zb|fd^T9uOVjD%E9na(`6l>z^H3aP@h`JM1MRbfX7&JbrsBE_RptPE^>z_90PLlLl) z2BkSFl(!tS`Pu;>lw~J-vH%wy>KN+!f(N9BV1K^a4S|jXeb*46rdrCzpr93pP7*1R z{coH4ORj6%tNwyN2EQ9JxjsO6{ob=gxBQqK@n*Ak(j#AN@NXo_>>$Gw+U(BYiw|ZP z4h+pPat+-vb`5oOF=DT=vD-76bNih9ip6g1MAz9L^wV6YW**fphOo7V*s%xPu#YHh zkKr`UOTV8t_RD?`54j`>8}vtBKfd=qdKD?z31$@~yZ9PCwhK~?vRHxI=o79u z5&fg)?tYc6A~++qFBbT7H*s&b@aQJ9cwSXpLjFwiZb=Mpr~I=khkaKO(!V8H{(TkU z|KXfv{~6T&>7FZHw49z=jQn`70Ozyi^rLGF!A7B;g)Hj_}$uyY(|**|CG zpAI8nQh}$SgOly%GK7X_D_n9Cv0pFq$<3oU-HF973W$_P>tgemanIR(pZamXTHOtV zK4b#fW=9x6vvDv??cFgRUEue0)8&UTakrk~w=O!`lK-nW(s_b#GYb0Z&VX--J5chf z*#JR;fhXn`U*Ndysx8Q1I+=>l>^MRSG|4b#yc(m;Sosf(R=p!(7s$cxF<9g%wz7up1Z?dSuNR!~FF60#QFON;^C~99t>DNQ&9Lj_C(oMb7o^T%u zK*DCVn$Of-3Hboacx{Q38br|1jVXd;hkRd%FvD^vY&7a0JsD5xtyda3Tk^X~d3Sj! zJg7<$3W`M?k#G1B%N#Vg?^l`Uf=Ek%W{{CfX4v{`fO)B)o|wU1cdb=yTwj#ML^1oh z<*Do-Es4bdRZE{~LmYj==qB|T!@Ue3zM#AvWQ)yLilI=k2}NQYI}|Wd(M%eJYJ8;4 z*tfW|K1<=i)()@o8tvI#Am+BHj-Ib)p1CWko{PX07D>9@{c*RVi^g>HS#)TafkzL# zaI&MaojACK=d(L(fk2GdrltPPW5@kM@KU`Qf=$)jN8!)FUZk_qldtq*-2L!g!x0Cp z;TA=^D^>29QBeUDF{#A{lN->(l6=QRXo)LCcG*dPIEDL6If37?QpfKS=(s-yYQoAw zut8y9Bjc)a2>xObaERQeY_Eh_R%JzDN?Zl*Wi>6Mm}EzvBqR1J$E7HW$TiaOPIm$G zOxQ$^k9QP*SPR?brWM5DTp%h3UgeNai<#Xk57!ty*A4NSYaBGxb5*3x1q{@vjOv48 z8SM%18zcns@WjFaxjYmp-60R`cTAJ@XU(1z^f%Qiquy&j_eHFxSnB1EM5(r1k;W|Kfdb$W4r>IF_nD^(Vx#JR)yDYs!j{ZTlWK zS&ZW@`JR~)7diS*s@M5`5KSrrsifLIlnSj8-lZNjCEHy{%@#m3feb_7VR!JVNW;`# zeAt%oCLQ>+H<+d7Le7=pyb=E3cbS%z1 zQ+I6ktmtT*U1MR&>}7%u`KnK^!$cMbEIs_omBt?JpC7#6`ML7g^EU~Ef}@_j<6mq-|Ka@Pq$K`AzN?*ARW6!03Jrws^up2o)GnBl zkRz*5U!U`6gJo%(OtNfxZT`;Z|58DqUxm~@6PnQD*_!BZ6XW68-ujV|qumF%1Y`-k zVt6xM7*{k}(}>3tQo2(s`_#cZHyV#Vw7`Z=hpaw|L$AnRdcuJPC-$TjnTtsh8v@2J zk?i9S!Wc&`P)VF1E~z0EFLH*FE5+(?XsjJ{RT^AYEz`I|bc>NP-!=mENA)+jEh&wy{o^;4W4~*p?tYK1Dk*Y~2(AhzhiT zZvCl7(Ek|Sausp4$DS7&8>-LtcF%FqSD$?z}{!9Hea=za@knoUDw5oh&W?7P}h1mye$hnR|a(qMphE#VQPSG0)c&NeD{H9*P9E*Mb=!aj^?;FS8C!6UV+wnwU>zOp8% zA9eliUx1TOYJG83r~m*ZO#cQr`H#D-|0#9&kFE93P1LCd<*B$ho89`>^404vN{56joX_Sdb)6BDV7CP%yu(p?@Gr$B;CQD1wx z7H&D=V6CT^G|soWZrMkB_;-(^`;KlIySs?EW%sExxJUT3$!*V6aIeAR`<9s^uBHHR z4>PK`m-yQ zu7n-R!&>3vn&2}dDD?vzJ3Ga#%04Ahb8TXNgFZ~OrGW7DjgF+{P+Y0l`=Q33dA_Q{?<;AfRLlTp6 zjBu#UnF~j#1v+pXyVyxZMUTSPr3%RO*rGC_P*t+I06q^c1gpRr-Hu+%!GkICTv0Om zL^E+Uo%tvB!xQ2d4IHb07VpMf(VD7CBPF_~6;0xD%Cbn7lwD$DDx&RCX^%X1;P3@XHbsg+_@e^8l=$ujyy#rGSE)Q(CpIwh4O`HEuQMtd46$wkhxEknB(1Tp>3Q{lS@ zRz_}%b@@lMV~_cz`C2L#Fj!PT`sr3eE)doEZ-dI*tab&#m4i3}Pii7IREytDZC$EY zXVUI6WRCD{#gnwAO&S$Qfts8?0r^GA`;mG6eDGk*lV=BESigO@`jwvKvkGdc3+O+l zQPn!xTX5}qK)WHmt_TkTR#<`u^&1l)M^313!&@eTrZl3re5|&jfnw!J{i?^M8pJ3w zd2C1O*%h@Si;B6nnQb8E-=#S1t&xDC4P&Ouj0eKxYf(iITGxj`tdkxD>YlERU7Sry zG9B3SO`Sl!K}W4x7SzpJ%E*9X2+{8i0PHEl6_**+Lu1aqvnHzMbnHS(1Pg;*z$(G3 znENqq1xaFFDd=dd7L_SgNWf}}MpQprqd9Qud7#{@I6sGJ+;-gkcoR){221VLYD%(% zS`w*Y$wIC{A353Ih-Ok3VnH%=w81mj!iH`EAv96*DBMJ3W{Lijj>dt@lVOD%87#PL4AVTCg&_ zQwP~REG3jBbPezQ>*}M_#Md*k2(M39kM)gu(kAo;z(j@-D2OeIF_%JFPwW+yR2~3z z4SYU&1aLdwLm-PVcIBtgZV$A%Zw3ivlmY2jbZ^e{TXS?n}R=8P`z zd=7N{lJ1J6pweO0L8*H)nC>xmuVM&BJl+#TL-#m`)vl>QW{Be_fr1lm)s0=K;1qi0 zt}MT}`UPM-Ogk((d~ph%#E_rB;&1&)Q#OiXdPJ%@1@*XQbM^LM#7=ZPF_Kxcg0y-!ipE^D>+!zfZk$~f{Fq{vPonM(RNcn)J)EQW><->tH1sEZx8aS|&jA&jm6RclshiOVEt$B5Qfjy!ohr2sc_HgTzf7p(!sl(O3IDp{PQ`4j({5hwjC zr=FER-R*E=$2S?I>s!R7&_??6frrB;r1db*TzTPXiDK^p*mS*$@^7@OZ)O5Q! zb+fB9%}~GEiPm(h%%S!b0ZB)VPLTxdf5dYQg_^b&(PDLSrQdvV_rMiMGg`mQjMPb@ zj*Hae)PU-hora$$1tCr{vNWXKK0nkf)EBlsFd@ZK%=q6gSthUJH8(+nl;xM;Vl7On zY%Ba}G+BBPd#upmN|9BX9yBhXr+QP2HE2dja-xh$00?gT1E`sF*d{#TY=WPxxM-YC zm$ftrg33CacYY9rE+{Zo2Rl-se(9K@MrQ;wzt-h_W1g*Vj9JJ5+d1H?v{O8r)odRcQ(?uMjUrz+fLfP=J`G#Pu87rO9w~`c$)&ufoL--Wh={Bs_qnjLvRAc{ zoW_E-9Mz(zd1h_7!VQSCGQYwUYD$M%eK}&vop2vg2vH(HJO}(+zw;lhn;=ZXNAK0UfxGZU0MbPd42d)p2dkefxT?3 zCU1@s5i7jw`nM2#CvUdrcEJ|NfFt9k-*M%$x(Md#4NrMTd`pMuxy0vh{M zoc7hWMAcnb=Ycn(Am(P!acaT-3kdi-l^dOyPY8~r%M6AiY2uugBd4$gb#6|Zzi6W% zyE3($jKG`pjJh}%s5$4>k1vF~XU>s%X%MZ0N?Hbv(j8q84oU_Ns6qwg`cVC-JMk0p zwbcaY{?Wi==es$7MM=)wQ5uS3k&-an!rK%xMD8jks%B$J3v}5d{Y6B7v$8)z4VI3q zYtnTdo4BlGSGgYX?$tvnK-Zs#C<2@%Iz8G~Pph0IUr1&eZV4IH{KeenOShtv zCEC1LSFL19aL`a77nL3PS9mZ5-xwFrlaviq)g$#}4Ja3EXU!e}CQN~%Q|@>~*M04P z6qi;6#QKqA9uZ&`&5EVli|B*!iZ;F0i(O^l-nf8bw_mF-?&+LY((YL<5=Pi4)4keE zZ9BX3=1i^&<{t~RhU#YEeqISxJO*Qg8FJW)$JWoG-W5_S&W!VS6$GkUA5kqnuY+T= zlCdQB4+k$e#a4IK#Y>|#PL-f#iUUT`V5;kUBDZp$NS-rKxF=o-gp@7WX6MIG!LqUE zyk%%H0fu9*@*O{C5aTdWBJROOGE}i_lLTcIL?g+ zsiQ`Tvy9Aj^k6IPX)nqF8*HH#$K~>=*;1)QvCYYYR3>asF$50S@tLD(k#uk;P|pW+ z#-e=_g??cykj6g8?xOVR!1d#SBjEHBLrRy__GsV5)#$}kpJg(ZhOF=EQV1>W3CnY~ zRNtN(B&CAR{^7V!%9KqpHOiS&^A~(3UX9AgeD9Cq>8@-NI)Gh3lI(p!4^FMDcP>e! zbu-DkeRwJ8lSH0Qf0AAgpt%&!07%7Y!_!qMB?9{}Vwh^!wwlb0cC(P_7b=*CRUlKW zxuwEOhbv!qg>^HXKzDA4KSdOOJ!4)`-)yElRd~6n(7Zw0(&ss+bJW+DOq!G2goRRn z5bjE|%q7yT6(F7@^)g=o{+u(@^%|w`&^V*DJI|EZXLq8@v6SbnbY>e{6#VYrzsJTe zo~}O@X1(V5tUKu6rjB)J#nfk zY<9)%oOF7?r_}}1=>zGAkvS&jib%d&?Z}wkrF`bn9z|L`Am124vqPFbGL{W?W!4$B zxS{pC1{QI{8BWZ<`~}`93&AZiO(;1f8(?yW zI^U7kfv>YSz%eTDefY0EyxHj9Hw95I2x_pMJzt{hbMS#|UBThCp}FavT|`o85O#I3 z6ruBDQ?oLoUP}ts$}GiKHEAG7s3flvf@VB84dqgo$|J?VS=wW75JIiWo5D9G-4MsS3s@wBhD0fBLh|t$H#??#jsh zt`-8&%%)Kv%2{#8(a`s&Cz-SP-I>;Rh%7x-#F_wctvu3;Hz(=Y0b$zoJ0Gz9H_?Cw zF@%@CHrgTq)I@ndpzMJJNNx5JW8;0}ocd37ZA9B=>|irJ&g56@VAI?IDKP3fr9@lDDToLSoON-B=HI78Kd-3TG0ieKPkFuvv;uSu|(=}4`N(&A7QXswxJLp((iN3+Fbsuj_xJ7pJn ztxFGsRR|E{JT<|zs9YWZyf_MMi5|r-3*s+IFx~XK!vdJHP2T2=unX&JR$9$$~3%mvm*$|Mq z=>&+So&C`jt-a&?N^et?@5$TlM%kl>)uYF`d<)w%B;6I^@&g_h6#C-m&pY^bPxM{o zJNovp&JndGN=0)%hq`p~%=O9B&2;b%hYbLMCO}{zfFJdZGHYg(Cao`5D%c$7$jkRf zitw+$ASxG`U{}AqW-3L;GCwQlI2{bni6bTl?L)m-Gp zY@5G2k;WPqPmlFCdC7?L+y~5n_yOFxe(b+F*yw~-%%d+#RXOedA zbtSECQdzaq2*d0@pM>v-75TW{=3;a#W#KlnEijp&=TSnbFUt$uflcR`_2~<%&YPRl zq6-D{$IWsOgdyT{5AaPq8|>olGEog}=?yx&Ii7{c$$4F6tby^J`=HoayrH)Gg5FL~ z{;RLybBt$x08jyc#K>lXKs*UN80TzwTz)%l@6;M(6yDt9ywF&DtW^-zBPDJ9ls{Vp zVD|hT5PDD~oW*%&QMJOCU6FK))3k<;@-_(Zi(Er~6wK=piS7A^)DMOW;z-Wl#F-1( zPqES2MY|h9-k+e5l{Rz4p1+mv@z(}|PrW};xxvL@Ieky*_S!5&8t`+S={DZ}-gD zo_~MuQXceK8oJeK7=8C;iTo;?JnS|bf5uaX`clvs|5|dsle41jE_b>WS;OZk>g*eC z+%_%f%&&dSJ!)`c+GG)QSQTe(wn{jv)yi?Ra$xFjf;OOR`~m61n}gpGV_vZrhL`)} zSDut&n?VDG+Q|<9g^sxNVkLmmmCVFggJMXcCINo0(2Sy2ejI#SMneTY6GjTzndy=zMCq)@1pi2kc|qo`-{-}t-}m8Tun1(83OoC!pf;)bjgF!^oc zQQlag5@iUuCe_?)3x;a0FaQ-l&On)5 zz2o$(C+4+9F$DO#Y-@C0cV2tF84uHbe*R$vxX!C02!>P2=rKZ3smal$506$ftYH$= z;XxfI)o(4^NrOa5u2)5U`$MH%*MdJGGia~CC)7&~QVy*~Tl1VYy9?cVCa_)mON@ zXmZ(4+TX(|UvJc0dcNigBa8g~gl?agt{ob!ENXcPX1$r~<5p-B%5wX{cJqmCS*!o4 z)#Uu#_g5n^{hpdAf$fc`EN0b<@cpb+|MyJ*s#1`F)m8PddIlA8{KAO5EVHE+vBQh6 z-g=)HT3A6Czlc-UsYsHdgle8kkOF>B`?;gkw&O(@P8M9a>a5V9_3h*gX;2p4OWFet ztG&o$zlHP;GlWl43CY+ZQX~8xMH7}RO*9rx&}zS}pCLLC$75!V#~Is%Q$I2*^HTX& zM~rwsaM7TB`ols^5GOPvEpvq`stwkXQZ(7L#W3I(1NM!EYcD zxp_yW_`tEAn>Y}&(057oJbv+`%&5Ch(OHbO@ItMEvFY3-mzYo7evc8$ z15juBXOGejm_nvjslwwXdLqbTqg`?ehy`$M(zxzRnpkk;5Z}X2@1CH6EJ8!Xq#P4LDgcd9We3kUv7xybYyTEbtR~vftSAV7CJ6-wSEl z5H+Rj!!0xd8_s?h?7XAy3PNz()|oZ(l=|>m7cgSZV<0q0HSNN7nWq$L>dw7JEM)Tm zCifOi(7*c0uo(SLj==5%d@wIq;0=7BO>ozT5HpP!dp*PJ&qH*MSI_(Xdw0)=;7d|a zJ8byEn8{dScH<&il1Y6PCqgKGKK)O1R)vDy(v#5w*cag69fm@#Q&rM;d2#5w@#Ww5 zx&LS7>f2fT_ufqfjc*7B@@EnCrn8lAQo5gbtC$*Od5B7cFalEinFJ-mR*_L%g{4cn zk@(MB-sg+%9zj!r(5~B^X!&VL6{Z=%_{r}&)UjuB{OUDtmnTR~02qloy;U9@BZ;-{ z(l7czb|eT@v$j+fiP0Xv(1tQm19}jROIDZ-hMEER#<>Ifx&PihjZxAMO_KHheR!%4r^v}f{ME|Qe;cn<1G$2EvKkBh}O$1 zhJ-P`la-BRZPRP&b-nRqYk?I8&mj6V*W4*D-k88NvS;dPN?<)crnI|XyD-KvA~gQq z2k6365?)L8ozw`%ws21vEB(+UbW^$?Uvy?kUo=q^Z`1Sh{^Vu&SXWnRh!xZ6OxjzP zkUrshx$9W1F=3h&IltfvsA#(^p#+g=3fggQ)_8Md~tOmr3=_H0jd;}kXLnA$9utsf`-Vx*y zqhjPG?IxMTv3~`AR#J$03q0G{;b5io6&cew(oLrnHzE`f7UBodhk?PriCx+OslaIF z!#%Jbftzw6npo5xY`;bwbe4eQeUsJ5d8F;+io**~qSi~)=PPWD1 z)dA2~Q#+VT*c+6&zZVIXB0Frdz+lf{F`?P1rI`c@@00Kxc=s4?+SLOYR`kiZ;EYOi z=%`p}g45p=JCNW&`ZY-t_M{ljpceN(MA2JZd-A=i_zjAuGI*f387&?4QJyu=L|=x} zyTl7%Mf#S-!F?tgQN>@m2^t+zMhNxguFQGZ*7gmc4BS{TGJc(86?QF{Y72Fh>^o%U zE<_?R!?)+^(R=uQj3~CI2!!ih!u6e#A^wPNQi_QPSg4i;)vxGRWuQt^a|5C=s_5*x zF+>z9^4=1{sE1xO!=#O;!-O2{Iip!~J=sH5Mqm4)2MBuYuAiTHIsJrQ4O&(3jUMKQ zHG5Q{zKf$Q>;#FP8ZI2q3rxd{OCrwXk-P>}yB?W}>6lIX-PoP)88pF1%*l79QT~DP z65W)?f9-T|8F+L9EMysXO!%Ht#OZvo zhq2Gc=Oa)Lc9t<+#5#tdok>hy`&fcJnMus=bYYQSP`h0$w%x#rfOGpQDE?xA5 z*(z{WHwn6f^6O{ZCqP`5PHK!dJqKTWgc}?LIwG`>nPdrQgTnio#XA=NPDJJqVvRon zwX0^AAuU5LfRk8@ZZ(qzI+c?})Z4Gu7{=vt8xO8z{wwS0PkYj2A4xZcQ~}FJ@?mTb z=HmL1tc^OdrFiQDJ<1s39|IZN@^=|UG2hCVA`*w*mqidtm(CgT5PSZH=xcEuUG2T= z!XE0vo4`R6$_t_Adx6zh+=Y(9vz#pghVkps&NY>v1Tk z39t(zX=BqILir^UmV6olDr`EaLDvDJzJB0fy$cRxeF%`m=>_nX!dpGPe1fJ{tga;A zo_pT1*`b}OSuH)aAQyW!n0L()R+J~Aor`#-qWad!AlCUJuE44FI~TV%vTO8l^?=nY z?ljM1G~4OAr%n7bbj*cF8xKEK24_yyEL_vO21|otDu#U^@Pn~M!9>u+45HutqTLbZ zM`?t#s2Zz033E~@YLR=IHl~!2!U1jf>@K$cNCNxnX))5npms4U^Vt&K--Exdms?x@ zw;3OOzhwW`oc}r{{BKD6|CWZab_RuY29xtoO1>XZa`+omN;k17oixk|f9raulznMY)*^1*7{U7N4fs{qn60{n`*`Xh`^=QDo z1lqbV5~3@Xx|_hAX@OujvU{KiSky=N;ZHmh`)=((s(L?XkWQcm0_=)3i7!o7?blZMR3C)2E~G_@&c?j6SPtOY{0k64z&=p?I#M#pC<8mSBkA?C9Qr-0s# zAo7!psilU36>{Z8Qr=lLND1HpeQ>_u0t4VToAB>2es%oIShF|AqW&7|{`X7u{r(^2 zoBlCYMI(DFGiyD||GltI(Y26$bm#%s)s3}IvuL&mf@nZ{M^{7?D`+9F3hMK~`sz1} z*nfd=BGUa~T{dnud%1OQ0{03ui5ThPCou#5L(57u|?dII@>%U}QdX#X3Zf%3Zix-zns zi0=3b!7ofvC^6H1;-*|VetfGMi5z&$#-U%898%YPrr5+y2eC$=pG9~xU~6Xa-!Q`E zsfT=yO_4Yhe4R5cTgRw|6di=IOxacs+1lcUhJF07+ReWvQSwe&rx`rti|XG%>G6{BNd}bNAo7nI*N7b zdHS=qZ}CbeMiFP2$t9^^z1;RpgY!1eoK-2ULL9IIn0Z?kbmRGt6h@<jucJj$Z{ zbyCb1tqUO~)-;q>tKn2^8bSK#KMFy!arsJF*Jd!h9{HDCmKxMFwq%*P&wJ{Hd8{Wb ztNE&Ehe?q|yQ}bhqR0 zf*KQ3=}Y%p(#7&)%2~fcCd52s|Z~AdhQ+7zOKj*NkRddD*zemj;orCMhFd z70SrYk`N=hJg@0v+|@Pr}WJfVM`Lg z=I_DZ(UKoyx7MFJj@e{{AO8f!7bk3IiZj`nr`wXy>JgB;5m&j{)6H6L^RvOf^pB>$ z0A(HT^$~bS=|A>-gQPDz%MRg9O?88aori60NIrqs5D6PHM0}C;HuicI8?zgllvxt0 zMYc*NOUxQJ(y5|*a1cB<7A=Q2^}=gD9f%d`J_s$mpdG$eR)n7#u748j;8BqO6 zFP!7FY)1oceZmFea?OXiM`Y`_&l9~JE;13yhLXVE}~$f#O#Kt5!l>-j||)-*EJ;u&Kr2KWoAz~At) zGkEB%{cYoHK>ZalIufyPH~B<1%9d1q3LP394#%1IhsS6=oWk_l`p^(!x$nXpMqGMv zlRTA_0ZiJQc4<&5SUR|gH`3&_`?Ws{q;@qlUWCvc^5aO!8<+xBuPGBfjNK=w;0lfP z(<*VF9c?M8tZ*dPRxO22Jlg+MF$v{dMQgG0nOayRmq*Jp#sfc4%LXieO(O<9ooNB) z2HtQWX#50Z<2+%($X_<}YZxVcNHz4xqUQQn%nUalg8$Vwn6Zce0D$=aIx7zUjH!*P z5Uz@gD4*9H6No0nTPhA%2x zl%t+2uZg3X=QiRagqcz{H90rG9Vs_fE?tT9y=FgcNs^2bK{p(}-5qtkO>sZHf302} zj!XGB-K-okgC3DG`|T4bYrxUK|$u;uJpXuI0Z_=_Ao#c<&!(nh=8 zIJvz91r2wS4e7aY?fUnzGJ8sBXFcq!6Wrp!$hgfC#clt|Mcls61>Hu&;hnh=fZ@H< zCx9Ir!y7-C*M0})O}z$pMIBgt6cvq<#n{Bne)bk<%pQbHJ^hr2{SP&D|tOKl6} zjLGDA(BB`gn10L$jnH6s_3E$YF{7NVbPz09(ahJx)mGL#3^YL35|JWNOmrK65)VqS z17}=vW1&z4d2w`;VxJO;O+XYOmYT!34Dy#|0sCrs*EJmqX3cBsB*&WTB~;Qk63EEyk$^$4U+&iRD`BdY+D6 zt0pfe?HaldCq`5jDM;Q>F)q>n_IO^d+|7n0#_F$~B909?Rfj;;SL0eEG44uFORGm< z9wbC?=fzHbPRUw!PfAh@!>H1ISHX%pYV#fBH?Dj=da+yY0 zhiq{Yq@a=M1MtjIANhxdxo!1XfZSinn;^F$YFL4iwdt{8d=5$i96Jk8gtTixy*HFZOagnqsh+ysq(m_TQ zUF~`e6i8F#vks_>M$*OugWTzG@5^b!+;;J zV0K^N%gEtkn9Y0kuL*;4E>SX7^r%3EaJ7CwM5L;PB05IXI|x*g*12`eYcWT38;Eg) zWs9k)xOXF0IB5eMiCX1;ERLw1ZOo`MwjfrghVcWtO!mB$NvA_uY2#k-VHuqETcI#e z$3uB*H{=s>1zhRHvocvXx4{uJd*zk$v0_Ip6!PM#p_1B&uH5v~GSvv#dn13uz*53` zTRs8=nTC`|ePM4eew9M=jH)5Z>Z&ot)^G0jgt>C?!AjAzl_Yt2!$;^5LS&ik$|RjfimzjMoq;MF-gVK zAAe56BB9~N7OCO)8!t^sr1u}whYBcK@W6gicJ2su2PRd?*;~4es`663W5!(5wg{t= zR0$_OEyEfz_@X7*Yv;lV9DWQS{A zZc?xnxL)?7v#$0GhHCC)g8^htlQPYi^kYt-?+xq50btLxjg*A>`Pj(KXZ)zN9 zmP2sHCH3+X6Y%Wk6_Mz9L9BLTBACYW>PhF!gwJAxYnf|Sz-Fd+!U{>CY4#~LsnEk6 za==2)HcwO)J|!+!$|Yb2T{GaUp_xi-!79Azo(S_3(zjMxB!&h~4ZaFlbO?z2(i~-( z-nqFubF$JlSy2<-q!L)U@9I{_y2f$@W=2wZcCF0Lw-_F3F-ueFtR(v$jJ#ioc`=c% z0Hhs(*2X=(@G@u$!8va`EB&aT)CcuFA2!TMx25WQCPRWp*K!&b6f3-@sNR1Tv4fhc zP^UC)N|7HuO0WIJwbcBeo3xTkouM*3vVsXHd5I?xK6%B1E478jYyCKobg|TG;@lPH zvczk`%$3)lR2V8VRQppAT0D+TTOLR~JnS4&O^?*53scS52RD$`Q7X>;*H?r6kbAvM zAe?(OyN!7`E#GBU=48$;1FbK8B=|c!SdgU80=t%6lgcLyE7wBN4XfOD8@m~S#x*`k z?R+4y>-IpB*Bn1igXZXt?zAGXeY{b4egAd_s0m?|gF9mMP7%zs2DJI)q=7%k0c?)g z2HeDXAf_E5^y`UfMKQfKEz);0oTtWZ-fJ z>}e%D8C z#F+G`eg5N5;dlJ7@xT)eb`D6R}_Vynv93o9)o^nQ{g-5zxDcETK% zbBBRrKx2obPcp7LfL$FKA%OONricXnp>n3aE3P-@)10v;k>DZWsCfbboj(k0`yDqX zsjMZgvaHLw6-f304R=S+V3z@PkHG+rWn`d=$C(h8hBsHF&Oo>BfE}fOLvOJFPZDfs zn}OnNOt~dGnP*EqnUQw`)W9vV8PB|(*1_t6X6Pu@B|+G|v{1EQZLq2Z7&)CTaz9yc z&VO^C!3Ewt^QBG)+MJ3uR_SRmK28g-4x(x`SwQvNr|N*DZ{n6}>Fnop&uC?Qa+v{N zWIW%b7u22Aw0*guX$(WGHVk@>>$Be2zLmD>_@Q`gMQxWRBwqGATgPH+@|Fw8mZoT* zTj<~qLxH`&M8|{?l9oZy3DD4{T2GVY zR|ymf3>Me+*3cmvi+yLvdybNu%vL0Jd(w{$FbIwy(gWl%rIdpA0)fPpFDr1RSJfpW z#*5JygT+P~`YN0O6%VrVszie(Qr(88RFZ_9%?K6HLP*=soHnD$jUM#znCH99W!Cl> z$wHyfFRCx>lKQbJMlz0jO=Rl&hX;LUWw?epW7MMe>pp`qkO~B3xK*tMBgn#b z<(Ubddfi1f9bLxt#d~)Ke9rJha7uOV3&IHQrFgG}ecg$EFUr2(Oa8(u>M(S-xVmqg zMhLYL7fCye9=}-R#tEW$Mu=?SUj`()*Wz+b#e<5dm?h~kB;uLu>ovd7)f=Nmg?Dw{ zmR1HlLk4aU%-wH(5gR7Eo<>yG=c<>WvY{%!JLlC=t61_~12W|DmPN;(Xk#VyZs%oZ z3D9-*!+D320tOH2q>1F*SC6t~|YGm~kv@TZ20(x09ep(qi!ed$I z@twiLE3Src^9eM=$Ic5Zh{*2tVi(l%^M9OH#HX%redd$20+zW{H=6~N<%sbv8phVH zKn0&=LQ!!b9JNzyD1LEIq-o2@+Msz{(Dm;rE2(7uI2I)iDC+Y_DN{muxu$xe5ij** zd?G2gJ(c(t)asq0TYXWEdPE`byGjf~mh8VGg=JCqk&BP&@kA;% zZ#f4ugiw9HYBDW5^1=}l@|W&uTpml+nph2m=4C_6z^8oFuL4lDOCQKkm%V|TdhkYQ zgPJP)V#FZd-~^r0U%MJ!wVax>f71Q(pn8ErNoal2*HsT}f(?H=1yDI2cz-e)fk4Px zxmM~(B?To=GuRQRn_dvA5n9CBwEqBdw{3p?I8SbKKWVh%$ShOq4~4G#*~L-)w}jE zkNL!m|D6O|xZ~gTE-ZSSL_m%*?Vp~R`f2oXwEp_FKd$_1x~9tq!b-SgPb#Dx|B7y5 zL*{7GGHAH8)<3|!*n)mj@+@KD0(_fha{JGs(g21C12(CYxqw0*c|ea;@W2(|^i02dJ&H94>#C$a+Lv6~X4 z6kTduic_>UOw(RASq)eOxdc{cwd}D@IqA^YnWzF2t-N<@aRCSglU7p-j7UDPJAgO- ziTNzbnCG}Xh|I^QBQh2DbEsZp*szf$Fdz?s%nN9372ycM9(QO;*{CM?W$LucS=AiB zNo(&1){jErn|fg%Lyh8hh)twf$%+}(L2|2I2-n!|`)#&=pV?+7IS{)4m~50{{#bVZ zPciVH2 z{rGkL?tRVmcJl7L38@oHIbVzMsaw(GV+P{L>|C}L6V%QKbv|R$97V8^zpDlPY}%q7 z?E3}hm6OGzFd6NDwEr8LXGt~))R8kFn29rw(9i4ft|VyKVWLl3;l3s4&%#bT{)fWp z7iB;(pNpEOn^1o}`%!K;+VrmLVn@#IpdOY_c6o^wL_SQnOn*1ju3_Oj#o@CRbhna! z_pDCPjXLoc2X^-`uEM=AboB`<+9!tAVy!^nXIk8gJec>=4J!8dOuMwJ{nV@_dbvA)0SLkGgC*tej>zMw@WkH^{(gQ#Y{kL zW7rAQo1|B~4+$^;SVW7Zx|IFcgh53Fo`aspVeF)2r7*;pQkIbw{keS6rt0<)yJ)+8 zX-)x~rLo4mlX7~g76lP6FYmbRB|aGvkh?^4I7vmqqU9=eo0ZT{@IM#l%BFTvbjh zLGb(LlqfI#BpyLmsX-gJ*G3o>wo-Ju#QK@JbXu)wM(35pANK^!l=VR|^YFul0%do5 zbFo(a$p8uW^CRl<+@=bBxA-TL@m-`acc&qOlJ(6MKqWC+mS!b)xBNm4P)l=2OVGHd z0yZl%Q|(oZW_LGDqgncP#VC0*X1}x#zPlr-Mm=TM$4W4gUMc&wb`Hzt>jVX#d!*De zId6QoO@lHoL;8FpvIvbhKlJ_C`bJ|QUPnZSB+10s!v+@@FNk0p@qDNB%g5p{jb}HwJE}cc9)LTLg<<@pqFl#9eaOu?Z$~TR_%Z7e0 zqoa_|6aw(4ri(2?Q2$@dG=qw`1*@omj}+#P|wPqZan;iFNFC$Z!fy!1wod zV>it&4u7~Z_|)s>nK!i*xspF{^Rpn3IW);=11cnmEanY;f)7!53S1!^)2)P236)&3 zDU+Lqt9=i?{O;)ZY?tjMSSlf8L+Whun%mvY&Dk%d)WW_#)WPAeIH^PRN?~&%{SI60 zPiSq(m(W*2 z5`3k5h|=!!p87O(nSbJC@Sbr#F*9v;}_Ny-)Rm>;?vZve*Y!r&O9&@X+?re zI_RdWu*qo1cUjug9f=8i-^VW>wVkLmqc(8ne@a>nx*(+M zy%+`GjPWE362DOdOrJ3y;arVg^z`eTm9j4SGp+fgay-~uSGAgn-4pX_=cCiDI4TkJ z3(Y!)q2WS+va=VH*}(UrR5TDjQO;1LQ2{*Z@bFw9udLqzL2@;I;>4)QrFlVk@u9Z0 zT9yJil9=HMKnM%7UWab|!iWneEg6w!6A?fGtPB||rQ3HF&R7ym#IkVJ1!i={cz*hVO5>J`6!L*{JJ{d#$_Q|1ZV2AuZOsNaUdy0p|&cAENqtRh@Pwr zkxtyDOc4yy|r)3iqJmAHd4jIc9X9Y(+R6~&iSy`7o`&iDj!F(@QomQ?wUy(P<= z-)Lx#z0py!m4jKt(qGl-7~jYsD^u5rkl2jo{8O;srE)%U=!1&Ubtkpovigk9wy>ua zdO%KY)GBbvMK&(E?sa>~<0>^&#UE06m9HD+dC#+jJ zKGEP}N@%krN!c=ck>p~cPs+(eHbu4P=Z;!vB6wx*a>#xWj;sQm11DQC$POm8r~d2D z{bvH*HLkD>HufrPnScKCf$Q8n(%_l}%Z()<#0zMOB9n+*#g%YQSrIOCsr z$Wg_-w}<+4C-T?4A_Zsr@NaAua*!DV2y#Q5sIox?Tqi`V_(#hC|1V^0EHfrWx?@@42~I6w-FE)65AQW zdJw~A9_3x3gkB*K-h(pTb=?8VATHjsP>q%j3$)zZ!&;57KZMf2Gv4QGg+d)oY+3O? z{WXTRt>IP!z5+9pDg+yb7VbNbUOjYzv4iK&_x4Gk@sO9I#Zt!42=&H+l3oi;9C4#+ zF^EnX5PX9)WgxBWgG2V~N$N4IR-vj#l{J0UJYoJ;)FaGm-2j?9a+=mVc|7ZdvI(AY zSu~_|bx6f(2qvSygwbeUGhXRAsxJg5mO7D1X&d10r5#@AUJGkm{#+Wb_+j|<7x{`@ zmAx5@!HZ#Sk^d%l4lE{p8};(Bm!FGb{s|fdN1DfQwLxCY z!hV&eCT0Yz0bS3r9lP&C!ga#Hh*v-fZ0=bF#70pBVV9z`&t$@8_j#GbnZFt(e9O1c zc^7sh?+_Eii6z5|0^f@R8;=4@&{(bT&U+{u7Jisp)bi`WHxwL=H ztM|?a6nu6 z=O`g}L!($)it&y%E3L%nnOzq?)p{oXvf{qJ{Sm(&qJJuG-6ig&M z*WT}7JgEzNdD-gusYi-t)xE|uM#Md&m&XqbNB-L@z|{q7(Zw&}k%;Wv6k(Bp^7FXG zW;z~6Ylp96tuA1CyN9OaT%C5+o6xU}TxB=w`rrqj{Ecq8mu zE@~J|ts^!OF6S92{0pSW5``-3oa(}Lm22_&hD+>y$tssg`wPWOF`OGU@LC^bl&{~( z6}J9$#%4Xv8O|kG?TgPNyL-KJ3mYg;O$|q;)8vNd-#JVw-wc83j}lP!M|<)Uy8hp& zZ2k+66|^w4G_-Q~PbyRRzm?OPZR>3^q=DovziCz=9guJRsE9-kN(n^4ZxL{Voa8{7 z+b8MQUk<)+P+!VIlLQdGeR#%PjMNF6(IR2pk230yJ&x0@jk>;H?x1@Jl;lM8sYBs6 z7D%jfb#hJe68He@-;O;XAW6?>YHh~*EHA0kTJ-fod+$DqRt_wCV@faYshu^h8Z+7; z3YN=gi3*mHef4x`NK3?|%M^n`KTg;BVEk*POrTEF9tMn7wvc<7w;c&Bx_dXVaYV3T zA()-{$+YRN* zv`NCRv_ylFBw2C}L_|WAE!@R*DKl5;1nGWh!vyI*JZBWQzZZuen-@g^9P~|RZ zdi_1-@sbE66(uN;E)an;D;;+l#@<*4x^@UyHc(+bXU-CXX4a%LI?XINy&cdosT^Tw z&}bMEt)L_sk& zKn1^-TkuTfL~y3vztkDByG7i))-jBDMjL}#>>{}RfHSHEEe|$;EuCPaCw?oTEz(by zfbGX6SZg)O07)a@n-@Nzggq&c9jGYsFGorZSv4oAl6B$IbKL*)??BZTC++P6|MiO- z@&6`}`Y%A0Fm(CfKI@6f-|q5<$ln_@qn#|RpM0c&K}i6WjFRH~;*M5=%`r$3MO2K1 zXtqwt4-m18r*rC{Q5~C@xde>$6eP@_v!v*HY@Ph)m zTj{0)@;B#HkazzIB=rXh4LR%3zAY*{U7?OzuQXfE*!g zsWl@)wP2=mAa7PDSJ-FQTO@x&z)15S>B1eLFiLIZ^RU1G7QQrRt&Vinh}c&!w>>qT zy;i}HG#M{Gh89z303UVZ5}l(4MKV7q{%MRe|y5xR#wv{y|0X2@jOfk@9+WzbbQs_{wt!urND zG_f9oDw;$7Iy8Y=05A6{6qHQ(9T%;i^J=f1~Nrq^nWD zVKr?``ipHtK4Z}fl|+VJ#0e6oQxEou@kK!ilhCJ0Bw!d4RdcD=SQpqqYWatMIi3Cp zQ2;)~hsIIzat7lF74Vfv%J+>tRELjmfw47L`XIEH==@dJlw(spGufT=g7KKeu5sRX zLi4XToew^fwO*e4qdRzw> z;|1QwaZ|fs-q?To!U|_LN8?ue&h^oT0+BHO+g2pe!fF!Ju%)9phe{1|XLAYh-?PMQ zSW<$s3e8F+N+IJKaikP_!pXWBY_3NK>+#1?)6xxjoiQ<+}IdSA4kT&&(Nxv!z6uY|(K(UMcy++WrG&Ym|91Fyz^rl)bZcsLxt9!{m~ zlnSEzgTkPhFxxC!B61rta`V%2>%wx63{R>IRh9;7@=|x}P=dzG6P#o#)Ou|KCm0qf z(6vtuJQO46$itY(_qP_s{7I{v=(O6GWOKtDAEW36HROjG9?#LMH1+!(p_Z9wHM)~@ z`SZ_^28A+jDLg3KdyC<>9Dt`8Ep<*Pj8`s>sa`42t-(nr^H$c5NIdi@rW+a=pe*Wk zg@V%A(V9TfoGgsKCUJ%`_tuJhh}ZOE4lDe4&R!6;=5N`x@}+8s=Qz+J zg!&wkJd@9Kb?tYT@(^E*J976WI|_F!v5#+}eAdJ}#T-6>uj^jBsU7dcwa5TEh*R&w zVJT-@?UrW?IqnR#WV2su2Q+2S#pWcO64E}1BWWC%&sHI{w+jNTLVyn0MM5sZ8G}zM z~7?jUN71FI3*it zd&O?>@AeU4tA$%M-GC%1yn-9iZ?y?vYfp%e4zj;#+A?uPa+Mr%#MY>Fp_o?mGPR%p zbdA8;dW4?nz;`B|$iQQhw6%w92|YX!ys_sI3O+mvY|97;hhCB8x#!wSH-4^|Mr&P3 zKcS6J&wpA+KcL}-ZthG+eti6)vUNWsxlo-cL6lVH*|kb*2j-8tLC#wXL3jZjL<-Pn zE{L=%henO6lB`567>tQ89}2!Qlo-OgD<@YHl^djigWb-a; z#m^pMjB+747h79K73ND2(bu2vv{0t*>@34Yi%DN}!-&J-S7}FVq$?Nq>f_?Chkb9imX1*TZmeAIkX7;881cDzfGDd8 z1xh&|EyH&LsX-zmWO9tqyk~cE!mN)_O*4N>PPjsq;OUCk zwTA2ZE{6Il!iA;PFRZ|(Jw1$Iena$;M05K;p*u+2s}>ztcp+!b+pK}4cz`%M40YO{ z5GiAAp=+FG4l1%?f0Gi~!BJfB$=5`5Etcf-o%3@M8*yn3fMgVzc?16b$Q(P!PT2dF zIr|EyxTUK?$N&RlCkbR~5x&_Eu|d8u?W!N(w748ELay!HO~evk|KF>&T+0f+lTT)6(H#N}W8;JCj3;k^`j}K26 zZF^;aP{Ztid&;MiQCI3}YU_RYHP0`L99d!XX)_nCe#oG+rn#|8+Jt58O9q9lbpBBr z7CAMqv3E_=?l3E{w84=9f=yJV*LM|FTdqVp3&9~04U=Rwue+pm4UWa+4OOyN8$69@ z+>6+V1DQ2V^T=0wkVAunMSa%MLk7I*#*1J<+gLQA@V^A7lc8U zNZdCNou&=&-PMJAWv+}zi5xX}Y)3xcXtH{1=-Kl0ZtNv!in&bMS2uEh)ng}`?AnQE z=$#P(oPJB>>)Td2gFDeglK=7g?K&eeQ1-dsJYb)_!g5&I$ z`2-7zG?4GE0+mR&@kasN1bjSUCLftICk3{8?1l~})&on-lh1@Hr}!VCF7qb>?ZZD% zS@_x2a{o`E@*kH%yjHHxCWdx~|IT;iG^OL|ki6K3nw%wqN)X|Jh)HN8BqLA*dJ*{W zRO={Dz;>G~49id7(&n7^y5|H4cl~gCqUkf73|Ls}b|k0mx!*X8i;v%~50QOfRYvuH zEaD63vWLYf4Qf*cDS}2w)RrXFvlwbH_>IKT56hqm7vE54Q8ggvcO{JzPZi9}g`rM2 zTd2^(91RT!Pcuc_Nu?MCjm~YwPY87rpRN5(mlchn(jQlxT4<%zx4uU#^)k*xuPPEg zKFV!0y*&ON8=Dyodwee?DqWeb#t$i?*>w#Eod8F2NXlwG1xf|ve>|OW@qzYbjq>v) zHvX2}OE_w;U8*}&um}lb3u@MvojFM>(+?1*JZ<_Gb~dkQSB#rr*&k>+=(@|-#A2#@ z)++G9N`e@{OCPlRU40v*yPuogb7NIe-hXHOy@J!tDV}foL1-#(B$a4-ZF1ReGE*d5 z!oFo=PUw}ml~r^IYJ&O6304Sp3^$wl=Nj=9(V%$j+`DHCvOD$-J*?;?1E$oJfK=`l z3gUnYcI-A}53EE49VG_!<{_F+d}-b~UNSavX}mk8t!E$_-<3qe4MRlSKM&tD;7>xX zY|t4(?(y%*&3~xklb8}Elz!lG5AuHtwD~XW@;@N*@6b@#w3in|`nKeDn_m|XHw71h zgUcndJRKAhT$39F!;qYxOMtyKO}{7zZ)V9{mn{Au^PFSZ#>$k1&$PW+{1!2m@pe}S zXh;F?A78CMzIUF=s`vi7KfnG}WV1d9SM){~;*71~5IfKi{%m9V>w5q0ml3V`Xof!p z%#mixOV65@$)Ym0$3YI!3~nQ!A`GUP`ricLw$^H6QYw zOdi_qBnuL{JMkyeyp2O0Qgy0;%`^jzl<@Rx6%XC8-hZK;Eha&&&B=Hd&Jg#;MKCWy zw65-1r8Ld@YMTN3mSJu}pp&bzSoC}Yg?>_^i6k6O3|gKfPm0t9hGdUusCV9--gKOpd%ML)sBW z9qj0XE;|*60Lsr#%A`3BKt(E_x?S6BsFh#%VP;aQxYfD8Vs-fz(HAmdGZG-%6}EGI`8sc7E=64B zj3S58Y(W}JS}Cm#qpfIq;p=*!yXxWgYio24)8#b^%Zy8Z)3&W>O9ZQv=f&rE%Q0iT zhi%_eZw;z{zz4si(?@3F*n!`vLd8ejIQc&lP5ai~g2L$!d-LrDubhCL>QrFxrBzX9 z+IM8GF%8Rhzzk^MSktB)S^!{vp+(&rxX|_0N3(xo#%Xi@HPih-Ex^r_&T;#~$MVId zj2i{x1rW31)2V$2j(cY6}R1u2rtOcG#{Ly)dN!QHCZb{3f>qT45?Kx;v zT_u#?GEdbEKoL#NvHRL5xM7R>#t{$?$9P3l_|t*zN7G&E^!2`8XpekI`j58sb7xWy zY;gSZQlkWaJbUP;n6Li4R-XT9G5^=~^8dM-%WI0O{~R%6&J(c=MVmQOaEjY zZs~J{qq-pCg*K~B=;KEYGA5w`pnAm?*?Qums|4aV7Dw0_2K5;|)}Me^1)AQs)sHoZ zCsrZ`9q6v)?Uk0%*P%F07g&ZcNXDj`tsuP#s2omD_ZFO&hzH3rHCR$d%qKl_+hC#> zx5aT#5O=r1RrO0pk1%^MfF8Y>3#+}#j#n{OJ(Q28oeYt8Hx9vJZu+RL-8i~mG| zKPYkWqpZ2ZO3$IxV+=GUxF3OZ`B4mxxW9Scf#3By-J*nYM0jGx6z_?@rZmjZV8no= z42q9U4=w`pRqH*x{bN*Uw0*ze`U4MD&|kk;{+}T7k7~XxuP%u6#mv)!-wF(rmi9HU zrU#H_F}~R9gKd%r5`9ju}R! zLlQ+}JblIXo_U?YW$gWaze@8Txr~wA8mB@uRca{`gi+6PEkVx=FTdo`CG>|vR3YtA zxF_%;qv>0sq9+4g_wPdkF;T1_9L{%Q?6l^+Auz3%b1l3`1~ITly& zFIP*`ASD4K-1A0GbqX#k7aHj+1|qkf-4=ACDHJwS@-JUJ!yvj%Zo;+5LG`r}dR_)j z9Vz~?cw4h16%H0-i(W3&vcIB|Rf0;z%rYa@mhL7}j*A5Qgv0htSWD27H(N8lx8$Q7 zwc%GRkwjIamArJD^4M`LE8Fb(qagP#t97YEPHxfC^&s|efGmrQW_D}^05Pxu3E*En zpgBXHzzzl-fYP!8Z%fYzq&nWEoD+5xM5gfcICszVJm!7rb1flUdj#fMQDOKvo2L;S zL%C6RV_Kg1LT%W5CB6xTp8Mo|w#Am|z-AJp=s3@$Y6#0T-oo2V=L3vsoujR@lWnuy zFJqN{5c$afnY~V`7mL11y30IYR~x{=-1S#=$Kw4M3GJ$a%R=F%FwhXw*>-x!vts21 zLK{-!YuX==c4;=#^EqpIJEPvd?}EcXtWWNm7) z7iPtLJ)wP?B%KC}3x6qXgS2#*ouH`?b}*XRpXQVBtyvkjE_WiDSMKm~$ZY49?9`5^ zxTM8_`}JCBh*<7i-9Y1>uI;M`0$nvmKx4@al)Obax5lseW%TJbnM8R$d_ivklvczw zqn%@8xYbBVD4Q=L;|sp_ny{GCP}<;3Fb>XCi>G%}W*pm^090U2G=m^zR^k_+H->Qw zf>y@yn&A40Wy zVGX3Z&H?B^7T)CH3d|H%gNMIw(jX2)Q5M>j*ZXpO?KK)Ze4!l<*%;*^I8^)x>#1~H zn|K+1yjh(bNhjM}<^bi?9@ae0kqyjjoQ|HNUI#XDcVqSk3iS>Fq7;74HHQTAw7mOw zK~FqCdR-><~7&dKi6MglJdBjWan=8Ir~zu`kx;F*{-o{AX0-#=cy{&kfvJ0yr}s8QC_ zZwRaGfn>Wl%v9mpa+NzJWA>w*56+!g+0ZAoDz4QjaVkWisq6KnZU6WyTd*WaSoPEr zJCzL--b51&m1$)b7h_&7!RiK=CZWy-m&?Q#fD6-l8C>lw(iKM@)e_qLF#Fy`yH|<; zm}?oHODUvbxPfrEKSXB0u>mzmty(#GrOv&lYg7o)EMF*KU|1F!rWzDkN{V*mmLzBZ~PtKKUV#UDkjD_cshnILcYWt6>WR;1LPGT~bGIE3C^T21oBiF&13RgQ!0q z@!in~#1QR7zF3;>@9+Q{BpOkU3%h#;2wb{%=)q6K434gQ;6nW{)UQ4DoQuH>YsUH@qzXX;~H|MJ0&GD2kvI-kAE2EINF~9PX8=7AAW33*#BRl^N;_6|Fnk+qNZ$s zJd7&Y0BSgF3Zo)LMQ$Z6!UG3NXwJ<{@HG?WAqgP~GS>bC{DMKGF;4c| zm}6{%WiXz~y3f2$XJgRz_Iv}-fvX;aht7lGLM{=g4(-B&dH|*S#S!rC0+*K(yamSq z&q8;=7A(n0f18qPA<-tsqYEaGHx4yqKthbx2Ywp%da;xyBknPYFKtN>e=tR_Jg0t~ z8KjlW0mUC0A-2A;7*%Iar*5c8)f`Zn2={cwynOzY4ve8(5HDtz_|qRJ**uc+w~pBU z8E4{+6o&Ajv}q(v8o`JpVRngHSEa&sr{8BKC^Z}+CQULhq4~9I%#bib9rR|8SFc7| z#W3bS1GOnwi+7k#FE~~{jZb_KRa|ZfWj>mG(`}i?h>jRw9?%`%C9YJYP_q68l6%# zxhSP?5|WYO-@n<=S(4~5pTBiT5pN|$I;K|+Wf?dqe;+uD3G4V}W(cmYRz{pq8I;m_zFH%3|+MR`sH^=OilDv}>cz!_rAm^{ZhfB)Op zGl09_#XV%s|ATY+9o|rw7X9cwT4t&y8ik%5Eeals?kz1+KOjmcQRi^;`q~pTz~BYS zO3pF{x#&$&fki6uPstThC8rQw8O9$imKh0j?302Bbubr+J4&u|X0;GYM2m*J$dsnz z#taws5&K|HU7$W5S^d0ufn``b$9GKIWPs~erGtN@x$+Yq`fmLAPW(dtZxXB(t@Ip? zjDCh82K*+vcJe>Q8@iVNDFBF6c6Cr##QwUPFklY)%co)t;13Uui0}8?02~Yq131ru zS;kU}o@O+DG~JfIzo^o@u~O02Qgf^*v1v$&Qgo(fp-HXLG5N#}dliq{ar#grZL_7Wx)ZqA>o)fKypO+JB$mJqAUfAGXmgeSmxXw)?Xc*9iz~@hY zN|<%Ptt2P%(7X$Yk8yv=U?#5zMFb!#X` zJX>+Xub3;OjoUGyIg-biuguIQjxIA6&6%wlIU1&oUtGZLFli|azflNOktTZj#dUX5Bv2cX;{ zi4@(Js^=UR9us*^)jv|F+3Uft{35CLsH!7jf|%xtY#3pxaSw*r;b*v7@FBK zr=8L;9e2&ojuR+6ee~2%68n%J4=Gm6A06qV*%;c#MW`ssiA-9DAyBMu!gy03j1fmnhHW$blHOJ=Vv(>BcJqZ`BEZ7VUejZ)x*RpA2PxB>Bi{CW?Mb!Rms*>A7Zklv`-Pnt|q8EpY9cm3Ug-aCDx1k@a!*i7gG%A?$J z;&-BK*p6P1NkK>N%E+p8T&W;e!@emQsl%8hK5S_=qS`*uBIL&Dr@fssn9koAcve0;oGf-Se2I+cU zF}i)~vSGe`U#W_QnhL4c%_3w6(4z!SEvxx(Mhm`Y70iol@dLSvAPRDn!r?DacTnL> z$~j%QyX{l*sM!ER!EH;%4O!OJocJ(c8mX8#hF89fB1yt+{yjy^OJ!fi^hD?JsmWza z;0LckvS;T*Vdx|3Q|HZ5!rUhn*Xo0nuB4}eEBAC5$@TMQ!rL@wJ5U zQ!DwV&UhfBD5cQbcf!67^`!+Jb-A^rHA%Db{g)H-{P!QxI36B&B-i0= z`b#TYcdOJKp2^>tl19H6UOVd$Ae0G!vS;vkCOrB=-L%f9&Np7ooV$iH)i+WdMpQ-B zZK`&|9L8_mxT*YtDezKCm=&Pybt$$+uJ`NYmYCVd)Z= zzrjRVZV4q}ifZMcsRCS`1VN19fR#IIyCJ5(ir|==*9Lcg&!()o{-*>oS}D1>O*6aX zid}irNm&zA|KOOqh)7SuRu4^o4I>B+y=NuB8ZMC~%A~r8s0I~zC7668X!OADrwnh= zsHN_)Q&Eft39qm3uC4bP$5z{2FnQ$Va+sV*1v#MdOkPvdDJU{390n1V`{hof&f3S# z*)36@4ZFhVUeFFTD=I_hzDW?+W|XkQSjYGHFnIsgzJt@#c*z(*y1P^5n zdtEaOrs%Ht$ZHk)crxogzTJl0;Vydh@;m(f_Kuf!1DCX;`!weD)TjS&VO#VC?(thX z39orG@|0u~F$)}$bxUL5rqXIGZ_l)0Ga1P`zU%2|<#!&Ql1NrFkt=9w1HVOae@f7? zSR5)935^&kQ0e}uL%UQK+B1Jtq5gDFiC*{$}jfQs^nsPBHc49l^|+tfJ{n|7CHOaIo(M9 zK{gkK%eP-`{J64#(%h*peUES5qK9)6wh`Ds*i^q}tDm)L`01KY_-@PgTIy9wJQpaX zCXzcuyrgiAvNi;OrIjBt{#x|7!odMIL52a$3O7elZ(}k(li1&(Q1`DBS8{fvZF*z^ z|6$+rU{5a98w4S(pgLcPDNiy{&6J}hy=1XCB5TyRL~V?*s+%b)f4X_p5KP+z9e;grQ)Ys>0LL<= zE0>QTuw3lwIbTmYr>{%i3tq(@m2P5eAIIbkD#jND$DMUbNVh)7SFg~^pU{2nhxcuR z#psptW3jhY(xNpyNfAyjdW)u&X?&L{-Mly0RJmG!zzgQK7}Tr#=su2bp&KpP4!L)T zQQ2i1Ws7VC?mJw+>l7`{=(PYXqRCK;FRTL}V^(ntsfhE?f&xj9Z>ByXfe z!LdKuw#G!a<)Xeayg-Uz_{hA87~v&l0{&$~08GEb6`-wT;%ACT_TiBS`J6{wackq#7U@roJukWUYPCubJm>F>Z!at5oK88*ZPx9W+eZJd)+_9|_(K0 zU&OTqggcJjS2;6UIEJ$)%1(L5FOwJZQo2BVosDZJ1t*8oDTh^`$qliiGM&{S49ZV; zhn5{kZANlgozg5XfI~513C}a2O`GOYdX5s#;W=6^h8IN1r5PQknP53ePQcv;@lskX z4_bL|d0s=fN>AwpV>eFS>QYhz_aiK2($G|D4GC8G1f)PVz~h++jw1J~Y>_;f5AMLF z2_xjROHvu!gwtwL@n))p6`G+hl^?DYRSifrLVzx+b>u81!mZ2Hw(x(ztPK||+_HB| zqCNwA1vs3BpOR>1hhfC6=_%T?S?{ikmtAIhO3>4|I?Mc*f9gT z>gV7O?dRa{|JP*r|7(>0HFf^4opR#841>_QoRcQvz{N%IXu+Z04FJIL1VjKZnlPXQ zB!B&`bWL>)0F6&|KtV}HNnR>zR8+5(6Od6a(}RTY4e@i5EmvAME3a&7Y+qUvw6vr$ zoA$gvn$)iox%aexe!u>Hy&j*(<@Uhpq3k#oB<$K7B-l9HH3_z`il0ifvMip#XjO?uI7H4*Dw~hW^rJV^pRPFb`ZBbdXgs3FhvV;~&O7`q~ zA{k>aVMa4UmNv9nS`^w9V+je7C6Yv&M9ESVTC|Evl;nR#$$O`nJNo_a`?*b@_tX8J z^PJ~A=Q+=EpDVR7shSwlRjn8L;pC^<3PO8N?Fi{=rI4C#=k?-p#hVvMpPvw<`?_W3 z96hr4#n*Z20;wie2TKB*;@s8ceKJ?N?Zbu`_UgW^*?cOnOIm!+!W$Ib-r6nYLuyxh zY6kmv@miPlA5EIoOYY(!=zgfxa<8k>TXrTvZu{$bdwaY-mrJdR7anbmOE!I~UecE$ zzN+TFTgdI*NmHiV_giktS#ri|mt(}Vd;Nw!al+yAB{Ji z#wVB|GHpp>8$Q~o=>o@md8OOb6Q=n7b)@`6hvg}ocGb1mb#tqxr_G#dA+WtXG9jBw zI;MNZ39Rp>nfA`qE6bY_rksQt~`8O-UURwshx_3t`+g;wLf1M^Da!kLe+{4d$FLn=DK9{?Y5cm-s1K+#TCtdjfxdjVpoLso8ITY z<1YN#v;Ixt8*b+{aan8Q%cqxpaS-i04~uAlYvWW}?(4*7Wo-!y5pDb-xiQCvx{J)? z(UP{HdWmJBv*#t@4;%f8z5O2!W*F=$O^PcHDV{-C({(ZGPN0bgW$semhwB%o$iJPo zS?$LuAuH3f+`Pj#E?k)>y@ajmVOCJ>QHSOF15Qf|A3fstZkRGNQFXQyzPPHLC||Y= zTb*{I?y$y4`sO0J_XZ2q;w`W5CFj@e^=><*aB{)AJK3C{KXr*{-`p!78qC`~+-Kyb zwn#%EH#gLL`J;mE7~R=1a!LOD*&V`4Q;hjNO!lx}5dYF89%8igqVR|^XFo;xyiwC? zChSVh*VM5>#~br%{)Bu&jDRJ^Jt_PNeo?DnDhW1!CL_thW!dFDDSlBjiA9A|u6 zaqW%_hnU0~%z~LQ863uCQxXeR2F^`c=mtAdc3gj_=U<(sR^C;e+%JFl+(y@nR=!HJ zbF`L@#x!aA$~op~uGaRsJG3az z%QPCzx;&L)IlZB=?5uG;`Z+`&cNy&MbKMLqM)E{X;CJCmBHuke4r@?2IIhlz{;$@8Z2 zW%q5*WlJ_|IK2}eh$<2CW7{S-MR?ua{Da%PiL=9RcgjXpsXZ;Ylst1ehwH8F62WcS zUeEa)XB+Eh{;(|(s8)5>oo6Cgo=w)Ym}l83tlW65(UWi9#~HpRlA>Ghw#cV-InTDEh2a)QNl`a;j|P(SBj}`WJ6(!Kx41C)km{BQGMrmgF{w}euU`}Z{1Qo8Z40=bM+Zt9>?jr9u;bzgwyz9NY%tt;U|ud9Z(#uxJ+YO@Waj@C5`Y3(yHH4DpBE%q=lLcFNzBJ3PrJGDQ2zVY{SWxAw#u>H&e4wb@Z~?K^Z4a-6Du9k+B>NNC-Pk_ zlQ_57j$YZnVmPyE+p)M|jf3+F*#sBu78G(9wCm+L9wF!=-SqUP{)fbMLD!ag&UDo~ z#ov*;H1I*PrGwIr8;yFETbI?S-M^k9W;UmGk#s5?@+=`;EYV7w)q1dSPE~bg?W^*p ze%Bl4j#zo}RkFQk*)^{rmAas`=}Au#92|3sZ+dKR6i0Zc$}@FrrFa6z!Zi=Wh01E> zzi#`Iv!ha}Z(XEVAJ-EF4R&jc@R@S~$u*L0C-?RQbs6Zo-aFNL$MlfV8;g}AUS7>7 zr$2gUbbr?Ifee|QBXa(pKZX}a8|d}%I|>}iqCQlak~CfVSxkZdwUUD?mPs2u!XB%Y zbr{f2e|EsGKK-upS%Wb3tbhhVt+l#-xMLw%>&f*J2A|p0ZO(|h_N<(%_o+sLDl=O~PW8-~!+IUX$ z>(ESdk;4nz#kX9I?diy@PtSP&VGr!^OFcG2Q$cgphr}Os*44$ghh`smYNYhETKmVz z`%$AF%dIr|S9KnFZs4ZK^>}wjJa05Uc=rP1O)jhN=^aVpUAtWRN7j>e-p16q{1zhuO~Z{n<3&a$T}cUn;J5zs>H#%F(>sv~3D|OgD1v&m6Y# zmsPP(Ua0d?r6y4MMU<;()%-n}5(z6WMdJj;8a@r-OErphVmMzhY@XH7=2VHju7+&I z`}T6S!);>7ar6=%|kt50f6`5Dc>w0Xwjd_} zj8xh_zvY?FH|4{l1g#OG*2u*k3%R+o5|a~0JBH%F)g4d$n0M#kYOLVQ-d%U|1qFr; zB<7Rry+fTWn_v2DUYL^XUt;#`s$}u&k)%-`+)PhMbs}Oho*HXB|Wfmd74`iPA0Va~s;Gh*6FFgVxQI=y3Moc`o04dH*)*hoq%%_C6L|@|82dQ=}=9dVzXym;A_) z*v2y}E~$9+LQa4F~Y*%6%uqi(ac?K9=yU)I4?QTuY2z zxmq~!meAL3x$lnt{VCitBvah^JZx&td!9->UVm%Ri<(9CSrWGW>CwepYr|7B_L!*i zQB1=3a%J6=P5QDhOz~Vs`Wk~oJT?8mbcf}B#@yj$2b1F{$&zBNv&~N0&s&LGP}h*a zIgc!lle`_`D>wV$O&{U1!AmF$p%kLolG*; zSsg%bt+ch{dDNzSg#W^fhh}6?N2~RIo*jz$GuPbBed5|KY5pQeUV$_qkmggjuKfNX z4#$hdjwh+<=ca{wX{XcXZu@TMIqos`x7En%lCE9sUmeUp;A^wlz4}RrN%a)Brn6W# zBa3RTV>?=SLyq4F;~8EoeNCT#wsxkcUA3sdr(j*z^Fj7e&y%_}%sqz5i`G>>vb60u zAumIW+IdAsI#F3i$46!UjJHcISDLH{^?YMN2>jG`rEB#Z{^4cEL~Y{yiJI7#@7E?D zF?*dw&~(ULe!;P#%;dY}LE9x+K3?~|H8)=}xqnCMVf*}I!uk!ftX%q)O7mLRu5i32 zptr0@C^L$O-)_F%rUAR@mmTfYu5_FrN_|!x@N}))W?3hbcO>id{U0nCzU5NO`CnQRL>^7Axypg&@sRQQ{Z0EgVTSG~sG%qRlAEsz^ zhvo-+sHi6%_2r2+ceA#6Cu*;2oDjY3V58!kb3bM@nOLX{;hrTg3*L93>4~L?*fXV) z$5`v9g)aE|$a1q?TX%dqd9!5wdTRZkYSy;P;>7BOt{aEjPlP2rsjI|ZAmo#tJ#l$= z>hzR%kMcdA9N%)W!n`T(i7ngO7ZH~)u$6vZP2l(zO{lVWES;HmfD$ox>d<`lk9~JW zZwTMJ!2Z;U?dfIib^5k(cYbzpd@3kZcp@O%GW>qU7O8}Sfg+Po{f?^AokaGN&0n&) zL+m>)kgpm!T(sMini>&mw_YZVr^)Xy*Y@YGeTNDYhh%@~KN_W$?XW$AJNcGZe$X^I>F!8FdVI)@KhD|~oy>U?#sKqq;n;k|7o z)S7RZ+N)-b=&kL2y!PT%;`Xb=2bvo$8@P{%Bm1=DA}z%o5Wo##dlA#`hB%Y(6pSZ) zT#)F8BmC;t0uJe$uhAFXeg9a6*}cMRmUo@X@G_5!_&D?x7j0Vk_~nx29fvoI4*RKo zXaA|#f3+uO>iYI!{+=_OgZ06K1N@!bJ+pjf&5p~Bbhisjx3qgbV4`*9a;#X!n3|!d1(5g48Zf?e!!7Xh!Z^x#Ss$N!>K1fzl zY@!}`!BbGy9*JFjOg~BYd~0TFPOGwFsr{QJg@fZJVq@F1Yr82}=g%bwf3q}l&{s9H zGFA`31jENLnEzwRzyC3O!9xv0p!kze9-~zQos5ac#vWd*N(v%S@Bz3#l&NeUpsCxw zm)m#4W*=^NNnHIOD1pQPwU7Y+3P;O>j~5A5d|oKqzuC5qo_{eAtN7?#@tm1^t z+T=gnsAGdGAmNTiT-U=V9yLJi;mOkt7=#v~hbw4o}Yq3?na9(6&M_QX{ zPp5^Q=P}XQk)bWRq-)OvH*%|UQkra6y$^L4x;u49OEI9W`jpHyF%|OKeH@sAjaOQg zkIO$)EIhSuYPI7|^IJMXxYj*3*obz$FW40Rb(OsEMYm**9r}apPm{6hQ#lBN6?;uQ zgXgVj-M&Be@CDq?g_l)~w$|q_U{9D{?V0H#G*#F@+daqI`e{SB@@djyEt9k7Jc4{<3C31A3Fk`L zY8Gb3sd`+_v|W06O3BMi@lF>lH?a?U_7K#TU2E&#bJVIjNLf~(gIa#+;o=|5JZECC zvaQ^O_`^%uX7Hb@5LWX2U~g5(9T0Q4dhVN@@1NQ$1yG%jRhC*L68qPajK$kx&!n?E z_OvI3-Q{S%oMxsQCnAtvvEozV4>7IsmsY+5WoBRbWaIDTFVUWkH4&~{KH|J>c|+;t zp)c7XH*FdfKdR;w2`EeS2VM9XrhH%ZYh_P?hTlcQpxK4Z8duh{OGWp-&vsm~A@s|% zODlsC7wj-UWMLV9;^FL}13iM-`KvZq^ldFaW;G{q;o{`hWyA5Qb{WQX3xyqd9dirA zH^gkYm!ejhHz+mUoTiSoJ(s5APkh0X{o!8vj~*RJA_n3}6g-Y>A8dWkTy?FAnWe31 zmP4PViut|gb^<(~wu;1v#`25u-OGu!yuha_#^JU`G?tI=UdbK1m}srfpZzVrSPaCL zK8X2b&Z}$h|2gKtfbi$Fr05din6;V@g^!r;jPzg^=}37{9$(k)paw70uycrV(zX%( z9XX&${=S6RKIqf_`lpRgJT{dL56xI|c`#lWn(+#F6GwFXDfp#EDE#*^OMNRdVo^a5%>Fv@vt>fM4GPSY}zk;JmU97 zd#(uaT<~I4k+ALRKaY0OKROZam`kTc+g}$=x(IBQrIquS)*yWxfuYbs_GB?@nPI%V zF{qeXAB4h?^Io#%Esm~ zJ6Wvb_(iEyxD%=@^LFDMpx+o1kv zx#IXmjd&@K&I2{Q@ji^HXQy@_;{x+$f)nbGBjJ}CQLHu@sy&V(H|{jQ+v4Tu4O7-+gg5@U(#wN(b5 z;6vZRNp%ns3!&owMIvg!y3eqWk_6b;$a3@zIRIY7nv@vE`lk*wt`-N2or4gjjnH4w z7#(bgBjZSTFj5$X=B(C%v_F4;z=^&+6ub+`-T@Xm0Wp}izhnHOMkJU`RtkEn+aWwLC>S}W||`Xd}_R8ffDT|OLPLBwa>>7U}*3X`TAwloT)E;5g7GgsHJ`4hs z5CZOJvJ!xTE&aNlA_&M1xRKqRKo%O7rm_*i3x%BZ*hlmuD0&pg$VTFm&5F#*7+#z_ zmuUg^5mY9!D^1BkVM7$B^_}*(vGgJswYRprl`wh>M2La^A)}LXE{X_492QT8m}dm@ zH5BH#fOCqU_#+^@LKjFo%zpfW+%9htbmrjoy!==mP&*E8WPQdIP6CWlpFO2L3&g3(I3l58OJ|IEJsKpMC*n8zm5u>@DT5c z$#IQBaM&QGLHjFJS^XARA`miCWb?GRF*!c-IJ@6pc8VTw-3935tjA53?D4dVu~|G4 zI#iOt)HKzRsnwghNuce=donrr8;Y}EI=jtuH|#qtg%fO$p4d|VFJc%M;yLG1BxzB13P7Mt>`pSF{@F znLww#?>~M~BbI++MK>dO!5N`m1}ue4bGD8rfRGUog7nV&1FVEt61{L}1+Y1w74sV0 zr{^!v-~Wv@n}o_9;zsh)7w;gkp#Vw)%i^njY}l@VSI5I zFBVyVV~K$}E%|DO8<_=k&P2xtqUT

    *W(Hp&s$jks@bEv?Wl$Rz%2+D6CRl4XuqX z0iZE0Gcx+)g0$%MU=|A8n&d@$pH+W6zSD-)V}3u0A^bVj_MJ{3G6%|p^!pU)e-p_# zAiH&3-(?L=b~hh=YG67Cg>Qo)k#WpZgONR-cg=xR>C85I@9CJ&ib?`I{pqY2D?LB^ zNT~=I~b3nDSl6EilbVK%-KsrT4@ z8LD#t%&v>@qMxp4bP^7W^TH9ZxJgeJ_NTt&e-CBI27g7CLjcl2rh(@V-zXU4&%BbA zZiajxfO60paC2CFLVP8)|bhkJ|oL7m6lA^Lcd~lM;KOoFK&hd7HEjs?6KQBAi{KHa4;x>zQPB3d09eMvV}CaUIejZb#@=#6 zdd1R3U=SHlA2|wOFZ>6-H7uJmpI8)Z8%(7Yf)fgXOuzON{fiJg#${-6O1dWpVbu{9 zWY!=&{!qm~;Gv_S?~)kH6RwfS(FS<|FzJJwRu{egZ}NVvlQEWJ*8c))0}j;%69>pv zmI5dFG41Z?YMwEB#Si0MwC|S)03X>D^y*OAER)LIg#MaRuuTzU@yKy~S3MdT0*^nA zLL^Lbf$XhMM=z}{Ujo-f_NM(0(Zs;y?4)ugfyUNgGO)S-$~AN!vEWZ4XIgUM=}}dn zOF|VO+rtP9A(&S!XiuXX5h$cklyIam>q#_i{T5;m-KZfHmUNlo$F}N`Sw&F+y>O0I zptl;h4sxth+lB`Jvlh%Ofe}|1=Siw+*NX*OOa;JQbo0l3e+cDVdC$ z#9oJ-y)OkNXTYSG9DQWzdd-ad`xK+UUe2Z;Y2P%}zIYxQ<_EYJAY!pGjBgnF9{tHk z^hn3B#C!@EK@>Ix$Rm)N!_1JxfB=|Cp4fXz&zvWq*G|jCzd)CP?6Kc+axhVIf@zGw z!h9@~?H*bp-E}X)*_MGHBkL`4Dr+>_zKl>y=L==v5igtJyS7a>1eWU-JX7CDbKKhkgi=~s0 z!5AuTL^Xc~k@MPLk<&*P1v)kt1U1LXE}bcRw~IjyE)=5g!V~nE;0^H@9|DmKdF><| z`goaG#S`#1+As^blKb6=3EvnZ^SH6W^hP0A+}Oqk#`gKy{4Fj8?Bo8IedNuV2pHRX zWr-&TU?^B$7Wn7yXV~up{Pe%@;xHx1(8JAOS(Fq=!oi=kQ`Ubc|BSVNqO?~<3GguV zp=*-8R?P8e;VJ2;VD40?%y|%`WyZZ6eyI^IHcW_PzQR~PrDg$t5;Vv`AR_aOWDhjj ze{8@Q?1p`|vjl8PfG!0&K3?yG2DTzP;c0I)zzhS6nj<#0&8F?P>J+4(#rA@|v&P_LN6{s!}L=)t`JZ&-)?$~D0@jX_P-S(ugTJ7juu+S_pKT=LP z1yv4hhnuG1@4ZfPFfnWfp2&Py`14wUP^lOj+g|8_ks}W0%%n%WF*4Rf<}Ll66SH1cGvueD;Gq$t#|F2pY6R9ol~ zG`_JvE(8y{)65Ub%Z-f^7#nB1)9bY#!8!5s>HGT5gntmh7;Y7N=KDHGtE?bhLpEIL zbTl}v;riglvJ}Q(sXgXRv=5RLL$xBSv?6a3U>Mk7{TP$0Pr0|%LHEfHoxdU?a@7~G zB9mZNnK3noOS0;^Bpcgim{&m>qO)W&RA@hp!5nWFwbQ)M7Q6&v?VpPp@$LZ&FjMBD z-~|G5VA%U$2IMelUlSVBg6Lz3Az+~5Six;EVqk-kF9M#k#+x2RHntrnv0e+}N$&4UN+TfyAO(ZRKkXlxq{p2^1D zk+a1*7s1GZKt=XoexK2aun=f~fmJDg*e6Nb{)L_bHh#YHJ{v0X3*5*#3lgj)F}MA% ze4gnZLAT{uzO?ND2f!dmKk@pChIPP^DR#_uYxl_AT6qMZCeT#m5zeO!`OjH= z`ZLK$4&<#57v_aUEphtMKKoBJrXvOK&ty08;<6KbvEa_0PKtAneEhJ zJ9r#yunTfOBwU@334CmAm?Q`DKv*352pW&yBJT{EuYnMXOf1EOSi$iD4n%u=7z+tz z3WIx2%doNCvxF=gQH589Q6(@AN9!Yez6U`5#Ru9VJJb_es5q86wtBId@_FzJ)j9NJ zTQgKL%VCR5Y|?Eoeq`ACe#2o?3$sa(cMEsl)rXwLPKLhuee_@n zW$Y85Dnf@|L+c2K7LAM&WZ1{WSWi|%%?61hr(&V(0#J73(sc3`)=XzS#TUk0RzbfH zPN$!^D(^N+p99sl4dNQIvkryN*)Y*~>{Vz>90g;DpXP2TdC6`{$xY zJln>Ei!$Mu+%LOQtjkoYFVi7~UG7$jW-Z6AfyQGRSOj7`X~t z+}P&-#dL{8W&Y=Ed-^KcEF0du3wX2zcEUf~#LY;097;z~^Y6(;C015pDbb zNy=Esel4Ctw!zpDm+UY4ehCIsxv{s}@903n;hbQ%JkveOyH#+JQDCENxRGhnKsuU~v7l`Q+d3F4PdRUDMq2><05yT^ z3o0`vg`GHKh~8rzs?U^=wZD538KqE(4GO(+OVXPW6 z_a7{J22w=9(&h%)O8y$endVFiZ}aQ@cP1+vq4zb{!*)rwcOU{8$6w@53Xkd}>6P1i zA!@P7{FR#-=S_<4jPdtlwgL2Uu8ws(7=AIRk8~B0LNxgJd(8&EK?Ej~2d4!ejhKPK zKSD>0oZnwwG#T`ty0xTD3N!W_$;;OyqM@0dgscbIOk2wSNrnxE0+EzSpy^g0U|$6W za)SDG1Y?a~@IGhd{~~3qKoGZKKt&+JOEkf-9yhkUOv~~Z7u0yB%?w(Pwh~nE9G4Hj z)Chdl|3`&CVhxEnG7P6-YMdMtfHQ_sHL6JlU9QKgz-Hu3NRg3&Uby=Ip%3H2b8#B} zcm^$?4_W|n0CBQyGQwzPb-?(bWFhwFf^rkVw6)+%$QE4JF&PO!M`;N@y_-2{k`VKl3beOyBQw;3S7=oGPyz)LLhD@_`%7~BodY!PbGVV?w=+FxTn8K} z01x}+nQOdd`@L&Y;3KbLwg>4av9BjfX5P6j*L#=Q1Uhd3Uy*~~@rxQU@E(=U)DkQ8 zXGHZv{7sjo9|-aGvLZ5>hX}gWxTF*mEC6Rl_87W9(2)Q6(lN7PTXG_0emF$(^RW4I z;dtTUmm0D9=OodL9pd{({g2K@{5RYpz&z9Trsd zMCje(0{KK-}NCq%uLoTMmPlV|vyMEX>c z{v+8FvUsKcK^AJo(0|@{LPpWtNy-@OH6~Rc`VYlU2y319FTzkuMF0KD2_fkVCMjfm z3)iFyMgP&m33*)#|0oZ&T=ZX!n~*bgArm;zKVkR_6N2Sa~C;RKd_EfXw*^9m=*|M$^cuz33W z5@H)2l{4p>IGStxh`)*RqUcWqgf+qcJZ$^-!w~EK9Qnr_Gm)Usbl8W6`RfS4aVq0O z0LRs%M%4cU_4kp06J}$49@_-`tkqv;n1;OUQ(%4vHmkvZOD);h+^nI; GWBWe^oq)yw diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-7.2.jar deleted file mode 100644 index 5058db4fa55694ac6029e146b00101c788b4effa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114873 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┱P>`HdjYi%%ZY>3NYm~14S3>Sc8na(tuavG;O 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

    GlX^?)Cm3Qv@C|&z3S>ezME6R5 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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-tree-7.2.jar deleted file mode 100644 index 031674ab644472caec03d0815a30f17d80b22c98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50283 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�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 diff --git a/src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar b/src/test/resources/test-home-dir/modules/lang-painless/asm-util-7.2.jar deleted file mode 100644 index 1047ab3e01fe00d4dae636329e4a66337022978e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80707 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

    A)$R(z(Gu+HwsmC$c!y`EFs7If={K*Aclx26V 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 E0FcirZvX%Q diff --git a/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.8.1.jar b/src/test/resources/test-home-dir/modules/lang-painless/elasticsearch-scripting-painless-spi-7.8.1.jar deleted file mode 100644 index 2c7cab96fc625045dabfdda732594cdaf7ef36cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27849 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ℑ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\qui}R{>>%xG<`` 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%0A#*e9y{E@us0-7fL5nKSz{nlLh4ON3~)geVxgE zvgtj&=BoSc^Yj7XXY+}~2kgZ_1e{!IP})(nEq@SVF+Cz`YHL4bTzbAFy>(@JE4)Dp zcw3+$!q*2w2KAKfxxEyf&@oWEaNP3HKBbuQZyXb3AkVCx%QD})L40@``lCc!ll7$H zmq1772kxlN*vmDZ8EMPosIF$$YHA90lUb4u@=!@*rWRV>le~0a0(LXW!Zd2(puN>PgNcZAZV@PzxE-gW0Q%Dh+TM zL`z@xsy>ufow?8R#F#I`k6OP0e`yv1n;Pi}x;`aXTmT_+txlO=P*#ihHnP{t13$mct$ye@43 znVFR;F@B`G)Sh6hJ!dxBNTDuB&8zFoF}-h(-*fo`{`$!_1jkI>@KBvrI*Mrzgrce! zKB?{!RO8Z2N+1A&l-Y*|FFAG8Dvrm|l4kKiqG-Ml#1WDi^84X4p~U9o&~0kj{WRqc^e;qnU;5qzM1)g zmA@|tSYGOwviIr%6bMKs2uE}H8FK#22l&ER;@6_DP{IBc^? zeCx2x%Oz#wAV5)|Sgbn=d}(>ebBwGFlEZo{#S3yxG709HYqI-YBLkDIXIgkjO8ng=6!iwK*FE#wR)THx3upduXUtfu zY-)nsa_7W~>;9}}R$mZacJ|Vi;Xcfq7553sz?Wm;;*jxaG!Y?=XW!v=1$vPrqnwbv z4C+CpdX{qPsDDABF0vD}Bv`~ov6|Sh%2{e(t}}4GvuE(=TziC7GToW^+(uMu z$5{)0GZe~&8^9awBA2K&)h8CTY}agNs#3lwCHID$WIzXIsC@=iyaAmRn_mk8URnzR z9fjEyf$}=l^&LiO)K|#5t`2Fi?K+&n3#AqC8P(~o84-Mq?Hp45-bxOcbu#}75 z9kGDoOf4-MJe&~8*)ao5loQfy%DGm&&9}c??BW@uxWdUeq*D;lPCOGgB-=aG2=0EE zoffz_Wo+FKv5ZWYkbwodci%Ul%tA>6uol_wJcG#3CEU{+R~YCiE>7GxQ+_JV508aD zud-tVUycYYh?wxS+igcAoGz;){7bD6FjE4RPn2xwE}h67`L*IUi^9u{8Sx%~`!$d! zu(pWU@X2GSg_l3AWYLcxkAa&ZapjnrcCH_#_nxR()Y8&yea{AX0_)4YZ^shE?0q|y;tykQiX-M>{=U}`Z$<7xzD zlGFQ~;`eGrP@7$Iy7r&u=&H}|;S}F4z+doPiqh&hX1U(SxL6C3vx)qIUCMSnAnr_ z$nv14i&bRGe1?Ds=--6sw}65Kop;q8R;ZSe>oL76chR<9dEupZz_`7z##}8*hq_Wu z;+`8P*&m!U?Ce{yIXf=^QhPoq7z!Xxh~|%UQg8elC^WEyXF&m=G9%mj^Nzx3>#~C) z#x!8B*8)UB*({|dvrBRn4Wy05MS7e$x=D* zun6BKu>PLAL+|WeQ@|E_$O>_vkH+osANa1bNqcL>TgQrS@hz?F?I~DgdNdBl>4vvH zn8e!>w@HkQvzt-j<7A^?mOy5*uZ62~q-)-F_!DM}2hYUK*dq%K@jhX#z!t6OAjyx| zqPGsv-Q5tU*V?C!-q%h9mQR?j5;7hKoP_ITBLopJ(T&M{dy1q7GCCLpf#ClQnP?Q4 zLX#sa)h}Vqs@Bme%3|Q=&S#FP8-DJstf8x1#JSHAo2QdC)(F`*nZH5(ugiB&_CiVN38_L)*sTBw{IfDdpqHWut4Ir=kgLu5?IktE zSTb?8A2Yc^SWneTbuEx@LZe*pHcQj|Z4T<{s$kt}$L<9z8}FW=zR?%&i{hIP?5Ng9 zIghEfwYXv{hL6A}hih&xMjxTaQneEp!jgfQgjoO^)ap3q2w6g4%O1nIJt!a^i&MEn z*)F!0be)(iB($^YUH)tCfpJ5@R3gq(f^LL-s5D7PTkEyBdtHYS@}aa__|aIka#e4# zmNK_E$m6l$taUpxS3uwZd=N2Q$yG=-_dGTSrD@EpwNDEaQh-Dv!?=O#kr@ug z$Lcn6nmMfWcydALAph1`Q4$(BE%SOAe}^0WD|WUOZq&rcF~|f_=m70fNg$7kC^i)H z1zIHYH=4-QQhMyz9zCTQROh|NP1{)dTs>3E#q5i$txi2_7^_Z0hm2y6wHW&R!TMYV zROS(>alj5iIV~@RR&Z;~uAvU^-Ze|k_{rTSWZ35CjhxSs4IryqRvvYnFdDnmeU?jN z2m20&@g`trvJtXYRpP`6)h$iD*flFz&*ND>PV4U6t0(~gG-Nom#$B!1Y?;92T27kJ zEnxW6qLnhzK>lgnmA?FTHlgy>>mw$^bQkJP6t5TPyn|BJ^dKxQk_b^rY41L`pGq>y%NcbVRwc!-OX#tW&Eo4Jb z-2>Xy{aogIkktgQ3~;k8HFMoEhfD%LViv&kz$Zvl>{c1*qe*0;}JLl3t9K0*8+V>E~a_3fOT9gP1+byKqZb@V{u7SwD`5|(h6ke8R+ z0B)DNRTnA>Q=;_pi+i8v@$sTjm&OwG@AY{|Es6&JAxQg*@B&C<2pZk=|NJhN3R1hxo z5RCnzkicCekSfz2rXP+oL0^%5HQQu#MKI@lA}v|DOaZ)Sbt|Ag+R_NEvwavtz7jo^ z+hW`f<@mOMsuY56w8|W*6Mcl{k$$;g`$H+dj9Kq3+V`*yxW~EtJ2~KDiDOZVA0cVe zXtbHEdf~G-YG(e~LIZ};L5#6bW~3KxFNELpfN^24A%SfIx|u9faJ%vFt065pa)~hl zOHp{R+hzqzkSgPe^(_^TxQo7&eF7oIckEa28^q7q22ODs0u4NaMk4DtlvX@EFL_1l zmuAI^G-UMha026tO#t+SjZtF$6cPuJ?re=qf5i!sb93Nj@Zi0=MAwqWmnGZ6U?JI3Gm`Cmi>{(m1#`Zi8h4*!K|_>T)9dbdB&{_Zptq5k|4 z{Qq)+|5>!<^c@_H9f@l#xb$P{AMp=8>cp3)hRQl0zFU zEpw=nn1&jK@x%Sf7-JY|4q?`e)`pDr_eJkGU-P@e3urUnmtl|Gt{n!f^bYvapH0zgxK-3I+u`1 z=&gSyF?vE&Gje6p_i}fYaHe1nVAu@bf!ojzf*4q2u|8YR5y#Gm$5+rW95#o>B0@Q4G_6lt*5_om zPoW7ACoJM3Zyj!Y$s}$-SDDXB)EhK08Ok;|-%+6oPW#IY)!oIg8_7lKS0rRT3T4R? zFF!Sxv3qB*Fp;nz(HLwy(jP_|{P6vyra6DU&2XN%Gt*EtymZi2-{ z!J9k*rEU{&#JtZ5Q^U51C#8A&lRjqS-=HS$qbe@276;_`49fN#Rs0|cm;LaaE7Fza zVoF(H^>K%-g4Ow(CWaN^8<=C+??$dZvi}=e1>eS1<>h)Y%I-)@cr3(|4M~94d=d}Y zV^0}9RU;@c%+sYvP$E&7btZE?a;^Mk0i1$73JSK%zv!=qZi&`|=pIaQdIZ)N)}pB(jD>o7(+C)OUh^HP9Q&zL-MIP{2pGXRU7RZ(s+j51lyI4IV>SMvmQMt z3^dBW33oF-JcQ^L2|itl7p|+9ZoppQkQ{%!o7b_f5FkN7_b3@3kg2Xdf){s{g5$VW2H*2WIzhW|AoDQW)4PT{+lIw_@D zucGuRBL6v{l3>56uy2uI$pPF7LpRh|0j0TP%4wrFu|>!?@CQ(r?p^P33D=lQ6UE>{ zf{N)Z+tzgYC5!PSGb^X3+vhJ`uqgj48j_?6vi@yIl_hjvQFGp6n+-<(oLs9prh>YQ zZfctq7`n(GZ~jM7xWPYy-JtyTe9EikO~g_mcS>bRG@Jn+lgmj2 z8O2pAK?aieNXnz>HV%e!8mMh_{b*1G2>eKOhKF@jPZ+73q3(|}r^PlW=$~ayL+pok zKqYV`K+F~0jHFcS|sD61Zj@P2tcoFKoIU*^HkFbkZLo@> zPA)~}VJ@oN33{iR6s5A`NW4!w3w>~8amHvA7sa`W)!=3K%z-NV#*zmj!IE3wOxXt0sy^bSk(F2Nvn_eqh1y0TD zTh}_z*52tfqKR-!v?}tF9T~xLFsdt09f?!7TR2)<`mbom&z9>jw{0Z_p_(j?_?Bef z99`OEGI68#SEwjj7|6H+5_3dy?+xa~Rv4uVpp=S3^BclnbT=AgarcpJq3W~s_|R$f zDSO1sZxDS3`T0-YcKX78YxnbLIex);1YZOZe(<0TK-WXDcD)kQep||ZQ`3Gs(tcyg z`utyJ4`FZz8UnN(_R|8QhghCAmmMwPlfqEN*M@q7i5;@P++ zG;DTwT37;SxAD+s-mu!@4i1A9eJn_Z{2InOU}+*rNF~h+%JH;r7vC@52i#BkG$Qdz z>0}=IC$;}1H&p<5hEc{bbOcr|x(AEQOW(68aVyh`I-#N!efFp#yCM8HTHYydD}_HM z+rK_0+hYF#Et((UbpM8m*8he|bLlCfE;ROKoVNCRs&ooM79BJN=;g@DXj+r>AaCK178yj zi61~nYx`(2s}6r~XmsB}s{YrP34{s9rMy;V&M9p1x$t(Um9;E)ZAme)sKO=3WBf6; zh0wJtg32f(uqBuZ8wpvV(Gq)z9@Qt=9;dlVKa%|q(yFb!ns)&b-Hmy3XiOBui79U@ z2cATc%}N;$9mCH#&Ha<4k9u3dNZV}WM|R$B8QZr&`aAOsvgH)EWg?J26U6({ym(Ww zk9RsLd_O}8TWA;}N(FBW1)%kG_2l|!4~78W>v2@Rs_fU!s90;gl5arEk2n!BGIG3~ zQrk|Ch^zQhpIJOJs(L^m_8g9T?5*YYalmqsY}pRpn*L4=-Mtv=L3NfV=e0&mTmz08)C5awLmcd=shtk1 zeYYk`p@U4FN7a>HcLXv=N{gtEa-lP4c-2F;-XtG;0P+mqyTI;}`AMX`wABds@!kC& zW~B@GIRkX{oXn;^RDgG3tbFADO{D%{_}_~ekOJPB*^m#tys>tzMq;a`gsvDE72nMJN31E*Flu=EDHKcl}NYY^EIBhi+4!)B>e zZ81*H*b>+q!rPRJKQgXtK3hZ=ITJ?}IZ9!AWPU?6qEV<|%Lxwa9Rg1{e__4H@Tc&} zqVfOAC=~1Y?Ilj}C1Q&Ik9d<5$}R>o=5wl-G=8i62A7DySi#m9!|Z+AxzY~oGQgLO zpIZu(!P<*p#N^-Lgt_) z^PV&5?hb@=ftvyV(2O7KCNOGKxB1TZJiXu`kQUVEVsWFAt;IA*wn!0aKTq zT0fUHb5go=ZaY;SKyrZXgb*MCR6kI?drfcC+Z=2AA`5=A(GZ;mvTxtvG`G{#pysq% zPwN1-)KFj!vDALv0xhi(SQ3e)*tg^aS=fQgnqFm_>c~gv%{YH0zKo`Apf&_f3SkSK zKTK-Op`eZJ*4 zHdwgOpjM{ncNuaH@~L@&H5E1x_#T?(HU>M1R`v|dJSGb2k~f7s{HKrHHw>CQLc}z_ zudVARSe1&eY-zbt<~5}YS7>qAii)giksdzp{)JvUsrDn0m4L3QM!{R_XlHHet(1KQ zT}{jH+h?NNHlCz}$ul-O)9<5zJ0B%Kv%+~@^h&4NmK?dofFZARN2*)*93sR;s^|Ba z;8TM1FLE`$UQ6mR0qrtck6VTsbhfyIC?aU&A(STW(B@vQKkqEI>2Ud;r)0jN#*s8V zfKcNwoiL0^N*aNuyhS6M=|jQp%FUO40>ev7P5TxijC~JIy8$*%+2u=c<%ZuEi;rWO z!<(*yHk<|%9^GEIjayTL76=>M186AIU((zL+$*++yqs^9giw2Pt_2H=Y8$^?=daX$ z0%}G~xF(83LBA@v_!H{^J`bsAtQ~hGs?6cQin#KA4Ol~tl*8iXUNvHkBwX8wdD2Bc zz}e)of(^@oQjf`8>KjH?BSg(7mPGRTrL|-wxj_u#mK-r+_inf?K^WOfvAi z`b{shPen0cKzAFC`pU%B>r+1Bn(>^va9I3zgXqBZyw6ykO(89kVrvYDTK5hr*4Z( z7b<^jirznUf4K?kt$m~2wbdD1{fuJR;6K^fdB~?SE%kOBZ1EFz!7f-`v>{YI4araU*eX-#pTX*|jJ-LptSz z;t&eFk4i};Sd>PBMoq6$H)4%F@`bwAZDQxHEv=Z-@|7`^>xE**4{IH)hNd$U%>Y4TFSNY9#qXC0l-pIj_OD@5j*lkE4)LQfEBZP~YcZgE*~lqUwmaV16W{v~jpzpg2#UG^sunL$s}@L?eN@ zoC%@HPlI`QFTNg?~Am zPVo@t`64D*8qZsdL0osQO+DI|G`;Y%+_Pg$Bd5QV@4wWb5%Sl$B~4{jcWloOYTMlFi4I4pZtB zt}Y5@h8ueh2(6JId-`0bIJ)DtI_^Yxk^jJQ0aJ_$Yx1f#D6r}%VQ;Q(JKK6cxh8Z! z$;Wg3_x{7o`O2q)Y@lu?#ZzKw?Ur#4+b|1GI@%zP$#8Ki&RW5o2Hv~HBRr>8H|1D2 z@3-UMO-*-Bg#`cHY!wwNWnN_g|ILd3PMLXG{2(@+`xO%NkYnS}HW-rcEA zz1&S=>_SZkNr==y%}3+Go8B&y2*T=Rqnf2=d}i(IOPKYe_YNy^npxD%_J;cODBKhq zA^Yqdt*o1z_GR7!bwM)~MMwK(bo!jIf8WV{b&F>#>~r%%k#@hZjic0it{t;A3BoF~ z=~Uy$1G#_wb-mujafbOkV^nqKQp+^5Nw014y6$J2(+=m!-pCGapJ?Lz4Jt*Xf*Ubb z_r%-Dj+5XhHm2LQ(=}xs)Ko&}bc1{yAq--KqZ%aYl;!`!0s#59sQe|8Vh92Z)Fa>s zOFaNifPH8r)BJ^TMYe*JA{$Emf+UGleu?m(L7i2O{tzh6s z{bOi6CKIGVlUUjmJ@WfOH_317E)o>JbX0-W)uUO9iukyL$CuMjj&m>;PjdxHCST?l`~Lc;Yy zJhvaj^IuvVlDYh-J3mTFlEN>qOye?d5fsy*ha=ViNqRCDIp30`N<;n!j(i zFwKd!#ceT%JH3mhZ+g4yE~Np_8MhTNoWJ?IMRZlH-T|I><|nN1eP84zO-+*Ex~r*Y{JF0JSCcW8E1HukwBk!&1`^KDKW>r?P0I z53H~U^oQ@%yE?55ni81~w}|F}2aIEm1%Axhr3jc%<^aJ9SdE+nv zcWsHkwXAH)ycw6t43=ZBUd{GnT|6xTAqt`e3!Z+!-FuE!{u zqyP$+*5>h4&SzcTqD9JIyKBaC_I=*dMLa}ZHdn6S>Z_}w(@U<4*p6AYDjAjyF_%ncJS~Q^_q?ijCao5By4;wkA%)%K4|U=8$e+D`^Pg%AE^iqU z<1l*-V}*QW^8lVgBP6kcBPim5aRp`Vc5ErzHQW5T8gH(YuvLk1Goz`(=JlEz9}OEQ zU6ZFeH=!RyPSf46VV+3MyAS$o3l5LCRvYF;FPI#qEWG?cRLdfo$k`)VU@k{irt`3M z*Zua?-G#L)oHxR&F$PBy&|DtV1`CdA~&(vO0mbXp7FpGd1n;X=%%drWlnpZ5>l*OFZFuna_;l^ z$+$)E>)RWYD2WO-5YKo;*$9)`yR@)9RNyIYVGm@9xH#WJr6jWoKaPCX(wC{XVb5=Y z-=x*VM0aNaK+n-&EfVjgmDuL&`ShFB828F?3~N2stgU`*)sUlAYjG6liBy#tgUPQ*YJYij8qYGkW1I}e;dEZ{sQzw4G zn?F5xi!$fI)1FP`kfFD*Lu6)UM3Jk+uOV}!iK8sjH0-kk*{rT!kB(nhJ^b-|(ipzs z+`V0>nYJX0!>XZgDckuVF$=gRX?}9BN^0Y084#OD!&RKAlR%%Dt~~15kN4KaB~O0? zfP5$!b({N0UCw0AaaN$a(zI;m4x6GTK;cI-fk9uz6;rYo2DZVWRjdHW8ZH~X)w~5T zHKl1vz-V;Fmh#>YKhx-DgsVibiu+!9ayba7shfRUZCWoND;z_5vEb}?$+nnr^K+5P^rGDw@CQmK6(Z1(#ClIr=d(BW@W zRUIY;-nV{ALl`8$N(Tm0p zsyhVOT7bvRxgfRa?=eTF@TQ2#GG9T_WJG(i#$DB8-oBx=*&=lN=n@w)=mA^Vu!x zLn~>+{RXs_9?ab0?*hOYR!Umv^`y#qxafn*4Xwp_R3+BKcl&<>`VACVT#Ca)QBxBG z(Xpmk`X!0VN53)jZv`aCXHkIGtvHDfSsgqbe}S0x*)+4I1P{$gkN_O6{4K&Ww)uq| zzpSeMnniBU1uJ)6tJw!R(j*8biU9M*wFHz|p!>xsQy&CR@{wLs^J!A_;$|~wjA}|_ z$1ElcM`OrhNGjgQ@CCN?X^$=JQ1K2*2ue3gk8?jPiJ5TNAB0R9={0e8=)JR()UIdv z9X;hZxhdCq6(aa?XlD8AuXqCA2}xb;s5PU$YjR`mEe?uEULr={ke}#4HLxTtSVoC! z9>J}7S=+}PGZ8cB7XA_w=-?)*4b%ECg2G#<%NuK1>cPbLS*|2V#o5o{kXrBGxY~Za zb1)$}`;*R@C;dA5ull6dUh1EMl7&_C@eSe6=kH=QD#O=4#!2z;MnAz`)`0hI&U4lK zjYGu0Fm~**VYnV=z! z`>*%v|Ec{Y7M%=mqNLQ&v9W)V4$~L0HQ6c>D00)079yX2bg7Y6*R8x)dsHsxzef(j z1<5OR7{HRF})-*us`>Y^-V7#0OBVcT<)`P+(Nsj5Z!vlkRdQUco3TZR|V zpw~aFMPYpNSwW(r*l@P01yWT^S&I8%ko zq8EpqV)^T>RCy08cC9Un4MYRA;jw;I-E#{{l$P%2Wo9kmXUC!MsavqTs9nK!pLg8Y zZkxyjb=Ci58ZY3DK`>Nz)$7MrWZzT4<$(T?jQi6952017iP3*9`P9cRO4PLN56y`L zDF$F5u}u;IM3DEIVq%YR$PGLpeHQx z_-;{>Y2(_)hCGxh6Z)qFGv{tf65A&$jvg*MwBzDo8Z3jZUk?#6H17}`Jo#|sm8+Jj5X%&J6;nUJ*J9ymqO zF{yMmgYiZ5iAox2GjTGw_mS)bci5Pcu<{~ePrxGOp6pnXr$NRI!xsxaut`TvnzFUE zj(4Tyni}-s2D9HT%6_eF)k7 zd{qDMxv@kcl0u?B7M7YC`g6z+a`K-*yhm200<<==E|gU{d|j{X)2811o!|=y6V87Y zI|t&wN4^p4<~rIw=mKK7kJj3~4|Dtv)<%L}Uhjy%$|>60n6nzzTEJ)P1lVdp-~Ui5 z9xpYImjAsK=j=adx9ghfkG*|lBNG9#0TA%xlQhGV>ZSBCyNwl%=KOsyTeJojLcIN~1c+7lMpY|C z%Pjm9#79$=PTSRSruD6V+CaShn$d?w>DWi@#yozB-wII=@pibh1h%01=i1_eui3Ko zS9Z9Zme%O-83+yft{T?CLtjBiY=#4$C7vwIq4bmML1v&l(ZjW}#^^kPi5mnf7?*u5 z)?_qvK;k2IavP0`kRIrcFAC79FpK_pJPEo`>@wA$`njjSW_*~ZITdTx-c2_$^!RQ{ zAtBR+27gw-#WPh;f~SH1U8c*K$qglFXUi{TLK zH?v-fq8eLeNlN6)%;vZ-f0fJJua!5-A^mMLu*k_p!&TQ9Cey{Zg(8PQ)ugg@Q&YNc ztJtho0#(GbR{YgI{`I!&QA2f3=M0S$19Ih-wvYm&{QURxi|<2Pr1e6FynWfl4C?3} z<`_dPpK4}klp~&OzqA0!^jYTSpvhApa*up;_OQwQQ<}FCtJSm?MYiepe?E}_Fi~l{ zNkEJJ7x@yGJbf2dcy9`{L6iU!`2Jwz-*e@^LZ;A#iwxzgLB_>@Eir2}fN#iZul}NJ zhMNlos>@0-u#E&xWOD8J>asjG&KjEMeIwge+a@dQNe+6 z9GUlErS9Hk?h{MeymDFRRn%`Uk-#^GFQ>H>+2n9?!@NHUC*msIBI?`4ywg5IrFQt= zosnwC=uCF(!$g#Upjx&MGCi4P}OcPmdPb2m$?{{g7~ zl^qt;^r0WH57AZ|iw^xBD5i{_s5_gWnZ-%>&BeBFXkT}<_qJxa9pi!S4e2Fx237iF zXP=#+obgI=bQUvt2Y{8Xb|$ zeww|!XaA;?%Mm=j40NE{4Z}CHuZ3&H&x)B2xt&d=3O{w4m~@ER0Z_=>c6Wt!cvcPb zb~Oh-z1HJ#G?$wUi|I6V5DV?Zxsju@|K8Qm4x$fz!HNonP6Ct~Cs!Db6$dYWL~ahC zO&%O?C`Dk$e3n8u_WD~weoDR0YtU|#VOB%(n;7()#P%3u-qJ)QNl=VaxJClYvFQkG$ry6A&Z};o6Tz=Dp^%6Dq#eZm5EYWW-&1?~aES*^0wSHtox`4a)!^y0(8}4- zSsT;x4C=3YGC`Elyrz>O8*;S-?5)O&=dpuz1~FG(e$J9mE%^O#ruAD?_+C_ z^Ri<_bksJCyb04?4sL{4g??H>ZX6;3$YU#>!S@$iMp3Xd(Z(DcD8fhbFV^V+IyE$4 zFG2)3g(gfz)W=!zyJRHekuBHE%ufz_J$eqhENjlj-eMJ zJ9wRsK88EVdUHh3ZxLbIXur?lLmN$$J9iibnd@t)l+U2?5OO0!`Tx?(I+`*PC22y* zoNR=^nI3g{g1oZH&XnPWHEZS@-|wz{Z5PfTKRtft*4gpZ`C=P_*>-GLb{BWJ9PR?OY@TL!(ziEL8gqvZ$NB+>ac1`33A2o_ zhQ^h){iBfMD6U(rRC`El&s2t49UaYiO}K?0a<$(pYHJkoF;h2s+C%s!4R3!jKyh_N zX@zj*(AD~GR{FG)ceWK-`L=a;)l^#f!lG<>a74BixcRy&YkOt#R9Qe+hjsF5m&`Q} zl`mFTSJdib%d*r~|In>(YAZVH1mLlrgn8jWi?&(#KhE&!7f?uW%rnQnTNSh!MQg*W7|tE=3f5By^|?> zqnTnTC93uMo=sJ6niCmaRq(@!%UaHaH}=q*x_=~zH~KwBr;Ld-KCrAskN&Aq^FtpX zN^)#L;hRtY%ya&7;xjiCYar6!+CzuSbIZzy8RfJ*A+MuY2+q*SNiC6)k9 zCLM)Nlq7*hrRE~9ES5ysOVtY0rPFp%a4L-cBlRtL2Uw%7LuMR>+a|XTt(OENr4Bq( z_b!b1BLSwn#qyKu1a7E17smgQkxjq=cBz{b=KoOvv)tms%0dA{W<^aCIA!q|k#Rt> z62QV)RWdbsERbA3aC_E;Oimsnsnmi@N*-OkRMQm5DUL@MizO{r4CJI!l1-ltpP98W zjp3BWV~E8bl-mVf&ia^!a*AcpDq&H}B?CuhEli_0r84N1u-QuhWE!JbWpZ=CqgfAA z5T`^2-2_&B2_u=oD2`hR5t+^?_Em`>naL=wm0SZ5vO@GimZVUX9?MFh0j72jJF0}d zm*x>@R-v0gF@b&{?;eg(A$g$?RH#XhJzB!v{t*H1-0EQD;L3g5v<^%6q|#VL%-p_8 zVy#2^dqw1xX5|-1wyTLMiPU_tshvC=vII{SMV6eBh7uu(AX*5;U4DUgw_H|a@O<<&UrNrK>$?dKA)6j%uYNL$(xN%?+S zZfgvei*a4ds1Pu8M87Ik5#*NZNFTpB?B>rU7 zGKDi+^e5_gIyMgVxPw>(tA^os%NYa9gUpK#_a`mOgBwfBYz?v0xOFqbPcgA|NXz10DyiR^yFI`tz*YGAv)zm}iTmT)ca=fu zV=NIBcShT@YfTI}vq;}ftsUk_1~vgR3g4i1lbh^Z=I&L}LsaLO+f@a&$kOfV8g*}5 zLt7tz2U|s3pYrIdQ_DN{pNwmJ^zP}uQ^T{($7p2&3mn<=GFB(Tn%sKN&~n(ABMf5P z2Nmk8{2f%h&zTWiU)xZ=k^XV~mh&BOp0`Hv>u}iEwo~RFKby7dd>|I=5HUm+MD6 zJLuKE@V^Vcmj>$$M_1S{BzsS`9NU#D+rf+CU%#%M($ zh!U%b9b^PkxJ6?*m_=iZ2*i@~$TQ%5GX3?(!em(_3C_qxiN?HWagRV}kPTTn&_-TC zqB$Wg{EWOBeqF+kK@!)9_*k?OVMb6VfHn?N$S5DVrWpAVP!Z}A(?;}nX&v<1H&HEz{nm?~kfjd^Y)I}uh zHh8z+#Bi%fIJ`0QKLl3!>?0L_IIK!G-Kp1gZ$t5q&XeR8ON|kdX{r|cIQ?%yehT7U z71D#<;WDgStLTeRagE)@vso41^Efna3V;#q+dN*_hdjUhhc0<<14j)3v&2;`eZyZ8 zv4D5cKs-w~l-t6mj0d&Gb#updXwZ}7X~`S^eEE*-R{07w<07{W@=|S+8U@@eK_k;Z zcH@Lv8DW{@!f<*c(~OtFFUO_$CZ*N5SG!m{hJBvOz4#Tc*fgot!qb88Ri{{TXR}_> zCa@b!iEG8D*xisFJZXEv)p7w)Efq*3uPYF)Y!@Lll-a++%;+zAohVUlBYvazL|`Y$ zG#2mJY!wqc)_ExkoB?HPiO_SSxhf>pVgb6=-! z$$X95KP!J^{HE_oohG$lJS2JP8A1fKiddS=)TrNSoo2NVJgkV0cGaw-r9*8_J4JEz z@cc5^(cdyyaUAUy%BWnQIg2`n*qqlNX#Q%@sC`_m)h;t}W_w@p^jfIdsbr6v4$*8+ zyp#S_0Hk&YbxNjmRCxETp42w}x8K%~oaW0%!3))syP`oKM6mW%1KA1Q32PH}1J9vH zEDX6 z9Zx6^-LusNj?rlKmLq)^afigjIrRDL-WjaH_YSHh`DAkH+P%p43rK_oRR86#~qI?$3p2HX;e#R)KfHT$aDBp$_>8kdhc+r z~kb8H5#Sgl=l%R34&;LIM$zdrb>g2j71OpmbA=oOA1Shz%hP;@J=3kzzN5nL1ePZ7MkOcF zg$gNwbRL-xSA?1YR32K2uw88#d%vbVFO|0bVpBQ;ouWuTZT_J2W$?(R-$Yp_>%uHJ zX)na7oX4=Eaxzk0z8Ak|V-7#lNpwK^6`k30${^ z0|od&T}GQ?9lOM%8x`k$YBxqtPCM)8YIh`oEVuRdfl1Fd)OLSL&dX0;P0CK7{5ZJm z7EsmidTUkh$X;3bYl3t|#Fu3>{f@yhx8~s9C$?OtrXa)8^7tTekx1qr`G1a_{+4U{ z*&UVNaaO9v=*EAKCA@l%3%Zn7Kucy0{_nr~J$gA7Xh!-8bG6&}5BadvPzQ(LsUWp2+Z zlr+z~HkjjJoaO{5AzF;e%iA{!=jIH83z}sz^RAvGa`VofC|)D6pk8##H9mbr&fU_` z6KCBhztY`4|5>8tbKo`)oB15sLx}7*N{9?wUHo%o3D44Rg)sY{3kETcOWi-`KWrn) zJUN>xJPbJrVyRCymz+-0writTSNbCWDsJ{cCPwyAEes`c zkZo5s1n}xSVmuob5WuEAyJi1!lF$;Q$Xi z=kQEQXHE_d!h{)f$3zbv(aPLVg`xNlTJBat4>9gWxhlCqnQ(y<5EaX9ceBJIq;}g} zlLy;Pr%mTtY^NVrTCkbAEvHRqTO6miXIjh+XC&m;%}E=l0`T!wA9@?v&LNZi6T1RKgk-Bs0lXD#V zWBIa8l1b)AFGG#`ozpwxCeHkfb0mM~Wme+`R#1jk$T7q5~IurJq?^*Ie_QpKUTR;0dOgBp2 zoU)p~zcF2NUpl6~taX?-{r;Z*!hKz{97@>dz-B;!Uu|U}b)LEBdk~l`*zdq`E|p21 zzU-t<$swS4_4zvFaaxUhX*`1dl=C|AQB(aZX?Cu<_ZAJc6mJ6uQLBc^#5Xu0E7YnSu;ywmG3Mq6uK*Ih#vF%gS ztDK8C7l{-)c91t{B)PA>uRXUkl&Qm@Q{GR-M`V(xgJ%tRjeL%zQG&!1PA49IA8{|0 zDM%6Uk-CcMgpv#wjtWBM8!PCRpg+Bk%qHG|C+)G8KsC?_@5o@b7If!_^X zV{_t8i``}9UexIFQTj4}+}5K$3F_Xlu1NYd9|Crk#?MO$U+RVC$^J&{K{t|}%JZ&= ztINJTQT8RW-J>^0&|VCbZCP)tT36O)Hi0;mmDF?9)1I@OOd&Ms(vZm*&Ee`>(1j(v z^TXe5G+M;kY@Uc`%+fc9uW})!tC_z?FMbb~p^VX^UN7f&j7oL_x3UGvB!-Er>wr|q zQ`B126Cy6dmxlH6v8XR)sSJ>*3}aB94|8PJaxD1!RJ&=>KQbC_L@vE~aj$>2K3so6 zU_$UvAJuy~^!KiJ%g}Z*4${tS_Hb2mb;?Vgh{(=PHObPc=WTBJGlJu0m3`=4zi3M5 z9u*yR6_C&hk298Sl$6S`IVt3Cb?*%%2X;a zh}~4m%;hU1jRCU8#UZw@TU6(7VVbHi?Ysb*DjC>UZfo(pMby{6*SJibt;^6>6h!yv zTn8bKToc0`3sRSZak{%yzW__s4hTD|^gYX7N3OT~r(@ZN76!evOnO@u zvAnTAW^*8ERw1lx#pKwq&O^x*kOb>c{CVAd1KwsCO_Yt<6zxcVD10cg7b6zyNM$l* ztT;S$H4i-NC48#$+-L+KrR9thlZl}y7a;j69R9tHzMe2%J@VDT z?v+Omw&j$>U(*}J?=NhOD2R+;AbnkE!n0Nzj|Yb)>vhL|3zk^hXI&`bt9p5xLPeY8 z^ImRJaVs?ovTl@25)%}UN8~!U>**(IK+68Tzm-`2X6PEDexh@+l)@EpqYcD64wHWG zd6AUDgOFWFe*h^{TM_9_ebFVwc+vjLH-ds&%tjkA5s)wTVTzU5RK93*Xvd@SorW%C zd@Yt4D(5>Nd`59OeANr&N6-M%<%1R9GD{)VZyK6s>?a8X{)JjH4w2}NOP+)yhHLSv zO*6Iu2AXH$Cq~8V`z`LRgDKc;Kvvp?l8Y(z9+R zqblvNpz20v_3L1J_ma})7ee@;4{|jTLP{&Gn6%{wa1@Rqu^Gew5lm^CxZh0-B8X|s ztFn3ozLXW|ncS0PQ2Z3LlnUHOM6;zm*7-AURyxC*_=K%x-$R0A3SZV-)>Tx-t{RO= z62Hib7ZYg{@M+M3Q@uAMN}3-p(*^)#&QCzmlMy*c%UXYF#?H|@DrNuVQFrC4JvYMG zq(0q6M3!|htI$mw@Pm&lZ z-C*9d&d3G7af8rsjvn2pK~2`Q86!!17=4WyKcs3k-cq|PcxG`W3v!#9!Etn-c~4Dr zmUfcoeuPe?aGOqraGPog2JGrvo6_Q22>t%)713+SDu`++8^<#I;$PT96D8qxF^m*h z0v9;S@k{MsuZ6_)liuf!kL{2a&vgY>j-H+vM4ummctpO!eQWt`j4EhR-w_?CC*>Q& z$PYe^-#T#H^NvMxELXK3C#>cu^`(tE$TAg;fL=RVXN@A!RQ;pyMX#N6M9M zP*Og|qb-j}|CAf|MLYmnBZ4Blxl&kFM=h4-vmlF)v0GzL&{X>)%t<2y=Vf=Zot&em z7FCn0+qXmYvLT(k{o6fdTt3O$J(ed?YMwf3RUIugqhHLbhdb%ZhPc<)f1QHDHi70k zflNUtsaiTZ5ObJG8pdNG{4Y(}o7>)nK1b!Te1u6a`pToY!I*nH)h~I&=k30P&WArX zakW71*oN88rR$-mc_%$Xb}H&5z1M-->;g9j$U7o*Lh&7woNhaq(Rthy3GvPsewMiIt8{6Wpg7(yZ>&I-$^r4J)+eWP&2|8>vRSLVRxOp&BPmlQZQ>so#{-gckf)=a`)fZdgXIJvJ5LS3& ziuJAJXg!e^X)JH1ptHzq{EdRHL0%oUG#BKXzc|Fuox?>E1)GgF#5Wkx+@dVMY%p)w zqfx?)O=n0$gT{*90Up1kf{8t1rQZ3#^Ej`_)1El5xCMWip0W!zo50=BuQgJ^NH_e^ zZw%8P7gq~J>cHKwoxMffP;I?M@31#k(QgLR224-qqCEOH-eTt;x8XX+in`(a;-%i9 zz=1fgfz!`SPjCgMr;Fa9Zp@?Ku))gFZz|I!zrZG8+DuQ~qHs)4JO!T7Z_d+YQtvo75jd|R1>H_F z-B7O|!|cvuicr0r$7AVeL}FfehCZlr znwT-~;7xOXL^L7$L-FD@-}Yh{gjSz7kSxQ0Ukf5w4)p&1OM=MF!1#1VruH1A?C1{l^;8V%E!J6Ecf2L!-R!NF9an zrpK5jM|>x=Zwiq#kaEcpmkKcpg#u`nnJG6>2Z+E7X4f z*RZ|fuVMSUUnTaEze?=SeT}@*>oL9Z?b*JP>Y;pO|56`-%_`M}l0m--O+>Z{OGLK` zLqydKSvGPHF}Ls4Gjj#i!*)gS;d+YM<9emhb9uG+iDsB!OOg+oSC0D=&6sHq-Bmt> za_Tz~tHc{pkK!W>MEOWC46o6feGmTC=BLS&cNA8IH~$`oN77I3dmk1^qwnw;H1C*S zx?aqC^sYppaE9L@!HMtKb*gXpTMmz#pE|F)p>RgtA;8J+n02~uEIoWz!BCT_?{IaJ zZziJMFK{i_BbV++lkP2-7r0QtDB)01h|T@6IzE66-|%Rkzu3&%ojN{@8v)_oz3sIZ zH9pVS8_4I~eb^qK!tX^#*ubcWq!B2E7YJZ<#C#xg;RPKS6LCtkT=jwT z1~Gg}v{}^$=PA6;eVPp`FCwq-LJv%UcwgX58^FyU(HA`}fMpzWR(R10CPln24x{Y= z2uW^VPfKBSeF~J^t}RTaeL=p#2xpPzQS*U$itKYmQc~qTD~v=OQsR``Zi%L5AZnh$ z3f~pZs&rYC#YY^X{4yq z%6pX4&V&_7szhOQ(#qd_JQYzS2`LrXg+=wGmI78$Gy5bJ8G=OxtCoVNsAdK)6lU6=@cQ;Z7?*UP`MbuGXibR)kdy?Hn|K z%3`yv#MIH6OX_Gzj+eWIRvoj-fw9%G;v1&~1*xIv)1$JKK{~G+=K0KdzgFJ*a~QE3 zygB}`FA{Ky-rZ4nMvHAY;i2D`h zrJx{QtRWXFHoNUFK6d(F<$cwvW00lW;=IQg2XQqei$dG38x07;Pz_B^R4irNHGZy~ z=V7X*+~B!Q;yo@XtC=Z2-v=-Qb(VUXzGjx8ffT-6^m!3|2q{aWL2&n*eO`a7_Q7PL z>CpkGbBaS;l`(`D0}zG`8e^@**bNW*Vb3+i`m1Q$4V+vJ&*covm4zNE0|bmJJhemujjUo#K>*DTaOO zDFW=nF5=VMuGf@&fW$F|aTt`RI?mtrhBnX3I#bLMr9u#DZ1n9?ybFhtimUX6M4C0U z&5c<+A?@+0pI0-vd(_$)sX;V+^p%QzXlhLcrManQ%w%~C%Tin`S$CO#?$Sa zxOsD@FLFE(rZXiyNdJ0o25Q#7nc8@6T`i3vEp9^bSz2?lMVfrhn5qj~vz6qkqI<{h z1{8V$(3PR-SNxwu2n`OUNK{*+B6AJvFTx?G$uQLk(Xm^q*%ym=y2WD-1&>Fb28>aS zOZyg$3aNKI_H`$YtIeL~>+{s~%May26=vgzz=K22)oSDEIrhbgCLJd#?@6TVS=ExO zFc(Y|@NuHl!S&SnR;H~7xADdpk`gsfE7!4@uiM}5I@#p5vp6;|dv;K8PYiO~IrEF$ zuVvuEO2kGVX2*Ua7rd`%kix=#-ajK3WEY0@q4neoQMs%?O;_FrXI}L7enz9*T`2;d zh{}$!AlA+3StnygRj6xMyQLU-@{q2O5G7%%d>Tq&{MB%I>jjKbD3x?FD#wS{=XRz{yxI~-$z$b(tkXg!(Xt;ym*LBFq#Ak3%tKd)RAb*638$O1&A82QjO;E zb*m@08UwZm?ELK*Ui)$xXP@(;>MxQP6s74{PNpUA4RUp~D$9?U|JhX6X1!LW zf$AB$dgnqH0F^IbjxEY4O4EIUR&GpC!cAT$JcPt_8vUW7QO#IE z5@`mVAe9{0(o=Jcs>p^nUpY>(m$twVECp9U+qg{2(2w(#{@_BMdTKHF_d>^@rIiAu z1!X`5e%U^Ykf(;R3ZUyIS?JN~%1omyVM&#mdrP7X>l60uLw8tU4-$1 zyZ*7AX#Q9JN+_W`GA(o@@d;^E{1vtDWP)&r?-ALz0Xh+nJ~p?Zy+!N@PNMKwy4Dh( zI{qc(88XTw21(9uXpj)sSX`G(qQsw#E1z444;l93beBBl1-dYv@b%o`(ejAb!YPYs zAh#LShyN?o#s)uj&9zYO3B|F!}@p;6lNGwABx@%Z=cQqD4d7fg!$5tj z>2=sVL=~Y3yr%7uxlF4~h-H&&BU6z!bNCtDxKJNU5xI|AG;uT*D7!&S$0}Q%Fjw==wp^ucWHg_Kh%HmV8Mk`X@rzzI1iXMcM>ZHUabHm7PTYSWvYy8 zVgsQ4BuxgpAcrA2GDx&u8XtIPux<`a{2ju|`UdI{FMS%mPGmlT_q2CR z{8=FOKqC=;qTRg{Lnyg%I80&w8`@Y*{Ni0s-T^Fm+N<+V14iMr6EhJg|0lroaVFun zXBk}m0_wl*%F^gv#93bfIE=U$Bj4DFl5iv~M5acQ!iMFeYi6@&tbK)F_b>IAfg?`0 z=&!hi`XSL>xnJWm)Q0ia5glMfv;qZ0aMigV|4UvhHpPC|_d6Y*4E^H=|NkGe^8X1W zRd)PezF}3goaRLVpG%AiG}Me~OEWVGj?`U+Q06Txj{So+J%clG=1ku{*A)q2<5A*D z=KYdu`W@1&$2=jux0w@ZGhmj5A8fydh65T-8jNMEbBycs%j0_ecD%38%lz~Y^qJW> zBZffxc>sQF;hAti=v2z;zpATn3Z_>2&KYe9d^LB>aCtHOP!?(I8HT}{G{%n#yvrsK zy$JFI14|`wt`&6Ne(%Q3Di^@YFDtWNxVJ9n_P(S%q+;5>sxzl6fopMfZ08WurDQuV z|N5+oO4sj=Fa*~RSF3*EWhnkvszK|T$5nF0T3d)5R+Xu+rW>&ugaNV>hs_S$6iPiF ztEi)q`smcTUi#%Sd)2cWPHZr7B@u7G2fPX>>jKuP-I5KQSz;=KaaxQ=W0UrkLTQp; z=PUZ^-~L$AFKiTN%*WHG2G0jRb_Ag=k(8iC2cMhV?MZs= zJF}x42m^gO9UCBr7_Wi(2jYid!S)V2Rt&*QJ$y0(+6B< z>i4|$imUd?3F~Oq#al<}?+v@P$bZhMb?5B8RkK+Fda$o~#3?%9zW4gk^rbGCQB7Bo z48FZEr$2Z;R+;AVjVX$!(soByuyz5R^wjd*5)3R1a!=DICro4`pv9-5u`=fddsr`= z+TwdXzJU^5jA6YZ+C)-lgBTK@$t2zC^cWP~&mh4HVcSYbgM@i;UXDk_hrEJ-?R!* z5p!pJJN=$Uh~(L^`X9-CbD`=$8Wy99YD2i-MVT5?oNoO~N>gll2DLBb5=Zx?UtTdZ zlZQsuIwE!53Z`F$*Jh#5^$nAMf_$yiQCJ=SbfCXD0}cw=^yVLA&T0Q4tj;&^XZKy^ z^ZSLcZAuw;lWGxqAqK1c&jn5S(%+crdv6zilP?7SH}yRZ8}Fde+a3_j!B~Vg3{ln2uSFIcxAI!89SWXuI82>qOG-aH$DJtXn(9lUZo> z{QC5NEKN_l8YUC&-z%1om>IwV4UFmi0T++}B~se@vJ!`3WtZVp6$3WXM((U=!=T=C zdl}6sWKc0=Gt6I{CT=<$aEYUP0;q42Q1vv*D!>h0`&4k+@ZA=FR7|6={X*goZXr7+ zmDy`02w7qQ`|(N}UM1UP173|&RgwBKNq`w;dfz#H^4oD`>*C2>Ow~WD9jy~ z+J=8QUB~bjZVu)$YTnP0==Kx=sqo*t%#i!uKR7?e0l`#QA)q$FDi-wAI@xcdLY4(Q z$O{MbM3^za3$0NkxyyP=Aw7T0{o4fR0m05T66JLI)uiy$?}CU{Rd^XX%Il|crSOAALQcKR^KZX?Ei7-eUC>xR;Zr2!v!qDUA>K0c{m3m$7jt}D-+fkw z2iaC5U-W2f!@$>~d41al)#g0Sp$-+je?_<5ddZcBdGRNCDrIV50zCcehGx!DBN9^% z_4Ik_pDW`|LM{;;jKxT< z-^YTk5DJgD!WDWWkU(a572T6hX(fI6mRkhO->i^<%xQTTUgB0tr! z2gzWlnV|)KDaI2gcPOJ@Fe%2?AmWmFqgc)sl}&_!XP5tVWOIu)swr`+F$^0@BC6|0 z`1K2S^iuu6oSp+s)@t7D=QF#U zyxauDFJ8HIIvq}AaXMXQGVyS~y{*Fjn2|i$`+<-EQ3nf<$6}eB#93rv=JL_@RUK-X zxbKLXl^HHJJ1{nj!C7YEA?M?&{;t#)Ioa%V%(4FQIdAr+vX-xD6Ao}=n}2TQUkgrT z>gSzAS@Gg>Qj?j>c@}fqdwxQg;%`)IDJ~08N>~VCElB5$NteeqS!S^FlJi+fo6h&P zVx9C4o0S~NSXKu{3Rt^G%ZN4-MaR6%uOFoyzV{w z$EH?%=I@M{k(YSa+7+-o-#Vvrwa{>qXt<8l?a3Q2=8a_tCAx&tap5AY+GEzu?SF2~ImI|zI|@3qdldw#j!P-j9F-HOxv0h+VmMkO z3L>-@6;xu}2F4e07xzzNP95RJ;5mEae=R#NBw2Aol2+YpLAc$RZw-$^OR?6r zL-p$&^R0f)?>h^*j?Ugfl~jxn!!v6z`b8udQ6yl0DlLSI#)CZphyghkfT2SOBUqcO zR4hw{grX1S#m-^*f(7%%50;dTSklG>zlcL#tDrp$#ww|{e6M00pyY5KCwD!3=s5Dl z^@I~q6$dvgJY;7)+&d>}$=-bhOJ)MBpTePBW`kJ?@aZ4AK{Rn$QL%z@!Apy@4A(g7zyBDrqHF{Sjn+i@uuOeavee7A z{I#zrh)4IgZ8su@Qmf1Gfa+!u)pD^+i?3E8(UexR(RRK{sDw_Z{f;RCfJb{1q={0k zBer+3CiULriBi2SzZab$*`ZW7z~!9e@qm5*IMs#X)<(i>etiHEW5Q~X!2Qvg5h z6(NXAM}VnLPOjp1b0B}d9Kd{^i$6D9Zr}QlOEfq5io{>_^8!rsEf&Qb6^W)17Age@ zc8GKgK$3QbJ|~-D{Z;DR%^l1?y%j-oqsv3N)s7fE+9~W#9_;p5P!nq&oun+H=DrPx zDA^J*=KpOrr|z2kc>(uaNV^ zu{b086be`a?`E+F>m30?2Z%fsEi9k*Y^vk+P82@UDNqFY48sBjm+F;pM@9sMTlk|& zmdOVm|H7tPpd}lo?uM;uGh=haZ^X#Usg6)@%NByfC^L_@jJaRk}1fKx)g%lS)vI|6rGcU5G9$JoC%p&hOFIz#TT&7X&v%UOB*ta|7%Z~Rh!7pEkeEhxg ze#34?f@$yTN@liUw5KBfy(EQ-S9?-?GQ9CE(=sphN*}y(e1hq{f_akcy^?&QLdo_@ z_F@g6?p*5>wTiZn_Nv^mtMtms?Vjq?ozb(KUESHDIJS1SLvdznWski5v#Hg98KkwL zCGt{vX_NoX_T;MI+pgjp>Q#asYG2~TPMPMF>J_WV6VmS1?iT*!wb7TdA=mDvWncZ< ztMc~EQHEg@?6M49+qM@T9T0M|bp_b@{g$hWuq*IHsBl8~WPsA~R`VA297cRu5O7j( zX%ui`bQzhy;qW9<Hw#22`=Gx-v}V5ai0q)p;6cGy#vvWBHBscOP9^rO^-l|-ejI6&IA*j z#m+u40ZZFWFQ9}n^E8dLuICmc<*DZpT;z7*uBV|;o?%|D=kM{r-;L$IkXmzWrNM=~G8w*pi8?$93y|FGejx^-5hw8WL6?SmA&xE_8vuQzWZ>?)~On#Y3@zjfW16fdEzfhhx{Y|+Vj2s>6F7}Et>NgMUB5*uDQF#4 z(&IEG0`EKJv_(kFO+Pp8PUlY7Rys-NS;8UzxkX9Dv&OZ^HF+TDo#EC7dT^LUH&@WX z+`+6PJ7DH%##s~JQ7_y!&b7`p9DMF|@%DN)*?sD^Ag4+d&zr3cq zr*l+z5!o8lbP9?TX}i?f(>cw5P4P^%phcoXJ;`uubqkJs*4ou6YZPu#Ed0Brvb9L} zj(=r&gr`+U1pkIvTS+C^H|dV6TnX#4ORi--Qz{8lH(_8AY&*u~u?#>kWPtZ4dI50%YTq!j(vot;Z$LArIY-!xePAZy&XH@>Ai% zXVOzcV8brUUTN?a^HzP~z*hYh$ZR?ImQ!KJmebbV-iOEEcknA@Sp51O3E1qq9ju@9 zTcSPegX}_Odj4<4uf^2iXsvb`a!`Zpo8*}Zb|H2d;KB2^llQb}_9=2ulkDs4p({6& zH?;EDDtle6T`vJs+&T89T`#=5h2F5vL2iWFkqq#= zz@RdyW#aQt`#`&rIbil18tZN14f{s$Wp(>X@MR7APH=X0`vP!w4f}fV;JQ~=HYEL2yXv_@rl$+h6`Gj0 z$6wY8!Ef1*(8FQ&&EUZV4;MBRJ-pij3f6prRIWYb$|!lq13r*Au=XQvEB-NKZYyrW zI8oPOSEbJ_1u}zYMqU5*9vrrzAzwMS!w-pG3a2dG?=_T}~jf53s>^a(8mIxtJp_C2t~EM>)GW zLJ@~KCpj|T;{is*NzMfZ%wf*I920@O-=D3%dHSCozO#Q`kKWAGXQcIZFig+%j`f7! zUol=VP`f_|KS>9w{lfhyZ%*`1^~5?`{L=NDlRghV(H4kb)t=R$y^HkR$-k(&<68V0 z{ffYY$)1;=gZDqIJ_Lo{&)&yr%!{j^V56_?uI=)+Ho9lKHN3aUx@VBSOuMg5KWRT@ z&;i(c+m<)olk}d3U#{C4sIS3!FK!!jJ+fbPH=OP7Z(!~1A6{T@UhjS5FFB8}@V8eF zk#q~)(_anX!R60SZ-X=wem(TcBYrb};w7k&qU}@mO@TqDjYI*|tEWptrgQ7sC zK>DB|QXmdBzu!MP5)f4#UtK_#rY66DUkzelg|7z2AT@)#2HW6ijk|{Imom&Q6)cPj zOvMFFPg@UukrgezI>8EI%NEiK)pfMLOu(6pKP|{ME)q7{3JTJPiN2No_mT|(ZvqcG z23ZFc><8fj!TFw+D>$eU)D^T9;+8Euq%Qcpnf;#Z-||^K^Zp;2T0vf*kml}aD;P)x zjXj^gF)IlHaTqBi~on_!+a_L=7__T2V@ zR)N<82W5K?qdk-Yhsrw*;(T})s|E1B75VM%{Yrquy(GIQy+U}!~NYzIZRqv2hS zZvmQqbVmWV^8WtZG#2_)fv2R^CM8ElEQ3!M@TFkMtYJ<9Xr*Jhmf`8J-}Y_<4Ni@h zEX)nnZsT%Li$NcLUtQDJv`2UdEBR=Fe#O7+Wkjf;bwg3pveVO(#E(`jzkXUWh2gUi zF%w&9tJ+TWY+UjrVlK2a?*ql6r0pWG1}uGTFc$pRF_UoEY@I!I55sI*IbYII@7jyZ zqNa>zI_`^)W7F%IZfn`Rkgc=aOT}cAa(eR>yH?+$9{n~Z*mpltu&fx;c-d#c;q#C| zZPd}b#&O1Tw+QNxt&bnESqx@w(3_P{;YRRsQsXTc1>snn1f0wT+EU{A;(H0236j(Ke(~`TfRilR#aZ(knG4Bmr3e)8$uP9`>gTU+f#c;8gNl(g zLYnB$JWr$6mO8r%V3hMp%Ac^~2Ns@td(JO{Z{~8{a?_2}YxAuFMCCB<1GeBY`k+;DP!KKrrQw+JARg3vI1@zqH!c z!G(75Ax!4P3S%dyJz3@z?I6nh`U*(CGz1dR9a^TrpZY;5D&qe+1%WdjoBAA7QuxUI zbtZHm=Y~4LhI12ui0U!z##)DSmrN)lAB}+Jw{ajghy>Z=yMSPPjf2Gxv0hknC{#3( zKf`p6{XPFPco0@&@ke*7XgFN4iRpgK*l0#(x)^ShOE2+n&D1oVpleksBxX_wy zZ;Yr=v04via?^u9#UYQ8vIKYnfqdnO*!9B$Q4_TQhul^<*IuJ*4hH{ zE&9aPeWH`~Shgh58EjRh2PiMJbSp6HaqnT>;$2>hw}s{VZ{&!x|O1B=ajcsaf~ z9?Fm~ASRw9Af%K_dl0xGY}mMFGmokkq_J>w91!H;^-6G_OJ6t*J?Hh)Eju)TTzq5M zfi2Gsj$H!c*+Bf>TUS=Ds{mMgf?3vwh};ko zoM8FLjzHbx6dbf8kzO(n99he2T`=a%{Y+`DEVuBfP~;Ia{jI`Z@rcrsF9YB?eSY@8 z!dyd`8>iy2R#)T^J<>9_F_1aB4L|&U<|N*|0YQ$IdDzAOQ9q|h-?xWl>fP{0OgwfY zQ-Hwx1#tTyZY!>TO@s6GPMf2!)b-u?a}GrfkhFzD1>HX^LqYf}f45Tg9_f7t*|xN& z1>svnGs8lJ9MvXeVkeUSXqb4v@yKI5xe^b(fm*@h0Mfe&5@HR7MWKZA7@46J67@GD zEXN>4X+gf)sEryq-1ok&57#8QTs0aYtizlKb>99p_q z)%wJ+a^(Wf(8!)`X&d7UqXt=3?h^rbi zEioNwug)13v8Gz~{mbS|<}Z-jBsXw#^wpeZaPYNG8N%gD``_%Ep)VbR>fV?6=OO>+ zTlFoFy; z2YH3Js8sDa;f@C=CH6r>qnd->i$ls{xB6T4X@wNdIYmP-1RdU)tvu-dFfCg}(34r9 zCR&}r*oep;Wz%suC{vj2ET1{a!aCk^O_3JGA=>%~!_N=0^XkXpTlnC1v*;x`hFlk3 zA_0B&M!Ek`cGQki+u`$!u@t4ch7CU)GFFp9V=WQx;V28@G`I6>8 z7o#4&eg-{=n~J&h3?kGCt<0K44Ryr3IB%Ako8LQ-fUwW;xoMX^Al7$cbK(C? zZkV`77N8mq8!LkvO8pozJ)E7=jGL2aN^KCZA;bM_702~$ySRf{(S@V}JzXe*avs}S zfoK;89)ue&a8Z)`NUMs*#r>J}#J>|OR5O6lKV3Azc!TspCxs~ZXw9i_)&dan-Z8dPh-#f(hGW(v^Y z8eTs@v0y=}pLlqj5MtbCjP7aCJ+gU04hQVntkfCjh@-319n^{TntuTy;KDdaPaC<;RNl zL7N?5Zg3s!GA6J(Ux(_Dn!Z1GAY|G`N*7;xR~$AA1s-07k9`r<(XY`%&Ar4QzoYbu z6`910Wnz-tF~_%J`?Jnkhc|GGpRhkNYRq5JxdwtxHP%(a2^h68gBVGEGhdv4WQygQ z`pgfnaUM$BPoQC_wGRFAjC$c6v3CT6dx9@O-djc%Kt+_DMtzGE2yp?RyNT3DY|!#> zadEK|v+(ZA-mQ`>?EF<~r^9@>%rYuL+v+>QjrDVIZ_?}S_NpF z!4tmii+oQiB96tK%*&TN0w30+fbsAIAy?m&p_%^n{%(swFm}~TMsfZfBnjw?5R{1% z<=!R`Km`z*T)#;h@Eq@*cyoZVa`{YLBcHGwMe64gjjd(fLt#ws6FVFVL2}{6MI;={x>P)6K|hxh>qaEnbG1+5~=@AhuU zZ2#yG&E(1hK z2Ux*jt$m2;)LpQ=?Vw59+RLLn>y4q;gTWL=-E@OlPXA!H!C&Bm*_Gx$S3Y_nqiN|) z83-)0-hx_TXXfkl^7L)%O}###>k6ng-WkKpO24_@nc#NvYta4JD;bgGRvS{&@=GgM zH!0fQWO$~Mja<7f9a?4%qm)!T!kJZyK~1{{lP8 z`sIKViyAg~yo(ytcvGhp?NbP+=LEpF)G6Ir50$Lt84sJR&dPcmpqk5;*byU;p#07` zD|XhSc#57e?vzJW?#MQR+aH-;`9hv>;@pGoA@XkR0OrDwzmU=a{c4Y%)^MfnIq z%Gx&~1+a*XS3A~O5|8R6Gvvhd0`0ESC6j$){6udX^h7<*#3QL7-UE-1t-br3Nya{fY&7%t>@-D24m)&#p1eOCa4BX) zEoguKCz@~?yf9c@q21l9+{|b;YcFpOE^(D=1VY<4C5`1h;9D} zYXr-{$Q8gsTQ2oCZ?O<$ltaXKs|m*RmQ#{^s)K^&wvlCIBM8!2u2c$siCMszcr7N? znu74SqM=Mga>+mjQ7sW#Rb>1az~cw83dJpl=pLn?j;C6dVXTrSNauOfH$vAUG#)4z z0r)Fb>k9ZQS35MIn6D3pBVcLFBsfc!w1U*FX-UR3XV(17b3mT@Cc&_BP%5G^Pn~FR zO`(Ev5Ga4n7U6>8tylp&h@Y#j*2_59rqqciEcC$gCqBPZA}DL(IZH6pqmWb)X4J#D zO`eG|S$98bdaCN^2i=34gxhS6StNc+0(Xs=rs7!5LSYvV#4!rO+%r;8V2yRNug}|~ zI9{ogP>r?Zazml5kFy2E(0s*nXYdJ+^T}tQa};91=Hq8ukP&Wn2m|PPffpZ1&}LTx zkY8BLAc;zRjuh8~1LFSp&qk%5WVf=8C#DqX(*kK5b3&9moiA^e-y-SxaWY|Nq7p;I zo%~j34xND=?ZbI$u@veIOxuGLURov)N>8pYQ)k|jgfKA{*@y=MK~hL@x@K?xF0TJmD4fPg93Cv>S% zuRBTkHRMHk90^%Ojs5{IDPJn`L@N>U48>EQvQkV>M>8hA@N&}yTBm|VUtUc|(2ueR zu7_$_5kDdqHVMKY$iN%56EBRQ7QDL_V{R)1x|6~HlI*@kD%I6MFt+`=;7MPQs%wS1 z3l{YeHYP!_wka^pmA!Go;61HMh{AQjP`86G=0XsvlOtTC=7!;+0Vy)BUnA;K980>= zUe+7d_Y+)NN)pv32tnyGUD{;Eh{|V@O*n^=yu?)~;h5#%l7}KhS4jq&;a4lhobWIu zdH9ffjA1_OhznVGlb63?{*7*ant7+1Fm!oHrdh&sK6|MMYSqKc-n*CS=uaZ0lmz8ZJTFL zJPbL1SH-ioG~;|!4&KtW252kbTEL^5%K!cB-28kd((@9kq8YYuL`&69uF@O&QZR)$ zxLH>mj>XDOU$!%LI}^O*kf~DD6gU&5R#EIHB_CmR2nr;DiPTIb!%6Y%j-o;sk9r>( zZ`-2?QYr zr-R9-2rJHo17`#bD9Wb0WMFm`7Eal_)1!Q0> z73BW}00A4K0y;3K3i3Gt5C9UznYaK^084Q$G`I|jHdidLVzk@Lsq~F<}x=I z9^8h~Tui_V1}HxhA0P{GF3yDomjE~y<>G*EQXUHk$ia9j%=`&3hPf=vMFgh=+!y^y z4)6usm+a8N%u!(S_wp~CGzd`ggrp1UOA1EDqDbWZ$ut4uU2^?HyG8?OqcSlarA{&Y z#u%Yc_Wq#{;jfgkCNtc;3quxPITWc7hv^12FooqZ!T(0gn|)RNqMK?0!f;}a=jMl{ z+Uw67Z)6)XnPs7~AfE{bOYpV8+vWxTSteArM*9L80VTDMkTWe>y}?3oPJ0e>{q*kUOb8}^oUUDYSDaU?Kg$l+N0PxlO}KB zX`1fWj9H}79h8lzg?(3y_UT|W-;D@mM~RjwOtMS1JQkl}s6!ZQEW>b)h$2snC^apr zh++vIBXN6;irYU>mHB)Jmi5K-L2<6lgn#*mS2au`5mvrY2%f~2H|>@=V0o>^KjHH> z%L!uhGvrSjT-)aZ*Fk)ZqIV?)3e{jW6yx!&8a)-$_pRENN=)$AImoZTOTXbkZU~;w zly$fG8l}FXQt^haQt$iNuClN7v*jgM$G(iuwle&4NJf7sL7Ye_oT+K?f) z&#cB14ulbJW#xZ`c?!A)w9U3YgNXB@`7Z|Kg2aSKuJ`mP;FONJR75Ddp)W+F23)on z;rtOfQDFnlQXF4M(CH|$oDAZh>yI5+_n++uY>dYb?0B3J1A}Orb}@xgbgn2AD54RU zucAyqnC;qmuF3TJRwpi%y23uY)QQP}|Chh|9+D+k4XXOFqIv`xXw1}tF z&2&5f>&8Ilu@*)~BQhqBp>m}KhL8T4o%Y&?aXMD1;93E&Wb|bO9kwRMu|kr^r}mpU zdM^;ex&$SJXvJ)m?!kyTSZ7MCJWuK|ZE?wp_^a3I(APx zYgqd+80K_Ek^wkD!Xe)Be?aNi>WieBiZWq*VnDdY$nTP0*`Kzgm1lD~xq$Ib(Eat_qb?SW8dags zzi@O3ZV1^re(nj`xD)L?tzCzNZQJ$Z5b{ohu#0kUhOi58_lK~HaLLBOX^|upt&4jp#dDp^U`9CY- zY@yy9uytVUQQNrN4XCYO8xJh6U2`Gp+4aBiB)V+gJqgom+U-a7TM9Az^_dAz z;Qx$C0Y5GH4v+JRv}d<^9g6HX9AZZNSp`oJ`25Dk z4S9oT<4(6nuzp<|=4aVYAn?wNlO6hu!RC#-r?-0TJx+k$+ax2NON77_Eq{oP(97QIA(Y z*~U6Kc?=kd?z5t*41>-SMxao!R+?|(Bw6t&54|`9pnVk&U&K#|1yna#&(^(=sz~|y zY*2B5u_VFpFAjv1qY2>umlr;qXR#+??g4WtE@4d}L7t~$DD*<&EE#p; zf|79U5<9>gH}RACp&jfdje$R3klaAL#B$8^SlNcQ;cp02tZdYYEU9c?rx1!!f}N)O z6TFGb$E&n3}^f}q2+^a6=Ha6*_>f%H28vIHlH1<&^pAJV}+>Ul2*8Ns(~a z(wJ4FW-c$dCmiKlU|~hwA~sY6XZ{vUT^@BmOjnZZ(5Z5W)|2Qbla8&Ej(}94u?|o#47yG;rDq4(7yB8b9qBt>^dET=<&-vqgcF$fqW1szCb|qG~2U# zLt;^s<4RBW-`_xy6MN(OqV$RLBS5Ib%aOeq8}t`g0ZDV3vAa;j+2aaVTbKi)|Aw$$ z3NEnC*IA{fz_Y{X2Uj|%8T_-1sB{PoLtmUgpJae1Gj?~g@h|zFdjx3xQk@@&DYms! zv@^_%hxqa97KdHz!Uw!u$-6~bC#wT#((x+vmc@VVMx}FtF@l|Q22&uT{AhP#uM>Y4 zCoTVc46Gn3_aZGFDCcKIM{Lw!75}!nV*UMjF`Jg4PJ29PDFlP9g53@uQrE@+7fl_x z80x+BgREYZ0UX|j%?booLrFaZqB(>$bg}~N+_<@)a0wf}fd|_N(jEQb3+4=(zHaIo zt)FUMezzztuP-{c%RBPbv3D*tBUd}r z8(y{M@5~!SQay{A2&L%@gRxeI)8+zh6`%+E&tZkoWVnKgVpdvc|Gjbbu`Z^|O9TVH z{!_X;61tBkM)}{G4yP(?7bDRu!7zFKx_31pVnw+t7@JApObnkZD z?D8ri$mdWMa>MzN!hK{fVD~)HWZdEy@-?WC)8viq;=Ea&+ zt7oY`*cwA?Af{&UoJeb|!x|j6Mn!$v^buw~fVI-ZuEynjJME6S>F3$zgzwP(_KGQj zHEin2lHj_2dv5V!cqeild=(g1?N^?Sc7t^R%<=MyI{Z>nJH*8`4ojz5xM(eMyO{xC zNPM260TOnnW|AT%LE#u1ON547XN`k=$OPUwsHk*1EFM2h0SJ%UCCcmIT*@6ZU6RJ# z@*@U*P+&VeNiZ6dI8#6Agx={KpKEy`avl@U>Mn^fHtpny0ocXT5t890 zqJFOu#po7nl8J26A(+KY=wcx4oq;uqGO(Zvq=kj0w&D%oPJgL-00K3m_D)C`+rRu`&-veBIcdC zeCF+DIAiRemHMzvtb0sw`(WW`kO+A+B5z6Yl8QK48tK|m2J~VyJnkUT3wm^{Mm0o& z#?;<9rO8)4GD&7Iom3IGCB1wu=2FdC2J)!Oj&5PMDv2kT{Dz+5`r4Y7!YRh#;^q&T z4$KC={)ob-?op*A*)Npil%z*DzW61F`YTx8l^)o@h;cUJHj2_#>u?#TZL-M^c6c`l zCnE!kv{O1*rOkuhJPVqNnrIm#gQ6ZyjTNdtOqB?zuNg>kQy}iCr@jPdOOtKO!Hb=| z6_@Y^4>kbxhG3hz#b(ZmE?Pppj;d^`sX>j?ED!@Hni>MJ^y1V;_kVCIWUn=3{HcHXYk|KKb0mI8)wpdbx$)&-@| z?Bm#iayhqlEI5+Dw@?h-sY@r;`Qf+Fv9Dbj0^EKxb`VGX%Q8T@0#R~Dnb^}YAiRPY z_i$71_v#_rLUp~>t%-dK>F36hz2(|PxdPR@QGTYsg6zKiv=7`KH0J$n;mr`aC#25f zOCYt6Sd-$7X*E8tVaA*Ju#ZI(9IFrNPKGlkRtNb^!4?o}ig-u!2;~>1cX;=V#+%bU zfpNS1jPi+~H^#R!{xa-M`jt`rkMHK;9lONOz&>$*=T8x4mq__Qv*h9nTiMTTI`}=V zqPJ%{%B-to(K{bSx@~%%F+_2t7lD%>d^C7RVuj4_LC)bhNg(e@&cQh;Tl;3l!5AZS zzOpd~srzH^SgjCl<1VdY>3w{PrgyQ);O|N%j9=OsgWd8=chyNU?>HvxUjm#He#)}9 zIZ1c#W`pB?3ZJ8XD!O~!lyx;S4i?1iD+GIM37FG1( zPX7`}MK9174V}6v{vVv3Q*WM#+pWU1^!gD@phhnZL-XVLL~t!&eD!y1G%Y-?SuJjfJ&(g`hT1<>KpJ z`E4?1f zpa?3;1fjM;F1LGHhqh94R>wo$jKX;#oIO+02i7BO0-Bvq>IYYXYd=?YOhlN;%thjK2q6-0{YJGvsJ}Aj zy9y6qY(%l;Ch^~ccXg1yx%DkLXrcyZg;XYLxgk49=d?{DXsAe!#0K5Y2{hWE;iMAd#AAjN9#748p>Tn*r=${`-4Lg^HpMe8#Y zOsmS69@|B_rIk|?^6>e&gOYp)apP7;X0KaZ;R$0_$QtZC)6XPNaSI#f#l%NZa2w&+ zbfiJ@dD2W0!VqdeF^d`>6nx2Ey*eML9YwCQT$yo(J06mZ)pol(){G3#SjLQ~NGHgw zT*kJ=39h%=ZU0*`wouahb(TABZ^kF6u>4o}7T_q8%)rFGhF#M)Nh8_N5(v;*ahSKO z?!AYyW9k{dOx(20EAi4sKG|ZB^vys_+B91LAg>6Vh_@=d=GJ8N8n2hstt`whpV!|b z@>2#(&d6>x#mpn0H{O%`8NUANq57EGOy~7ePG50sCq zNOYqfwAMkI!HE*_vm1F%au~r;vtD1}&rdFZtu2)>2>XlYABZ_$1uS<#Ox8ZwBI*1A zOjdjX({I*Pd(4i>J>LK;jZ(Q4@bt@|90rlwB6;YK#Gzqh$Xub_LZA7 zN;S0c_%Ki|@%VTC7OFfKWrR=OY_uWZoJOu-yGr}+ zhi61#ivSw|U9qov2u=sxpK&0GXzdKu1njwN2UZU4vgO_W`ifWwz8=$)@!5X9ebc`j zhmgmOzzw^a_FYz`hiDfk-7(a;=SwHAVc zzC|S35g~Pj%2q7C`BK#BN`Zmt9PM`hyW1`&{lVDT^wTMwtQ_V2PgH%Kn1~~qT1*`~ z%Z9e?xV>%q=a5v8Ueji~YjAq;L=E#aNJqLM20l{C1W5~Th%^&{#YAcm10OPuWNJ}) zA2#^pwi9ZMX)3%qnbvY5 zvHD*4@zqpY(&DIC<*f`ZzaiUf;y45RJQ(J1DM3Wr`>Y_27 z@azw;#mpMuM2%idpH+tKpWF4UpUYHks9~O)SwbDavJt;P2#HgTh9ZLq@jn&s6P!f9 z4?z55{KCh75FAV0ii+AtHi>;_%^oOY(fLFcp!~uvofPh8c%jc^3_^t8cQS5yXS5%> zH^}_t7z~3!o)m_PU|Xk3Efy`Z7cY8dC`tu?!24Iz5Pe`K?-}PbsFyDCn;}F%rN43o z0!{NHe;*$o+tdz`aGC-v;KnPceuU97Gr?l zU%RKL;749Mx?h?P;L-|u@ z=44O6deSIx3f&`$ zf_o-JctTFBSUw2ExWx+CINJ4iKzwz3{qr2!SWr?=Xj5(alWh>!7zqj+POBFX`Isoo z^?EQy1+fox8hgxf`|%;GYZY4`WLwk5<)h5s@)PF_(!+(AfbwZ=-Rh&>1O)d9M)0&Z zJUr#`7Mo>k5%9*uFs>11amr3gj!$vqo(p!)@TG0vTTCWb;YT-mPeT@4adF$%HzNJYzi|8Oor%^f^>cC~Ne()*;5$({!7^!KlLgZ3)Iv_#YOT9^{^k@9& z&tL@Ag3y3zXR7+bUu6E<@K>1Ia@^y$MH4-o_HV`7IGI`vYjQe@<*)D>qre~T3`-{P z>O=Rl617O0wX^cs_guY{-~>?Q5ekt-Two(*usqm@@YZK)sR1-OA2d1QG&$rnImI+N zW;8i_b2_}Bf~jhWzjLK<^F+10u_9>$$5g;rR6D{WpApRI9Wx8Pjqyrn2k$#zu*vmH z^^qou*cY1+98#y}G$9UHzz?pG<&l7*y+}hG>0@G^>DtkG0dQXp`!|^uR{U_<=s5z} zNdmhz9Xu2XbrSMgt-7yg^#_?wgZ9_!EaL&#t-bF7u+X;JcY5_%(#F3NXUXe{Uh-k+ zAvg|hQQ~+~pMEeA7wQX%b@+$6zF-{O5~ogD%^AKBbkZ4#G~QC)YxRbbPAp#s-y)jR zZT%ML4UG*eo$$vhNtzlKf>84UrAX?d5_FP^*?qS_nAxUOy26^5NqC9y-}7VL#ys8b*T( z#*#F>kaxXM@7IMV)#4vsYfjnQ_moq3Sh6+EB~TMARRE?`GfK&>L00e0@w{N1#g3px zg)Nq*Vn#d_uYPzCl5s%RBo&wl^5z9CqV_-C{~1G;6%4K1@wq z5M~W66Itil z1V-rDiF-#J_O>YEhIM9F{6k!5@1yFyDF&(Z|t>wjI)L4vuBJmfk~q*&aask^n9am=d?o8@EE5M$&SiGec*2b z;_S?Z?4aM^s~=~>f262ae{aln<`Geko=~r_{h(4pjw7N`8iHmwQ|FKRIn2v6GR`q# zS1wdH-@qQ;tOe+;{rvqafIberxitiN{xFRX7Q=%L=hRF^CxBoVNKGOdfF`dLhIOiN zTs{-(cxrzPn2AvLAVN^V?uYRp6{uzky*V|_tYZq%I8|LKWD46jbzLc|4KF^W<0-4P zJOFxB*LLP}s&UuzFUD2(b^b#9!QF)50iRRuXwkHIVc*-C!l>re&~i%DD!MU>RQa}Q z^8nISPGs&>9<}0kYVrv14gaVlI>`3T?OIIf&h?Gf`Z0TLd&;}1E;zehiS3R3Kt^0? zxQkpldu{A_t` z`~%b~!Fk}U2z`yjsOzN#YHp>UR$j?DEIyUgp1!FzzJ_qfd@Y$_W)pPL8&) z-MZ<dy>qy={3X>(#I!n358|!{>=}-R8-(Ial)6-TT@llLuBMZhS&5(my7r`xo!y^ZaJ2 zz`?RnHBIVklYp@Q2*Rk?to7}(J**4(S2tIPt;8U;_h%55YndM&aw%|9)2@%QDVVWs z`ayGEpE=}lb-f7PQNI$s)}A=UW&mRk;UZWYlhpN3}))tj>{G4Y7v;N`U z*UZ@}ABfZ|RT6)UqpM3e-qK{jpvKq(^( zg}7j$u$A6+yuc~38#Td*pLA_jORUQafz<_7_&YPeZ~?}!$TaABfmXecA5xQz|7cCb zQ|PnPei#NejqJz>0(wDwUHz!+t>cHZxmer(wsv=2@d)N$(*x6I&HP<%$U;-xFAezD z&wnBh3r9b9y^a@yoEyL(ZZW&~AiLPslaAAsMX~ z6Caq(>GvS%MXNu?bvAEV;Vb%E;7v=i1Oxl|c^LFM7gSJJN-W2?gNLem>ylY+lA zl}mOt+K^WqOi1M_Ee^NUea$$c_bxl{c-H-~3MN(7w)!ivu?W!{mh+(BPI<;VFa!JD zZHk}dnmNHd6TJl&S_le@N`v$;{yDxNQM!VG^`(|su2!;)xWHA^L4?8YMH$}dRS4VuZoRwQOeZJy62Io(*-Ak{C`w~q8 z?{xA%Y5Wul`b$q!RtN&v^s0qNG*1$m9$wMyb3Q5jbc3P^m&)qVU;RC$jQVFz*jIf5 zu-wj?R{QRG&k+@Zpcl5ppJ4}Q?;{3Z`9k2-ihi|7JR>bOp4XHAa~z&oXSj_ilrNloL^&DfH!#QJst2~y>2@w*9 z(v6BQOAaYbw=KN!1XpC5Z?YF_mIZZ7!SfZ5Tpd@h1F6tmR;ATysCx;*?86d@;YNn2 zpRs%iQhmAPX6}0%0f0RU++3TEW&5q9_La$AQATg+(DhV$240E>UNY^MWyBSv=44>M zcT2r@qq;%|DB?Lq*3^8yVa;SsS;mA9Oj}CV1F;)=AQ;8{utxm~zu*xs;PBRBtgV@g zih2;d&g#TEKk;Jcw}J^i6miPF2{jLGCXt^=)xa;r^?R?sD?-6xuTjnlUl=o|U!ZlL zxOgke*S|gy{VRf?zkq#F1rJ}plRo+>KBO&=zr@MkesRtPNe#V5Y!n$;$I-^h`$)V56cXM*pUq{ zBTNe$MPCx*b}Id1=zB{_W`UXXy(%z7pRWUiea(TTVpTqbM*h- zV>!RuB}DZ5b3TU?zu8OSYZS$yt=|?W%XucxWV|)^b|q%8W_;6I@X{*^T3noe9;I?* zZpe4x)I0k5B<=g9b__#_&aGsoI<=5nfLUKaJ5*O>mNL~HwYEHkLSx+bBhqe{D?Mw6 zXkn~&?@SOfcgEV)MQXvMmy5aB71wB%ahtCPOZpb!uH_>1)Dg#^KQEOunvG`~;c5Lz zX$73B#d_*rZ*T@+YWF;Pa!NqKyw=(xaIP12XdXUh?bXO|NAuMve|j{DU!)xl(~-c4 zVVkZuve4txjprZY_6j6x{07R=3OsClK;rQVasofnpu#9=<`oavB!RR^%^r@u3qe#~ zJbFFx`f27KN3MHrL`*!`HSf%jTRi-A=N_5=Q9DE*|33xS=gd=>dbaq<>d-wMtgC10 zs*7jrsx$9=PLJ+>N3ZTbd_0Cy8P{}YC*FAvZruY=yql&^yqlJ|@j*>V@lV>ddjXH- zd*YAbd*ob0H?W;Qzv?ODXIE@TvF%g#}nv5KD*_<{*$kSp&Fx+syT}QxnGMBhH zl)~Md_<2AW*Vx_lBmaq&?wX^RjM!Fv7a1?@g$8_mv3zJ0ukFS~$|K)taXTdzLTIRb z9NX;GRlz928GLYBYGYgG&BNOE@l0ULv)0}2TK`1VUA0bEsS+u*2P(nte4}-_kTGVE zs7ERe4;B_!Ma|J!ynp#_bROM8+rGMnfq>z>?n1&84-PCVp4%^#N;@sBT&Io>i*Y|v zv}vO{_L0hz!;5;&!*Qp}vNYwqi%qm>C!hY4{n#6~O=ne9SKeUZeif#M~8BP=~WG3N!qt^VYp>c_+erA;dfsgt~uat#yQ27-fwS4 z%fOO8U~9(v|3!!J?LPm|)-DezyWDgFV8TBQEageqtA~(s;M*_i!Lg$V@sie&9BZ3c zCHYmOG7<0qGwjooo#2dC1$xO%eJyUt$UExZp~3Wjn!SsH>5bEZJ!uIfXbHq<2_o=D zT*~cogAZ4_JUEm@iT4ohzc-VAx*!2ui2$yk0JLC&JvIST0dSv4d@3BGW_)IbKlgyl zUa;@;`uK4{5QGM9$EJ$5xAsRwT+jy%I0rY8AHhF}Xb0@*i|OqiXvLp3 zuqpTx1L*YKvb3R9)9}hDEe+lOO29S;soFIu+AZA$C@I?g*E^WFHo2+;7ClEM533#f zAgzGtuhFenux3eFy@}u7;-SrP>i{k|>x}kKxAZW)890??9aKDCdQo{R3+uhuu$dXU zxdk2kOZTOa-Wl7((`qE}T+VG!D=>4DR~!Z67-xY&*qQZEBs$<>Ar+(^7rfphpVx`viT!{XYSL zdUj9xMVJ-lj$O6`s8?pbjD5=Bm5@LBOGlja%3}45(!RmW5MI7bPZ&M!8d9Qas3Axus)a9PxxYb%k zx`D@dIGStZaXXK`6YvB2g!Jrnj|sUNni}yGm~8QGoLiMeeO%tV4xj8P zl@(-oKzVZ>S>&Jlr$2dprXaftjb6EZ#w55K?j-OO9HHkj-%#f<-(}5cJ%b%p`B&T_ z_Kv(zZ5{f@5PSBHD)Vj~9pw=_*WHN+4!@v&jlHmbO}xNk4 z5QfEYxjgq{^;%~I5oyVD<725-dL3*Nc$nFhV&;gcHtaqXC9kpe`nc2G7ryg8Qz*RY z_yo&ufB1B-sOV*td2-p9w(&Gt+O>6AaRy3P1Sxn zkW%}~G71Dq??N-FsbaNv;SAZREp?s)BE)y-4(e#pUw1l2W$1hL=hSjt_f`@5@1KGc zbny*%)y`a}RKe?eQL?V44Z3R?9lAf5Gifnnot;ka8jM#Hm2&^Nr-IQV?H)>d4XVk5 z&yABL9{pl>%Qu*0Z?f`|>0&%Xv*0#ZszH>e829i>Qd4!(DngO{naod{9PV1x%0sG$ zMNN_BYqxNa=IgPbnCz?JI{TJmrF0}vrU_6M%D)S+^ekw)D|q>^`bI2R=4(@*fu3R! z{__e5dwXd}nt)2&jq1Jl8H=%=Iq(rWgi)G*(I6GU1 zU&@_1SH+z-@bAYFvSizY(LCVs6A;F0bXWG^lSVz)8wzvHN96~Xge)J$^n=l0r2pRzlEK(>0w0NjE$-p|v zfJx%^MdG%z%r%mXGXw<>8X5s4YRmzfKK987{i9an34;21A-URr2A2Wy_e9W3$ckJNtUUiV)SXW#X=MU()VypIpOk53INJChgi^C#;KOyM z>eMayU$fT^!hP2iuP+znDa*4?(%?zyN{h?Ibp=NF3W@g28KF86H}ifU70NAX<26x z4q3{qO;F$KfyvJr=qE#!pO^n#g&g=x*cyjWzgGY&^u*O+hy%ho(cWR34_WB z3u3bBWVnnOxpDyUGjp^aij)(=lX+;>`Lag708(Xu0b5*e`bo2vEgwx48);ROxer|x z0+c8tyZ@v_e(a`K(8b-5EvvA5VYc%7(}v`D_n5n6ym-H+uq1W+71GUQkTA`^^|AsX zDPhJ?PKU|sO<29i$e;j~=Z$BGg6G0|gTt{pIUI~lOY%C!>r4EvaZ!^jY0=f6Z06{d zlsT&L_EJ6OLJvvPC%&tpuj62yI<2LojfioH4mPp&(qxe5{%iYXi1Cu3&*R(APiluYd zl>)RU2#J+-m4(?px7_2kP0aV|-|a!K&s{-#bxtDLBfYIk4qW3rhyxog#C6WZKZLGJ z^3|Dk{)zAX_Ntup zSN<+C$8IzWTrqmJ zl*F@&(F`&>?-rHzI#+LBZvBnJzMa30T=Na0cLi%#V#?FcqZ*jL4Frl!RO0fD3>Nq2 zFl<{q#E;{G@p`&J=`1_xQE1Yj+qC=7aQdKlWaaeC%?}*6gN++m5@_^N5dyjP$NI0j z)}Pl6hifi3uw4J#8({d=D-36%AXm zv#4i16k!|!C?u@~)0|KD2gRRwsAp=AVWq+eww>7>ZD)B?QCzc5fq{~QXjso=*B18= z=^j^Qb%{d+h~NwRaK;JKFJP zi1FBalR85;n1G$mpxkDNLzJ-$*Oqcxt?Jn2fuTmF%BDtFJO{|< zt0s6gx!q=p`<~v05aDBWgP_EXuEShu{{_elN~=&c=0CV?E|YKc}ESZbyo&b@uDhX(~BSj6hMIB48oIH@aIjeeSs6P>qRTCd|?;i zoYn#@vo?fNUw+rwR-Y~aXX7wJG`BT`$}N4tBay#r5kZ_@2Ib^T09nlzM(#g;5OJ91 z#>hxU!18@$(~cQ3$p_#I%5(dqJGQ3x+B0sLG6qcRzIL`W|I_UR>b|zN+#A@PaM_)B z+MPfz%@Z!oCsYFpwB@~Y<%QeQ18o>LEEqQ&7&puqH|!WcHg!8^bzh5H-1}PYgIn$s zTkc_0r0>i`45kyn%k0ct>+`X|%IhM)bBiR|oJ+B2MZg&=L3nj#NVHfP*X7d-T zT|358#E)?eJOgKvKQlpoT3Y(<@3_A^7qLO}F^D_xH~E}m%*-(0w_Uxo0+lWXZW+o( zoVtWEIp*I<8A<(1S;_my60%osRa7lMRn+D0aoI-|mHT@P5Ultan6Lf^M44_EOPS6z zks8ybiW-x3F(n%3P*xJ*sf0}GTUIPk@$>Ju%;39ef6H>eB?BqZnftPm3O6NWrQfqH ze9!du-Lk$V4BwL0v%I|Guzd^we8DZ)jY# zvoPy!Qi0#glhnnzVp#gV<;933q8dfEYi*r&+$l#uhu)W}%BI96Vh;EtaW|#$hl`;! z9YiUGeHjX;%oKfMUCicYW#8K#Q=G6|Um#w4{6;Y;7@rQl{C@jXi?g}sSEWi)V<`Udu9(*QF29Yc;>5izq+AW57t zkG~?!jTw^<`A1UI&*(hN#SPkGqM6CXN!qf+Cd3I3*D;V zJ7I<3M4&0(BJ=m$khFe~Ot8b?w1HA%%zDb>(1Z}QbJ*YZDB$YYb;{Z9<7pp0dy}Y-(_QM9WarYmRG47WnWUB}BQMQV2V;Zpp-~SAT;Ob`K zD(UL#5QJSU^8Gx-1yGCy;dx5m74L2Siz z6El1A&JJOH20wkr(A=6h){+lJEGpC)Vja~4C&jb9g15GaUmyL|^>;aL`Z!^k>1Qbw z0n;W6uIG93+)K6QHiF;@^jdT}3nzU63FgoQ_0X|cTPPvwxrB0)^-;Uy5iQ$LYpIrp zVJd!Pp3mjx*g<<5r8xYfxRMn#bn!_fm4FXhxB)^JqaNdgwuTl_C2yCxg*3)J8vh2b5wnTE0d0Y%a})o75(R>%uWal(k_Z< zEoMwAsJMSUQLgpIk70oUtU(coD3@>(?451Ek*Kf*kE9y;zBIHR=?|yue%_J#qx@HG zH+5liJ`IPMDo-V-jR!Q@)N^#Jf{&sv8Bm2T=;k?>e%fF{$IJ=u*Y$T!7vLfJM4Op6MLG8qFdg94fieg;c0aJ)J zmnf4iCLTqBI&fSn+qkJ0$Vy+oI9?C2Re~q7X9=VsN4aNLS(s>GRc&fs;(#sN3T3u= zoTXGGsq^X#8hGbICqXOFp=N%795MG?kWQ+gT9(BQHUSssD)Nf@5WTwKxDb`0t9>vU5e@J|V-iKezJ zI{;HVXCFYHC!zhZ6RUY&uc>0Xa$`9zQx$4F!B%04Fuugo>OYLC3tTL(1htx;$6X9+ zka3PW>fwIC6n8aM4pU7S>t~g7%IA8WFO=Ai0=)pcmv%2f&-2uhp*z@Ffzq}=_M_RF zSHo{?_AJUt5d)pO#2}__%HhqUcNe>$-g_9^NrmvF63)> z#48;jW>vfC^VGuEJMn+I^92d5L#uDL&E7Y+O8kH3&TSm+E!^DxAGb=)-NfC->_2I3 zX*x~|A}FI@>*;(^dL$wtsc%!DnZ>!Vw27)P5arg3Udsk+kjwGsijc$+&=eFD;Sk8z zsu0L9hA%2V8+s5s!uPpU1-i~ww`Qh3sb4;hzUek<-sL7gP1YXL5gl`SG16xhXLVV# zOP%d6-y%j-wjw8d<@+tb5u_pdm zlVyxKZP*hXuWoMB9QF%3T$K=y@-6;?Jd}eqinxZ8Nv3J|s10Ubvf|N2Xxt^d%Ng>u z>L`e>RJgN$CgaKC&Q{_H5!Sod?{VXw$}$r)byZiS44xZP#h|)4&X*dX(bd!1Z`8G{ zH1hd*qgT8zQeNhC zLbX-_xuU;EDw~ThU%GATw2*B-*7b=9381Ks^@>ZIC=OItb^U&z=cEtksPF52sp;1l zL(?nkttZ}P@i0XGawJW9P0eH)*-nj#lhQt7RZV`_OYVgr;)xQi<3)NJG%~rgYo9d!(@lNamai0xcJ`WchSj0_T!s~0eAnud z8d%H@BUEh66GtF;$I%sQf(Lpc7KvDA_DsEEm5o$XsGsB=Mi%!lhG^xS&M?G_^YPO> zT;`E%6G`HmAao0d5`wsC6QSTsXx6j7hAD_KPe=x|k(2UcdQ%CJr93YV%(lMhq^eN8PJ7CRroqLP+9+rx z{b=cs+*;o`MyfQ2Uy)K`&y-A#&mItLlx=)E$)eID&mnyS8UJt4MT6ih+L>=V2Ec)U z$p0_wSkc7U#?i*z#>C#n*TVHb?72qM&TU-+L(r}(iFl$I2{DmF#hNy-1T$Pk&LO$f zaV?uqmfB@uhZOsD%y$92?Ec4Q4`d)0CD zPf+Vo`0Mk5I~da*_a}?CVw)puPMe^P9sK1IQVmu{JmZ=}41fNGZo>Tq`DJTFjs(IH zfiq#4Z`}+iyldQCF^7<|IPI`7cb-oY6P3LvxH2Dq-gT=&wz2wd#NGE;zx{JUn zO8OC;iAKbFB2rshHuP^}lJWXSJPLs{g)*&d1@x3m(@ZKdenP!tX@|(ktO>QvgY@aV zPL1CT7hUrk2>1Z>l_ zZ4#)m3F~W2wb{VH()k_C%=p@b!I(=u@{3nXkiRsO5jFsA&f(i8o*Z;#wX!)KuUxb$ z{d#cjkSIG2KEKozY!@Rh3FR_*_e5@wYpePHowcXF-((>UFYo-_s*KQ>aN#a~J5mhB z$t+RMnlX_s80wgRJUr~QU2)zd&rSH9F&q2&d7Gly+V)d2CZ(txU;0v%t=PSDn*3zZ zOYri?fa1p~EkE=wt~f`E#;tb^l`e$;n}#N#yKlQi+@&lrLtNM}i`QDNaGMfBrvQ`^ zt5MA>WW0ZjZz4-vjO z@V52v;=RkI(Du@G-8ek}pb;8^&i-+BS(h>@0M~eb_pg~m!2(ApWv5cPg&Xv;wc}&! zHXj2Xu250^Po#w7YxiB8ih*lendip7BX(j-$tG=bEL1!-h$iRQ6Koj-F~OUnL*I3d z)a-zG{QKOU7?JtLbd1?)g>akK(gbyZId^u61%*?brm&qYB;Y*&*-d_d##T{+yah#U z?@dVbMnpvbMI8pc8I9^VN=5YEpn7i-gZKgRfcZ0|EeLrqg|6d;{G)PL=nr7CH8@t3 ztan~a>sNZ^B%Y()ik*-m318FoI!N({kksGczkHX+Xx!H7okw@f4bSwYx6JjKZ|GOj z*8<9W7I-H%)d?jcYws0xrgxy@KB>+bbKIe^wg*Jhmv5^&y2P{Kuc;ra%ic0(*_Nzp znxdhf6*)=I|Bb``^Sv~=77PT0>>FY%@xON)|KTtGFT;321!MHfD<{&89 z(289V_es-688J3zm&r||iD??o3)gkVZSEVrZT#3?mggm83xSJ?L1Wfc?Z$jJ;#dBo z&)JiYyQd>&5Xf!~6qD!ev2-SeOW)ERIHtIOo*~6`wAw1S^`;U-_$W>$1JaCEpV4N; z+5Pkv$+2iNzuh@C)FDntH9QOj_EhTdNRG(W^lKpxM%GLki%RJ3QID8)#vU>Aw)V7| zSCiLnL(vR_b@p|!EArVM1N9=ZB9R4_uvOT`D%qy#gTEwM70CtmS)|$HTpz_o%g*4k zkv2mo1P*d#(<xXt;(*tS!1IKnMEuNX~7 z(KjwnA~=SuAsm-k@6GkzS9(8mB*9YWg>sFUBoA9xNV`%9w@UsU4Ru~pPkODQ6T(aZmC$<30$}yULr;{*IH@n9v1IqaVMKZWZy*e~)eu&y>)keg6l) zz=47={!i>d%f#N!!u7ub8XE!7{usc=>kbRgWQ*X$IWV%Gh&c#UG+jItSWvNJ?R4`H znd}^h0mJ$yrf5jXhC*!;)Lk|El`bLt$J_gg+1vBq@3TE>o}OM@Qhr9Xf2nmMT;P6FQ7x@HDn-3Am)#j%*wB#-m)l37 zs2=7TtY`~$Vw2HM_Wd+mI9_PcyNI~6p@z7InZZvG{1UYV(J=QhlDS?|)qIFX^rT)9 zplsO8T!cu@#P)pY0nM#(VWddihpc3P))Awvi31006=Dr2t&J8Uj@BmhH!9MGg+Pj=7oeyCO!FCpnGhGHu!|?xgT+%3 zHc)}|C~pJCH4cb#;6N6`(o}_;pyHI_HzD=d-e0SzIhbiEI`iO(JGcKKJN}h;tYCxJ zK^H4}(sc$)7fU&})lk$uf1BL6tE*n+7#zrh;3^R{E(z{|HYk8eg@V&$^aBG}3$v&R zLC;tLtp(r5Nkj#Eo&sC_bI5lfT12LdQZ!+|+EUb6C}aorR4GDCyt@Hn3AnfjOkb`+ zSjuLj5B|>ls-QXG(LWK+cnqd^Aw`ac{Il~GHU~+XNkhuA28kZ}{9C15X^dqKN56Lj zd4Y5kncXBEu8ETdz1BI?&PJvM^%w_kX|V=Q?hmB~V%)%*ak;27>m;%pXhlxl0GPIn zu?(2u&tP33OI4-m0p5ub_AjJH?J!E`@Z;x!ky78io#TK`f9eNZHX*sNVp5WBkNO|; zLX0YUI*d3I@#G$>#AN$cg_S5K<;fzOh2Rh1bPPj}gnG=?a13=d=-%WM7f~eDD2J*M zCP8y#d4*|s>flhZ%_0^Sf9f_^tUfh$v7qV(n9vgf$v;%!N8xk_FWQ6I!&k~h(W}LR zx&&6V8Gh>o(5%qV5ZTLcM(&H4U0iqH&hu(;Dgr@c|IqXRBhz?4H8a`?$uQ%i(A9Z< zgr#holMlN>Awtqu(Mgo&gw&>pEGH)yM`P_{rV^)dllOU_{)mt~kc2!KW|vR;_xwl7 zRJ1IJAh&YB#+h$Kxq0wdYPVtnG!11(mq#t4iGv4!=GRfaJ8UYaMh;Yz4Oq0Fk{L;O z2J|R;vpaW(!?pmAQ3O0kI|>uo9OI`lY%^yA*0Ls))+CcY!)>&DxQD)6VUzeX4Us?{ zqCS#VxibJtYuHL`r0>?aytI-_#ej}7jV@bHt*N768!y^HI>R}zVc90M+F+SM^AE}S2v>@>0lJIWUr}6$FJ{1y|r|o+X>}TTt zlQ&lV9jnZW!>O&c^BM34DLBAV6i(4JGQ;i72CF*jcw=J*c<1``+R%8zEx9G zH9cplXQq3mx=)|;`|}v9XYFB6eDxDL2U47B8+?&5W*+KDBeN_!F=V3YzU4b)Jn&;o`X7X1ayrupp^y|sjDW9B-{^w`&^_!5f2&{ zfDtLi=7*iCc^QP@>`9=66NI6>A#_H&L|hq5%h%sELf7?IL0Yk#cx&J0n8XrHV(pys z1nnUqeZo1K6srD&-Is=@jC+w!g0Y@%+#9<4CcCNZ>yz4FPZRJrzjZD#BAEDHaHn$asjN&tGVQSxCb5WS@iZSJ8GXssr>XJCc z#T=s`a%p*}X>rwZxH*n_n~xDuUHOI)xlAO57uXj>D3ZGi&Ypp?tWN?X71@@zjfH37 z!2IGA#Wi1POYpYN3jsLTes?bCH@*vn;`3h11^K7R~zm9V36zU}X zKq7ESPyB<5lG{^1gD#Kl2TV40xG1cjQ3_8+8)THEnq}P5Y1j@3)sH1BQg%fXNhTipcF6ZGT{ZTV}wV=A4hlgJH4)7 zvdqVdYBqdeN0BK_o@~zXi@cySF<+j-TQuYa(m+OIHr?COh3G#`N0w;Bn-sFOl4Kf4 z7mO=|plB?OG3wxq+XQ8kq{JIHoO!Q!;XOb^3ZCe22_z>4OVw+aI46RE#)KWpJ?cn{ zNLRN7oXQ`v9@TL@LL*IRmgs2!f?A_8dCa&8$_8ptsS^N;oR^Rj1YyLK+sqtGaxs?R z#1=vlV4%JkTI&bLBWv|!1s<|xtpT}RQrqY=Evxw|^B>_cKxBU)cRXh-4Zp>ZR zR=jj%lSVtI)gVea*5TYFU7KG`W*f?#0B~|khA_Wij?bY+JfT40QGJP4-gZu>P;@4T zgF65KQcT~E+~%+F3n~f@P(zLBTkzZlF^f(30wK{C2yqA62bc!(46WP0lJcq3EVo zmx}IpggK)by{iZxeG#Sxa~)Y%MxS!&B1R4XZApCML!RjE)H1z5WhXbFOt6tfQ_Nqh ziCDpN@vGpv4+`;Ct0Myzo{1@(8QMVtQ5Mp9(l&J5PQ!yKI~x_5rjGBhwT2VT_am@7 zAnK-vEruxg>%za)NE${_9gZ~_;%FgTV!ntomz5m$~!igCy;J(Q8uOsU;{-Pwy30Gp!WL={%`CLJ3ZEK-o z^-EY;gN0WX4{hA2Dc~6@uABPxM>b0vMOwGKfyzXcS4?;7HKDPE|J<|*%tZ{zxo2Yo z7yF&kx|Z=R|NNS+7N9N)aBX#@|599S74CIMyz&V6X?64s{;R83=6}IGe@#*1xXbcm zwRGt9x?`$7SL$6F?=v6EQ`Msl>K!F`E&8%L(!G_=O42l7R^Wdlz6Q;HRwezU98Bi9 zo0!#F&3~^<+I72o00bK82i}!QekLoOOad_L8S|AZRj70)^YZ}}K=_^c{0e-9BxMAP z^e8~UcP;F3t!c%lv#UQ_#t4o$(mb4!pmF|E9hF(LLv*oUO7A^ETrU_Cefk%fUMx4W zJrQq=h!In9c4zLVd6Z`1UsA2+$WDg+KpCW+#QsTGJ)hSZFcmYLvh#gE56f0UaIEUV zi2aqHMv0Oza)}kZHnAN`Uv2G1<49Js ze35IY#qxU=n;aq+vu4qKXrQ?kPMzy zO+r#_R1ras`?t0l9UU=L8+J}Mj+&j?f{uTfID!MSb4%h(+pK6rDPx}27;Fr6?XE9# zOo*gTgMq$cbf~|d67Aw8;t?%}P<-Bl;TT!o9ptbA+P+gU zPWrS$*g;LW!l>T5Cgq;4w1v&S^LI;mZdzB$hU&#ed7caol113{AjF&}B7S-V`81{{ zqhk0=7k$+aYW$VY!W1Z+&t_`M;l zpdKdiXYqk2PEg5E*yc=3ox`R2#Qf1U9hop*jLDm%wz+}|H=5)ME3TIo5Ot=~F;%Hi z_2AA`>rOl9mJ*y1OXe|8oW758WaOTmhzbgG1V!fyi?USI`iOZ?(RcT`_muQ1n0GlA?zz5 zM6u!M+r4YT+s(}b?N=1xA`QO!+Bho+AGqgnf=g9D>9F&jB~~;|U06jK7#Wy;>!?v( zAkGjkozER>$v2ocD}-!&y& zpr*wwtXYYa!#Gly8M$lj=G-+NEL038x`ZB}EUsxa4E@n0s@C6WC&PlBn%80^P$DTZ z1cI@^4idmu;e*Rng;?pDCH=@QZ;-KL4K|*^owUU~^@)bTDW}gDUafz>m-p((XAQ$b z$0gR&|5<7ZEu{8f@G)^dLVUg5MOK>MKNBnTujSjee)gpS5zZYX)x>tgE>>k-Y|OwC>4 zL_kAmCL1aX3A@c&?Q%~CXL@Y17swNoa1rS>>Wqt(5l!bypHTW6)Rz*}Q6*`Tu~ zFbFNK(vF+7;m{a66A))j!i@aSRHn?o#d!?gEW#Joj50~OntN2VTEsjK-`1pxpJJR1 z{1I)qwQAl`s~OuD=q?Ev&s%g5Bbl`(wg>#9ily!`|>hK z;BL@972tQm)*6+0s6)%QIudP{lo$e%#}%G2K8^X-1+G7aIP*o*m0goCir{nOz>iYd3)okG`E5`9-6oR17UgBImpun)o zE;pjr5xHpEl`2%ftl{y(hwu7%i|yKYD-duU;DOYoV#?Kk1o>{2v#j1yb*2H`lS@in zzjyg@iydcg)>a6}Frle$aW?&4ys$rT#Gavw+n%}V&+M+I)zZf+FYmY9;bc>UBd?D+ zWsI}8@GR;|KFBh0JT4tRKAaohr3W(LcV%oxfa~DHt3jfO3%?jcdVmQ48*1#bX@Gvd zbi|NH-)6KxY>%Qz;s=o7;HMJF#*t;s1!>xcm?=t3H`{)Lr~K)_QInH}w{wATEb^BM zPSbr8WU@(=xUfKN1K>!x#tqrzt|`|p1J+&%P3z;!?8PPN7m1&w^j~ch+u(*CDH2}; zQzlsA4^fR*YISp_j`0>t89(rm!+<9;Uv=pdj&n*%nY3xLQ?qxZLA56(l;p@uDq7zu zq$%{d*`4CC*Yz$k(sc!+%7{?$>PSs!(X=OThT-v@)kyHQ62S+fFP8HrnhR5Kw_7yY zwIExEhL;Q&XMMgD?q0IHEIT z$}dn*LQ3$Un<<-itxG09UDzPPfV{4OF2d(~q5bTRr+!2^_?9_Udh_i{uyp&FLO!@5 zF05k)v`V)m0E_|}KrMQBpcg@$ZFfy(C;Sq94WgHCn?h7*OY#r#O@l-0ZU`{-ZXR+> zy%YN@|7c`F$(#Yc%I=g=K3|_IDab5of<}4+Jm6g|@qvF7vfV@z!UcMufh1X&8QUI2 z+RqCM@zP(%rvmMnMaMmG^wRNIqdFy%Z=LHqCcQI7^zGBLZ$+ku5d3z*8E+vO5>}`U zaA1$d>H&FBU21}%!VM8|!msQ1oywRVUg;>y&&LLQ-!;}Swnt(tTgv6S8x?eUWrU>$Ht|> zc}HkzQdHuj@Nt^Arm$w2X5!T}OTJ{I#xkU6$(0-iLn`P*?xt}DDLgA7%e+hz6ryT9 zqY1}rKAJMAL;VrLzYao2ehO2H>lKY=Khv^FiziqKKt*v69fXeS)HKu(X4lC~E@_i7 z*!ZCJig1%)@)!C zqgy}P#pMspa^$wR6dz4QNij)NijTkG_x)#Rg>J$iZ`bIVF9%DD1O`L4?LJM+9E zuTW+Q-9gk$ulAPiInAQcG!$HE1+8N%7Zpv@_8q@>CN=Euo4^E_O^oojQQ0>y)dxI4 zCVUINp|2+MZF?XI6^zT~ovL?0{&ku`lQ_9Il1Lmb$th-(>rNN0_>8Ef0>5jN6~!MD ztcSf%=CJLaPaaDiPK^svph8&GhjfoI&hf-E`#mG#cW~Y_&VL5KcMETQU;HgR**%WE z&*GCdn=r@@z~UT_H>Ww)Z}Q}oSXeFOEJcf(t=>g?w;vEs6g8CcNNou0M9rFQ-bp_b zoW?Nu0tGzeHzf~4rM<)t`Cf`j&2a$`{MwR76~UpAUV4X0H-JAo-vR`_XGE>JcW@kE zsiXNPvzaSK#49&uNGbpUbh1O9IH6fX<`NRcJg?;7%W+xJKYhiw8837e_hdBpOWl`{ zir*!rx2rD%kgD?6!X%&x1~2P(g}AR59!54 z5~`NW^~sl zUecO(xkJMnrazFPdEk$!!fOdRRO0=b_+P&RO~c_o7$EaRC5HK!(aH98;{wO}xQIg6 zUauxZ)@B?5OYeakpX6T?@aXOwk2}HQ&+5?Mj~g=@c-*JmpwqiQtXtjMM@UJE{yFzd z{AtM@h3J*?-(`&j97mt#FJV%RN?@Pcgl;A3?O>^Rq;h7dlLU*Yd%@$Y2TB9)>*Zxs zVu6ipbh3@lU(q){7y&Qq2u)-vQF#J|`P9}EQ7MDrH!%TvH|`!mb~Kj_TiM?W1E~rP z{*x;qc7!`wzhPPMelMu}HREykNb58pZ2O4oj6$80_|-|9MFsZqntdjKih5i4Dh>;( zrGcRln0C;0=q1|}Ym4*gawZdhSV}dJbzF3h5>Uz0%eeIa4~}D3^VciQhXUoeCWen{ z@P|Mo92&FoFKC*OKcIp>xy4@(kzVeWq7;bpsdnb&=8*>ig*%8U!ak%%?WM8GlD}(p zjZm579*;T|jF`+~7gFaZ3rcC=SI;Lf?HzL!%3p@q&8u1C|EuIOlmae@9l9I*o>@-4 zorH9aRA)q&MiHxaQCcrzmH9Qcu&brzBcJQ6p+q*Wk zr;t@db3Cc%>TIF-j6g_?ZE3P|_#2k=p2Iw-aqc%*i@)R86r$DisRuf#c|$3^N<4G! zE#~>65pj<5(rN2=kET}O(Sg${qCFgHH;`0EGo*4;2v#jntCUs#l^*r)rZvHbg*s>^ zZ6Lf-xqgASkN#nI$*5;#u)iYE_Ob2jx>vW`kOluIHB~>t*>KzCMuyrlv|P4LI<(mF z>!4}p*0V(|B|g^&N2IwVDhyuQ0n|3#uw8UaZp$bDcLb0cmwxXLQ>405SYoOXASx z{(hdN`<(j1v4%vL!1nM{&?AB}s2joq9P$ojs|`KV?Z5aRAw4haV(bmgpzYy<`)Z4# z!ZxXmv)?|81^{ue_}#!UW~gL7G~KLBX20jn0CbT9_^7;XVe<09nbL54+o|JNxVp66 zniZipDhG~CtXmP=>W3Io-ccdA1^8st4rPUbZx8A%5f{#`#Okh^JjtymMA)y$4?i0{ z&5+CX6fdPW){x;Sm~?J$QvRHKjJ2|l3nqK^o|Dg^BIb99iTE(bjMj87uK4M@9#oT` zK<~f8^QQ7lvI)3!zGz}cPP;L<7fn3|h+~{vL&(acy^f?gVu}aEDggvTP7yHdw+9pS z_H0s+R6jvm835Dz**$L&R2CQ+ATyq81!QzGt4M57RcYik^#wpTnF{UkFO*Vrl#bjD z8Fs{9Pw?NDVxmaF^`V#BpI0AIJ1$v~C1i-n?)w>ofOrO%V-$Z^cc(1wIHJmAI;g0B zG;gZEGx$k7WU!;)Cp-3sqZ*j#d|1FE(p)gxTeL1K`ZjQUdtj+O0AMGd%XD*u+S2a| zTiKgWQeJ3{{;m-?UT-^?Oe{R#@wtF1q&074T4tuIha)ete|+9&yJ(xO-LMos|FX*5 z_$}yiah%2N5r=qwH|MSnU829-t`btM86U4=_+4kqG3C9J& z!D35u#TdmAR^2FM1cXi(V#0)-!sI5ehl{ouE+NS{%UcSM=z22?f9o(WOfKp6;5^xQ z)_(`h6pq^?vJnF(VgL9fD*2G-&a{Zi@^&3IgF)Q42_26ikc8$+JP;#YG^61qVa$ga zTx!}Kp^XUPH(u*Ts_F9K_i=+Hv&S>z$@ls8Y;+y$$#>enIMRBzpetPo#8b=c>UvNkaga+^|aL= z0M`D5gj7BlC*yqnF^?9?F2*%?A%6C~U%~N^IJ}0$hsX{t*%RIYIVH7n@M$ zhJ@%;lZt!q=_YQV2j(EYO3Tl4G)jE$(XZ>#FV&WUQCX;D%4d}850t7- z846fx_d)%%KzCpb=E zJeyF5TA?R~g!qJ* zP*IK2dg<6nn3m^*{b~4D@?A!`m^`x9uTf347`*5x$l$1hSrm52(`6VP zubrBIlYn1TQ9WttB{IuDHNy^=C3EC*qN@_@2t&>tQVWS};jVG5IK9oc`ZL{&{jP*3 zaVRuNjb98*@ixd^B;bD=Dlmc&BlM6M22YUZA<6U@1zSdl#R;;d$)v?YB}E5=e(c+? zb0s^@qKYr>Q$UvBWT_#zHYdQS8OFif{%MITtN$3c*^JyzKjTa9Zw|F|df+01GOa1F zeV4MgD*~{WWQx#!4su$Eb&SO)hB2&30wXCc{NgKNl_1J{G58~u0&e)WOw3y1><_?g zTPx5W;8ie~MSIYiq$;o7n0~fLKZ^^H#dVf_y@naOb4koxmnG?ieW z*RR`P7%mfIu*qyjWFR4eP1H-7PTX}7%4M3-q3q_ovI6TC(^nsXD8UeRkXyd2m+CrP z*>JYGH^5pZ?jKvIKOHxY<>)qsJarDqig3ViUIcp(@E`e*F?q;YSBUTxSoKe%(}rcW zT?-WC;a<1@pzZ1^dl`s9O$-F%pao1x&%Ov0QJ&s83Q4f*m6g{b zDETVU_!fl{QrkgE{~>`1!xtZZvE9%TsSYqrIeY_&a|>eV-$Vknky$566Oj^E)ctq} z&$&b^8}+oo#484Mh)f=gv*zK=j8_sb3bOcrS%bA=E&1MZs>cuX3EC0v5t~zf=9Yiy zRiumWrP;-g)6J8lX$DhJ)rlYK8Nl6P`qjevHQq|yL`5IBS7TeHaF`Jko14G3ii}mu z_ab##mS1oT&fH*TbiN66ZmTi2b$n8c@{!g0%S=jo=g>Yz%*CT3k zM4&Lh3)jbp+}{Y0{6rlaHb#N4_#l~vU!u{-tSFm0UKIe1a7e)>Zvbb}-ijz9j}Htz}RC&lc7kVMBQNm+)CkS31-OV&8~kiOyrkhG~Uz5h#k zb8&pXiJ3Srgx?FSbSQ?Iz#s_f=C^{gl#brds6@E0ofS@*@NDYizZzK7AnAk15sm4^lu1Xy#B@m8 zQM0sm5Xbi1FGbbdd)ghs!*iXsKI%*H6yd5^^x|Hx$gry}Mgz!+GBOkx8@n>mI7gE0}q+QZ~Jp3sHK>y*i(CwhoG)j6{c4bycPxPf;n+3FPVGMo4hM1AgX}j^L!)3_t=v!y5DQp^_ZXkp6MtuC z>ho$wEC=5^!M-pS)YpK6rMt%eUHYI-x<#32{Uk!Lhg>d(fIpeA@RF2%D!IJDmt8^4 z0{Og#nHW6ZNY!x->2{JV%P*svDLGR@z1S(jdyHU;Tgl!E5PeTc@2C(@NA}y~5Zv-j#($A;rTRNUQ&gqe#@@5 z^al>w$o`{SC+;K&T39u$ zsiaLIqGyt4VbdcbKh1R>llyhwG4=jNHmKmHf*mEFJ;7k5Zl*23z4x)I<(bZyIwGhO z$AwhlnP!blFYQKyU^+1SM_k(%u@#-YCD5Ct9k4MAZeB2dTZT&{q(51Y)oYmfxr_Z= zffo=!(KwqDV(%}w-T2^U_5i+qI+fM|J=27kW2)lYcOCpB8q+6-_33_{XaWAp06xkv zmhS#4eR*0B;b(jDq^i{&cWRnVJx)5a) zMNi-#g(XVQf@C92f76hu&>&Bp+(@sdhAvn8hRM3sinyIm&0%JUaaJ@^{+B}EN=2%x zIU((r>C&c%USmA|mmLSsO}RvrW|M6Csn(@Fm~{ArMhU5k?Wz5ZWYi z;{}p$0jVOhEV-Ac$NY2t=-X)M; zB-~bI-PR}PwA{cj^d;Ck7Y_=%6blK85jp2_{{w|;{*?=bQpZ;*UbsQ2G3zj9W+J6D(#`t4*0Nt}%nne&?u zXmJ2z8?>gah{-NZR_0cqjN4~VtA>9&S>At_KmlYF3Uwj!CezKW8blQw(ITR)YCXA9 z7blsfotIGlXbbyz^o|~?wFSq=I|@s?U;aNCi?FaN`R$vt?5sIY+%SK zW%x}OT%JGA&neHJ*NMaWoQp;>w_29igErl)Czx5vk#Kx5EnZr?07Q>+88~v4|;=7 zZfRxDIoK0cS?u2}w=n;;mSbxE+Ta}trpqxMxN2`ON;zVdkl{eI2K!xui)k1>UW=`= zd9qg<=iwyB0ORQ&AAA+JMLlF5ucWtId@6R?WHu7{WJ9-J&n!1R7{%x>r#LyM;gao4 zjxiRNWrNVM&E99LJE1Q*xGH)T-`beKjP{J%vscEP><5i8e#)Hxj!<(hH*NNbWIM5% ze9G!}f&o+>RsT61LH`$3O)FmUz~dO%j~Cq{>2Wf*@lDTS;)FHzk3MS<_pCI@!k(MC zYbap(dduExAtdMvYWvT?TB(q6xoqv&nOiJ*UofavPX)d8&-LNPNtUYXS`WtPi>qFa zCw$I96H0oO9r>{fyUiD|0M=mD+o1N=$G&*Eil#c9cmH%`YfB<_g#p;MsE716!K&z+ z7|TeH{*n9_>}D15+h>1{HOgqO5DWcvn2a8Flrm8Hc*sn{i8Abt}fQVguE(>|*Q- zPW(E80!o>|n5oi_vxwGaB)6hVAeTK#h&6sJkjRK$LCW5uUu^?T)*6s0#W#f3i~wn^ zSzekoC*3sw*UXnAf)adhh0-2NjCgLPv?lC3aM{eYCHE$baEXvG7f>Jb6oK>ihgS%4 z=s%FrbGn6G4TtF+*AMIUV1qQ%JTn6<9ZlEjs*;uEhLz=tmF1C@Wu%qm?UiM*m1WnJ zWxf?Golp)sNGq;?CiB>zRa=0?B!`<0m%i!izA$9o&<9ch;C4Q<7UI9CjhUxD0o>#9 zDJw6byL?2ck8+l#1_fN=OEWh9rr>a?E?G(suIjL-#ASoIUV?Uozi|u9r_w023fv!jsFH) z{RTLf{z9mhwdwNq%*_2Ah0XN{Te8a4IeSkHwD2l{HoX&*$C?AT6^uAwe#u(U(6K|p z1U-~Tq3FQl=fV;Fwc8w)I)b&Vnhxut-lQlXD(G=bLxg*d4|GJmNikN6DG^B9xU68e zQ)(*tJ*7}Ho3Sk6-0~f|crF#zvLiK}z2IH`_)`8TQT{km{zzH=NUnS?HL&ki(enGa zSb}2F#EFGq$VC2E}ffGvwdTthL&ldgF5rc zym{-3NGF-iky1vHiH0y$O>mG~34@P>g$IKw&-!G@=!2os1XM_n^xKEa@8HO~AUyV3 zmJ74`V%rjZ1xcuy5>7jY$N3f21W_UEupOhO^Z{& zt#bWc4XV1BS8aSP{N|){mlMc-nA^vX8{8ze2oOe2GRo~^^S=j{q2$0D9m}x)w?CEq zwhR@QSxDZC@T}@ z6u^@FUjN9*Lxy@lY(8pHmYfX@d!UD%YchrsfI0iy;Y28aqF8V`r2PQi9%%rpxe&AG z4+`G2>hJaC@2GUby_#GyYIl{n3DJ`0AjQpP5+*JZD4TML zLH9s)^-DhRwGEPV!nuHQSJ+K(LJX<&ioewOpVOn82 zNt^5$unkY@xEs72Ge=;^zK4>@5~I0VTfy{#|Is^0V7HOR{24z888@*Nr5DV>jhVg2 zA-uEg{KM0?gU8huAbzr{bZ;5UeyTOJYmc@@jEGRJ9t|?aobS-`Ra?pH-+xub-XXi{eg^bc? zRZlS9CqT`Rly~Ww$f!16tMKeyLqR7WAmNZh*H@NO%KT9UIpVa#^Q)Einx4B%G%F7m z*TW%E)5h8ut7mPtIWvsvo-I+K=-(K{hJ`tOjep=aJZY*mh%*|k#PU~9AxBOV<1A>C zly2VyBmc2YSkiqA=Ij@KjdmIC2k!DVKNB^+gw%`(YQ*^0j{qoQwh^(To{^h>alOoR zWWS@gW%JW?O=$G~f!my&S$i5DX_YhS%Gk9O|3`-^N?(D6xGozQ0|L`Nn9+CzeEOz3 z7{Y81KIXc0UD(k=|C*sfw6>^67;R>?m_}eWH%9n{q61TbM{kbt%$nJkWqn}j!V6ZH zt*wJF)sExnz6EuttDW&7;*pvt%Qm%Cu!!1Q_TO00A1$04e>;Y<7o@e%tBorrWAFA$ zOt8KLyguVOXeKyBOGK9}@Rw;A1^F-xZFoD=iW}7Xp?}p#@00AT$t?)km^Ag0$x!9h zWy;ze6cXOQ0!RY`t+Rm_Q*Pa3FoJc>66sc5$;`byAo zwqxApv*~@4{oND7ePO?NhQjhm^fIj44ga?|$_jQofkXr+e-8}NBt>9 zXZABRIlKcaCq^&R1zMbAD0?rq2MAFxDQ zNzm@(9X5Vz&H((J30g6Ahyt7M_I`r&+SY|)G#LM2du&kNKIC>$iVK^WO;#mN%_Mhz2fT;$&_Fev8;L~B3BjUWox z2q0ma2I?ct2RQ6txB46RH8?Rjn~dwjkj5DK(K$R|`6nd@Fznd*N07sC){Iwh?=%S2 z1?svZt2X>dq0B=<4>d#)@sq?syGoMiG&A z5n^KXgURRF;Y8HGDf9y4*NNe>y0dj$c6*YhJ*cjTtVd!UuArjz=hGR{!R(c z$*CIHP4hA_O!9!ebI9!j0(Qq~!lU~l8J?mFugQ-67%Uw|BDt3K?Flyg8+xf_X}5T2 z;;U)W6>4Z>q-%EcLmzG3xsyb9{nogIc0pmgpP#!ixRT!5=vu88k&Dx+mUUkLvUUL8yd=@82Vh0>Qfl2;w&H-; zXj&v+L4V-8p1L?C45)>WzzL`66fXlUFiT`e{c^)pbz@g;W@nW6iHoV3F`;`u%_4NmH zO2n$m(YG%dVpQY5$x4zq^&w^r2vcna$qApSnTVkL-bz1ehJeD6G4ZTPH1Ef_yQJol zsL8Qll=r~eyQr-m6PIG4wVlZi ze^%HQ*|scj-O$eN!u97gKo8Jv!CW!#hn$C__FjjI&WFT@qXJ%spC4DtCbr7)V?}k` zV4aN^^O`x3A?p*&(YZF~XcE}o642fUXBf5+kW@oN3v<~GRnLFnruM7bU7n>U_h~&^ zg6_e^kc*PKEJCI%ej#th5p0$aKDDJz&WN?nO0_Zxw=#*hGPO4FZ4{a`i-fhqH^t<* zqi#7Il~GJzra5rv$+Oe$NEcf0fx$p!&3aKny{ zb*M3!kz}-tHmfH8#F)tJZqrbP<&Vz_?j@4wAIu zxvXJN2^D;^byHcd9Q8?!v0q$~?nagYqp7l1t@!>Dr~G*+n#Lo- z_cA$+alyL=lR$ck=CnE)tux(2*^gb-Guie2pt;&x1z2$0+CmC)mqUeq<%g8H)_iH)RamNIW1Yq`hRMwiQ6y+&_TWan${zss(s*C?>WhB0$U z_+u?%)=*Kzg3#C_!oMGFJjKgd5)K#OuT)pq9Hc<4fo@ZbX=OKwd^GX9eApyV?xD9E zIg@bU6S}-H(-8j?JiS?+_CY4Nbvn1`_eLH6HLf7w8b?tqG#!Z^5daV+B(G+`c4@+| z+izLPv+~DSTDl1UJk{I>0L)f5t}!hN7Q+XRYPMf6WoEAA0ov1)ehMwHpuwd_{9tGc@w&sE1Z&y23wqKCzpP2WJv&Ix}IG7Dg$}NV2 z=uc@SJ4qmaGUu7g5&R#2Rh{jjf~)??P816Kg3;m@RrXv;TbV7%z2LafwudZuGP>!gccD)C0%; zbQw^elSK{u@A_SyyRuDrxkn5)#B#7z*EPCavlf2Lh%8lGD{YMbr8-sb$a7IhHN-Dt z*4N)={m2v{hd*df`cwZ)fhip(_R)@7E1d9M(&)+5^HjG_$M&d(oWz{zVbRjuOY+E?+L<%R)A}EQnb{_a*lmZOL7{&BPxQ9)FS6|k zI|GZo9P$JRhzGmlQ56C;6(MUXFBaulgJ)p53|c^DO;DZ&gg`^kt{DWISH*n)h$O^I zq=OUNEGHG{ZEcfai@r7ccHhD_8|X?WL~-DZ@RO*;HZLLK$qyXy5Q8)!p>00JaXuyC z;oaeZ4+~V!iuEaa5dE?b?d*E|V*KAu&AW0D&&o8);`-@{I>OJNe*%MQdUiB?dm4I# zD83~8CVL_I2QZxi_`#H7==KDJ7w){0Os@P1ji-&H79+b!Ua2pL&=Ul!jMg|rap(eh zM3mfN1jN?QAqBRH9_;2vObRSJL-Nka73W;HM3^2_0HBvEV8RUx05oz1gb=)f^iSmj z0hOGC;|1%`VLB&IU4sp-kUJ%xtF%CA-|^rN({FUI;+;@Q_o<*8KMUZ zLjnNka9hOj!CG++&=Jx*xw-=Ps^&R&?thsBoOJ@+yZT+`0%yO)l7g82z`gQ&&SgCF za*G%qA-}>Kc49o3UjgfG&A$tdk$rmViZC8pu7Hkr?k>T-14Iv!hL!+O_O{6G)%o}Q zBAXBNr?*yd&a*S5cQxZLq<;b*sHWFJaqeGNNWk3cHeBaA(SulTNDk1mJ!I$a`99=F zJs$|*2g4^Kbb|b9ZKwnQ>0bf!|2?_{2dof1O!e+4&M|d{1Z=O4!M&<`&N;rk@``*d z5;CGsoZE(rki z)gJOW&$R~k3gbD~_u7~P4D^8M8RHs;d-c?ugMV(!1r}*$916ScD#KWXb%rS3BDn@X zb%d<=4dntqu7HbvAp{jS2wGTmez;;#`8SPLMk@9Gfv72Cjf_ zFUan}SBJHe{aRP z@20_dzRLxkc7zxl&^ZMge7BjEVF8BQ!#N-aNIIekc@k;U><2zan#)cnSI4p9{L|?0 zDn_Ju7Ws#q_>7>i=I@}mrV`M!T@7^I&tcMrU{}{CL;~$B%qBF7uVvZ5% zcSjpBr<;>_ciK34Qzv*qSTrlyo05e zGWMoO&oJ@EOxHB=W>1&Ug09DW&M@KmIrW{3KG29hMUpN;Z(FYyZVo$jtd$pe3{S5# z)(Ag!-oOt%CDou8b*X8p9rIXLUp?d_kWMOHlG|X{--tRTNpESg9%}w$N?i-S{jlC{ z*o7mVpk6QJX3W%^Y~_0Bj)FeBfgf+`QY$a`cu^}ax{nWOimm>WEZw#N(}f@7cq#Z; zTkDH(s;S|fc*^zW->HeW;7Z`Y9r*jUG(FR>3rjkVF%75#cj~&n8&YoIt3>NF_Sjsj zcJ$7LUTO3WUiuhuimo95EnU-?=E#d9y++F*_o{HXa)CY&&aiCEsouC2pwFhgeL2D=cSe%|~|JrfvPLck4@Xmq$ z`kT>CANEe%??RXUM+?5gE@J5m;{USd{$|J%nS3*<7XLq4b21L*#->*Phc#29uCGKO zg(+a#Mc;}eofBSKDnpRm`Uza;ENC7WeQ|O!ogf|8>PE>%vuoUGu^595ko|)4Czbt4 z`?|5a*j!mz+GEOu&6!;uPQvo<>LSN=_CkQ|^YYJZ-w&-}QwSF5sf^9^?^J6-K2*I8 zK8*;zJi6figFKg#7Gl9#S3KA(QShI*nasvU$;RgL&wn}r?LEI91t^~|hmKm68NR}9 zaIsw;eR>OCUi-HtSwp=>e?A0sem3^}N1;60f;kx^k@idL(T*k0mzBNqcpat2T z@tQ2x9N3igqFQg3jFd3U$6VFINb{x~&$bO&Zdn?aU^lNXR*QEn%8&6+Yt<$l@t;GD zt>sG<08Xh)i2$|R?2ms}T#c(#@$cJ>_e!H?Z=uBY zFNrT$TB#A-S>+#>)IACRWi2s&3jRYzunl>*ARrCaQT5#@KI{1Mhs8x#k49ue8pE*N zeo9Yd=sjMLFWukV+CEyCpWQbTz2pWP>TwMa3D+{s4SyvUsAef1-qT~L4u73>XLOIF zT4q-J5@zP-hq%14UNBtK@I_qyXXMB$v(+jQ5x?}|>F&40JfF+uk#O0}jEpmM;gtQ4 zZ>*+Q09vVI?K|^$n6ssz{o?@cI+S7p$#V0sl8z=&)qx>D-2l(>+Bla#?kEeXkIr7j z)vZ8oX!k9>cF1T&AfdC2$v~tv7yspNyVoR#TLem54tA~$QSD+)M$o5R@V?xU)%4<` z{V)v#6#@?Ht=KRMbwYvgVQ8LZUy*djx?u>EpG4BW2IfxWU|;;OuFA6o=4XQR|8Vw| zL2+%{x=4TkP4M9E?ry=|p>d~i_n^TVcMb0DE6auuD3qw?sxW>D703_+?6^8i@sRW@?oniCQ!9BYBX80H8 zbaiNw^r0tDudqf!z)>jFPo(hf=ov( zF6=I6f`EVs0}}~=ff4?n@Z(53*_b(5fGpL_{!JUH1oHWBx|}rN>A(4ZuUDy=L$n&y z$gW5rRMGEQ)EQ-J=HzhMqs=|n43pEQoHn<}Z=TyOUSM-=pO?`~xg5(SYPrso`aH^B zlXKgSoR&Xf6---RbawjX^|_x5Jg$iKy&&#j^u`vv6GaXrfPF*YtHhMQ(`7D{W#>Mm zff|)uL?GCH7G}=hmBxSZJawt(#PKG<4txk;{}~Soa|pLRRD&=Q#RI=bX^A(=ki;+z zS<3RpVnDDcIe$=a-PGDUj?&YE$K6$R(-xaRt^;PP8c-QMfvLC>_I7a@sw{lUHoZ12 z(Ha~9N%zAt&SGkhp;5X~fvM5%FH@X(UunT;313Dt4?Q{uXS4MNG`B$daKq2pIQ?zo ztFhJu5X5{>!wmekA;D!gfe8|-=fCa|btWk5gsRltZE>_6z=+m2o7A)3@s86|A3Qkm7q284hf1t0L? zvM}Nc;9Ze(IlE@38k);=)ti^3)?GSyijM)Fhd7eV=_>Vmw-!I;cXcI(1BnZ=$VW!r zT7#*oQ}_0pNSN$DK*Zr3; zHfVYbe|Q2wF;eq|rpBDdlCt9yCUP<7uuD?mi9BMooRpy4=i8Ba5{9oq^1~qYXz^U4 zkL4H;T(G4_O@DD&;fypxpFZojqc+1;#gucJ01u{66@mJOwk>w4#~iD#fjbKB6YZP8 zm5S0qjp||?h$lF1r6_u+Sci_*#^SpTm3SeX36{dC;0)74K^hxgrK&cY%^SXg=o}5- zJsxr+FHT^?N=5xD$?D+lAj4YFj;A4Ig@I#EbV7zhN)gwSqXKT8?x z<;Ix0dZBB4IVC0B+q!GGlGSklF9UU$#qIGZElV(wMI&8K));~{WGc%;u8s3Yiv{QPX@L*lH3(@5Eg zThu%>jnI-?40`;qvRwDLI&_I@emAEX5%>y!6Q2@{==+XkPcCQ&HhDjWf7#z3mTu4S z1tF(M`4@ry`@|FUwm$)={NLzW<&+-R4m>Qr^pELlDd`xqo*OlWD0~5O(O;qzZw7Ps)*X#Z~ zLE?NS19i={xMfw%X8uZLl}}^2sv_D!7`TQA>WH7G#V{{tytgC9E_0dO=hCo!gVlW{ zNJY-(T4ZN@Zfay@g&&Ryuow9*^6Men=O=*KZuYgx5t{D>rqQ4Du6uVrk`*k>Y}$R< z2bNwqFDlZD41&5&?>FOKWBv{=_Z{%jYp^gdm~UWURQ@OM^53xXA2wnYXD171Crglz ziyM@p*w)$Uufd{*kt()0j>v+OcOi2sy0jJ!j>JRZIjS?haTdmkmc-yqfG#b_Lug@A zh3HAO_i}L%DG)|%9IB+SKp!Qqyt*|x-Qzypd6zf2RiEDu^R5xE0D@u56)82&#gwAt zl42-L#j4HN#Jo3NMk~lPz~#hg_Ty3wbtmF&L%++;F@lpD{^!OfH~J#DhmSeYbwHq@ z0pe?q);uZK7u(;5`@}=Fz12YP(scZ)DN5sajUk8w5=FA#RAWh@O%lrvx9~L_{`WJL zcdD%lEnPS(RFd+QOAhSy)ocio#dK->BP+4Q)g+f?j**$FwctBw6W*1@8yRBt?NHh?9Ao61M5a; zG3n+%HeK<(Zs~~bE-KfgvKv)pBfB}AnpF9OYj@$EU-fU+mU!kC;cNQ_7i_KN75PeT zpzzw%E|7@^hz?Lid!yo$T5x3`U%oM*-t$tuik$__G#ZWfmi7r%*YO5UQU_#QGj$s3 z5@)#86_+LxrY-9GMGs~BSze&KIm#G+jY;-bI*yiX7t##7E5B0z6>4bK{9&r>>MGeQ zwn<39Is@R&EYrsEWq8l|uQAHgWB=4!XqqtujZ@hECr0#d4nJy+f3x_tYOiT%a^Sy6 zpc>JKqz!EqF_$tU;ove9g;Xq6#q#qTf+gu?(FJn9FBXcX8NcNcEWQ&B!4r+%&u{5a z3*TP-{M}#v<>FgP;GdUW>`%7B3IzyB_(cpYMR8`-YBaLMTms(>h~ADqGXri# zQMn{VIHjh0-VNjzz*L z^<-Bs0ngL``+7}OaHX(hcinj6#i}5emfZ`_%?#HrBF#w;MIRwN6AodDYX#wku23C4 zktw`#RX!sAL&8n4h6HZ;Fr_9_+afIuTD-b~lA;C$s>ivLYb&vheGhreZ}O&E#UPE- z7i`&|UA%*QGPPLVuExBuEU^9f?3BHSaBD&0!zNDD($-IsJDt!iO-cP{d59U=kaV+ zf|6|9C~aK)0a8cnr19ko-N&NsF)1fpZ+wdo=bHQ+ z@bKpGkaO%xZSmm!MgwV`zVl6dt2sd8$rWRn*+F?uV~?rZ%eu8kT(Om6?h>c6n`6HI zUMlY1Auo7@T>fK{sYCj>E$;Rm2OhKjpwWX&W7wmQO|d0V>^bmnf&ZU_H8^6ZQ@wrr z&xm5BKo$;OW`8A?F4Z>p*LwU?)?SLIP#F@_qg$V5hVwmG3``7bl7za4SnNBjE8r;GUBx=^<>3LXA8>B-mg6|S z>IAZfrjv#CHLbI7rL%=)&gOX2i=|Wy1)R`f_crar8+Eis9Bu%|B--12eVnqTJ-e@s zMvZ5jfTb`4Pu}n;_FS&mr)1exnKmnrr52-38V?=hLY?sSWZrgQj;H#3qG^Ya&5hrN zr!>{cYA}qmP$dpH$x1FIbwpXwqb1ETj&o!wZQFtWi@fN#1aH z{!y1YF=%ap+3{rhb#B&ON75#DS+kE;$z0 zb`1{F8g^=_@*sk9g!#LrS5m)RO~%S!59fT0p)Cf}Wi9r&8Qm>9R%)kjg2)Dp@iqXv zhIzCWo7~d5qerjW6Z|CQwM|FH>x_vdgCNCxBFhW$9AS~l9o+ItC07&Q;CD}YlQG7`3f*QK5`W553cM6A zL``L1s{~Z$3NwQ5qJrm+xkYAXk5M4sVI{*S_b=(f#1hFMS`F{!j`$S=t9lTRT=JM( zmD&6|@m{1={Yk@Nf>`?LP}lf(Q@&w-Q@(17pjfno^f#7tf4Hn(#0?KV%+nBmL)Y=Lyr7RqpSqzg1kOpGvl=ahD_eoGQa7`>ATzuL$AkQD=W@0=ew1`6o?a=Jc|5Zb``rRI-1&R1T*TW z2+?A?dy8vudklB0D73KD0Ys6drsUHN{NztRiuT%e+LVQ8W^RY_W-#iJ`+l6g%`kIn zGn@v(&GUA7&S)sFWOPHW(=dSA6-Fm+M``U0D2T~`86@q779E|IWGJ4#VJOwW|4KhV zFR$k)SX5lgZ?JaA;v}$Ht4D*fKu=85F!e2*l{#rSGgt{_pMQ*ffh?8+m|Ay(7vgq9 zRFz`{<(j%Q?RTr00N;p!%;Cy4`9m4N9!#sJb~ppsZSng&U5RIm2d8n4W{(Ki3;fnQ z{wR1ZNfh25N0RG|AN4r~bYt^3|ft78t2! z+8GqUBQ1@r!QP{Ub&9R@cB-xQteJrEj5Gp`2Uo`KZ1V&P&g{}D-9*LQ(fsFXvxvv7 zZdV!mAi_h$UGq%g)uQ&>XWlKS|7F$#QBlRuQ=5C5Cr`7e8)@xX@3Nzx4$M7YoKH|g zzt`ib}H3poUfX|e^R`mRHC{c?6>j! zT&H8>NrZU~Lxq>%FYz6|Q?jEff#MI*%BX5fJk@%}Eee7+)WiYb3C>|ssxqnV&|l^`U(V*g#fM>@?G~Vkn*Te-SIiN-fI{-kS*W@ zXN=@b|3q|}w|$rxWKs4Db#P%z7JYt6q%2lcFDX9e1##j?c#mn=C>;cu?vcp+`o@v; z7@{e8pGfDI&b$@p6{SRJkwtN8NwkJ35Z-+gG+iAgpB#KtB~ zJ4s^y%#F6FcDIXg*(l|64oyqC$g-l^?5GFee1+vL`Idmjx*>NOwjgw5zo{4VoX`p$ zmo37&C6vN-=IbRGdtEx_p_BW7nGz}qYqP24{t?98B@>nBpZv{`@uWpBQT5vFJb7rt zg6$t)PQkRpIDX}hrZrWIBtV!tD_abYUmd4J`|C_D`s!pOyCFHVFrS(BiS2{R$!^pF zm73IB@VuZ_$;@}@b9OwxsaKbg!2N1s1_adLZKIL@}yE+oXIRnK2z8nc3UQGkAVOy%U(YtZk4y3rY% zu+cF<$=Vg;7fZW2qQcNU(k)bdpW!Y&qkXJd_a3LbG^=}7VGN*X)gv-+y~J~UWHNdy z@DUAN;hLhD>D|`(B!(f`A(rPuGLr*d#UFN3Qa35XfK+#{HMS8-uei%M6JmeUO#Av< zoBUsy^z7?Z{I2* zD_;c`0e(|okH!wuKF5`${wC`h8=sXHBPYZ4mBpf+8mGaUoa}^Vv*;&39`49sgnZ75 z1~I68F(Na|Wn?OM1PKu>Shbnwxp&3~1^MZBU{@+6#ckf+xIli=B=kRSI-$)S% zV2P_d3r9)wsmtULAX=+3+6n?L2z!ROyUm)No0lA_Kwvkj5hhV!qwzHq4?fyyynid!m7IiCZAe&c&vqP+xa+2R*E@MvWw<*`W^SX|==PDFF{07dcx`#*d zPjWns!>oQW$+iIT1>7C7^AWdjzm?Vg9tCMql!(YMwmFyZ5YX%~&&yB8xc)WEK#=!) zz{Jm|r>=%(To%0ff<&MJ7qiheR!|>B-Skkk4=_?_kX6sCS|l{6JDaS+SBxuSDu?G{ z_^Z1hM|AHf_Xan6wK+F0SV#8(^{=3R?H+jkuaLVG3i|(K!I5`@t~k)WcW0}=m`-iF zf#$*os62yWAs<|L(dZCS^g1e`w0KF{gciYRDnt$`KcnFT`IZMS13cM~b0Hi5!_H1M z+4vQ89PR|DM$$T2#P2cpHP1cyW@M)R8;tOP`5O{|vqNhwYK%~wEq@4;g>1d6rar{g zgVjj!q*~lNjY+oRs)+^7z$rR3t4Mqy9l@Y$uRpFB+Xyp^M+yU^>yTlP8b47=@v|0Y zbhevi)7w*#8|k`op7q;N*U&+mF?mM{Q<-93IilO^=ei&BJk=7;YN|h{r7^5$H&PFB z6&7YgjluL|m8*UdoJu9pM*?1H7{1aKRScclZF~p<=N6gHe5CbZW}Oi{a{x9;jRBZC z_OM@N+*<-*HO8KE2I55*G|7_L2Kxxb@j6cCa)pevHA7#K5KQn1Z}4fEMOWL8VfH%v zj^J!SRDknO)hdGR_WEC1rQhf2#?3(%I`~d?MC}~!zmlMNb4(`+i0O#7N&pKo3P*JG zRyk^w4?upjp5j$KSicth!EeEVYlK>04aR_voo2_(iQXuVW2r@k^-gcKcZuG|Q7g86 zt@W%^swV?@bqSRXsC9%@a1F*Bw2qs1UiyNfByt{(=t3Ahx#*pfugP|8KJvfC=iGz` zw`UNnvhxAdi&v&0(tn&;@|#b|n_jy+XxGg+057>xg6@fb3sq|;ECgOTP z#;D|tJnjZ=?RBHZ(>hkFiuv|OKZEnRw<`IUe|B*WCZ7lp-V6Oq5EcXIt1A>f;dK@i z5eu>r+z{tpeUxj_f*n5A9^HBFs_2P$^a%RU!w~j#b*_{g9*-f2_$asauH=~XcNxS$ zE~SZvZTuLW`YjD3q*J`;~PuItx6MG&VAHa1#3_JNHRb+n=LZza)>G;bjhK3 z#$spNwqQNdlV(OV=5qEXsAP<+@D)o_D&MK*GTx@+ojKjDe)%C9%xiQ|B#T^Y_@;Ib=8p;{w?qmdHTD&0D;s zxRR17XOq*@!biF8+iSn?@-M_-CQau);DsLe(kQNO>NFjrp5wOHa6(m-{J-tRH;J6u z`aGuk^b?3OnRai9)b>>Vg%!NedH^w zaSg)YMF%W}Uz2q@LGI<2ps2HQ?AD~{UG9># z`(syvONwhg$qpzhRI_PlzSYk^u=NhLku{*wu%65!lil_G5k6v-Z;dfI_=pEnw!*2$ zNt^=6XB=ImaJLV~O4wm(j+H@>j8x8T`o03su9j)iN#1W^0p)@$vCOn{T0<=^DAM#8 z8_k+)aL*CZ;&^)A{My=B(7d#%nc@rFw+374bnlo=HP>%y6^X#1bMGH%?w@ylvi&mqpr=>Q;~&V#S&Wde||IOsPcqY@r0P;Z(XG7 z9CR6!3GG;FgiEM3!mc~JLYw|2(z(JT&fKhp)|^LGX8A~>c-r@HhmsdBcc0Vx3is8j z+~cXf?4&V{p3$v8eK;x|n(dHdTf{t8#R2HJ;2L$vc(+%877536zoW*VskftExe!kB z$*Fy-Q5MHyuqzJ{Sb?8JdsxmCkg@?B(@lP6JARFlWBTFviLh1~RlUo4msZ5O#8NO! z8CwbIr~JFA#ESje5^v=qUkR)Qwm&Wb@yoIyBBivw=JysBAM@Wi^~x?jVUV*fmhlYY zcPRJ$Z0*^m&=chGc4ZqhMz@4ZDva`GiT<61BTX26zAv76Kw@{>JEGag{+lqgG9OwJTZ%3(qOd-zcG1trz8~qY@hE1r9 zQ&*+qRSY6*`AK*D{5Rb?*azg;5NAO zsz;8}kKCQ#AsfymE*4S@H3(VU*LD?D#=i{%#pHMDxaWS#M*vjvqGz2Wd*d&omg&_f z?ube_FI;x1kgIfJ`s5HPpXZ{CH05{6ekn4GH}eC&7qTWv$O}8Ahto)}vmiwU#7Kea z?cHz3tvmE8`kH*x%?wmFD%45)G=3&{z?%_iXi8IBdKyZ{o9%MKNqXX#CJ%}Z1RrC3 z)En{BHIp+*jnZYoo#bE^?T;Y576iJ+?f&*)z)#lhq&H}~Uzq2NK_V12@8GkzLJwnu zTbVFLTk+iNrvprg2=H2>finVFot^7rmQW^Me_rA`BcuVGb~Vx3J^jIOlD19XB#vos zaooXw5}nUn#KY^wwm0g|FoGeAdDe1^6*T3`;RE?zs_307 zE$%3uLfNAht!{6-1_Pm>lBreojK*P+p{ACp=# zUJjs`rl0Q@d3}ZGp&EyrwgSHw-3%*5?77xN9 zve&s5Vm#<#F1n5ChrGkzm~=T5c5|Yq zt$Pr!<6iS0^)B-5Zg_bPx_bPiIW9@>F3vJ=g!5i=mjgFXF`tTyn3N2=7jya#XV{t+GbvUKek(zUp2)}^QAtE$ zGR2}oP*zBCPrXaRHkUt%{JL7QMyZ2aPT3+%rB=zw3%>H&q(C}&U;&#a02?B##$Ba= zJvUktUzkLIksAG`lv4agL|cxQVn|Zrz`k$)`5R?{06`7gY<}?&#!ufM{WoQW65J0` zeKfk2_A$|05k1&tuzPDy^^%)S@Pzy7QKV)DX~(JhV?rh`MD~5Ag-?j~rDB(^fclBW z?UM9uT0}WkigGq|`e`Vulus;SVGtfDl}c!F1Fg9^hw86Hn4zKw&#uVV-hoq zvXShA*k5DpTTkWmB&hzG6|`0){tp%k6;B6;zeLxiTK}mr0>|4XB5I44(WTTMgKH?U z_Lmjr!@^1y8Cx#~I2qtKwyeB1`cppFlO#m=^4YOT1xIA}0EIJLBsdU50{fm%^b!y|uA2Esib+$Y~OAI?4D8NrU{M z0(-ZAd}rFK>-J*;^3A@mJe76R5re~@9()Vm7ogSMW}q#(`>$bw>%-WyBs@z7&bqo; zCUG?6=n79W`>7>CT3Bc_LWU$cm-tMIvJbdmpWa!NUKjllZOh1l126RD)D5$WL;DOS zi}(8Sh8DU6m}N8~C*6#3%vK(o{mO{7WP@-F1ltMIr&{Qf5{?;noo4Rkj$by`anqg4 zk_OJG&yPD|`~X8id^Cgh$#|}onQuR9dzbXohP3sLo6Ihtix`AG3rD<>EP81K7GM8) zB}MJhq?usXPKmF$6Eu+E`ID}kq%_sqv9+gw_(-35>0L5%d8h$5Kdbv9I`9KD5;~k{ zkbXQbTxVRet~WQM!?q^oGzOv91#k^0ka#34=@Y`18`|+sp%f}RJZ!FS>}H~LQ1bd#{N3SIBr`*>l1HD! z8b?#*9-ht6JZ70_zBqlvTdvTWw-lG8`^dRm-_;A6VXCps4ivwwDFne9G|~+dl^JV6Pd;DigzQRy}>$oV9Z)LQz5D{^J}67s3Mzbg;mLC8z@eL z$z`wtTyLNWAdY0A(G@C7me8;HbmL%(s`3?oC=DRMJn~JJN|mUb>CL(UOChAJ10JkeP%G0-6!qV^fm40> z#co5h@xDrKxFe*>^B!{HblpPHB5QGzc9ZaqU3eIu(nrFZ4H~8nb3HRfM3SoEf8{q4 zdOrWopQlm7qgg_|I0hM0-m^^hrCw20(^X?26KRZA?g1K@F&h$j;npcW~A#m$Q- zVW4cJwWala$KWn8hZ!{&5kyaHQs5AjE_F!c%e5v6@OPxJRJD;OwwIsPP(si*o;PXf zMkLweb9z~jQ zdI~eQ1#nq^66bc3kMFazGDMrF0zdExj9$Lm`g<=6v7C_ID->Ed{$cj0>H=~z^Kkxq z$@IUpH3QFikMR#2>FGmIip~+};V7E~!Z5LtzeWO{{2BPvj@J+Bs4g|1@a_?c$pC@S za;d7K>@f3SI8D#dX2y}gQQlF@o!PbcQPJ zID>eGR+gZyA&~ay6-mrQ^A|^fy~QYs5MG2cMjR=Ebo~QHVA%I~mH6~P_QbDNotO78X8^Q)~dE|E3dm7<;>Ce>2FDf;Of8EOXZF`U@dQ$uPUB`mh$3;rWHu$fWEjv6JT<=XvKlbReE+?Hh^1x|?i z{`_MGV@wkVoEKsiHKqSibrkCxmo1HPgQwHEn{9`C5XT-dp?31~b}L8?7(E2BYLwDe zdh!mMU(ylvE4aM=!5Ft8#Kiq$nnCisx76mSij zB?2VF^oSd67dP(g9LOEM^1WJTB=JKsvnS!a=uoUGrt?(o?+EDyRspd zDZ%$+?49cKl-ZN5RD zk=yhAeLgPy@nW=GXryt6<{>XndS-%LkynNEmQQpRyO1s-{%@MsD!je(s+ce^CqXbU zAO8QrOv20^1hjRxh5FckI)4n2{Yj(=@-J>P%aB+c3k@kLZ3MXAjxK4~%rnuHl%gHH zZ)3~;K9_L^=~cG5gp*3rlvYN&dA{iVV(E1^#eXqz z|ET`5#`fps)!FLk-pbnRBIs^;BOIgqaGOi-`yfBVuqrP0pcIx+MrfW@J>l! zp}`uu$G@@%`tP#w>T1J+GthN>#fL7!K+1(0Zzo`*qJE*4N_2c0?C9L6{me`oMaw{| zimN%Oh2X)cwLZ86O%k>Eq^a-OhR&(h_Jo`3>}1IO zlpW z76s0=WFEfuF%6RrY)3tNglzOuD+9wB<%lCm>>fZ!ZJW*v!;d#k;@7_du%w79<9-e04O6n>6VdrXbc>@=1uF$jrQPQghJDoD#fCfh zlxYxfjK{GQb$n8Gg~jvxV~mBwJ&h+o7}If=Nk3OTg0E>f`lDt8c)f4VX|+{V-B=Je z(=M;EOq?C9Xxo(g6{C6#GUJ+}jjyK+jFThK!%NenIxTA2Px4GnOrh9y3yl{}vvAQl^c7vM1zD0ScbaQEXyTG6Mv~D;r{=zOK#ZxCmy)p{&@bW2x zzJJcMs6g!+3xTJsBT+NrNCiELe0*)}bFI0Fh58){6I0ZXMS>DZYV?7yyIQoc5xN2+ zowJ&PR4I;!t4R?5AfwICla2yp6`**E`Vc}cN6zVcNQe$IF&@u;s6f;~WMAWKj3Il9 zjXSoPAuQ1_ZbO66O=v^A@azInGJlC{U|PQ}LQJk&itahROewC^=L|fbC2Pl6V8OkR z6M|=^UTuMKm_jtcvmo)0qtZ+s>k$U4tn@T1fQr_s|UD}skiM;mh+J`RV3tGL8r(0T#Nva<-q2e{{@BUvlPZtc)0f6T9&KQ+k|8e$=oU*}Y#vsW>UboF1ooGD89% z5ZM27W}r9z(LFkCDSsh}CeK7Vd#C0|=hXr}=hu_M){~V;Usc~#&ma@fCt}E4b;N%E z4V}GXPOL&_HVM4+wngsf+|?HJkMici)HFvyK`A9Y#KGwl%n#AhIK)YfRJ84?ej*JL zsXl=keYR6b%92NlI)l5TA1raH#Aud1^ihx2xmoP%rUuKD_#XY9mpHk~vdv6J7L=pY zc(zKYG|%16mJpYX>I8&(Cv5eXjiv|7ay~fUMh}_am?NFOd5COpT#d{BFmu_YQea)I zi4xDyRM z1Se~dE^aBc7z=1FuV3&PKU{em!a^MdSB(wQ0moYv_j8U{I|I)HO^iYygeQzvE>?T) zFg8yrVnBCaVXXwn5T2A`*6J$|U7B{t0aWf*MA*Kb!*DeeZ^jmQ89nJA_;b=Sh5Qv% zw<`bhf>i?~1T8TdF<&+G$@^T7rTlT7>RRKAE>U+zvducpXD|-NpQ#4t>8s2O0@Wac14!zTHEL>j#05DIHoci_7`Na{{dc^Zrvs|r z3>WbQo_CY-oNjt=;qNPCY6_)lB8LY1>%Nnz+LK!z%fN|ilz=h~_6us8N9sWHI1X%p zRD!Q;6*!5vT%NdmO3)X$UK6K%!h6N1Iy~>F1vj!)M#@vYu^7iu7q)QZeV&Ha_TbQ~ z0D4r;`w?MGh{kf8mN~ZMT+SRNR^I@+R!vJ7_veqsrwTBr40B*5#D0n{38((;G?Gm28{OKa9qlMLI8N2yX4Xw%lw1jMRu&aq(>bQI$y3l9g7eB33w^ZaftZxoxQXa z#h{byi=WHp1~fL1JyO)8CYiDc_(8M>9ZE|?he=evfa8R6I?@+sBGm)F5pYyxBs1p7 zh&_6aQ==v8&ibHgecKx9;;~KS9_-{8H)xuRQ)i_K2obO7jYE;R)tE1DM0EPX zR!#;?%>2xwAeba&KVU!jb0US>YN=7-ftl*}&+Mp35&P7ek1{&SJueY;Sxs_+adVT& z7psMzY0#3VEjx!SVOUr9$#*5FH;*keSFDwY&p+3EmY4S`r`Jg)HI1$M5v2wl zN=qULt{5WNF!Q0mjsqyE@s58OO};bzMo}hdDJ6`)$(P|oUS>jxWHCnUIlDp57d+>m zT)sQ&pNuF!!)2~a!Y5e+{mKk{Rh;?qPPs|BZ0ep#a+UmaIM;RR6Ytn{1kvlFWLA%5oM2oO-;>xdY(;DR;u&JU(^MK-5NjwU^G2(e5$Z*#+>hl}a>4Jhl zar5{?zT_8q^Um&H$keHFW_aA4{zTrEhDOQ)YXV|l;_;?r5}ykcAIb2n1Fh_yZ-nU`fEECS88&@5~F^Tuw619rcM+VB{pZr4baxi$<;7GA;QQFW6G*b+P z_?c}ee3?-&v#*6LBZl7%w8gD1E0_t@LXZF`WMPi1{*E|a^NbG8YOAnqBtsE3I9@A^ z{;LJEfDM&BDj*7K3yKgCj#sdw&Xqb-_>g}1767GtpeD$c}8M8HGV+bzz`-7 zrQ8-*)JlyXtF3tUog>clJYx+H{dcodtll(8r+&Cos06x0PmyVI`CKMvL8eKG_ zu!~YFF;<`kt~DXHD0Qg?Qn1r&nW7GTN`u_BqJ$!bTbLQJfopJ_78r@G)$aKn@;^AY zs&^<>UowP3%FTp~bD;O@1MW(NLaa@NrDCJ+h zy7&hac0blaJ|l*+_5YT>qG1ZxX+g0j!082S=nSp_QR?k+d+pTj2_241m73Lk6sukG z#CQEySuybR8NL*2-*<`c5;Yi6v$m-hkzXoS|k@0D*;1X{Y+P~DQ z!EaD~$rlRQXm~byf=)g3rebI)7yZB4uAG^|6{ntft`bnDVXCz-uC|5~P0ZBmvmEM`y?1nzVzzaN&q#0e)dQgFPD+>4- z>HC6Ick|uLRC$RJ|2LTpDSwsNRC$ku;fF_<^cddt41Jpmzsx*unc`@+J@A ziSyE7M<@6QW(FY-{R_;!=MLW|Ja{(PKx`j^OO&0o{_5awaK`Xo-usALBJOwxe}mtC z`vutt^%A(_*iQy`0rT?KhwhSfN2K2`SPb?B=bme4CKw%#3{DizALpL`60hF`HXlY5 z!JqJ+`BGp9wI46I5Ag-@9_6yVUnjU8_7%pT7H$; zyZ=>9F$eO+ZJu%>&zCD{bm; z4yHapD-Y;U@&}p!|IHd|&HronY$2#K)}!#-x+uE)OCuX(a~tKlY;Xf}Ty`5pE1GlX*HW625Du_4RmdSPOZG+)tCG+P zyW`b#Joy`Gaor()O29-hR=V#!KCK;O+kpV`ZFCUT`D3;{BA>l}d`GQ^sJaWBC;rAA z&l;y=4{OUiTRg$q56=nQCIAI@i6LYq&Min3D;Uz@aG z2)+sIpwWs!8!1hV15NX|3Cx3`5x}p{24gb9I=^kdRMr$`0VE& zNAn5~E#lI#6Db|p7z1bNB^6m$%nTeupeuq7L2?A%5)DhrQ6-4~+-~yhc(~1Dy~#ta z(6B?3uAK~Cie0MYmTxJ|$NanD<2D8*$%MKv7#m>==d|`AJrUFknpLTpt#B)bl%Ci0 zOmX|M-vf+d3Q_+q`VUE?+RI^^XRp zHlpq>J$H9Y(~pQtLiE>%Z9cN!uiiL1q>YE( zKjp37vO8lX;|CtgW4Ug1=XFr!Bsp$UlDI zCO}0L+g}w8@oNE?=G9Rgy=U4%{9|{-F_=WI*c_=PCfy>5c~(mQu0*$AIbp9(7E?u~ zO3L*M-fI&o+3%}%|0fdkdTRL4oopkQp@;?aP^1}b;bVyAQJ?9L6!e5d1SYCM<4&9m zp@fe(@#VX1vVIXwZxe$OUT8dQ@J0pi;0hB&LKuxg;Cc&?bW74gYf?%_GnJqFCy|s& zesiQeK{wNXmW~>eD|(M~arer^_PFYm3(1-6Gn1M}t&;u0%*`G7UOHCZHI(QI5-xOJ zzRfdV3t&D@za@CyaIqAlBcjP3xc}S9$*9}V+YD&Q!UtLnm-q)hD&Yn)v;RvuyjJT! zN4!{=Ste?w7k#DG{ltNoQH{z}TJn(y$lL*oN*VHctLMDU3y6WyuW%;p52iQ&>UHZj zdV9BOnldfmemLpf`#in&{CxC?4&$D=f?>vPxW*2xhJ!xm?aXg->TkL^?0!V_PGyN} zb?F{1rL%$;$1MqD7}KeM8&h40+Q#h+$u%9c?e>QHFQS0q z#q6-wDi5=CbVF@3=e8RV-04`>@C_i5DhiYoRjPBce&Hnq%8H14*QGNd#2sr@L~ z<_aW13|MmwW7f%=0-@l(Ua?cmHz62erKCovgOc#gy>ehKL;;$HY##o1d1#kD_eyGd{u+%34fI|O&P;O_3hgAMNP z!3i4Nb#Rve!QI^*&g}mqZ|!~FQ*~L zGD^9#W{G~(l`30HMEkGBjs(#=8s%?d z7)L2|jbLMpGDo+JUpU38{l=~2Jj)yNh~xI!Rm$iYHVAo#y;ZnaT&YLLq$OX>z8+|H z`?f7rz>T`SJY0Rbvi_ELeKt7Q0S9mn-B{r*1mx>;jFdmTR5tPZMd88QFH- zBUzD$?vLSmb!hI5Ruoo@f5FF>K)`z{NDFU{S^I zIfO4LU2m(#aK>qOMYMOz2NpS=@1OW(u?yh-cJ8p!?1K=6##_`|q+>-Y>af)6yg@yNA#VKjk&7<5(AruM zjV`HdbWnY4?(Job9IMR3A7rt6mG*=DFgI#eVYGZ{zuux?r_@87 zoE)Y15kid5QMY=nk^xzM=Os1e(y|Zyq5O8OWcda>`_i~0=7NuQ3+aMLcnz{QM#rfN z#u0T!kJ}PO9!D((-u7ZHjxR9p1UbsQbL-CsLG$4pa@q1t#`yC%wRP_b6FXDM9qw23 zG>W?x1u-6%#C9Eh*OWdx#WljGU4Ew6Hq*qN5UXYW{2R08&;z2s7mD)=tDc_VXk-BI zZvLAjq-kko`~M0=2Xsk{w*mLsnvNC`2zj{s#?C@pgiY%Os3-_~#Aq}+e#I2!TElbg zx^3!5npf4}Lp3b9ah-Y+zcTlN!jdNQu%P5@=PMREr4S4!h&W8wKOqdDufILo`A$1In-`!i| zEQ;Bry0IpUoGqOC{b#sTBO298a~r%W^rkx7;l}c;;$KM^y=4fCuDWZ@`vNFX5Hvvi zg1xGfMshu#9DKAXWRr}vJ`50svX;%gBb~W5@*`3c-pXq2NYVh4PnaQ07gYxA1ap!E z#n;rVGBQyV2$yGS$D&0Q@6~<2C?>#ICU;=LGxeX0>c4VZnZ5czWXy3Xnkawb>eQ_c z^Cf1?w8oOYjf1$CJTO`Av^yPs5fNe#moYl5e)A#b$`mh>+iD9#fvwQ}Mwgf$*f8C4 zE7KTvirQbDi5yZ1ZyQBcl9AKAODCt(w8E1}zId^y%1FVc&?kyh>JNO0tW1G4u7j zYLVo1TDH)DA7hs8Lj>-U6mLG7tIY8vBu?$nbXrOIby%WgT}yiUgK8g9A`u8JdfO}K zHT-;ti_gXp2}=ujUa%Ei`mhjxDWs%J^=6EdJ26f{BlwCoEF9M5MLeSyhMsWOC-^E(a>$8uwAxERqQ;O0QiH~Rd=kB@{X+3G zg8TU+p@4c;&Mux^)s0E(7YmUzBP9vlB-nj(jJhxuITddCXNV@86!heBN_WDEWJ-^v zdVKTowf%Z>;Ii^c4}mDN%~xQi2`qU61BoA31QRNi)9P7P5@Fl8l6>hx@{C+9X0Ik- zQUb#kR}a*X4ZG*W6!HA68-)k0(=P@WuV9c{3A`n9&)U*)pL1+a85sH%U_=uk`2Zww zyS?*@kUx5KVwLlr#zaPRSx1G_mi3|J%cpH0lL|CUYXEX3lB6`Nl>)ZKXMXT%B1SHF zoeG?>HwYy1v&_wN)D`gnzujkVpXCW#7{2hdVf90nNKrF_a$io=9$>w0tmC!@2;q|0WLue z9y2`UU2~|ewTI@jvhS{-xf^8l%I!$Cx^e7O(0FvMz5$fwh_ zRzJ}Zq0~zo)=v6egQ16g*0+YF$)N{v+%B5kI#xgF0nNe}S=@K20SD>FtSE!{ONYXj z)+kNWcG_Ko;fF!iPTJjb;hrI0!tL7_;a9p#G&V^oTF zKg(zB%Nv8VcPO?)#Wcm&nCig`7Wvap4L5Epvq+KgJxyUy$JjU9`%g}`Kje<8CkwE1 zVZ3Jw~wv9NKdtXd7706EY+aRoUm*8(D7uQJ!P_QfQa{#T!)p|H&NuJN)49 zD?U0NKKT7;IpYvm=rZsqupJ(9a13xHjp#5igDm0Fu&<=Kb`)2`Sqchr=Nh`tgp!-#6?eW#&Pto_U@$35z$&c(!V3lzjpV$3ssycZNO^czsG|F%B?y}HoUTSuoYp@l1aQAle}hrBUkef*LC{UBzWB`v2U` zq|cartef-5PR{?1tF?rb=A_Iyi`^pS%0Df~l)jX62&X<@Bmm*(ms~1KCcCVMhrNsH zcN@nPdBI%&d9%fQXQy@d*P$U?NUlHvH}>MZo7>qRvq#&JUAEpu3~lXPc^2ip{gs|P zL$MtTQ>*34X3L%Z;H#$`#99SLZx!xOF-i1;1D#cqgzkl8lT;EpO*bUR$k12)ZyyWq zNAVW+Ke_qlI!I@_c{jHj?W-(7z_(^EE}z|L&)B{q3L!}VO^+SG|HV`0jM*i_i|wEI z{-)Z>(}$EKGg)Yn^*GC6SVTJ}To(BhTKWmESDwwEvZmI2>Qbe(Z?>bzBTsDX^{cro z@_VK>f=sgQqN2+R1MG{k4&z=5%^;T_k9~vyYS>U< zW00d6xq!ou&5Sr~?CvP@$vlS%~_b1@eRoKJ+LdORBS zJPF$en6uULH=5cA#L5p{VX$-~k&?-xlBpik80#h@E--o|Z$D3jSvG4#*�^F?K~= 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

    n<5TUiKEtnV-av7uQX>veoWq%!QZS}g~ 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%0D-83>F z#~IOCMx;a~?OBJhyN&ImXcYr!N$rSwDUhHrvWKUjMDNOmru<4U?^z4yB?l5S!YyuB zFkE zz#N5v8Gj)@k8FJ0#Sc5IfbDy>UCZ44!!4rd)g7Ib$I*odk~EjZ;7UT7TI?v-w{60x zl7lOPYZf)r24xp(noF7@{8P%9-)=tGTk_g$mjs}btp>hn;Wl0p1ONd`G1f7?reH3g zFAEpxnlKi4)o60{W$f@(wvNHHL*xvYI-b#-T-3ow{bSQkD}I8skmcYq+!?99ZvyA< z?xC}dNl)SRvPJjiieLXmF}pZPY}-yS@{izbjzS?CnXAzefVR;Ok!AsNgGMkdKct?ezf{+()&U zepPwM^KWkteAyS``aAN}S8KGiyx^*``G54agD`5% zQfh`VbZ_ipeK;*LHl+o1N8~jd=CN2h8FgzB#IbRz#e?MreGu!u@z{`6n)#)!enn;7@+*FB;HZBW zh(Gm(YJSGU@h3rU;y&Wu-@;AF&#Zx%IOAZeD9b||kC^aTHq|ECgfPp@OzSHu5F=0S zF}YDNu+Egi(B#+)7ylM+{RZ)3n9CW3>6m-GfPO#B3e%w9&L|?st%O%>k30%ApE{@4 z9@KpRl^UtJsL`t4y+`v={U=v!%PFFMN9Y2p=RGW?`z=f^bn%nsfnav=v(2U1D2u}Y z(ZHTK4ch(^8t?lh`O{>RADYXKc#cH1l2o(kYko0?K19{=iy#wdEfJD_0Fiz z2g#^eQ1t=0uGk8*cS0LnEh?fvc8HNX^V<@1UhHNQsnPPfZa52TLg78VBv9#VnnlH8 z!y=&D;DF}&R=E7lmH3&WhGm@FK1L_nYuML&pZsdvbAkA%yn?N&R9DxwBH}HBbj>+h z;Pe<6a_0Slr?}T6^U*jwST}C->iuwg2GPYEu|x3n@kU6QZPjI;pm!sDdM!4+KwxLi zm=eYbN)gy=IlA6Av$FkZ^RC>~$d%z&I}9)kskc(lY1S@o5{o{D7el1drs$jt6+u#K zGx<&_#871iq`sB1%lcs=ibbAXvgZ-SuhwtrK zATjKByJ@QPPPkv>RkJY9qATUzdh8%_S_!`j)yBHtjrYe^8*#zu?%Sxf(iLr81@<=A zZe@0>t3*aJdaIP-?00?Iba_zJtA`K!XdVBOnI#2sO=YW=1oAGLz@pwSeSA0k_Ctn21mb!t_L z6915+(1iCnVEY~>?-hq8S~GUfz^$-tOKPF!Va z0KOG%QljNaRWf)T0nlO6q$CqoQ-0Rug!nF}I|I__%@Q)Y^L=q0wf<1(krhhbfBVy% z(F%rXxGuYbotPxZP1f#+E(F-sTsM?fbb;Cy;e(fglEZrO>itZH<69g*3_z+tuE!@7W5W)$e_{5yL1jD@9GSmi@fg^W zt@Svo&yL}Jt;_PU?!|jl5kg!qBIT71!!YF9l5Ly6%oZ@8un^vDi{H^Xz^}<0N7oV`sCk^_?Y$ztf1t8@NJm#VLKY3ItCi@$RPU70;~qOviKX-&@;j zzCfulTO4CA8$J$$^i7QgCrHm|h3@_mbGVg19Rvzh1^lD2nG5D+7lR!Q3z}TyU2fbFj^|(bx6a#xGaH52N$#s z6|7uY>U+{Gow<5+_GVh}CBvR2h)iy#3{AN@upqSHqrC4y7MHZIqjw8vp%&dgvJ)5i!!^X*nlLITHXm=lWCjcuX1$B(ip zYTy3}7u#8e0m?typ6;(Z_n}+RyN)zd#-fkyeLL5rAKOj-!9J`n?pW|0_BV`QZP9a0 z|1daQVy48!LJRA7A5I<9i79=9c4=v(KuC!Uy&?HUBX8?Jp zg-{un8S5{ETgWqsrkEWYv@cP4K zH4eh!7<&ySIByJj(kl;w+S32`AjBEL9>epq1jI2|BPO7QIEi2i-KmEzJLA5`FIeC>()9@!2(sLR~1x%%y!_)2h($W<=ECwPjmrJ+%3Au+P3N|i) z152I&V<^iH@YvpQ=cH6@d-Hrht7ng<_su5XtnQBw{~L%twgdKN7Ws8W9c)U^6n6c7 zLQ}aq7we1xcXtPBYrVJ5-#sr9IJsyUeRv|_fFWi9Em+IUG}?s)gTVxiLn4T9U2(2U z>{v0e5Yht}!$SL{3jO^Vph3kPaADa%A^`JmFj>lORw<5;5@0}P6h$ly=tYpzKE=Em zu0myCsl0pq&@dOl&;Elh>)zrfe=fZ-GdYJWz~pI4B&{h zZJ$BW*&4%U#b1*ER#4tpRyt}b6U~S&>E2R) z6YmXIga&ed-EIYlk-rZWtM{!nC;VRS2IUN$2b2RikpLVrJffil@kqdKyXwMvi)Tpg ze#$gj8O&#d^x6!OnABnM)47@4Qm_qvwNsV28PKJ*dtYNwf%jM_D8O6SS9{~`VO4#9 z@hhzO-K~DZBjaKvT3Vm_k!aRbmVN&6>+E1aNKq8Op$0mi;1RtWe1-t73ZZA1odax! z8RePFv0Q#T{bU`|Vvyt3`Q{v21%fo68)%-pNd#Q*2eCIIiA4;5K(eZ|P;^_3Mnd_3 z()1u1xHk*G@kotD{G`WYWw+J~6>7!`cMxn>vI26jNg~b4Kp>8NW2_2TlB|O3 zTLFP`eS(EX5VMAFaS7iiPWrGM-VHg7Heut*+I>UVaJ;?|?(_>@k=-J02_k%rHAK>b zP~N_s__h;|1t2VmKu3&FkK7~+;`*uL<(i_Yfv9V6El`H(5}U}6rDwtl**S0;i<#o} ze{@7^bcxLV521_0Ieb*(OZTe72LqG*|5Mw(N}Q{ki@T|tqs#wWQLoYV7RFe?{U@M} zqYbo`5RVywa5tFK=z>fUi&ht&Kubt38oVMY>f}4WsuoepVn5w#R>(56#`irq18jJK z+bCS7v|4Ajo_?Wl{JHEiAAB8wTL4cI;kVJNF7NBFzwa~8-QE`&QE_0}vqzXepgYj? zS?}U!>qX*-AF2Qp0IU9x%Aw%k&-6lxL7N{S+0>4CciYK)2&xhkqQH!@k2FtZ zbXLdj9HrMm*@t|gTBMLa`JguYa?c{LP_#|fND?;sbT=-sSCK!f6;Ok+`cXu7q=B$N zo$VA(Qj^5h)O>Z(jA$1xdi_>+s0bW)TGW&R69VtP-R$!Y0a~*uNeZzDXZlhP8s~NU za_2$@wr46th6~3PG)aHdN@lGAe%yO!Ow?#2i!mxlb&3JzpYo~N?3NwUK1;r1=S>g2`M&u=s(su&j*!g7WcNTY4pA!zn8I5+W5A#Ftvs zVl7=bag#rmqU2Su=qS~1Y+y{)+%lDoIpBYd5r5&p{4MpBTD%cY`2@{`B{uM&I;SJ~ zs2B^$$yOXrGy=~wqxEOkXRZy286vJUe#ye>>e}4a!se2+RkN*$fylUiCIBe`O_Ymb zw=G)N(~L0(67di#M^fMQpyIX-u=fp}a|jNXv9HDzA0a*KnW9>9-^2j~=v5oO)HCJ$ zG&hp8QMB<04EDtRcIym+O8V|lRD9%SEV0*~tvTk2>ET@fK+L$>A33uz>%#J2X+v9c zQdgVf;53NilxmY5#=E5e$*W$guMM4plkGBv%g$f@8MX=%R*MMstu~KlaBfUK%yAud zKRHnU-#kF3xNRRV#HU2B*iK@Y8m2 zDT}BHG|LP5hn09kn;O#y-McWPJhN>dHWu?G39G)D0y~-Ve?-$ruqaR)<~aFsnyvfu zg7rQ4;|4zCVsZ@TEvGO1I!6Iomvqujzh$e4rGa2$FfoWBDSI(Es zR=5X0+X!&SNkB!cmNVH?msTSR{u9=y=cUMj6SgN-Kdy3OkxY;KF{I`eOLg?l&{@y4 zM%Uj=>5n^bXOE+T;}hKnqJ@&CPqX1qoJ{l36e@9->`ny1A$+zg(vn%*Lz!L6t;@idV=YuJ9OlgvSbHjiUo_+RBaS!H0J$!mm3ED1&9$9 zA-ShQxu{eV56_sBeQZ4y*%4%}&uM88;Z{DJPauzR)Nn7E!n3s6q037Ypg? zpR%3B;O4#@yI8~`$462+tYQ>ZwIYZdA7$9@%}FOb#9y;wDZG&QL7RHZ$fph}qdHkD zRAy(OS_l~&qwY12Cq&C)*KXYt8f9F=vLf%xOVlLO5U<%i(2b~T$BjBo1mki)@%04q zO&mVT2IjU#m4yXVqE0iYsf_#+2ORIfP3#+fQMooOlt__*>5=;|EXW{roTaND({w?y z#hGJ@v|>AlJYv!tgj7=Ox%{IV(6=@pw3u{nC@mBy@$4W%o!O8$3|@(- zi)8P^F&tR_!u$-=BW=?D6w^FBM0mU%^Dj(x8~RnP{tchwpsb4L28Ml#=?u zJ>22%+&JD>vZTKoh*w2FE(cqoTxP81J7_|S;kSn#rG_7^E((v4Paa8MR}zy6~)40tN*C`BmM;6cOYBk*$&A5s$^KEe6(C`b|egYt9*wxsae_Wt08_#W){ z(U$vg4G9`nKfw2t{xo}q>@B7osJpTGeu8ql!_`Jl(#>uWk25?;afE%hygs2BnzwmkoVSpF+UD>7>*)Wjv5u_OYyx6c6@p71{jJ>NQa-yz~k<|$C6gqX3t zztovy6xNNa$$+WVZ6l0aC*O;P4*Y4K-Jh%p#B$HoCX1+U5%=v?cCNm~r}Cjq1y)$}9?=<;G(&QIbYO>`v2iEV19y;N8q12OjA^3Z@7uXbe^G5Y(TIM8 z$bXC_zn7^>T$F73+AWf2U*Prm@Lm5H_A6DrrqyMR4&x(aqa3X%8&jAWWD>}Vs{?Tp@lQfy6i&!Ar^?^x~%$QHMAp-ndU;&}Gf zB0KZU=Qe=TE(OFOZF9vU9_v-+BXK@XGBuUSmQ?&+lZOG8Mk_D`0pL@?S_UIM7y=)dfq8vR=D0-J?Q$m2)iVIh1~d(tGgTy7Qv!_y!%_1lZd-<<_y3`4hy7$| zVPG*u27P9`l;A@^F#qq3s~FH+#KFP!vrRR2B$JmG{qLDj3(iw*5%XQqT>cL%lMqoL zN&-2p@nWJ95u7fWu`E$zTbCTc@8I7P_mf{kmqJ^t8^9VR-_^f}hZMGiCl;%S+f>zn zqx3I(*4DbgRjE=RFI#3T+EPLOcas}0SGe^+V8`zW<>Mft1u5%3+fV#LIQSP|R{#+j1PA3Q9FMt3 zuft-mm6EXJsJAmVUZ-M>VUr$#rXvxjE+In9qTzl)Y)PJjNm~VwQyQ{s0dc3x#yq6E zTonoznkwburq}JN=ut?;;okCWTC-5SCEqp5+fHn!|AeM`D3BWv>C$B?Y<)X%Y;1HZ z^1J)Ot~lB<^+aIQAu z7_=)=nBu*rSg)jEsbtfuy`QR&_N>CxIF~7~Mr7BLR}iKl(c;Vxc>}n^?$!RsKo@!d z-=>yI(*m@_(< ziA3RfAZ+_)aRDxc%Mfun=l#VbV(cvjLy4=sw!YxPqZU-qDwr3y~VE3zke6bhdv@DQ%QX z2#_TA+G&EFTeTBX=ky-_@E~^9>k1pPS%+xrM}C8gC%CZt&Zz2JtLbZh0`4YEy5G1O zk(WE$@ElA%d;sq zH=$;ztJf^(nj(M;)i~THH4bzZIq&1UeAK@z{s0Joc;T>q!yl@}&U&f)F>5cLcd}oo zKJauqA2yDuYiib2tJ?|`>?S>7kRxy;ZD_40tzL9h7Es2=6r2?++O$y~7C+G1ES~uR zkjfVkEWjr6n=+USVQd?9LX6!NRdT=`CW8CjPbPt*8k5y8NAnXz8|%dyi4;vYP=5#> z0|ffk@Oj_eIcv~vclFW006&}dCIG%BCf!(v2Ny-=T9VxtE3Zf)MuRL95*-|Tss=u^ zBic0PE8Qg{u*gGS*zY?^UWqnfs_!u^=ZjW_-&qS+2*&JMS+K@~Y_EdKd)$>qEK^_1 zrNHGU~t)Ug@a=Z?8IN&0qsY%InR5>@b=`LHk7{Z z@0+x0Bd9L6H|gIsk+$x+Yc&(hn=IW^B=<*O_#a9&Q`^+`@(ompOX-|fk=2myLp-t| zhTQd5`_@V+kF!fz1BJC#$7Y(Vg*Lx`b^QxvcYSA-Mtx}JHgYL4m6p1C%Gz;lG~3+f zK-FY@LkGCzCsXB(&gKA#Fn_ahtK37jmg`8Ce5t$B1N6qln5PXu3GHt{MCY2y+4zz- z&OS+7kwn~D+4D^&0l%MS#$7YdW?_f(DmrIDdOwitQUdnH<KL zaH5-=#rny?HM8a74h(Txh~}n61^2f)AcCf>KrJd~JNtzm7ZKzA~N_IB3{eReWZ2p)03Ci;1ABe*#e# zZxP&f@nO|92E6k7b!5fdX<#JdmYks5&!XP-M%8T&_IZ(!UiC38J ziuZTtF1z$coX5@^m-i_#ih$|m9E_Q^SYa_LH>$wIYPm^}f@E=11>VMcMa5=Qcn`w7;aE_Z?>2Ic$ zbnE%(P3JR;!L*i!qmBn-R1?XwZF0j#?PjJi(L?6H`!q5F%`-;vcF8Uhez(ax zHyAPuL$N@|jj6RH%-bPj%;2;B^NP`s8z7kSpU!A>_nD);e1a;SrL9{_NY3@an)glT zJCm0x?L-e%LUy=$BmB2Dd8>HPjC78!>`t4POlZNK=}@C!ZIG_i4W+3`I5f&I`4;*E zRs%a%>WnA%Jrtv#Q5=VwwZa9i$cp13*XBI_@sE#;=bd!uo{^x$;DTU?L;K3oW9Lg7Ut{^K*{8n77Qsn zIl$gYDnh_s-z*{Ewav!lHIV5R-*}(>6-1iuj^=UbnI2KngYWNISv5N3VfX1$F7>Ev z+nR@YxskNuFkeY`X%W1BwASsiB)#E7d_PYeMcPQBDdYV-nzYYQ`UTm2=ch_s(KGSH zr=V|s+-vLr&Zl!jad(A6bH~%}8v*shktgJcOV8eX%s^IigUs&<&ee{yp(E__8Z5M)-0Id0m2t`?tAPgd>@~} z@3|x6F9sum<@&r|F7tfP2V|qy0-TP_GZmbdV2dNzaYw)b>#iPquv~{t+9w5Zk`(iwfk}c1meGb8<89d3z$|9xBt^ zU{)_{3&_~>1ol&Wu4ngtQgsjeYy3X5Z*;<($YD;q1MrTw$7H)fbLD}Jy7pqllE@NRAKSWQg8Y7!)| z_Fmzn(e%dWsC{0(3N77z-W)|y{t4KMoj_t?pB2^ey$=>FyQo1^RA~{v|3li$8Z;Q< z;`g$Iu}I|GLZwb()tp;F^0P?nVg2dCFE*EdrLRx2nTq1kWW16qY23fwKL(^Aw;TkmmX4ovM8)m^MSt}Bk~SK zZ0jiMMan>RAM&2P7Zt8!tMbb-`MAI_5-tNN+AgNh8aKiC=$VpWT~|dl8L8b1wAQs9 z{9mp94#8NqFzpwY|8t-@&=g!Q|D;a`kU>B&{qF;fs;RS;qwD`0PWeADcb)H^7|U+& z$lepy?15S+o_4__L`L956cr{IxP2lNqWG`EkO+|oMT=5^rZr`E^S(BF0`Q%s%G|Jg z=1#MloXLJ^&3+pZQ}K$MPG`iA8&T)x29G)A=>-^~R8Ig?n-SLO8 z@z3t(HsN&iibuF}mqc@uX8yqQPcrgmcnLn~=d-BRYYm~%O|mq~PD*fWCC}|wd)pQB zE<;~F_+T!eV=3^TM2^HL^Y<`tX976U6pk;MP5YT^LV{rWyY!x7lW_?-5{1Q-v3{}i z*Iwo(HK*s!RExdVo5v~+BK|DNfE$sDJz*YL%4Xi29lj3+mD+GX4I$d;WlG52Oof5J zI0OWLicn`^LIMwIbY{lz<|rwmzpmF)Cpu*N`gqZ_d>5QX-hpX3Ba&?aJJDLf@`q#& zvk>n}U{-}dLB<~bfk73{3g7;Ve^*j+3BN-jBHqsgvfGW!Qtu)-=Q6jIROI< zPtD(BFa+a@R@yZ3DZ!!1I1%LQ^UupU^x%xFs{ahJbgft+`D41YaECM=iRT@pwAE|j zQ}*jpV>Z};!erypJCS}2ggw&|UGWo=x-lm|BDu-T2%iO%>E_eLZ5|V+3%CA#o#sL) zFUbEh(z41m@=76-&YAy?$GhLSVfo(O-Tq{~)o(M_jX&othxhO8@sSg6TB&17CtZHBRidvFQ?Xsc_qv zgIrt{beQO#=(}f-CH$ zsAs(BQNsd<33-M&Zu838m4s)6TnMV)+ABjH0e|Px5cL-YlZdF3=h|95YzXT8h~0ox&6N=)%J|mh2!Y z`0LO=AE-3XPo4_*@Gdj-?Us0oYPrq|8tzfAU1(eYo1r(a{QUP^MA5NZ>NbFwZh;R8Gs-<`BA#Nx0X~Qnr*VP1BICoYnTXZ*igXFbn?3JvY%TF=%rv=7q;JMGcJkjt=s~^l8aVuQT@8Xn&>;vQBS$tXau;`Vu0Q5>fN->B! zrrUgT8N3p-Z)i&eAxHHpK~Iz+TR@#*P5~Q>DmroBRrNc|HpPpgl&ph-@*{C4~n&l}pSbr@(}+vrxR?DJqF z;Cour2tWC}u15wd))RYy&x}P-bicc`Nxuvapff&Z4>~(;)dIFxsz>v0MiE@j>EI=E zD^7Jp?O~Lh;#5N85j%biq=UF{SK^O&Bi+Oi4Iy3Owp$t3uMfV4)P@d-P1@$}S#U+1 z>;i+DBnhe^O0Agl`!550E=s^>k9GfyaWHd4xANS*7j$P9(YlfkLZZ(%&q6M z$KOcHWtpKm-Hv&hyKS1iO8!OTry1Q|PI4VE<&#D3`xZRg;wIm`@8P7&l){U;26<6K zOVK-O1Cc{rcO{%M&eFZNSvfyyFV3iuPNpu7x)@XfPIt^&kDbjoC(8()pPQA)>Y7Mx z$8~*c+BsCa0Dsv1LQ=%d^jJOydBfy;ICZx+Y_Q-GAb*LoG?QR0U$+G-;>QX;4yjXp zH17uI@)Ay45w?lkIs)X8}{JZe-)VBXKAwoH-;UYI;)aY{wE zXSi)V{sR$g&*i`-UXquTggyQh3VQ}=+}W10LeW#)#GJfaKUfyMCK24wfBag&r+T5(s;_Gw@G?YD}$i-T}%aC@t*&Z z!Ty4=z@y&Xe^5RDpmV2xX9R3;e$boWv_ban--_p7h^w*ioE*=p=3DMdQ!RWBe~;Py z6D@!4^GW#2ZL`JXv(PlAY7mlZsw-gLJ#g`Ig?A}=5XneqLnA2 z)bQOUmq!!-bnse>WFmhgr<}aUwHMoNcMK*1 zfRrnY#uXDx;35vAAs`sT`?}(xIeQz`qhdTv|&Rogp0XxDAcNX8r zW+Q1fei^qVik?VJjL^{aS-a*V>dwRxY=m@cMd>=Rf*O#h{r@P~4vMaXP|k*?Wt?H! z9ty4Z7l32bY|E;ie7Ex z%GIBaIg74DknpwNF~xZ{(Op9ya=MgZR1YR&grI~kzV$E&pAJFY^XPbIkO zG!v5O@i3^Xh-ws!z|u=JD(NB|ivg|ui)b11s}~dY!5g`7a}W{oVUTYd)#$^-yRh#l zlozL@5p;mz;>?OGOaNn5eEB}|HC!5JPCqGRtK1&UVS`K1ot277o#Veb?Lkt;D9>gk z^8_6FJvj!`Tx*>Pn?n}#BkyUfF*(P)91DKEx77OLb*Gj2YiZ^YBT27kM#UlxwUOb{k(+zAsd4c_2oAo)3Z3sn_k80z0g;l& zPg*|N>|TkY@AG=SxrsiJ9gPPHM3S=nc(sMFi%kmfI#gpeKxaz8^<)W8UV-(fQjSF> zz^c9RyAs!nx!&<*L&9?GPWKgo6{{>JmtYqm!8TYv{Wd!-;ZTTfidyRZQ8< z!^k**;x?}!jp8;Z&Wtbx8mE}q5^dWLl94|#^u00esn_>Jg*+7V4ehTnhH1Fx_Vyz} zhg`BU-#DA0(I>8Q!L1iH?V{(8YLi~|&Cooyj%8%oXzx5DU->gdtT`G{BZkMi^w1VY zHCE@dg)Y#THD;QsVaQuGG-8}?SBv=pL6&=H~4^X&?!5&Z^4G7kw39!&6P8)>Ydmw(N zgyy!q=ZhDYyg@^()HXchji8d1%OsqHk;EtL-%bSRn!b z#~P2>@*2163j~DqC)M-+vc{8hFg3PyAyYDTHns!00-gVBjaQ>0uedIR;)jlx$VGvY zSXyG3%m|0DP&tS=2n`3vUYMeC*yE&WoS9X$-TBJ3T)ALH!ekFpNZX~8$2 zt*aidJ97&M`+(Q4^`R*c7LzqrA0h{J`3Da+7Uz%hEVD3l`9jaB&t2&Mo$#*N*l;l?U6svw23%Sw~ zyLIaal=*bxr%WJhQ_eP0XQ;CGj#d+KrX?yxqMDu_3P91)M~{4)Laoy}U!0kZZvOej zmvRj_cDxwy=V4=@$=Qa#r7O+vSZDr6$>HuzG2BbdC{j zPwz6@_P4U7f2YA)yB}vm1~GP&C+4C_qkh0e8xIWu9R^~)86Ch#su!+oNN9upjS#`h zFUnlw2*ctqke_xm!2N>ZkCCuvUt0(VX)cQai~kUB8opm_%?SXbCQd1qLn1wrL()=@ zyPNyHl^Y72=gs58vCNZ}MU>$gf}Cm4{tABa=|k?VNqqU8etKUvu-GKN4;uK}_t}V*ylP zT+yw}aLixxf#1`@5?n?4pvvs79Z%ay5H7tMK6CiK1T>*U1WNkf$hGm3P;FX_UOBf8 zF5(8aY>gU2XhU(M2Q%URS@%s_XL!{4`)9btkpwi6eQ%})luDtkk{N(Q9~fmVE@`Fy zi?bqv1Rae-mB|%4k1)_njJSL}$V6o&N$0?fF&-mxH~P;uw!Da9$|PF&agabfI{9T2 zA=`p#a7lqo|3%Y@tfXtJyjsO^a~p#!pPIj6!K<4%=-79FT(;npcSHa1r`mOda@-n= zS=;h!p2Cz0t)|)dzA`0I>g>_3N_F;H^Dt90n$z(j$+omJ=0|zix~>S{2`9(P_v~{U z@e~smT7ODMF;SX#2)G{&7qM!`>Bg#CbNDZyK2Zl?$dV+e#}%dkvVqC8C~MF*Z5VZHn$CvR^lp9@p@ zi(qX-BdrQQ1V6GQP?W2tDs&B~`fqxDptM$KS2S(2Va!`{O^A)F=4hFjvH@pi zxRvSNV@CD*cV=V-?qR{APk3mEXO0Fy=NRp7HX*&d`VzZ}gn$4F3;7A0f;ufk1Hw^2kF#^8r4`RaI0uU5@%Vs{iZz3D_hbvwf%~(I{?x%BaoYkOQyC`n5ag6oihEUO~!I(a3RbDI8wlm8WZb?V`+tVCMcL5U0B_H6rh` zy^48TeFH!Bmx7*BbY`}4w>0+Crr%Z5S2cNQ(y2-er;mG{quUEKJnG31qTp(Evh;}% zfwX?$M~b)L3*3#fpX!E@H0zh=~L zSLvjV(YG7LU{RxO!q38ugN*At2oN&Kv?75gg3~7mjNG~NOyX53VCZGcIo2OO+A@+L zridjJzv+1%^P6~K&g^cJ-{^F%M(!coZs(&gL5Jv|?q~Z`m{?0S-9N2-IzqjU>~L_}X;o!@ctCXchWtxh;0Y zex?13@j#rH>8m+unYR+VEumw^nVGHHDZ5Xa7%;vh;fmuqE&hZ}wt_ISQOq>VXf{IB za@KU?sZ!)NBv;t^D-x6Jv_WIVPMIgnQxio1e|`&E4fQX^`%(zgS%(nGM>rmZu$~pT zs~I)k{uyESy|1Q%O#j|-ZVmn6c?g+h`e>{uV}229k7AFwYUMnA1;KfTpLxd?E0ViQ zkb}6ph_byh&joTDyNXw<=1BxBLwa`7z$-msA*w)VG&5zbKFbT(h+v!Vg5n6NP0(Xp zvRZ#Xb+dnKam4|Nm#muNjA<)X#4a{!=ybe`zN~9qb&fY=O?7 z{vxhc_7*PxeRQbVxd7BL{Otql3v?5S;5h6St#yC4%q%_048|kcE!)GwOt9TUHQ8Rp z%ctp^dpPO59Z9~?`d6&YI!Ocs3Xa`w0Pje&%~djXxA+;Sxu^LbvtJ$s174wxFm5Sd5{JW4oKCZ)@cZ;HyaM#S`z74A75U zrnQ&&^jLZ7dBg<&QR1|V@-fhMf)SnHvyXb|v3leO-3tZOa!)BaNwiGs!<0sP-mzfS zkH+I<4mV*JU&3DEu{4s1YbY_f$*+`-jjYlh|G8W(+I3sp`oX2) z)Ov$#klyA{GgNj|_e|5s7+5z1Wj7sRphg&ch3%+#|r0 zfCH|Xk=CMtpayxUjVEWsqnX|aBB;Mzlu7S|JJyXZ=Fi&iNw9BPa>~^FhiHYPzmoXI zuNRg-R7`ps6@t}*r%QNX#F`#y{ab)jc_Mw2!}Fk*mah)W{r69#p?J3LBhL=l8RK|Z6q>z%u{Yz& zj_f82qkHmAWPe9q3a|d;e8}yl&lM}^uvXuQOM|l$Y;L}lmXFLG7|ZVUYp^NM8huy1^3B!u${pI~N;hrqPfGh#PQ5arK8G(;>w2DEphb3l0-bj)m zO=3@$FnJPbMiJpFn|@u2QW1vfg`%BMB2BU_iROi)|DQWSl%o-9F=t_MGCrQG{`Gru z|J8}ChNnEO)u^{<+M4a#DaN*cETcaC=YS#AU|YjIr9J#xBsJ2oSm^lzx_03 z;~;^6p#0wt+W(pv{(Dl;wlY%tT##MSc^A!!qCq9n*#_HwjW%b4buf~}fr5-S`2ydM zBD{IS=8XnblyORDJGDpQ-ohZAR9Z8?GBualJOt-16oj%q=;m}@ET36AdDdc;b>(x( zU~lrA^O9?xgc9@=cGT^$-F}>Vmvf!%ay>6w7qF`h(OQKF!w1h<(qyXdJ~wuVew%Fv z-2c|WqCt|1 zi@|=!IFr48L2u{d|9#lh!d~m>*H&cP$hyW}&d5&;xoB31OAqf)nuZ_Q}?;Sp~x-Ggy~ zk*Xgd4KT^*8XnAPixQ5dtl1yIJW?c0mwHIoit0R7i5#a184JNl7PFQ^|3`p+-XL5s z1;Aak1EMcECiY9#O4-;=0K@frhPPsADWzT(`kOnkvk+`K8pQFl4ON!Y#@0>UQ?D)n zfED~-8XdiC844DI5u6!qirM9a4U*{8J~BCCj#&|xE5iBcVp}9o7@4$Mi^s7^Fb=~C zP{9=LyZ(FZ`XO|@Mu#oyl6RTJKEPoDbceq9{OT}lkcE*H%F7Kp3<1+^l4q5O8I};t z{;C*7UEhUlOerQ-f>&1D+O5demiaMqv84OjKM@Y_xfaM+N2wtb9TF;4#1xG9We~dl z^{1FZb%T7gNi@978mHL^{JuNQ^y_zZ2(k*P8o1ETBYV$I(~IOeBBY)8h~hTFoy=|# zJzTjAso>C|ogMedd6}={>6z>aP{g$s3&@x(ME+c^%108V~{BgjrTIf zr}&k+v*Ly? zqq(eiHdRBr_bZK%NTvVLRN-W>wBMjp$zx}bYP(VT6B{i91G=PcO6n;hX zU;R~=?ukK2y5kbgW*pUYc6>RxT1{r>(Y}`xswTi}k3C!IXtp*EA)qkO%&3vbBN>bN zhAO~kzX#W?&1FW&n>ZDFaCRf@JNBzg{uSV_Z)_l*SEk38Gd91Wm(psVbFzZ>3l2@M zE)DGB{NF@Vwz?lkphZ=JT3HC$R^QQkN|a3F~bv(cU-8_ z3zKyE`nUh7enESYk~W)}nb=P`ylpcj-pWEgdjPxbk8v7L`q8{RZlc@~QenMc;sxtb@awf;Yq_d6 zKOZ2}qxfr2MA{ATNWC@=F)M6hvu_9+k$q1A4OGJYpY-umcdc#&))JAZ`H#?##>F8 z_q9Rf8&1{hhi1gpYB#x-OpU2kYliRFowlwrc1+=Ew;m$-y_%Nv+ZG*oa{5YIP4B25 zW;=QEuixKODg=_!4`hkia|xuQt=G<;XEbV6@(?O>+ow;q8%zU#FUVqg(GFe3)2%ep zuC0v}$y^$l&;c97R_3y3j%stJ4%`-6>jAr9RNO7)jB!@Ep3E(3z;Ve1skbjvZmOk2 z&U}U~5{qjOC%=j8o3XL`*fK*|AEy0MPHI4TB z;>PKDRu(5XqaqlR_ZnY`A(z(7o@ChunEh1M{kmT}Ibk+$is7{R9cwWuC}vRto-a0N z%T;(y`mN0^IU;K|&O}9Ch4K98S}3FONT!**^T*(Ig%0pi-HZG{TR?sQp?Z-HZ$kH0 z)U3Mm{&*|hDDs(bKB67eo8X(xqtr>v`?T+G=J>?f`XJ~}AJvWeG%?wQvb#F0T=vio zfoTqIKeJ>B8)Mfr?b1jME7!)H@@FWF1?fE`)ZJNU7eJD*C?)I(a349fdbN4ZrKYokhuw3)m_kCR$(kn_XRdqr}w-W+b#_!U0F=-7|lQA8h>x%N|q6Dc|N>LJC;w!E`FG#i}_)FEkndr^4N7|Ue8t8F6~ z2%&T9(3Yk6F-3`db$Az$%#VE6j^%9fqWJa-FY>1%=#iM48*9Yy@D3f*nSlG_)Q8|C za{oiTUFVhaJ&g2YJYjw3@Q0EQfi)Ei+%+}*UqFD(eH8Caz$^O?;#Va`{V2j+HyP!h zGLG|lBMslcK~rVMa)q^>6z)h5k>?Cw(|V_Zo3wn9E(vny0Ue0fXF{rhXvU$6#_HA7 zjz~Fwtkpeg9Ng-`rQpA8_9=Obf95wavVV2(BY#_nkTtabBN#ip1bATM09`%E7dj}~ z#H3%$Q%HtGI3k}l5GdOc3E(w^rvEjjo!tsl-Ut&tDMMce>*8kiKu0-BN2vN)D$974 zo04Ct85Clpj3g`aPV)Y{s{HAxWO_a8@Ky=J8O!Oz74XB}$;s1*uF{#RDWHdVDG zQ?rZZbL-MsFm|3u$ds(`j^*fo;n4u(ufaS3mL@z%$^lAMfJNVL{-8eO;ALXOfQ8WQ zWiO;R_|12X4{n;FBG~aCv>AbV^Jg|Ss3A6Ajo)2;pm)&IdYp;^&uPCcYeIT77+A*J zUy4v(Q8srr;5rc7igvA+ebJY+;GM1hQiIwQxr5m5n!@~ZqUic76(jpr+0Q>#o|!ow zfLv;?q}cCNh&S)BlYnH-UQkL51I0nJPCiyg_WRG*wD4u)J~BYYFN1HXm&}-Jgn*@3 zC)dHg(d9E2W*r(2KoQjDd%E?5;!gf+^f@jigWn5iWEO>1l#*h{lbwsxruM>O0p!GQ z%L2q$X99h}C({diGS`E0<+am|`d2Bd%@v5FJnK9_mPtb@*bsKu(NJJ0>IH7_!EM3n5g6GULuTOJ<)on$<29A< zZ&%^rdHqM^^+;U05tgAx*a!7wnE+&~I9b=4ZDsz4oTO0Cd|9G7zByWXOqQpe?7fJX zft)*~Zl6nUE~_8Z+EMGFtWo^tdd#}$w{Hsc8@LASQCSrwW<^f?I8vX`MmeQK4R|3r zJD3aDo1>joaSwH^&duMU#0gV05fG?ZD$A)^xUECD%yiM)w$b?y3R2lb~v^tCe(m!eqNN=bUw-{U+}b; ziN%f9z4(H7mxbfm*E-irHitYKm|1GP>6=q+z$-r3@E4>n9KB~Q?meW&jtQ>zfH-Y` zEv7T)Vr0KJ)DC@B!LCVEf=6AO*iomf+SPoC819*QaCqW{g6kUfhZ!@^Au)qm*i#9v z$VI}(VOx^qKeAWr-GkrQ)Fin4zn5GMGT%Z~JkP-^npOkL;r+|wXVS8>`>7f&32LErDPYfQ8+xwM_*y{w#bb!tZ%L@wd1mbk5 zNspcLpBSArSHIgdVD4zIjx&Rr9ABJoT^=z_nSzG+;mdr{98R)+J?}pa59h!n&AcJb zs-lh_TYn)=X9IPdYp3J7*`CH2~nxPz&MUY{3Y$HFj~eGIaqOJDXZEIvQKq+X7u&82^i3sq(2A z`)^oQL)QcSKd#*@u4}F`j1fdZGB#F8((BapL1-A{ICP~2XwfZO>7`|tGr#4sGun2B z2=@qY)R#%bf%I6@?^I5CNi!7l#`TQHEypi^A1+uwUSA$rA<~RWDwX$oHEj}4I45@JyT|^jh zHt9l{8+U}nix`5e({4mDDJ=ujfvJ&r>uj^_mAV&-)>JGbLi%F7cr2t2G92#Fz8tJe!e74N z_car$#2G`U7X1QWg8@hckaDl#FcWqe@1R&Eqe`U-L~Q3!OyyTt@Hjv}{Sg;*wpT17 z0POUZ74q%hJY4ulDt(K}Lr!pcxa_!o=_F9{IPg}4y*h`{=Dk%tRLQUbU(_o&am#=_t^lcYD z8Y4bzN-<*PEx#&w4{n91pV{CxMf^6c9UCwgItV)9AJw&pf7;-`i-do5@=*X~gZ~Uk zUah>BKvz$dgI&%k>69k<#%~UWBI3;FSMiOkg*xQUcE_H4wjh{yQ>V-RoCYP!7~o+EK z|2cp*NZ%qGp>Y18u<7~VA%<{-hg9O1%-;AN|IO*M{Qtz7{{c1sFaHxGFCzuah~Q(< zwtdyvvZ-qIbXWi`VvoojNui=pPo>QLm|9vOqtj%P^ltPCoGWtsZvg*a9FkdDq&su` z+qm>jH+!Dm4L-ng!(L&3eNOR#_~@28Y4l-5x-fICGfhl{Et-H{v8AaG2So=3xcwgE z-_p+nF~-${a;aTdAuEy?$)nRXj10|`)7~Rj*^vE}=X@Z1DY`%a6&mKtPcLh;xPtXP zzVu^ZOy20D@BmotV3qIXf6Wplx(k2oQ^hw*+2m#rah~%PY4ssh3g2I8&H71#M0-5$n$t&hVG}dOC zO%QnJ=J9sNS!Uz1Jp()P-hmg~LzKOR_kwYt)$z0^v?uDMT7rZeM7ZWhN36{gTpmMz zbn=M!f}nfs{wphRd@6og_Y3(izk})j4E@puHipIq|BIaapTt~@jFcsi07^BxQMLop zI1RTyv>FjxAbB_m0fojP$lNm{{)X+@^`SkTqdyK+aSWH5s)9-u)%nTGC#-(R7!anx zwRh35eRvMspl;jwa1JX{;Ksd!-#_#d!|+_WC6fTag6p@a6obw37a#gRNR{v}XD!_> zq7VmJ>-&r3+)DZ2wUgx(W1gmoO8ewE1F$Y({n%gaugOO|KbdfLdqR8h1p zq>6ZDoT9a#9Zbc1U5oRW^H(291-F^p1)4HWs5+w#Orzd5I7)ae}%(;b}c>4K?##-ql#NzoD4ktf#( z@Aa%%gK-(aX|!LTR^If6yUXkz{OQpqUN4+EK3Tq*^@D$V1`HW-V$5tl`m0M5_T2b# z&zSnP2oSoCGKl$Ef%gy!{pW0z-1&3^tR2}x6o!a~=8hV-r1d49 zV6+u7j`JA|%CbRtqHBm5^|fg*me(U8Bb-j0-D92YG@=O5XPOJk9QsaFZNGnbK&cS( ze{E|037_#-f|)ub+f6XnghlYU(Beg9&1R6kqjSL69>ZV9u36v6av7&x;Epe+*A3?+ zg)h-7zDJcQY}WhCcBxhbD^S|44{B+f>!k&Qhq@W|Izvc}vlJ^CR>L$LD&4a*i=iwh zbV}vMN`aybJBkhAuE$cyZ2bW;y?Dl@Jhq64FcRUgjCg(4PQiMtOkqEjS&u_!TKu0^$q~TH({9Xz<1CV z;`n5CEz z&AJ!&jf`#|9T57^2X~DG7MXkiUP!!+aSs@e zLTVD3%u%ZGclXPNQo~cMDUB7rfvZ%t^{{Ta?^+T~#+>WNt>@8n^_#+ute*t~Djr5xYJr+`;I^ty($A<#6d@ZRjpKXxN2n zGM!Ide_by3pJ6eMOL`+cyY-M08Z~s@e7am?*57fpAY>;GH4>j1VxIRDM`01yBGX#V?v zWoh7QKxbp%Z2ljCDo4%6u8Ixidq>aU$ycI;X1nuO)+lEo=(eC3F1S(YmPrOK+mF3A z%_dW5`QtMdO2Y4dPNyj0t(*6-?{r#LC1*S!_z#Mx5Y$1jk_8%79+Ry2AEG!B2Lho4 z8A-gnJ?(nwykMcJrX>=Vls`|ra`Tz4o*gW7M(^kEP?xZq<5@?va|jKv(v+?x0r2B0+wX|}kr^6FvLn{w;aavCpO zoKS7_ertu;jnyUp_TTuD2WHDaMt}X@^wUg6zqD+5UZX=!@EtkrZFgO(vpci|oZ(ql z{+e|$GX}z-b_(&_!GcI2ZF&!}5S+bn8s6^=nG1V}BiL#}7&>|oILdE$2bP${HX&dt zo#99&jA0;VEWN3#Snh#{j&?G6Y#-s$pb@P<)ovrAbpWZ6<)~G8MNI$+Y|%M`#xVRn zl$kDljZ`TC_6Jen%xj7urg}Dj++i7(OGVQcZ0I>@BKy0kYMHsl)6Jhj{vy zu3HaLk?TEoiKH60PU3aH+PgR!hz2#zZkBH>&fGIJ4gLAOv_gp8@~;4ve0br)8^^eH z*ESBz+8DD8wEZ*7-xcZbdzkth^r?jITc?JF7*jNq&Whr0Tsw&>ByMMcfFH3OnHT!fbux~71UYmHBHTXH4h zKWmqb^P?5_zpaegGL*-cqOUg$e+(&J^1pAg-p010oc5o?HH}gqV1`W>h4+tF2#f3R za$R>AGSW9fb90p5w-nQe2_Cbg-^t>aquvwes0k)6@FUHx z@=UI&2}G{QK3Q&OUTLMAvcj;;=CCds0f-i$zip+&^=I?^vGT;%QC{l8)?n@NN;k|m9e4hf zbya-RU}9!tv3|GfHM5O&k!BWs2&19{Mg>T+l-(y#@zE7fQ9D#b{peV4UepX&Rkzk< zxRF!0Xs7_UAp&`2A;v@#|@1*D@C=~l{6b&{|zm} z<$ikD%IJt&8gX;ub7Ai7yD0s66^i;kq}>v8yPBRcuOvFvrd}r1WK*@&8MnVUNr0W~ zwc%0^jCH#TefHYinsz|1eX+{oe$ne@yE54OsA9W&aK5`WOKUdan3H8cuvjPK^T=g( z3e@lP?9tbOz?bsHdv#%RO+b}5ar_4UuQ>vqOjCb11^_^Z$NxQMS{vA!{Rd`V>1f#< zj63@7>Iqy<1cBLeo52TiXLkoDnnxH#DvM9z<&6mDm!uBsME*_u>z+;U!?Vn;+ZFX! zS{4rB639wRMenJkv+}*LHka?~mV79}jf8f5hk|)Xvam4P4K(6@d!oJ6D-l~mGMa{c zRzo&gCpFdM)04IdhXk3^jQe+L4BaT1wPo4(mB)gc_&@bVx~N`TbP!2@XF z9tC|=EA__|C;!sCFK&uMs%SV|i6EQ!ePVoqaq`8%GuV^<#>1OCg&?!1goIx9?x=T3 zdm%dzebzFRuE$Jm2T_%paayW5NUw0!Z4?!+{qQ1IThg4N`Py4zpJE$vg-11p;t)?*&z(^8SyR+MR^2Z8a();S(HXY>cDI6t z-tX)6?&|95xA#rY-2H*rdPm%^R}E~nU+6PagiL09A%M=8Z;X@t?L`-&PCjSXDJoWm zu$}Ym8bkwPC|LJV{^g@P_@Ia@#cp9YkFfVzR!k5bJ79hd1?U<6On-e4eoO`C+Ca{o zb(oYLGS*z_O_r^>R>0od=(N*`tGO4QwQfcBj{hrf6O-bA(#6?-9fb_V^+>2ql_Pd_sN+PA%`dJ`9m7~&@cLkC+)_q%KpZ6 zdJG(V47jxh+UaO7hX`fUDC-!z*o3&Yq9(2)(Mr;emNwP^Zu))R6O+-J-8^^-GC|Vdi3y_`doh7=5C8giJ`*9k512PUP#v6*yLp0>o6hW>S znu3MQMd(Rzw3|sTVDhv6eEC9W4crZJ-O&1kV_u8SZy!+@9Jk4@JKcB|2#E~`iT

Jx2h%Xq?qtM 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 z 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