1
0
mirror of synced 2026-07-07 18:50:00 +00:00

Compare commits

...

41 Commits

Author SHA1 Message Date
Christoph Strobl 4e572679dd DATAES-662 - Release version 3.2.1 (Moore SR1). 2019-11-04 14:55:02 +01:00
Christoph Strobl de9c664d1e DATAES-662 - Prepare 3.2.1 (Moore SR1). 2019-11-04 14:54:16 +01:00
Christoph Strobl 8187c5362a DATAES-662 - Updated changelog. 2019-11-04 14:54:15 +01:00
Christoph Strobl a8eb260bbd DATAES-660 - Updated changelog. 2019-11-04 10:34:54 +01:00
Peter-Josef Meisch bb944f595f DATAES-679 - Upgrade_to_Elasticsearch_6.8.4.
Original PR: #339
2019-10-31 17:40:24 +01:00
Henrique Amaral 598626238b DATAES-673 Create a Ssl Rest Client using SslContext and HostnameVerifier 2019-10-23 19:22:34 +02:00
Gyula Csörögi a451f8dca4 DATAES-671 - Missing indicesOptions support for scrolling queries.
Original PR: #332
2019-10-16 09:00:44 +02:00
Peter-Josef Meisch 4fd070c332 DATAES-670 - Fix version compatibility matrix in documentation.
Original PR: #330
2019-10-12 10:42:27 +02:00
Mark Paluch 091413dd69 DATAES-665 - Fix plugin ordering to deploy Javadoc. 2019-10-01 08:39:10 +02:00
Greg Turnquist ff74425132 DATAES-625 - Create CI job. 2019-09-30 14:23:41 -05:00
Mark Paluch 6f4d1dcc57 DATAES-625 - After release cleanups. 2019-09-30 16:17:54 +02:00
Mark Paluch 9713e33fed DATAES-625 - Prepare next development iteration. 2019-09-30 16:17:53 +02:00
Mark Paluch ab4fd17520 DATAES-625 - Release version 3.2 GA (Moore). 2019-09-30 15:51:08 +02:00
Mark Paluch 6045f1e0e3 DATAES-625 - Prepare 3.2 GA (Moore). 2019-09-30 15:50:44 +02:00
Mark Paluch 102d7370bd DATAES-625 - Updated changelog. 2019-09-30 15:50:42 +02:00
Mark Paluch e22ba228a9 DATAES-624 - Updated changelog. 2019-09-30 11:16:16 +02:00
Peter-Josef Meisch 52105fcdcc DATAES-227 - Polishing. 2019-09-27 21:35:28 +02:00
Sascha Woo 8a1242fdbd DATAES-227 - prepareUpdate does not consider UpdateRequest options.
Original PR: #327
2019-09-27 21:22:20 +02:00
xhaggi 5f78ab8e25 DATAES-657 - Sort by _score not supported by ElasticsearchRestTemplate.
Original pull request: #325
2019-09-24 10:52:57 +02:00
Sascha Woo 0899df94eb DATAES-541 - Removing an alias with ElasticseachRestTemplate does not work properly.
Original PR: #324
2019-09-23 20:10:12 +02:00
P.J. Meisch 327e0a207c DATAES-652 - Polishing. 2019-09-20 12:11:14 +02:00
Roman Puchkovskiy 8d044fe3d1 DATAES-652 - Send if_seq_no and if_primary_term parameters when index…
...ing via ReactiveElasticsearchClient

Original PR: #322
2019-09-20 12:05:06 +02:00
xhaggi 642d95b5d1 DATAES-305 - Allow to put mapping built from entity class to different index.
Original pull request: #319
2019-09-13 08:23:42 +02:00
Oliver Drotbohm 6092da6fe7 DATAES-648 - Unified version compatibility matrix into reference docs.
Added information about which Boot version uses which Spring Data Elasticsearch version as well as hints about which versions are still under active maintenance.

Tweaked the readme to rather point to the reference documentation. This needs to be updated to point to the "current" alias once we've reached GA.

Original pull request: #317.
2019-09-11 20:31:23 +02:00
Mark Paluch 4773da32ab DATAES-497 - Polishing.
Fix compatibility matrix in readme.
2019-09-10 11:57:38 +02:00
Mark Paluch 642e42e01e DATAES-626 - After release cleanups. 2019-09-06 10:21:56 +02:00
Mark Paluch 0820ede014 DATAES-626 - Prepare next development iteration. 2019-09-06 10:21:54 +02:00
Mark Paluch fb49aaa2d6 DATAES-626 - Release version 3.2 RC3 (Moore). 2019-09-06 10:10:42 +02:00
Mark Paluch c67b3082cb DATAES-626 - Prepare 3.2 RC3 (Moore). 2019-09-06 10:10:12 +02:00
Mark Paluch 0784cc7226 DATAES-626 - Updated changelog. 2019-09-06 10:10:11 +02:00
P.J. Meisch 2ce1bddce9 DATAES-645 - Polishing. 2019-09-04 22:23:46 +02:00
Gyula Csörögi 48d2cd1461 DATAES-645 Fix missing highlight setting in scroll queries.
Original PR: #312
2019-09-04 22:20:04 +02:00
Mark Paluch bdee49f815 DATAES-646 - Adapt to Spring Framework 5.2 RC2.
Un-implement ClientResponse from RawActionResponse to not require us updating the code whenever ClientResponse introduces new methods. Retain only methods from ClientResponse that are actually used.

Consistent versions actross netty dependencies.
2019-09-04 14:48:11 +02:00
Mark Paluch aae7734bc0 DATAES-646 - Adapt to Spring Framework 5.2 RC2.
Implement missing methods in RawActionResponse. Consistent versions actross netty dependencies.
2019-09-04 12:13:01 +02:00
Mathias Teier 054c02bd41 DATAES-643: Added searchType to prepareSearch() in RestTemplate (#310)
Original PR: #310
2019-08-27 12:11:46 +02:00
Mohsin Husen 4798136074 DATAES-589 - change spring data example link 2019-08-14 15:24:08 +01:00
Mark Paluch 389a5bc5e7 DATAES-627 - Polishing.
Reinstantiate schema links for Elasticsearch 1.0 XSD.
2019-08-07 08:03:01 +02:00
Mark Paluch fea26b5751 DATAES-627 - Add HTTPS entries into spring.schemas.
To resolve XSD files properly from the classpath, their HTTPS reference must be present in the spring.schemas to avoid internet interaction for resolving an XSD file.
2019-08-07 08:01:11 +02:00
Greg Turnquist fd7a380edd DATAES-583 - Force check for updates. 2019-08-05 10:21:32 -05:00
Mark Paluch ff021c1319 DATAES-591 - After release cleanups. 2019-08-05 15:53:03 +02:00
Mark Paluch ae38eab00d DATAES-591 - Prepare next development iteration. 2019-08-05 15:53:02 +02:00
40 changed files with 886 additions and 513 deletions
Vendored
+7 -7
View File
@@ -3,7 +3,7 @@ pipeline {
triggers {
pollSCM 'H/10 * * * *'
upstream(upstreamProjects: "spring-data-commons/master", threshold: hudson.model.Result.SUCCESS)
upstream(upstreamProjects: "spring-data-commons/2.2.x", threshold: hudson.model.Result.SUCCESS)
}
options {
@@ -15,7 +15,7 @@ pipeline {
stage("Test") {
when {
anyOf {
branch 'master'
branch '3.2.x'
not { triggeredBy 'UpstreamCause' }
}
}
@@ -31,7 +31,7 @@ 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 -B'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
}
}
}
@@ -39,7 +39,7 @@ pipeline {
stage('Release to artifactory') {
when {
anyOf {
branch 'master'
branch '3.2.x'
not { triggeredBy 'UpstreamCause' }
}
}
@@ -65,12 +65,12 @@ pipeline {
"-Dartifactory.staging-repository=libs-snapshot-local " +
"-Dartifactory.build-name=spring-data-elasticsearch " +
"-Dartifactory.build-number=${BUILD_NUMBER} " +
'-Dmaven.test.skip=true clean deploy -B'
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
stage('Publish documentation') {
when {
branch 'master'
branch '3.2.x'
}
agent {
docker {
@@ -91,7 +91,7 @@ pipeline {
"-Dartifactory.username=${ARTIFACTORY_USR} " +
"-Dartifactory.password=${ARTIFACTORY_PSW} " +
"-Dartifactory.distribution-repository=temp-private-local " +
'-Dmaven.test.skip=true clean deploy -B'
'-Dmaven.test.skip=true clean deploy -U -B'
}
}
}
+2 -11
View File
@@ -118,16 +118,7 @@ Add the Maven dependency:
// Always change both files!
**Compatibility Matrix**
[cols="^,^,"]
|===
|Spring Data Elasticsearch | Elasticsearch |
| _3.2.x_ |_6.8.1_ | _not yet released_
|3.1.x |6.2.2
|3.0.x |5.5.0
|2.1.x |2.4.0
|2.0.x |2.2.0
|1.3.x |1.5.2
|===
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].
To use the Release candidate versions of the upcoming major version, use our Maven milestone repository and declare the appropriate dependency version:
@@ -214,7 +205,7 @@ The generated documentation is available from `target/site/reference/html/index.
== Examples
For examples on using the _Spring Data for Elasticsearch, see the https://github.com/SpringSource/spring-elasticsearch-examples[spring-elasticsearch-examples] project.
For examples on using the Spring Data for Elasticsearch, see the https://github.com/spring-projects/spring-data-examples/tree/master/elasticsearch/example[spring-data-examples] project.
== License
+28 -14
View File
@@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.0.RC2</version>
<version>3.2.1.RELEASE</version>
<parent>
<groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId>
<version>2.2.0.RC2</version>
<version>2.2.1.RELEASE</version>
</parent>
<name>Spring Data Elasticsearch</name>
@@ -19,9 +19,10 @@
<properties>
<commonslang>2.6</commonslang>
<elasticsearch>6.8.1</elasticsearch>
<elasticsearch>6.8.4</elasticsearch>
<log4j>2.9.1</log4j>
<springdata.commons>2.2.0.RC2</springdata.commons>
<springdata.commons>2.2.1.RELEASE</springdata.commons>
<netty>4.1.39.Final</netty>
<java-module-name>spring.data.elasticsearch</java-module-name>
</properties>
@@ -72,6 +73,19 @@
<url>https://jira.spring.io/browse/DATAES</url>
</issueManagement>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId>
<version>${netty}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring -->
@@ -253,14 +267,6 @@
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
<!--
please do not remove this configuration for surefire - we need that to avoid issue with jar hell
-->
@@ -278,6 +284,14 @@
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
@@ -315,8 +329,8 @@
<repositories>
<repository>
<id>spring-libs-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
<id>spring-libs-release</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
+9 -10
View File
@@ -31,15 +31,14 @@ Requires an installation of https://www.elastic.co/products/elasticsearch[Elasti
// 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 Elasticsearch:
[cols="^,^"]
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
|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[]
|===
|Spring Data Elasticsearch |Elasticsearch
|3.2.x |6.8.1
|3.1.x |6.2.2
|3.0.x |5.5.0
|2.1.x |2.4.0
|2.0.x |2.2.0
|1.3.x |1.5.2
|===
Support for upcoming versions of Elasticsearch is being tracked and general compatibility should be given assuming the usage of the <<elasticsearch.clients.rest,high-level REST client>>.
@@ -21,6 +21,7 @@ import java.time.Duration;
import java.util.List;
import java.util.Optional;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.springframework.http.HttpHeaders;
@@ -30,6 +31,7 @@ import org.springframework.http.HttpHeaders;
*
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Henrique Amaral
* @since 3.2
*/
public interface ClientConfiguration {
@@ -118,6 +120,13 @@ public interface ClientConfiguration {
*/
Optional<SSLContext> getSslContext();
/**
* Returns the {@link HostnameVerifier} to use. Can be {@link Optional#empty()} if unconfigured.
*
* @return the {@link HostnameVerifier} to use. Can be {@link Optional#empty()} if unconfigured.
*/
Optional<HostnameVerifier> getHostNameVerifier();
/**
* Returns the {@link java.time.Duration connect timeout}.
*
@@ -201,6 +210,16 @@ public interface ClientConfiguration {
* @return the {@link TerminalClientConfigurationBuilder}.
*/
TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext);
/**
* Connect via {@literal https} using the givens {@link SSLContext} and HostnameVerifier {@link HostnameVerifier} .<br />
*
* <strong>NOTE</strong> You need to leave out the protocol in
* {@link ClientConfigurationBuilderWithRequiredEndpoint#connectedTo(String)}.
*
* @return the {@link TerminalClientConfigurationBuilder}.
*/
TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext, HostnameVerifier hostnameVerifier);
}
/**
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithRequiredEndpoint;
@@ -37,6 +38,7 @@ import org.springframework.util.Assert;
* @author Christoph Strobl
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Henrique Amaral
* @since 3.2
*/
class ClientConfigurationBuilder
@@ -46,6 +48,7 @@ class ClientConfigurationBuilder
private HttpHeaders headers = HttpHeaders.EMPTY;
private boolean useSsl;
private @Nullable SSLContext sslContext;
private @Nullable HostnameVerifier hostnameVerifier;
private Duration connectTimeout = Duration.ofSeconds(10);
private Duration soTimeout = Duration.ofSeconds(5);
private String username;
@@ -103,6 +106,22 @@ class ClientConfigurationBuilder
return this;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl(javax.net.ssl.SSLContext, javax.net.ssl.HostnameVerifier)
*/
@Override
public TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext, HostnameVerifier hostnameVerifier) {
Assert.notNull(sslContext, "SSL Context must not be null");
Assert.notNull(hostnameVerifier, "Host Name Verifier must not be null");
this.useSsl = true;
this.sslContext = sslContext;
this.hostnameVerifier = hostnameVerifier;
return this;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder#withDefaultHeaders(org.springframework.http.HttpHeaders)
@@ -171,7 +190,7 @@ class ClientConfigurationBuilder
}
return new DefaultClientConfiguration(this.hosts, this.headers, this.useSsl, this.sslContext, this.soTimeout,
this.connectTimeout);
this.connectTimeout, this.hostnameVerifier);
}
private static InetSocketAddress parse(String hostAndPort) {
@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.springframework.http.HttpHeaders;
@@ -42,9 +43,10 @@ class DefaultClientConfiguration implements ClientConfiguration {
private final @Nullable SSLContext sslContext;
private final Duration soTimeout;
private final Duration connectTimeout;
private final @Nullable HostnameVerifier hostnameVerifier;
DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout) {
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable HostnameVerifier hostnameVerifier) {
this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts));
this.headers = new HttpHeaders(headers);
@@ -52,6 +54,7 @@ class DefaultClientConfiguration implements ClientConfiguration {
this.sslContext = sslContext;
this.soTimeout = soTimeout;
this.connectTimeout = connectTimeout;
this.hostnameVerifier = hostnameVerifier;
}
/*
@@ -90,6 +93,15 @@ class DefaultClientConfiguration implements ClientConfiguration {
return Optional.ofNullable(this.sslContext);
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getHostNameVerifier()
*/
@Override
public Optional<HostnameVerifier> getHostNameVerifier() {
return Optional.ofNullable(this.hostnameVerifier);
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getConnectTimeout()
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import org.apache.http.Header;
@@ -52,6 +53,7 @@ import org.springframework.util.Assert;
*
* @author Christoph Strobl
* @author Mark Paluch
* @author Henrique Amaral
* @since 3.2
*/
public final class RestClients {
@@ -87,7 +89,9 @@ public final class RestClients {
builder.setHttpClientConfigCallback(clientBuilder -> {
Optional<SSLContext> sslContext = clientConfiguration.getSslContext();
Optional<HostnameVerifier> hostNameVerifier = clientConfiguration.getHostNameVerifier();
sslContext.ifPresent(clientBuilder::setSSLContext);
hostNameVerifier.ifPresent(clientBuilder::setSSLHostnameVerifier);
if (ClientLogger.isEnabled()) {
@@ -15,31 +15,22 @@
*/
package org.springframework.data.elasticsearch.client.reactive;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import org.elasticsearch.action.ActionResponse;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ClientHttpResponse;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyExtractor;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClientResponseException;
/**
* Extension to {@link ActionResponse} that also implements {@link ClientResponse}.
* Extension to {@link ActionResponse} that also delegates to {@link ClientResponse}.
*
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @author Mark Paluch
* @since 3.2
*/
class RawActionResponse extends ActionResponse implements ClientResponse {
class RawActionResponse extends ActionResponse {
private final ClientResponse delegate;
@@ -51,139 +42,23 @@ class RawActionResponse extends ActionResponse implements ClientResponse {
return new RawActionResponse(response);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#statusCode()
*/
@Override
public HttpStatus statusCode() {
return delegate.statusCode();
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#rawStatusCode()
*/
@Override
public int rawStatusCode() {
return delegate.rawStatusCode();
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#headers()
*/
@Override
public Headers headers() {
public ClientResponse.Headers headers() {
return delegate.headers();
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#cookies()
*/
@Override
public MultiValueMap<String, ResponseCookie> cookies() {
return delegate.cookies();
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#strategies()
*/
@Override
public ExchangeStrategies strategies() {
return delegate.strategies();
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#body(org.springframework.web.reactive.function.BodyExtractor)
*/
@Override
public <T> T body(BodyExtractor<T, ? super ClientHttpResponse> extractor) {
return delegate.body(extractor);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToMono(java.lang.Class)
*/
@Override
public <T> Mono<T> bodyToMono(Class<? extends T> elementClass) {
return delegate.bodyToMono(elementClass);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToMono(org.springframework.core.ParameterizedTypeReference)
*/
@Override
public <T> Mono<T> bodyToMono(ParameterizedTypeReference<T> typeReference) {
return delegate.bodyToMono(typeReference);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToFlux(java.lang.Class)
*/
@Override
public <T> Flux<T> bodyToFlux(Class<? extends T> elementClass) {
return delegate.bodyToFlux(elementClass);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#bodyToFlux(org.springframework.core.ParameterizedTypeReference)
*/
@Override
public <T> Flux<T> bodyToFlux(ParameterizedTypeReference<T> typeReference) {
return delegate.bodyToFlux(typeReference);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntity(java.lang.Class)
*/
@Override
public <T> Mono<ResponseEntity<T>> toEntity(Class<T> bodyType) {
return delegate.toEntity(bodyType);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntity(org.springframework.core.ParameterizedTypeReference)
*/
@Override
public <T> Mono<ResponseEntity<T>> toEntity(ParameterizedTypeReference<T> typeReference) {
return delegate.toEntity(typeReference);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntityList(java.lang.Class)
*/
@Override
public <T> Mono<ResponseEntity<List<T>>> toEntityList(Class<T> elementType) {
return delegate.toEntityList(elementType);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#toEntityList(org.springframework.core.ParameterizedTypeReference)
*/
@Override
public <T> Mono<ResponseEntity<List<T>>> toEntityList(ParameterizedTypeReference<T> typeReference) {
return delegate.toEntityList(typeReference);
}
/*
* (non-Javadoc)
* @see org.springframework.web.reactive.function.client.ClientResponse#createException()
*/
@Override
public Mono<WebClientResponseException> createException() {
return delegate.createException();
}
}
@@ -81,6 +81,7 @@ import org.elasticsearch.index.reindex.AbstractBulkByScrollRequest;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.index.reindex.ReindexRequest;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.elasticsearch.index.seqno.SequenceNumbers;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.elasticsearch.tasks.TaskId;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
@@ -116,6 +117,8 @@ public class RequestConverters {
parameters.withTimeout(deleteRequest.timeout());
parameters.withVersion(deleteRequest.version());
parameters.withVersionType(deleteRequest.versionType());
parameters.withIfSeqNo(deleteRequest.ifSeqNo());
parameters.withIfPrimaryTerm(deleteRequest.ifPrimaryTerm());
parameters.withRefreshPolicy(deleteRequest.getRefreshPolicy());
parameters.withWaitForActiveShards(deleteRequest.waitForActiveShards());
return request;
@@ -315,6 +318,8 @@ public class RequestConverters {
parameters.withTimeout(indexRequest.timeout());
parameters.withVersion(indexRequest.version());
parameters.withVersionType(indexRequest.versionType());
parameters.withIfSeqNo(indexRequest.ifSeqNo());
parameters.withIfPrimaryTerm(indexRequest.ifPrimaryTerm());
parameters.withPipeline(indexRequest.getPipeline());
parameters.withRefreshPolicy(indexRequest.getRefreshPolicy());
parameters.withWaitForActiveShards(indexRequest.waitForActiveShards());
@@ -917,6 +922,20 @@ public class RequestConverters {
return this;
}
Params withIfSeqNo(long seqNo) {
if (seqNo != SequenceNumbers.UNASSIGNED_SEQ_NO) {
return putParam("if_seq_no", Long.toString(seqNo));
}
return this;
}
Params withIfPrimaryTerm(long primaryTerm) {
if (primaryTerm != SequenceNumbers.UNASSIGNED_PRIMARY_TERM) {
return putParam("if_primary_term", Long.toString(primaryTerm));
}
return this;
}
Params withWaitForActiveShards(ActiveShardCount activeShardCount) {
return withWaitForActiveShards(activeShardCount, ActiveShardCount.DEFAULT);
}
@@ -0,0 +1,52 @@
package org.springframework.data.elasticsearch.core;
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.core.convert.ElasticsearchConverter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* AbstractElasticsearchTemplate
*
* @author Sascha Woo
*/
public abstract class AbstractElasticsearchTemplate {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractElasticsearchTemplate.class);
protected ElasticsearchConverter elasticsearchConverter;
public AbstractElasticsearchTemplate(ElasticsearchConverter elasticsearchConverter) {
Assert.notNull(elasticsearchConverter, "elasticsearchConverter must not be null.");
this.elasticsearchConverter = elasticsearchConverter;
}
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);
}
}
}
@@ -104,6 +104,16 @@ public interface ElasticsearchOperations {
*/
<T> boolean putMapping(Class<T> clazz);
/**
* Create mapping for the given class and put the mapping to the given indexName and type.
*
* @param indexName
* @param type
* @param mappings
* @since 3.2
*/
<T> boolean putMapping(String indexName, String type, Class<T> clazz);
/**
* Create mapping for a given indexName and type
*
@@ -22,6 +22,7 @@ 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;
@@ -78,6 +79,7 @@ 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;
@@ -92,7 +94,6 @@ 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.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.client.support.AliasData;
@@ -140,13 +141,15 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @author Martin Choraine
* @author Farid Azaza
* @author Peter-Josef Meisch
* @author Mathias Teier
* @author Gyula Attila Csorogi
*/
public class ElasticsearchRestTemplate
public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
implements ElasticsearchOperations, EsClient<RestHighLevelClient>, ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchRestTemplate.class);
private RestHighLevelClient client;
private ElasticsearchConverter elasticsearchConverter;
private ResultsMapper resultsMapper;
private String searchTimeout;
@@ -175,8 +178,9 @@ public class ElasticsearchRestTemplate
public ElasticsearchRestTemplate(RestHighLevelClient client, ElasticsearchConverter elasticsearchConverter,
ResultsMapper resultsMapper) {
super(elasticsearchConverter);
Assert.notNull(client, "Client must not be null!");
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
this.client = client;
@@ -223,11 +227,17 @@ public class ElasticsearchRestTemplate
@Override
public boolean removeAlias(AliasQuery query) {
Assert.notNull(query.getIndexName(), "No index defined for Alias");
Assert.notNull(query.getAliasName(), "No alias defined");
IndicesAliasesRequest request = new IndicesAliasesRequest();
AliasActions aliasAction = new AliasActions(AliasActions.Type.REMOVE);
request.addAliasAction(aliasAction);
AliasActions aliasAction = IndicesAliasesRequest.AliasActions.remove() //
.index(query.getIndexName()) //
.alias(query.getAliasName());
IndicesAliasesRequest request = Requests.indexAliasesRequest() //
.addAliasAction(aliasAction);
try {
return client.indices().updateAliases(request, RequestOptions.DEFAULT).isAcknowledged();
} catch (IOException e) {
@@ -252,23 +262,7 @@ public class ElasticsearchRestTemplate
@Override
public <T> boolean putMapping(Class<T> clazz) {
if (clazz.isAnnotationPresent(Mapping.class)) {
String mappingPath = clazz.getAnnotation(Mapping.class).mappingPath();
if (hasText(mappingPath)) {
String mappings = ResourceUtil.readFileFromClasspath(mappingPath);
if (hasText(mappings)) {
return putMapping(clazz, mappings);
}
} else {
logger.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
}
}
try {
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
} catch (Exception e) {
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
}
return putMapping(clazz, buildMapping(clazz));
}
@Override
@@ -277,6 +271,11 @@ public class ElasticsearchRestTemplate
mapping);
}
@Override
public <T> boolean putMapping(String indexName, String type, Class<T> 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()");
@@ -714,26 +713,39 @@ public class ElasticsearchRestTemplate
}
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 IndexRequest define for Query");
UpdateRequest updateRequest = new UpdateRequest(indexName, type, query.getId());
updateRequest.routing(query.getUpdateRequest().routing());
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
if (query.getUpdateRequest().script() == null) {
// doc
if (query.DoUpsert()) {
updateRequest.docAsUpsert(true).doc(query.getUpdateRequest().doc());
} else {
updateRequest.doc(query.getUpdateRequest().doc());
}
} else {
// or script
updateRequest.script(query.getUpdateRequest().script());
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());
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;
@@ -948,6 +960,27 @@ public class ElasticsearchRestTemplate
prepareSort(query, searchSourceBuilder, entity);
}
if (query.getIndicesOptions() != null) {
request.indicesOptions(query.getIndicesOptions());
}
if (query instanceof SearchQuery) {
SearchQuery searchQuery = (SearchQuery) 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;
}
@@ -1328,25 +1361,44 @@ public class ElasticsearchRestTemplate
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()) {
ElasticsearchPersistentProperty property = entity != null //
? entity.getPersistentProperty(order.getProperty()) //
: null;
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");
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);
}
sourceBuilder.sort(sort);
}
}
@@ -1439,11 +1491,12 @@ public class ElasticsearchRestTemplate
try {
JsonNode node = mapper.readTree(aliasResponse);
Iterator<String> names = node.fieldNames();
String name = names.next();
node = node.findValue("aliases");
if (node == null) {
return Collections.emptyList();
}
Map<String, AliasData> aliasData = mapper.readValue(mapper.writeValueAsString(node),
new TypeReference<Map<String, AliasData>>() {});
@@ -47,6 +47,7 @@ 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;
@@ -82,7 +83,6 @@ 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.Mapping;
import org.springframework.data.elasticsearch.annotations.Setting;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
@@ -122,16 +122,16 @@ import org.springframework.util.StringUtils;
* @author Peter-Josef Meisch
* @author Martin Choraine
* @author Farid Azaza
* @author Gyula Attila Csorogi
*/
public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
implements ElasticsearchOperations, EsClient<Client>, ApplicationContextAware {
private static final Logger QUERY_LOGGER = LoggerFactory
.getLogger("org.springframework.data.elasticsearch.core.QUERY");
private static final Logger LOGGER = LoggerFactory.getLogger(ElasticsearchTemplate.class);
private static final String FIELD_SCORE = "_score";
private Client client;
private ElasticsearchConverter elasticsearchConverter;
private ResultsMapper resultsMapper;
private String searchTimeout;
@@ -160,12 +160,12 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
public ElasticsearchTemplate(Client client, ElasticsearchConverter elasticsearchConverter,
ResultsMapper resultsMapper) {
super(elasticsearchConverter);
Assert.notNull(client, "Client must not be null!");
Assert.notNull(elasticsearchConverter, "ElasticsearchConverter must not be null!");
Assert.notNull(resultsMapper, "ResultsMapper must not be null!");
this.client = client;
this.elasticsearchConverter = elasticsearchConverter;
this.resultsMapper = resultsMapper;
}
@@ -220,23 +220,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
@Override
public <T> boolean putMapping(Class<T> clazz) {
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 putMapping(clazz, mappings);
}
} else {
LOGGER.info("mappingPath in @Mapping has to be defined. Building mappings using @Field");
}
}
try {
MappingBuilder mappingBuilder = new MappingBuilder(elasticsearchConverter);
return putMapping(clazz, mappingBuilder.buildPropertyMapping(clazz));
} catch (Exception e) {
throw new ElasticsearchException("Failed to build mapping for " + clazz.getSimpleName(), e);
}
return putMapping(clazz, buildMapping(clazz));
}
@Override
@@ -245,6 +229,11 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
mapping);
}
@Override
public <T> boolean putMapping(String indexName, String type, Class<T> 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()");
@@ -609,27 +598,40 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
}
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 IndexRequest define for Query");
UpdateRequestBuilder updateRequestBuilder = client.prepareUpdate(indexName, type, query.getId());
updateRequestBuilder.setRouting(query.getUpdateRequest().routing());
Assert.notNull(query.getUpdateRequest(), "No UpdateRequest define for Query");
if (query.getUpdateRequest().script() == null) {
// doc
if (query.DoUpsert()) {
updateRequestBuilder.setDocAsUpsert(true).setDoc(query.getUpdateRequest().doc());
} else {
updateRequestBuilder.setDoc(query.getUpdateRequest().doc());
}
} else {
// or script
updateRequestBuilder.setScript(query.getUpdateRequest().script());
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;
@@ -808,6 +810,27 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
prepareSort(query, requestBuilder, entity);
}
if (query.getIndicesOptions() != null) {
requestBuilder.setIndicesOptions(query.getIndicesOptions());
}
if (query instanceof SearchQuery) {
SearchQuery searchQuery = (SearchQuery) 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;
}
@@ -1072,7 +1095,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
private <T> SearchRequestBuilder prepareSearch(Query query, Class<T> clazz) {
setPersistentEntityIndexAndType(query, clazz);
return prepareSearch(query, getPersistentEntity(clazz));
return prepareSearch(query, getPersistentEntity(clazz));
}
private SearchRequestBuilder prepareSearch(Query query, @Nullable ElasticsearchPersistentEntity<?> entity) {
@@ -1123,7 +1146,7 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, EsClient<
for (Sort.Order order : query.getSort()) {
SortOrder sortOrder = order.getDirection().isDescending() ? SortOrder.DESC : SortOrder.ASC;
if (FIELD_SCORE.equals(order.getProperty())) {
if (ScoreSortBuilder.NAME.equals(order.getProperty())) {
ScoreSortBuilder sort = SortBuilders //
.scoreSort() //
.order(sortOrder);
@@ -78,6 +78,7 @@ import org.springframework.util.Assert;
* @author Farid Azaza
* @author Martin Choraine
* @author Peter-Josef Meisch
* @author Mathias Teier
* @since 3.2
*/
public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOperations {
@@ -283,6 +284,10 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
request.preference(query.getPreference());
}
if (query.getSearchType() != null) {
request.searchType(query.getSearchType());
}
Pageable pageable = query.getPageable();
if (pageable.isPaged()) {
@@ -1,2 +1,6 @@
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
http\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-1.0.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-1.0.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch-3.2.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
https\://www.springframework.org/schema/data/elasticsearch/spring-elasticsearch.xsd=org/springframework/data/elasticsearch/config/spring-elasticsearch-3.2.xsd
+41
View File
@@ -1,6 +1,47 @@
Spring Data Elasticsearch Changelog
===================================
Changes in version 3.2.1.RELEASE (2019-11-04)
---------------------------------------------
* DATAES-679 - Upgrade to Elasticsearch 6.8.4.
* DATAES-673 - Create a Ssl Rest Client using SslContext and HostnameVerifier.
* DATAES-671 - Missing indicesOptions support for scrolling queries.
* DATAES-670 - fix version compatibility matrix in documentation.
* DATAES-665 - Javadoc not deployed.
* DATAES-662 - Release 3.2.1 (Moore SR1).
Changes in version 3.1.12.RELEASE (2019-11-04)
----------------------------------------------
* DATAES-660 - Release 3.1.12 (Lovelace SR12).
Changes in version 3.2.0.RELEASE (2019-09-30)
---------------------------------------------
* DATAES-657 - Sort by _score not supported by ElasticsearchRestTemplate.
* DATAES-652 - Send if_seq_no and if_primary_term parameters when indexing via ReactiveElasticsearchClient.
* DATAES-648 - Unify documentation of version compatibilities.
* DATAES-625 - Release 3.2 GA (Moore).
* DATAES-541 - IllegalArgumentException on ElasticsearchRestTemplate#removeAlias.
* DATAES-305 - let users create mappings with dynamical indexName.
* DATAES-227 - ElasticsearchTemplate.prepareUpdate should call setUpsert.
Changes in version 3.1.11.RELEASE (2019-09-30)
----------------------------------------------
* DATAES-627 - Add HTTPS entries into spring.schemas.
* DATAES-624 - Release 3.1.11 (Lovelace SR11).
Changes in version 3.2.0.RC3 (2019-09-06)
-----------------------------------------
* DATAES-646 - Adapt to Spring Framework 5.2 RC2.
* DATAES-645 - Missing highlight support for scrolling queries.
* DATAES-643 - RestTemplate ignores search_type.
* DATAES-627 - Add HTTPS entries into spring.schemas.
* DATAES-626 - Release 3.2 RC3 (Moore).
Changes in version 3.2.0.RC2 (2019-08-05)
-----------------------------------------
* DATAES-619 - Migrate remaining tests to AssertJ.
+1 -1
View File
@@ -1,4 +1,4 @@
Spring Data Elasticsearch 3.2 RC2
Spring Data Elasticsearch 3.2.1
Copyright (c) [2013-2019] Pivotal Software, Inc.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
@@ -23,6 +23,7 @@ import java.time.Duration;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.junit.Test;
import org.springframework.http.HttpHeaders;
@@ -31,6 +32,7 @@ import org.springframework.http.HttpHeaders;
*
* @author Mark Paluch
* @author Peter-Josef Meisch
* @author Henrique Amaral
*/
public class ClientConfigurationUnitTests {
@@ -117,6 +119,25 @@ public class ClientConfigurationUnitTests {
assertThat(defaultHeaders.get(HttpHeaders.AUTHORIZATION)).isNull();
}
@Test // DATAES-673
public void shouldCreateSslConfigurationWithHostnameVerifier() {
SSLContext sslContext = mock(SSLContext.class);
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
.connectedTo("foo", "bar") //
.usingSsl(sslContext, NoopHostnameVerifier.INSTANCE) //
.build();
assertThat(clientConfiguration.getEndpoints()).containsOnly(InetSocketAddress.createUnresolved("foo", 9200),
InetSocketAddress.createUnresolved("bar", 9200));
assertThat(clientConfiguration.useSsl()).isTrue();
assertThat(clientConfiguration.getSslContext()).contains(sslContext);
assertThat(clientConfiguration.getConnectTimeout()).isEqualTo(Duration.ofSeconds(10));
assertThat(clientConfiguration.getSocketTimeout()).isEqualTo(Duration.ofSeconds(5));
assertThat(clientConfiguration.getHostNameVerifier()).contains(NoopHostnameVerifier.INSTANCE);
}
private static String buildBasicAuth(String username, String password) {
HttpHeaders headers = new HttpHeaders();
@@ -0,0 +1,91 @@
/*
* 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.client.util;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.util.HashMap;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.Request;
import org.junit.Test;
/**
* Unit tests for {@link RequestConverters}.
*
* @author Roman Puchkovskiy
*/
public class RequestConvertersTest {
@Test // DATAES-652
public void shouldNotAddIfSeqNoAndIfPrimaryTermToResultIfInputDoesNotcontainThemWhenConvertingIndexRequest() {
IndexRequest request = createMinimalIndexRequest();
Request result = RequestConverters.index(request);
assertThat(result.getParameters(), not(hasKey("if_seq_no")));
assertThat(result.getParameters(), not(hasKey("if_primary_term")));
}
private IndexRequest createMinimalIndexRequest() {
IndexRequest request = new IndexRequest("the-index", "the-type", "id");
request.source(new HashMap<String, String>() {
{
put("test", "test");
}
});
return request;
}
@Test // DATAES-652
public void shouldAddIfSeqNoAndIfPrimaryTermToResultIfInputcontainsThemWhenConvertingIndexRequest() {
IndexRequest request = createMinimalIndexRequest();
request.setIfSeqNo(3);
request.setIfPrimaryTerm(4);
Request result = RequestConverters.index(request);
assertThat(result.getParameters(), hasEntry("if_seq_no", "3"));
assertThat(result.getParameters(), hasEntry("if_primary_term", "4"));
}
@Test // DATAES-652
public void shouldNotAddIfSeqNoAndIfPrimaryTermToResultIfInputDoesNotcontainThemWhenConvertingDeleteRequest() {
DeleteRequest request = createMinimalDeleteRequest();
Request result = RequestConverters.delete(request);
assertThat(result.getParameters(), not(hasKey("if_seq_no")));
assertThat(result.getParameters(), not(hasKey("if_primary_term")));
}
private DeleteRequest createMinimalDeleteRequest() {
return new DeleteRequest("the-index", "the-type", "id");
}
@Test // DATAES-652
public void shouldAddIfSeqNoAndIfPrimaryTermToResultIfInputcontainsThemWhenConvertingDeleteRequest() {
DeleteRequest request = createMinimalDeleteRequest();
request.setIfSeqNo(3);
request.setIfPrimaryTerm(4);
Request result = RequestConverters.delete(request);
assertThat(result.getParameters(), hasEntry("if_seq_no", "3"));
assertThat(result.getParameters(), hasEntry("if_primary_term", "4"));
}
}
@@ -1,222 +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 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 lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.lang.Long;
import java.lang.Object;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.elasticsearch.cluster.metadata.AliasMetaData;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Version;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.core.query.AliasBuilder;
import org.springframework.data.elasticsearch.core.query.AliasQuery;
import org.springframework.data.elasticsearch.core.query.IndexQuery;
import org.springframework.data.elasticsearch.core.query.IndexQueryBuilder;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.data.elasticsearch.utils.IndexInitializer;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author Mohsin Husen
* @author Ilkang Na
* @author Peter-Josef Meisch
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
public class AliasTests {
private static final String INDEX_NAME_1 = "test-alias-index-1";
private static final String INDEX_NAME_2 = "test-alias-index-2";
private static final String TYPE_NAME = "test-alias-type";
private static Map<String, Object> settings = new HashMap<>();
static {
settings.put("index.refresh_interval", "-1");
settings.put("index.number_of_replicas", "0");
settings.put("index.number_of_shards", "2");
settings.put("index.store.type", "fs");
}
@Autowired private ElasticsearchTemplate elasticsearchTemplate;
@Before
public void before() {
elasticsearchTemplate.deleteIndex(INDEX_NAME_1);
elasticsearchTemplate.createIndex(INDEX_NAME_1, settings);
elasticsearchTemplate.refresh(INDEX_NAME_1);
elasticsearchTemplate.deleteIndex(INDEX_NAME_2);
elasticsearchTemplate.createIndex(INDEX_NAME_2, settings);
elasticsearchTemplate.refresh(INDEX_NAME_2);
IndexInitializer.init(elasticsearchTemplate, AliasedEntity.class);
}
@Test
public void shouldAddAlias() {
// given
String aliasName = "test-alias";
AliasQuery aliasQuery = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(aliasName).build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
// then
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
assertThat(aliases).isNotNull();
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
}
@Test
public void shouldRemoveAlias() {
// given
String indexName = INDEX_NAME_1;
String aliasName = "test-alias";
AliasQuery aliasQuery = new AliasBuilder().withIndexName(indexName).withAliasName(aliasName).build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(indexName);
assertThat(aliases).isNotNull();
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
// then
elasticsearchTemplate.removeAlias(aliasQuery);
aliases = elasticsearchTemplate.queryForAlias(indexName);
assertThat(aliases).isEmpty();
}
@Test // DATAES-70
public void shouldAddAliasWithGivenRoutingValue() {
// given
String alias = "test-alias";
AliasQuery aliasQuery = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(alias).withRouting("0")
.build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
String documentId = randomNumeric(5);
AliasedEntity aliasedEntity = AliasedEntity.builder().id(documentId).message("some message")
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(alias).withId(aliasedEntity.getId())
.withType(TYPE_NAME).withObject(aliasedEntity).build();
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.refresh(INDEX_NAME_1);
SearchQuery query = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).withIndices(alias)
.withTypes(TYPE_NAME).build();
long count = elasticsearchTemplate.count(query);
// then
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
assertThat(aliases).isNotNull();
AliasMetaData aliasMetaData = aliases.get(0);
assertThat(aliasMetaData.alias()).isEqualTo(alias);
assertThat(aliasMetaData.searchRouting()).isEqualTo("0");
assertThat(aliasMetaData.indexRouting()).isEqualTo("0");
assertThat(count).isEqualTo(1);
// cleanup
elasticsearchTemplate.removeAlias(aliasQuery);
}
@Test // DATAES-70
public void shouldAddAliasForVariousRoutingValues() {
// given
String alias1 = "test-alias-1";
String alias2 = "test-alias-2";
AliasQuery aliasQuery1 = new AliasBuilder().withIndexName(INDEX_NAME_1).withAliasName(alias1).withIndexRouting("0")
.build();
AliasQuery aliasQuery2 = new AliasBuilder().withIndexName(INDEX_NAME_2).withAliasName(alias2).withSearchRouting("1")
.build();
// when
elasticsearchTemplate.addAlias(aliasQuery1);
elasticsearchTemplate.addAlias(aliasQuery2);
String documentId = randomNumeric(5);
AliasedEntity aliasedEntity = AliasedEntity.builder().id(documentId).message("some message")
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery = new IndexQueryBuilder().withIndexName(alias1).withType(TYPE_NAME)
.withId(aliasedEntity.getId()).withObject(aliasedEntity).build();
elasticsearchTemplate.index(indexQuery);
// then
List<AliasMetaData> responseAlias1 = elasticsearchTemplate.queryForAlias(INDEX_NAME_1);
assertThat(responseAlias1).isNotNull();
AliasMetaData aliasMetaData1 = responseAlias1.get(0);
assertThat(aliasMetaData1.alias()).isEqualTo(alias1);
assertThat(aliasMetaData1.indexRouting()).isEqualTo("0");
List<AliasMetaData> responseAlias2 = elasticsearchTemplate.queryForAlias(INDEX_NAME_2);
assertThat(responseAlias2).isNotNull();
AliasMetaData aliasMetaData2 = responseAlias2.get(0);
assertThat(aliasMetaData2.alias()).isEqualTo(alias2);
assertThat(aliasMetaData2.searchRouting()).isEqualTo("1");
// cleanup
elasticsearchTemplate.removeAlias(aliasQuery1);
elasticsearchTemplate.removeAlias(aliasQuery2);
}
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(indexName = "test-index-sample-core-alias", type = "test-type", shards = 1, replicas = 0,
refreshInterval = "-1")
static class AliasedEntity {
@Id private String id;
@Field(type = Text, store = true, fielddata = true) private String message;
@Version private Long version;
}
}
@@ -16,17 +16,22 @@
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 lombok.Builder;
import lombok.Data;
import java.io.IOException;
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.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
@@ -34,6 +39,7 @@ import org.springframework.data.elasticsearch.core.query.UpdateQuery;
import org.springframework.data.elasticsearch.core.query.UpdateQueryBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
/**
* @author Rizwan Idrees
@@ -64,6 +70,33 @@ public class ElasticsearchRestTemplateTests extends ElasticsearchTemplateTests {
elasticsearchTemplate.update(updateQuery);
}
@Test // DATAES-227
@Override
public void shouldUseUpsertOnUpdate() throws IOException {
// given
Map<String, Object> 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();
}
@Data
@Builder
@Document(indexName = "test-index-sample-core-rest-template", type = "test-type", shards = 1, replicas = 0,
@@ -27,10 +27,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import java.lang.Double;
import java.lang.Integer;
import java.lang.Long;
import java.lang.Object;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -49,6 +46,9 @@ import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchResponse;
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;
@@ -81,10 +81,12 @@ import org.springframework.data.elasticsearch.annotations.ScriptedField;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.util.CloseableIterator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
/**
* Base for testing rest/transport templates
@@ -107,6 +109,7 @@ import org.springframework.test.context.junit4.SpringRunner;
* @author Peter-Josef Meisch
* @author Martin Choraine
* @author Farid Azaza
* @author Gyula Attila Csorogi
*/
@RunWith(SpringRunner.class)
@ContextConfiguration("classpath:elasticsearch-template-test.xml")
@@ -786,26 +789,30 @@ public class ElasticsearchTemplateTests {
assertThat(sampleEntities.getContent().get(1).getMessage()).isEqualTo(sampleEntity2.getMessage());
}
@Test // DATAES-467
@Test // DATAES-467, DATAES-657
public void shouldSortResultsByScore() {
// given
List<SampleEntity> entities = Arrays.asList( //
SampleEntity.builder().id("1").message("abc").build(), //
SampleEntity.builder().id("2").message("def").build(), //
SampleEntity.builder().id("3").message("ghi").build());
SampleEntity.builder().id("1").message("green").build(), //
SampleEntity.builder().id("2").message("yellow green").build(), //
SampleEntity.builder().id("3").message("blue").build());
elasticsearchTemplate.bulkIndex(getIndexQueries(entities));
elasticsearchTemplate.refresh(SampleEntity.class);
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("_score")))).build();
SearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(matchQuery("message", "green")) //
.withPageable(PageRequest.of(0, 10, Sort.by(Sort.Order.asc("_score")))) //
.build();
// when
Page<SampleEntity> sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
Page<SampleEntity> page = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class);
// then
assertThat(sampleEntities.getTotalElements()).isEqualTo(3);
assertThat(page.getTotalElements()).isEqualTo(2);
assertThat(page.getContent().get(0).getId()).isEqualTo("2");
assertThat(page.getContent().get(1).getId()).isEqualTo("1");
}
@Test
@@ -1435,6 +1442,22 @@ public class ElasticsearchTemplateTests {
assertThat(elasticsearchTemplate.putMapping(entity)).isTrue();
}
@Test // DATAES-305
public void shouldPutMappingWithCustomIndexName() throws Exception {
// given
Class<SampleEntity> entity = SampleEntity.class;
elasticsearchTemplate.deleteIndex(INDEX_1_NAME);
elasticsearchTemplate.createIndex(INDEX_1_NAME);
// when
elasticsearchTemplate.putMapping(INDEX_1_NAME, TYPE_NAME, entity);
// then
Map<String, Object> mapping = elasticsearchTemplate.getMapping(INDEX_1_NAME, TYPE_NAME);
assertThat(mapping.get("properties")).isNotNull();
}
@Test
public void shouldDeleteIndexForGivenEntity() {
@@ -1479,6 +1502,33 @@ public class ElasticsearchTemplateTests {
assertThat(indexedEntity.getMessage()).isEqualTo(messageAfterUpdate);
}
@Test // DATAES-227
public void shouldUseUpsertOnUpdate() throws IOException {
// given
Map<String, Object> 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 = ((UpdateRequestBuilder) ReflectionTestUtils //
.invokeMethod(elasticsearchTemplate, "prepareUpdate", updateQuery)) //
.request();
// then
assertThat(request).isNotNull();
assertThat(request.upsertRequest()).isNotNull();
}
@Test
public void shouldDoUpsertIfDocumentDoesNotExist() {
@@ -1589,6 +1639,114 @@ public class ElasticsearchTemplateTests {
});
}
@Test // DATAES-645
public void shouldReturnHighlightedFieldsInScroll() {
// given
long scrollTimeInMillis = 3000;
String documentId = randomNumeric(5);
String actualType = "some test type";
String actualMessage = "some test message";
String highlightedType = "some <em>test</em> type";
String highlightedMessage = "some <em>test</em> message";
SampleEntity sampleEntity = SampleEntity.builder().id(documentId).type(actualType).message(actualMessage)
.version(System.currentTimeMillis()).build();
IndexQuery indexQuery = getIndexQuery(sampleEntity);
elasticsearchTemplate.index(indexQuery);
elasticsearchTemplate.refresh(SampleEntity.class);
HighlightBuilder highlightBuilder = new HighlightBuilder().field("type").field("message");
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(boolQuery().must(termQuery("type", "test")).must(termQuery("message", "test")))
.withPageable(PageRequest.of(0, 10)).withHighlightBuilder(highlightBuilder).build();
SearchResultMapper searchResultMapper = new SearchResultMapper() {
@Override
public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {
DefaultEntityMapper defaultEntityMapper = new DefaultEntityMapper(new SimpleElasticsearchMappingContext());
ArrayList<T> result = new ArrayList<>();
for (SearchHit searchHit : response.getHits()) {
try {
result.add((T) defaultEntityMapper.mapToObject(searchHit.getSourceAsString(), SampleEntity.class));
} catch (IOException e) {
e.printStackTrace();
}
Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
HighlightField highlightFieldType = highlightFields.get("type");
HighlightField highlightFieldMessage = highlightFields.get("message");
// then
assertThat(highlightFieldType).isNotNull();
assertThat(highlightFieldMessage).isNotNull();
assertThat(highlightFieldType.fragments()[0].toString()).isEqualTo(highlightedType);
assertThat(highlightFieldMessage.fragments()[0].toString()).isEqualTo(highlightedMessage);
}
return new AggregatedPageImpl<>(result, pageable, response.getHits().getTotalHits(), response.getAggregations(),
response.getScrollId(), response.getHits().getMaxScore());
}
@Override
public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
return null;
}
};
// when
ScrolledPage<SampleEntity> scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery,
SampleEntity.class, searchResultMapper);
while (scroll.hasContent()) {
scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class,
searchResultMapper);
}
elasticsearchTemplate.clearScroll(scroll.getScrollId());
}
@Test // DATAES-671
public void shouldPassIndicesOptionsForGivenSearchScrollQuery() {
// given
long scrollTimeInMillis = 3000;
String documentId = randomNumeric(5);
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();
elasticsearchTemplate.index(idxQuery);
elasticsearchTemplate.refresh(INDEX_1_NAME);
// when
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery())
.withIndices(INDEX_1_NAME, INDEX_2_NAME).withIndicesOptions(IndicesOptions.lenientExpandOpen()).build();
List<SampleEntity> entities = new ArrayList<>();
ScrolledPage<SampleEntity> scroll = elasticsearchTemplate.startScroll(scrollTimeInMillis, searchQuery,
SampleEntity.class, searchResultMapper);
entities.addAll(scroll.getContent());
while (scroll.hasContent()) {
scroll = elasticsearchTemplate.continueScroll(scroll.getScrollId(), scrollTimeInMillis, SampleEntity.class,
searchResultMapper);
entities.addAll(scroll.getContent());
}
// then
assertThat(entities).isNotNull();
assertThat(entities.size()).isGreaterThanOrEqualTo(1);
}
@Test // DATAES-479
public void shouldHonorTheHighlightBuilderOptions() {
@@ -2869,6 +3027,158 @@ public class ElasticsearchTemplateTests {
return indexQueries;
}
@Test
public void shouldAddAlias() {
// given
String aliasName = "test-alias";
AliasQuery aliasQuery = new AliasBuilder() //
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
.withAliasName(aliasName) //
.build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
// then
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
assertThat(aliases).isNotNull();
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
}
@Test // DATAES-70
public void shouldAddAliasForVariousRoutingValues() {
// given
String alias1 = "test-alias-1";
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);
String documentId = randomNumeric(5);
SampleEntity entity = SampleEntity.builder() //
.id(documentId) //
.message("some message") //
.version(System.currentTimeMillis()) //
.build();
IndexQuery indexQuery = new IndexQueryBuilder() //
.withIndexName(alias1) //
.withType(TYPE_NAME) //
.withId(entity.getId()) //
.withObject(entity) //
.build();
elasticsearchTemplate.index(indexQuery);
// then
List<AliasMetaData> aliasMetaData = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
assertThat(aliasMetaData).isNotEmpty();
AliasMetaData aliasMetaData1 = aliasMetaData.get(0);
assertThat(aliasMetaData1).isNotNull();
assertThat(aliasMetaData1.alias()).isEqualTo(alias1);
assertThat(aliasMetaData1.indexRouting()).isEqualTo("0");
AliasMetaData aliasMetaData2 = aliasMetaData.get(1);
assertThat(aliasMetaData2).isNotNull();
assertThat(aliasMetaData2.alias()).isEqualTo(alias2);
assertThat(aliasMetaData2.searchRouting()).isEqualTo("1");
// cleanup
elasticsearchTemplate.removeAlias(aliasQuery1);
elasticsearchTemplate.removeAlias(aliasQuery2);
}
@Test // DATAES-70
public void shouldAddAliasWithGivenRoutingValue() {
// given
String alias = "test-alias";
AliasQuery aliasQuery = new AliasBuilder() //
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
.withAliasName(alias) //
.withRouting("0") //
.build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
String documentId = randomNumeric(5);
SampleEntity sampleEntity = SampleEntity.builder() //
.id(documentId) //
.message("some message") //
.version(System.currentTimeMillis()) //
.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);
SearchQuery query = new NativeSearchQueryBuilder() //
.withQuery(matchAllQuery()) //
.withIndices(alias) //
.withTypes(TYPE_NAME) //
.build();
long count = elasticsearchTemplate.count(query);
// then
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
assertThat(aliases).isNotNull();
AliasMetaData aliasMetaData = aliases.get(0);
assertThat(aliasMetaData.alias()).isEqualTo(alias);
assertThat(aliasMetaData.searchRouting()).isEqualTo("0");
assertThat(aliasMetaData.indexRouting()).isEqualTo("0");
assertThat(count).isEqualTo(1);
// cleanup
elasticsearchTemplate.removeAlias(aliasQuery);
}
@Test // DATAES-541
public void shouldRemoveAlias() {
// given
String aliasName = "test-alias";
AliasQuery aliasQuery = new AliasBuilder() //
.withIndexName(INDEX_NAME_SAMPLE_ENTITY) //
.withAliasName(aliasName) //
.build();
// when
elasticsearchTemplate.addAlias(aliasQuery);
List<AliasMetaData> aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
assertThat(aliases).isNotNull();
assertThat(aliases.get(0).alias()).isEqualTo(aliasName);
// then
elasticsearchTemplate.removeAlias(aliasQuery);
aliases = elasticsearchTemplate.queryForAlias(INDEX_NAME_SAMPLE_ENTITY);
assertThat(aliases).isEmpty();
}
@Document(indexName = INDEX_2_NAME, replicas = 0, shards = 1)
class ResultAggregator {
@@ -20,7 +20,7 @@
description=Adds "built in" analyzers to Elasticsearch.
#
# 'version': plugin's version
version=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -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=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Lucene expressions integration for Elasticsearch
#
# 'version': plugin's version
version=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=An easy, safe and fast scripting language for Elasticsearch
#
# 'version': plugin's version
version=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Adds advanced field mappers
#
# 'version': plugin's version
version=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -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=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
@@ -20,7 +20,7 @@
description=Module for URL repository
#
# 'version': plugin's version
version=6.8.1
version=6.8.4
#
# '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=6.8.1
elasticsearch.version=6.8.4
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI