Compare commits

...

42 Commits

Author SHA1 Message Date
Mark Paluch
4c12979bb0 DATAES-704 - Release version 3.2.4 (Moore SR4). 2020-01-15 12:37:44 +01:00
Mark Paluch
2c1613cac0 DATAES-704 - Prepare 3.2.4 (Moore SR4). 2020-01-15 12:37:18 +01:00
Mark Paluch
5a92340829 DATAES-704 - Updated changelog. 2020-01-15 12:37:16 +01:00
Mark Paluch
e317bef992 DATAES-703 - Updated changelog. 2020-01-15 10:36:37 +01:00
Mark Paluch
be7ae214a4
DATAES-725 - Update copyright years to 2020. 2020-01-07 09:08:12 +01:00
Peter-Josef Meisch
6eda05ddd7 DATAES-720 - SimpleReactiveElasticsearchRepository findAll() returns only 10 elements.
Original PR: #364

(cherry picked from commit b634f318abe771b98d01bc38a3885ffb20e5368f)
2019-12-25 11:34:13 +01:00
Peter-Josef Meisch
283b27d170 DATAES-719 - Add customization hook for reactive WebClient.
Original PR: #363

(cherry picked from commit f7a14c1135189a62675a3345d70ccb1a6ec16af4)
2019-12-25 09:09:43 +01:00
Peter-Josef Meisch
b731b47b1b DATAES-719 - Add customization hook for reactive WebClient.
Original PR: #363

(cherry picked from commit f7a14c1135189a62675a3345d70ccb1a6ec16af4)
2019-12-25 09:07:56 +01:00
Sascha Woo
31a391522a DATAES-702 - Travis CI builds currently broken.
Original PR: #351
2019-12-13 13:08:33 +01:00
Peter-Josef Meisch
0a0ac102cc
DATAES-705_-_Add-support-for-PathPrefix-to-clients-in-3_2_x.
Original PR: #354
2019-12-07 15:42:09 +01:00
Jens Schauder
325fdb47c6 DATAES-692 - After release cleanups. 2019-12-04 14:29:17 +01:00
Jens Schauder
fdee09dc04 DATAES-692 - Prepare next development iteration. 2019-12-04 14:29:15 +01:00
Jens Schauder
060cab76d5 DATAES-692 - Release version 3.2.3 (Moore SR3). 2019-12-04 14:12:24 +01:00
Jens Schauder
afb8a35eac DATAES-692 - Prepare 3.2.3 (Moore SR3). 2019-12-04 14:11:44 +01:00
Jens Schauder
1c0dd71020 DATAES-692 - Updated changelog. 2019-12-04 14:11:42 +01:00
Jens Schauder
1633668d7f DATAES-691 - Updated changelog. 2019-12-04 12:09:51 +01:00
Peter-Josef Meisch
6756f792c8
DATAES-699 - Fix count implementation.
Original PR: #349
2019-12-01 10:03:56 +01:00
Peter-Josef Meisch
bae4db8a7f DATAES-700 - Enable proxy support for RestClient. 2019-11-30 23:30:59 +01:00
Mark Paluch
c47fd2cfce DATAES-685 - After release cleanups. 2019-11-18 12:42:05 +01:00
Mark Paluch
cb08bb7196 DATAES-685 - Prepare next development iteration. 2019-11-18 12:42:04 +01:00
Mark Paluch
f3500623ff DATAES-685 - Release version 3.2.2 (Moore SR2). 2019-11-18 12:32:12 +01:00
Mark Paluch
4c4cbed43b DATAES-685 - Prepare 3.2.2 (Moore SR2). 2019-11-18 12:31:53 +01:00
Mark Paluch
23fb5689b7 DATAES-685 - Updated changelog. 2019-11-18 12:31:52 +01:00
Mark Paluch
b551466f94 DATAES-683 - Updated changelog. 2019-11-18 12:16:28 +01:00
Peter-Josef Meisch
0a7af69d69 DATAES-680 - Fix missing import. 2019-11-08 17:03:37 +01:00
Peter-Josef Meisch
2cf42a4763 DATAES-680 - ReactiveElasticsearchTemplate-should-use-the-count-API.
Original PR: #341

(cherry picked from commit 62385edaa568e9e3ebbfc56ad59e76ffd72b47f8)
2019-11-07 17:07:39 +01:00
Peter-Josef Meisch
6f0d1ee9e7 DATAES-684 - Polishing.
(cherry picked from commit 24751972a8f266281e948eaf5f73f66003d4b896)
2019-11-05 10:41:21 +01:00
Henrique Amaral
f82dd229d9 DATAES-684 Implement bulk request from reactive client
Original PR: #342

* DATAES-684 Implement bulk request from reactive client

* Update src/main/java/org/springframework/data/elasticsearch/client/reactive/ReactiveElasticsearchClient.java

Co-Authored-By: Peter-Josef Meisch <pj.meisch@sothawo.com>

* DATAES-684 Implement bulk request from reactive client

Added author

(cherry picked from commit 6ae424428ccc45d72b80dcd3ddb7e3fbc6f32073)
2019-11-05 10:39:40 +01:00
Christoph Strobl
3b833f6f63 DATAES-662 - After release cleanups. 2019-11-04 15:34:27 +01:00
Christoph Strobl
2517fd5c90 DATAES-662 - Prepare next development iteration. 2019-11-04 15:34:26 +01:00
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
298 changed files with 1244 additions and 473 deletions

View File

@ -1,22 +1,8 @@
dist: xenial
language: java language: java
jdk: jdk:
- oraclejdk8 - openjdk8
before_install: script: "mvn clean dependency:list test -Dsort -U -B"
- 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
script: "mvn clean dependency:list test -Dsort"

8
Jenkinsfile vendored
View File

@ -3,7 +3,7 @@ pipeline {
triggers { triggers {
pollSCM 'H/10 * * * *' 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 { options {
@ -15,7 +15,7 @@ pipeline {
stage("Test") { stage("Test") {
when { when {
anyOf { anyOf {
branch 'master' branch '3.2.x'
not { triggeredBy 'UpstreamCause' } not { triggeredBy 'UpstreamCause' }
} }
} }
@ -39,7 +39,7 @@ pipeline {
stage('Release to artifactory') { stage('Release to artifactory') {
when { when {
anyOf { anyOf {
branch 'master' branch '3.2.x'
not { triggeredBy 'UpstreamCause' } not { triggeredBy 'UpstreamCause' }
} }
} }
@ -70,7 +70,7 @@ pipeline {
} }
stage('Publish documentation') { stage('Publish documentation') {
when { when {
branch 'master' branch '3.2.x'
} }
agent { agent {
docker { docker {

46
pom.xml
View File

@ -5,12 +5,12 @@
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId> <artifactId>spring-data-elasticsearch</artifactId>
<version>3.2.0.RELEASE</version> <version>3.2.4.RELEASE</version>
<parent> <parent>
<groupId>org.springframework.data.build</groupId> <groupId>org.springframework.data.build</groupId>
<artifactId>spring-data-parent</artifactId> <artifactId>spring-data-parent</artifactId>
<version>2.2.0.RELEASE</version> <version>2.2.4.RELEASE</version>
</parent> </parent>
<name>Spring Data Elasticsearch</name> <name>Spring Data Elasticsearch</name>
@ -19,9 +19,9 @@
<properties> <properties>
<commonslang>2.6</commonslang> <commonslang>2.6</commonslang>
<elasticsearch>6.8.1</elasticsearch> <elasticsearch>6.8.4</elasticsearch>
<log4j>2.9.1</log4j> <log4j>2.9.1</log4j>
<springdata.commons>2.2.0.RELEASE</springdata.commons> <springdata.commons>2.2.4.RELEASE</springdata.commons>
<netty>4.1.39.Final</netty> <netty>4.1.39.Final</netty>
<java-module-name>spring.data.elasticsearch</java-module-name> <java-module-name>spring.data.elasticsearch</java-module-name>
</properties> </properties>
@ -248,6 +248,24 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId>
<version>2.25.1</version>
<scope>test</scope>
<exclusions>
<!-- these exclusions are needed because of Elasticsearch JarHell-->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Upgrade xbean to 4.5 to prevent incompatibilities due to ASM versions --> <!-- Upgrade xbean to 4.5 to prevent incompatibilities due to ASM versions -->
<dependency> <dependency>
<groupId>org.apache.xbean</groupId> <groupId>org.apache.xbean</groupId>
@ -258,8 +276,8 @@
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>3.0-alpha-1</version> <version>3.1.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
@ -267,14 +285,6 @@
<build> <build>
<plugins> <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 please do not remove this configuration for surefire - we need that to avoid issue with jar hell
--> -->
@ -292,6 +302,14 @@
</systemPropertyVariables> </systemPropertyVariables>
</configuration> </configuration>
</plugin> </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> </plugins>
</build> </build>

View File

@ -35,8 +35,8 @@ The following table shows the Elasticsearch versions that are used by Spring Dat
[cols="^,^,^,^",options="header"] [cols="^,^,^,^",options="header"]
|=== |===
|Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot |Spring Data Release Train |Spring Data Elasticsearch |Elasticsearch | Spring Boot
|Moorefootnote:cdv[Currently in development] |3.2.xfootnote:cdv[]|6.8.1 / 7.xfootnote:hrc[via the <<elasticsearch.clients.rest,high-level REST client>>]|2.2.0footnote:cdv[] |Moore |3.2.x |6.8.4 |2.2.x
|Lovelace |3.1.x |6.2.2 / 7.xfootnote:hrc[]|2.1.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[] |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[] |Ingallsfootnote:oom[]|2.1.xfootnote:oom[] |2.4.0 |1.5.xfootnote:oom[]
|=== |===

View File

@ -104,8 +104,15 @@ static class Config {
@Bean @Bean
ReactiveElasticsearchClient client() { ReactiveElasticsearchClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1> ClientConfiguration clientConfiguration = ClientConfiguration.builder() <1>
.connectedTo("localhost:9200", "localhost:9291") .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(); .build();
return ReactiveRestClients.create(clientConfiguration); return ReactiveRestClients.create(clientConfiguration);
@ -124,6 +131,7 @@ Mono<IndexResponse> response = client.index(request ->
); );
---- ----
<1> Use the builder to provide cluster addresses, set default `HttpHeaders` or enable SSL. <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. NOTE: The ReactiveClient response, especially for search operations, is bound to the `from` (offset) & `size` (limit) options of the request.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,16 +20,21 @@ import java.net.SocketAddress;
import java.time.Duration; import java.time.Duration;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.web.reactive.function.client.WebClient;
/** /**
* Configuration interface exposing common client configuration properties for Elasticsearch clients. * Configuration interface exposing common client configuration properties for Elasticsearch clients.
* *
* @author Mark Paluch * @author Mark Paluch
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @since 3.2 * @since 3.2
*/ */
public interface ClientConfiguration { public interface ClientConfiguration {
@ -118,6 +123,13 @@ public interface ClientConfiguration {
*/ */
Optional<SSLContext> getSslContext(); 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}. * Returns the {@link java.time.Duration connect timeout}.
* *
@ -135,6 +147,27 @@ public interface ClientConfiguration {
*/ */
Duration getSocketTimeout(); Duration getSocketTimeout();
/**
* Returns the path prefix that should be prepended to HTTP(s) requests for Elasticsearch behind a proxy.
*
* @return the path prefix.
* @since 3.2.4
*/
String getPathPrefix();
/**
* returns an optionally set proxy in the form host:port
*
* @return the optional proxy
* @since 3.2.4
*/
Optional<String> getProxy();
/**
* @return the function for configuring a WebClient.
*/
Function<WebClient, WebClient> getWebClientConfigurer();
/** /**
* @author Christoph Strobl * @author Christoph Strobl
*/ */
@ -201,6 +234,16 @@ public interface ClientConfiguration {
* @return the {@link TerminalClientConfigurationBuilder}. * @return the {@link TerminalClientConfigurationBuilder}.
*/ */
TerminalClientConfigurationBuilder usingSsl(SSLContext sslContext); 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);
} }
/** /**
@ -267,6 +310,29 @@ public interface ClientConfiguration {
*/ */
TerminalClientConfigurationBuilder withBasicAuth(String username, String password); TerminalClientConfigurationBuilder withBasicAuth(String username, String password);
/**
* Configure the path prefix that will be prepended to any HTTP(s) requests
*
* @param pathPrefix the pathPrefix.
* @return the {@link TerminalClientConfigurationBuilder}
* @since 3.2.4
*/
TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix);
/**
* @param proxy a proxy formatted as String {@literal host:port}.
* @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}.
*/
TerminalClientConfigurationBuilder withWebClientConfigurer(Function<WebClient, WebClient> webClientConfigurer);
/** /**
* Build the {@link ClientConfiguration} object. * Build the {@link ClientConfiguration} object.
* *

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -20,8 +20,10 @@ import java.time.Duration;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithRequiredEndpoint; import org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithRequiredEndpoint;
@ -30,6 +32,7 @@ import org.springframework.data.elasticsearch.client.ClientConfiguration.Termina
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.reactive.function.client.WebClient;
/** /**
* Default builder implementation for {@link ClientConfiguration}. * Default builder implementation for {@link ClientConfiguration}.
@ -37,6 +40,8 @@ import org.springframework.util.Assert;
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @since 3.2 * @since 3.2
*/ */
class ClientConfigurationBuilder class ClientConfigurationBuilder
@ -46,10 +51,14 @@ class ClientConfigurationBuilder
private HttpHeaders headers = HttpHeaders.EMPTY; private HttpHeaders headers = HttpHeaders.EMPTY;
private boolean useSsl; private boolean useSsl;
private @Nullable SSLContext sslContext; private @Nullable SSLContext sslContext;
private @Nullable HostnameVerifier hostnameVerifier;
private Duration connectTimeout = Duration.ofSeconds(10); private Duration connectTimeout = Duration.ofSeconds(10);
private Duration soTimeout = Duration.ofSeconds(5); private Duration soTimeout = Duration.ofSeconds(5);
private String username; private String username;
private String password; private String password;
private String pathPrefix;
private String proxy;
private Function<WebClient, WebClient> webClientConfigurer;
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -78,6 +87,13 @@ class ClientConfigurationBuilder
return this; 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) * (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl() * @see org.springframework.data.elasticsearch.client.ClientConfiguration.MaybeSecureClientConfigurationBuilder#usingSsl()
@ -103,6 +119,22 @@ class ClientConfigurationBuilder
return this; 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) * (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder#withDefaultHeaders(org.springframework.http.HttpHeaders) * @see org.springframework.data.elasticsearch.client.ClientConfiguration.TerminalClientConfigurationBuilder#withDefaultHeaders(org.springframework.http.HttpHeaders)
@ -156,6 +188,22 @@ class ClientConfigurationBuilder
return this; return this;
} }
@Override
public TerminalClientConfigurationBuilder withPathPrefix(String pathPrefix) {
this.pathPrefix = pathPrefix;
return this;
}
@Override
public TerminalClientConfigurationBuilder withWebClientConfigurer(Function<WebClient, WebClient> webClientConfigurer) {
Assert.notNull(webClientConfigurer, "webClientConfigurer must not be null");
this.webClientConfigurer = webClientConfigurer;
return this;
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build() * @see org.springframework.data.elasticsearch.client.ClientConfiguration.ClientConfigurationBuilderWithOptionalDefaultHeaders#build()
@ -170,8 +218,8 @@ class ClientConfigurationBuilder
headers.setBasicAuth(username, password); headers.setBasicAuth(username, password);
} }
return new DefaultClientConfiguration(this.hosts, this.headers, this.useSsl, this.sslContext, this.soTimeout, return new DefaultClientConfiguration(hosts, headers, useSsl, sslContext, soTimeout, connectTimeout, pathPrefix,
this.connectTimeout); hostnameVerifier, proxy, webClientConfigurer);
} }
private static InetSocketAddress parse(String hostAndPort) { private static InetSocketAddress parse(String hostAndPort) {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,17 +21,22 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.web.reactive.function.client.WebClient;
/** /**
* Default {@link ClientConfiguration} implementation. * Default {@link ClientConfiguration} implementation.
* *
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Huw Ayling-Miller
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
class DefaultClientConfiguration implements ClientConfiguration { class DefaultClientConfiguration implements ClientConfiguration {
@ -42,9 +47,14 @@ class DefaultClientConfiguration implements ClientConfiguration {
private final @Nullable SSLContext sslContext; private final @Nullable SSLContext sslContext;
private final Duration soTimeout; private final Duration soTimeout;
private final Duration connectTimeout; private final Duration connectTimeout;
private final String pathPrefix;
private final @Nullable HostnameVerifier hostnameVerifier;
private final String proxy;
private final Function<WebClient, WebClient> webClientConfigurer;
DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl, DefaultClientConfiguration(List<InetSocketAddress> hosts, HttpHeaders headers, boolean useSsl,
@Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout) { @Nullable SSLContext sslContext, Duration soTimeout, Duration connectTimeout, @Nullable String pathPrefix,
@Nullable HostnameVerifier hostnameVerifier, String proxy, Function<WebClient, WebClient> webClientConfigurer) {
this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts)); this.hosts = Collections.unmodifiableList(new ArrayList<>(hosts));
this.headers = new HttpHeaders(headers); this.headers = new HttpHeaders(headers);
@ -52,60 +62,59 @@ class DefaultClientConfiguration implements ClientConfiguration {
this.sslContext = sslContext; this.sslContext = sslContext;
this.soTimeout = soTimeout; this.soTimeout = soTimeout;
this.connectTimeout = connectTimeout; this.connectTimeout = connectTimeout;
this.pathPrefix = pathPrefix;
this.hostnameVerifier = hostnameVerifier;
this.proxy = proxy;
this.webClientConfigurer = webClientConfigurer;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getEndpoints()
*/
@Override @Override
public List<InetSocketAddress> getEndpoints() { public List<InetSocketAddress> getEndpoints() {
return this.hosts; return this.hosts;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getDefaultHeaders()
*/
@Override @Override
public HttpHeaders getDefaultHeaders() { public HttpHeaders getDefaultHeaders() {
return this.headers; return this.headers;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#useSsl()
*/
@Override @Override
public boolean useSsl() { public boolean useSsl() {
return this.useSsl; return this.useSsl;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSslContext()
*/
@Override @Override
public Optional<SSLContext> getSslContext() { public Optional<SSLContext> getSslContext() {
return Optional.ofNullable(this.sslContext); return Optional.ofNullable(this.sslContext);
} }
/* @Override
* (non-Javadoc) public Optional<HostnameVerifier> getHostNameVerifier() {
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getConnectTimeout() return Optional.ofNullable(this.hostnameVerifier);
*/ }
@Override @Override
public Duration getConnectTimeout() { public Duration getConnectTimeout() {
return this.connectTimeout; return this.connectTimeout;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.ClientConfiguration#getSocketTimeout()
*/
@Override @Override
public Duration getSocketTimeout() { public Duration getSocketTimeout() {
return this.soTimeout; return this.soTimeout;
} }
@Override
public String getPathPrefix() {
return this.pathPrefix;
}
@Override
public Optional<String> getProxy() {
return Optional.ofNullable(proxy);
}
@Override
public Function<WebClient, WebClient> getWebClientConfigurer() {
return webClientConfigurer != null ? webClientConfigurer : Function.identity();
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import org.apache.http.Header; import org.apache.http.Header;
@ -52,6 +53,9 @@ import org.springframework.util.Assert;
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
public final class RestClients { public final class RestClients {
@ -75,6 +79,11 @@ public final class RestClients {
HttpHost[] httpHosts = formattedHosts(clientConfiguration.getEndpoints(), clientConfiguration.useSsl()).stream() HttpHost[] httpHosts = formattedHosts(clientConfiguration.getEndpoints(), clientConfiguration.useSsl()).stream()
.map(HttpHost::create).toArray(HttpHost[]::new); .map(HttpHost::create).toArray(HttpHost[]::new);
RestClientBuilder builder = RestClient.builder(httpHosts); RestClientBuilder builder = RestClient.builder(httpHosts);
if (clientConfiguration.getPathPrefix() != null) {
builder.setPathPrefix(clientConfiguration.getPathPrefix());
}
HttpHeaders headers = clientConfiguration.getDefaultHeaders(); HttpHeaders headers = clientConfiguration.getDefaultHeaders();
if (!headers.isEmpty()) { if (!headers.isEmpty()) {
@ -87,7 +96,9 @@ public final class RestClients {
builder.setHttpClientConfigCallback(clientBuilder -> { builder.setHttpClientConfigCallback(clientBuilder -> {
Optional<SSLContext> sslContext = clientConfiguration.getSslContext(); Optional<SSLContext> sslContext = clientConfiguration.getSslContext();
Optional<HostnameVerifier> hostNameVerifier = clientConfiguration.getHostNameVerifier();
sslContext.ifPresent(clientBuilder::setSSLContext); sslContext.ifPresent(clientBuilder::setSSLContext);
hostNameVerifier.ifPresent(clientBuilder::setSSLHostnameVerifier);
if (ClientLogger.isEnabled()) { if (ClientLogger.isEnabled()) {
@ -114,6 +125,8 @@ public final class RestClients {
clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
clientConfiguration.getProxy().map(HttpHost::create).ifPresent(clientBuilder::setProxy);
return clientBuilder; return clientBuilder;
}); });

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -47,7 +47,6 @@ import javax.net.ssl.SSLContext;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.ActionRequest; import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.admin.indices.close.CloseIndexRequest; import org.elasticsearch.action.admin.indices.close.CloseIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest; import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest; import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
@ -58,6 +57,8 @@ import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshResponse; import org.elasticsearch.action.admin.indices.refresh.RefreshResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequest;
@ -77,6 +78,8 @@ import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Request; 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.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler; import org.elasticsearch.common.xcontent.DeprecationHandler;
import org.elasticsearch.common.xcontent.NamedXContentRegistry; import org.elasticsearch.common.xcontent.NamedXContentRegistry;
@ -122,6 +125,9 @@ import org.springframework.web.reactive.function.client.WebClient.RequestBodySpe
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Peter-Josef Meisch
* @author Huw Ayling-Miller
* @author Henrique Amaral
* @since 3.2 * @since 3.2
* @see ClientConfiguration * @see ClientConfiguration
* @see ReactiveRestClients * @see ReactiveRestClients
@ -216,7 +222,13 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
WebClientProvider provider = WebClientProvider.create(scheme, connector); WebClientProvider provider = WebClientProvider.create(scheme, connector);
return provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()); if (clientConfiguration.getPathPrefix() != null) {
provider = provider.withPathPrefix(clientConfiguration.getPathPrefix());
}
provider = provider.withDefaultHeaders(clientConfiguration.getDefaultHeaders()) //
.withWebClientConfigurer(clientConfiguration.getWebClientConfigurer());
return provider;
} }
/* /*
@ -319,6 +331,17 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
.publishNext(); .publishNext();
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#count(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest)
*/
@Override
public Mono<Long> count(HttpHeaders headers, CountRequest countRequest) {
return sendRequest(countRequest, RequestCreator.count(), CountResponse.class, headers) //
.map(CountResponse::getCount) //
.next();
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest) * @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#ping(org.springframework.http.HttpHeaders, org.elasticsearch.action.search.SearchRequest)
@ -423,6 +446,16 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
.publishNext(); .publishNext();
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient#bulk(org.springframework.http.HttpHeaders, org.elasticsearch.action.bulk.BulkRequest)
*/
@Override
public Mono<BulkResponse> bulk(HttpHeaders headers, BulkRequest bulkRequest) {
return sendRequest(bulkRequest, RequestCreator.bulk(), BulkResponse.class, headers) //
.publishNext();
}
// --> INDICES // --> INDICES
/* /*
@ -553,13 +586,12 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
// --> // -->
private <Req extends ActionRequest, Resp extends ActionResponse> Flux<Resp> sendRequest(Req request, private <Req extends ActionRequest, Resp> Flux<Resp> sendRequest(Req request, Function<Req, Request> converter,
Function<Req, Request> converter, Class<Resp> responseType, HttpHeaders headers) { Class<Resp> responseType, HttpHeaders headers) {
return sendRequest(converter.apply(request), responseType, headers); return sendRequest(converter.apply(request), responseType, headers);
} }
private <AR extends ActionResponse> Flux<AR> sendRequest(Request request, Class<AR> responseType, private <Resp> Flux<Resp> sendRequest(Request request, Class<Resp> responseType, HttpHeaders headers) {
HttpHeaders headers) {
String logId = ClientLogger.newLogId(); String logId = ClientLogger.newLogId();
@ -742,6 +774,18 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
}; };
} }
static Function<BulkRequest, Request> bulk() {
return request -> {
try {
return RequestConverters.bulk(request);
} catch (IOException e) {
throw new ElasticsearchException("Could not parse request", e);
}
};
}
// --> INDICES // --> INDICES
static Function<GetIndexRequest, Request> indexExists() { static Function<GetIndexRequest, Request> indexExists() {
@ -776,6 +820,10 @@ public class DefaultReactiveElasticsearchClient implements ReactiveElasticsearch
return RequestConverters::flushIndex; return RequestConverters::flushIndex;
} }
static Function<CountRequest, Request> count() {
return RequestConverters::count;
}
} }
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,7 @@ import java.net.InetSocketAddress;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpConnector;
@ -32,6 +33,8 @@ import org.springframework.web.reactive.function.client.WebClient.Builder;
* *
* @author Mark Paluch * @author Mark Paluch
* @author Christoph Strobl * @author Christoph Strobl
* @author Huw Ayling-Miller
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
class DefaultWebClientProvider implements WebClientProvider { class DefaultWebClientProvider implements WebClientProvider {
@ -42,6 +45,8 @@ class DefaultWebClientProvider implements WebClientProvider {
private final @Nullable ClientHttpConnector connector; private final @Nullable ClientHttpConnector connector;
private final Consumer<Throwable> errorListener; private final Consumer<Throwable> errorListener;
private final HttpHeaders headers; private final HttpHeaders headers;
private final String pathPrefix;
private final Function<WebClient, WebClient> webClientConfigurer;
/** /**
* Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}. * Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}.
@ -50,35 +55,38 @@ class DefaultWebClientProvider implements WebClientProvider {
* @param connector can be {@literal null}. * @param connector can be {@literal null}.
*/ */
DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector) { DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector) {
this(scheme, connector, e -> {}, HttpHeaders.EMPTY); this(scheme, connector, e -> {}, HttpHeaders.EMPTY, null, Function.identity());
} }
/** /**
* Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}. * Create new {@link DefaultWebClientProvider} with empty {@link HttpHeaders} and no-op {@literal error listener}.
* *
* @param scheme must not be {@literal null}. * @param scheme must not be {@literal null}.
* @param connector can be {@literal null}. * @param connector can be {@literal null}.
* @param errorListener must not be {@literal null}. * @param errorListener must not be {@literal null}.
* @param headers must not be {@literal null}. * @param headers must not be {@literal null}.
* @param pathPrefix can be {@literal null}
* @param webClientConfigurer must not be {@literal null}.
*/ */
private DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector, private DefaultWebClientProvider(String scheme, @Nullable ClientHttpConnector connector,
Consumer<Throwable> errorListener, HttpHeaders headers) { Consumer<Throwable> errorListener, HttpHeaders headers, @Nullable String pathPrefix,
Function<WebClient, WebClient> webClientConfigurer) {
Assert.notNull(scheme, "Scheme must not be null! A common scheme would be 'http'."); 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(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.cachedClients = new ConcurrentHashMap<>();
this.scheme = scheme; this.scheme = scheme;
this.connector = connector; this.connector = connector;
this.errorListener = errorListener; this.errorListener = errorListener;
this.headers = headers; this.headers = headers;
this.pathPrefix = pathPrefix;
this.webClientConfigurer = webClientConfigurer;
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#get(java.net.InetSocketAddress)
*/
@Override @Override
public WebClient get(InetSocketAddress endpoint) { public WebClient get(InetSocketAddress endpoint) {
@ -87,19 +95,21 @@ class DefaultWebClientProvider implements WebClientProvider {
return this.cachedClients.computeIfAbsent(endpoint, this::createWebClientForSocketAddress); return this.cachedClients.computeIfAbsent(endpoint, this::createWebClientForSocketAddress);
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getDefaultHeaders()
*/
@Override @Override
public HttpHeaders getDefaultHeaders() { public HttpHeaders getDefaultHeaders() {
return headers; return headers;
} }
/* @Override
* (non-Javadoc) public Consumer<Throwable> getErrorListener() {
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withDefaultHeaders(org.springframework.http.HttpHeaders) return this.errorListener;
*/ }
@Override
public String getPathPrefix() {
return pathPrefix;
}
@Override @Override
public WebClientProvider withDefaultHeaders(HttpHeaders headers) { public WebClientProvider withDefaultHeaders(HttpHeaders headers) {
@ -109,31 +119,33 @@ class DefaultWebClientProvider implements WebClientProvider {
merged.addAll(this.headers); merged.addAll(this.headers);
merged.addAll(headers); merged.addAll(headers);
return new DefaultWebClientProvider(this.scheme, this.connector, errorListener, merged); return new DefaultWebClientProvider(scheme, connector, errorListener, merged, pathPrefix, webClientConfigurer);
} }
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#getErrorListener()
*/
@Override
public Consumer<Throwable> getErrorListener() {
return this.errorListener;
}
/*
* (non-Javadoc)
* @see org.springframework.data.elasticsearch.client.reactive.WebClientProvider#withErrorListener(java.util.function.Consumer)
*/
@Override @Override
public WebClientProvider withErrorListener(Consumer<Throwable> errorListener) { public WebClientProvider withErrorListener(Consumer<Throwable> errorListener) {
Assert.notNull(errorListener, "Error listener must not be null."); Assert.notNull(errorListener, "Error listener must not be null.");
Consumer<Throwable> listener = this.errorListener.andThen(errorListener); Consumer<Throwable> listener = this.errorListener.andThen(errorListener);
return new DefaultWebClientProvider(this.scheme, this.connector, listener, this.headers); return new DefaultWebClientProvider(scheme, this.connector, listener, headers, pathPrefix, webClientConfigurer);
} }
@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,
webClientConfigurer);
}
@Override
public WebClientProvider withWebClientConfigurer(Function<WebClient, WebClient> webClientConfigurer) {
return new DefaultWebClientProvider(scheme, connector, errorListener, headers, pathPrefix, webClientConfigurer);
}
protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddress) { protected WebClient createWebClientForSocketAddress(InetSocketAddress socketAddress) {
Builder builder = WebClient.builder().defaultHeaders(it -> it.addAll(getDefaultHeaders())); Builder builder = WebClient.builder().defaultHeaders(it -> it.addAll(getDefaultHeaders()));
@ -142,7 +154,9 @@ class DefaultWebClientProvider implements WebClientProvider {
builder = builder.clientConnector(connector); builder = builder.clientConnector(connector);
} }
String baseUrl = String.format("%s://%s:%d", this.scheme, socketAddress.getHostString(), socketAddress.getPort()); String baseUrl = String.format("%s://%s:%d%s", this.scheme, socketAddress.getHostString(), socketAddress.getPort(),
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);
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -30,6 +30,8 @@ import org.elasticsearch.action.admin.indices.get.GetIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest; import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.open.OpenIndexRequest; import org.elasticsearch.action.admin.indices.open.OpenIndexRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest; import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse; import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequest;
@ -41,11 +43,11 @@ import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse; import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.ElasticsearchHost; import org.springframework.data.elasticsearch.client.ElasticsearchHost;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@ -58,6 +60,8 @@ import org.springframework.web.reactive.function.client.WebClient;
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Peter-Josef Meisch
* @author Henrique Amaral
* @since 3.2 * @since 3.2
* @see ClientConfiguration * @see ClientConfiguration
* @see ReactiveRestClients * @see ReactiveRestClients
@ -329,6 +333,47 @@ public interface ReactiveElasticsearchClient {
*/ */
Mono<DeleteResponse> delete(HttpHeaders headers, DeleteRequest deleteRequest); Mono<DeleteResponse> delete(HttpHeaders headers, DeleteRequest deleteRequest);
/**
* Execute a {@link SearchRequest} against the {@literal count} API.
*
* @param consumer new {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html">Count API on
* elastic.co</a>
* @return the {@link Mono} emitting the count result.
* @since 3.2.4
*/
default Mono<Long> count(Consumer<CountRequest> consumer) {
CountRequest countRequest = new CountRequest();
consumer.accept(countRequest);
return count(countRequest);
}
/**
* Execute a {@link SearchRequest} against the {@literal count} API.
*
* @param countRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html">Count API on
* elastic.co</a>
* @return the {@link Mono} emitting the count result.
* @since 3.2.4
*/
default Mono<Long> count(CountRequest countRequest) {
return count(HttpHeaders.EMPTY, countRequest);
}
/**
* Execute a {@link SearchRequest} against the {@literal count} API.
*
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
* @param countRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/search-count.html">Count API on
* elastic.co</a>
* @return the {@link Mono} emitting the count result.
* @since 3.2.4
*/
Mono<Long> count(HttpHeaders headers, CountRequest countRequest);
/** /**
* Execute a {@link SearchRequest} against the {@literal search} API. * Execute a {@link SearchRequest} against the {@literal search} API.
* *
@ -430,6 +475,44 @@ public interface ReactiveElasticsearchClient {
*/ */
Mono<BulkByScrollResponse> deleteBy(HttpHeaders headers, DeleteByQueryRequest deleteRequest); Mono<BulkByScrollResponse> deleteBy(HttpHeaders headers, DeleteByQueryRequest deleteRequest);
/**
* Execute a {@link BulkRequest} against the {@literal bulk} API.
*
* @param consumer never {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">Bulk API on
* elastic.co</a>
* @return a {@link Mono} emitting the emitting operation response.
*/
default Mono<BulkResponse> bulk(Consumer<BulkRequest> consumer) {
BulkRequest request = new BulkRequest();
consumer.accept(request);
return bulk(request);
}
/**
* Execute a {@link BulkRequest} against the {@literal bulk} API.
*
* @param bulkRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">Bulk API on
* elastic.co</a>
* @return a {@link Mono} emitting the emitting operation response.
*/
default Mono<BulkResponse> bulk(BulkRequest bulkRequest) {
return bulk(HttpHeaders.EMPTY, bulkRequest);
}
/**
* Execute a {@link BulkRequest} against the {@literal bulk} API.
*
* @param headers Use {@link HttpHeaders} to provide eg. authentication data. Must not be {@literal null}.
* @param bulkRequest must not be {@literal null}.
* @see <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html">Bulk API on
* elastic.co</a>
* @return a {@link Mono} emitting operation response.
*/
Mono<BulkResponse> bulk(HttpHeaders headers, BulkRequest bulkRequest);
/** /**
* Compose the actual command/s to run against Elasticsearch using the underlying {@link WebClient connection}. * Compose the actual command/s to run against Elasticsearch using the underlying {@link WebClient connection}.
* {@link #execute(ReactiveElasticsearchClientCallback) Execute} selects an active server from the available ones and * {@link #execute(ReactiveElasticsearchClientCallback) Execute} selects an active server from the available ones and

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@ package org.springframework.data.elasticsearch.client.reactive;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.client.reactive.ClientHttpConnector; import org.springframework.http.client.reactive.ClientHttpConnector;
@ -34,6 +35,8 @@ import org.springframework.web.reactive.function.client.WebClient;
* *
* @author Christoph Strobl * @author Christoph Strobl
* @author Mark Paluch * @author Mark Paluch
* @author Huw Ayling-Miller
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
public interface WebClientProvider { public interface WebClientProvider {
@ -96,6 +99,14 @@ public interface WebClientProvider {
*/ */
Consumer<Throwable> getErrorListener(); Consumer<Throwable> getErrorListener();
/**
* Obtain the {@link String pathPrefix} to be used.
*
* @return the pathPrefix if set.
* @since 3.2.4
*/
String getPathPrefix();
/** /**
* Create a new instance of {@link WebClientProvider} applying the given headers by default. * Create a new instance of {@link WebClientProvider} applying the given headers by default.
* *
@ -111,4 +122,21 @@ public interface WebClientProvider {
* @return new instance of {@link WebClientProvider}. * @return new instance of {@link WebClientProvider}.
*/ */
WebClientProvider withErrorListener(Consumer<Throwable> errorListener); WebClientProvider withErrorListener(Consumer<Throwable> errorListener);
/**
* Create a new instance of {@link WebClientProvider} where HTTP requests are called with the given path prefix.
*
* @param pathPrefix Path prefix to add to requests
* @return new instance of {@link WebClientProvider}
* @since 3.2.4
*/
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 3.2.4
*/
WebClientProvider withWebClientConfigurer(Function<WebClient, WebClient> webClientConfigurer);
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -60,6 +60,7 @@ import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.Request; import org.elasticsearch.client.Request;
import org.elasticsearch.client.Requests; import org.elasticsearch.client.Requests;
import org.elasticsearch.client.RethrottleRequest; import org.elasticsearch.client.RethrottleRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.cluster.health.ClusterHealthStatus; import org.elasticsearch.cluster.health.ClusterHealthStatus;
import org.elasticsearch.common.Priority; import org.elasticsearch.common.Priority;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
@ -98,6 +99,8 @@ import org.springframework.lang.Nullable;
* <p> * <p>
* Only intended for internal use. * Only intended for internal use.
* *
* @author Christoph Strobl
* @author Peter-Josef Meisch
* @since 3.2 * @since 3.2
*/ */
public class RequestConverters { public class RequestConverters {
@ -386,6 +389,32 @@ public class RequestConverters {
return request; return request;
} }
/**
* Creates a count request.
*
* @param countRequest the search defining the data to be counted
* @return Elasticsearch count request
* @since 3.2
*/
public static Request count(CountRequest countRequest) {
Request request = new Request(HttpMethod.POST.name(),
endpoint(countRequest.indices(), countRequest.types(), "_count"));
Params params = new Params(request);
addCountRequestParams(params, countRequest);
if (countRequest.source() != null) {
request.setEntity(createEntity(countRequest.source(), REQUEST_BODY_CONTENT_TYPE));
}
return request;
}
private static void addCountRequestParams(Params params, CountRequest countRequest) {
params.withRouting(countRequest.routing());
params.withPreference(countRequest.preference());
params.withIndicesOptions(countRequest.indicesOptions());
}
private static void addSearchRequestParams(Params params, SearchRequest searchRequest) { private static void addSearchRequestParams(Params params, SearchRequest searchRequest) {
params.putParam("typed_keys", "true"); params.putParam("typed_keys", "true");
params.withRouting(searchRequest.routing()); params.withRouting(searchRequest.routing());

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -598,6 +598,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
if (elasticsearchQuery != null) { if (elasticsearchQuery != null) {
sourceBuilder.query(elasticsearchQuery); sourceBuilder.query(elasticsearchQuery);
} }
sourceBuilder.size(0);
countRequest.source(sourceBuilder); countRequest.source(sourceBuilder);
try { try {
@ -616,6 +617,7 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
if (elasticsearchFilter != null) { if (elasticsearchFilter != null) {
searchRequest.source().postFilter(elasticsearchFilter); searchRequest.source().postFilter(elasticsearchFilter);
} }
searchRequest.source().size(0);
SearchResponse response; SearchResponse response;
try { try {
response = client.search(searchRequest, RequestOptions.DEFAULT); response = client.search(searchRequest, RequestOptions.DEFAULT);
@ -960,6 +962,10 @@ public class ElasticsearchRestTemplate extends AbstractElasticsearchTemplate
prepareSort(query, searchSourceBuilder, entity); prepareSort(query, searchSourceBuilder, entity);
} }
if (query.getIndicesOptions() != null) {
request.indicesOptions(query.getIndicesOptions());
}
if (query instanceof SearchQuery) { if (query instanceof SearchQuery) {
SearchQuery searchQuery = (SearchQuery) query; SearchQuery searchQuery = (SearchQuery) query;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -508,6 +508,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
if (elasticsearchQuery != null) { if (elasticsearchQuery != null) {
countRequestBuilder.setQuery(elasticsearchQuery); countRequestBuilder.setQuery(elasticsearchQuery);
} }
countRequestBuilder.setSize(0);
return countRequestBuilder.execute().actionGet().getHits().getTotalHits(); return countRequestBuilder.execute().actionGet().getHits().getTotalHits();
} }
@ -521,6 +522,7 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
if (elasticsearchFilter != null) { if (elasticsearchFilter != null) {
searchRequestBuilder.setPostFilter(elasticsearchFilter); searchRequestBuilder.setPostFilter(elasticsearchFilter);
} }
searchRequestBuilder.setSize(0);
return searchRequestBuilder.execute().actionGet().getHits().getTotalHits(); return searchRequestBuilder.execute().actionGet().getHits().getTotalHits();
} }
@ -810,6 +812,10 @@ public class ElasticsearchTemplate extends AbstractElasticsearchTemplate
prepareSort(query, requestBuilder, entity); prepareSort(query, requestBuilder, entity);
} }
if (query.getIndicesOptions() != null) {
requestBuilder.setIndicesOptions(query.getIndicesOptions());
}
if (query instanceof SearchQuery) { if (query instanceof SearchQuery) {
SearchQuery searchQuery = (SearchQuery) query; SearchQuery searchQuery = (SearchQuery) query;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -36,6 +36,7 @@ import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.action.support.WriteRequest; import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.client.Requests; import org.elasticsearch.client.Requests;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
@ -247,80 +248,133 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
@Nullable String type) { @Nullable String type) {
return Flux.defer(() -> { return Flux.defer(() -> {
SearchRequest request = prepareSearchRequest(buildSearchRequest(query, entity, index, type));
IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type); if (query.getPageable().isPaged()) {
SearchRequest request = new SearchRequest(indices(query, indexCoordinates::getIndexName)); return doFind(request);
request.types(indexTypes(query, indexCoordinates::getTypeName));
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 SearchQuery && ((SearchQuery) query).getCollapseBuilder() != null) {
searchSourceBuilder.collapse(((SearchQuery) 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);
return doFind(prepareSearchRequest(request));
} else { } else {
return doScroll(request);
request.source(searchSourceBuilder);
return doScan(prepareSearchRequest(request));
} }
}); });
} }
@Override
public Mono<Long> count(Query query, Class<?> entityType, String index, String type) {
return doCount(query, getPersistentEntity(entityType), index, type);
}
private Mono<Long> doCount(Query query, ElasticsearchPersistentEntity<?> entity, @Nullable String index,
@Nullable String type) {
return Mono.defer(() -> {
CountRequest countRequest = buildCountRequest(query, entity, index, type);
CountRequest request = prepareCountRequest(countRequest);
return doCount(request);
});
}
private CountRequest buildCountRequest(Query query, ElasticsearchPersistentEntity<?> entity, @Nullable String index,
@Nullable String type) {
IndexCoordinates indexCoordinates = operations.determineIndex(entity, index, type);
CountRequest request = new CountRequest(indices(query, indexCoordinates::getIndexName));
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 SearchQuery && ((SearchQuery) query).getCollapseBuilder() != null) {
searchSourceBuilder.collapse(((SearchQuery) 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;
}
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 SearchQuery && ((SearchQuery) query).getCollapseBuilder() != null) {
searchSourceBuilder.collapse(((SearchQuery) 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);
} else {
request.source(searchSourceBuilder);
}
return request;
}
/* /*
* (non-Javadoc) * (non-Javadoc)
* @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#count(Query, Class, String, String) * @see org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations#count(Query, Class, String, String)
*/ */
@Override
public Mono<Long> count(Query query, Class<?> entityType, String index, String type) {
// TODO: ES 7.0 has a dedicated CountRequest - use that one once available.
return find(query, entityType, index, type).count();
}
/* /*
* (non-Javadoc) * (non-Javadoc)
@ -457,6 +511,22 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
return prepareWriteRequest(request); return prepareWriteRequest(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.
*
* @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 * Customization hook to modify a generated {@link SearchRequest} prior to its execution. Eg. by setting the
* {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable. * {@link SearchRequest#indicesOptions(IndicesOptions) indices options} if applicable.
@ -557,16 +627,32 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
.onErrorResume(NoSuchIndexException.class, it -> Mono.empty()); .onErrorResume(NoSuchIndexException.class, it -> Mono.empty());
} }
/**
* Customization hook on the actual execution result {@link Publisher}. <br />
*
* @param request the already prepared {@link CountRequest} ready to be executed.
* @return a {@link Mono} emitting the result of the operation.
*/
protected Mono<Long> doCount(CountRequest 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());
}
/** /**
* Customization hook on the actual execution result {@link Publisher}. <br /> * Customization hook on the actual execution result {@link Publisher}. <br />
* *
* @param request the already prepared {@link SearchRequest} ready to be executed. * @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.
*/ */
protected Flux<SearchHit> doScan(SearchRequest request) { protected Flux<SearchHit> doScroll(SearchRequest request) {
if (QUERY_LOGGER.isDebugEnabled()) { if (QUERY_LOGGER.isDebugEnabled()) {
QUERY_LOGGER.debug("Executing doScan: {}", request); QUERY_LOGGER.debug("Executing doScroll: {}", request);
} }
return Flux.from(execute(client -> client.scroll(request))) // return Flux.from(execute(client -> client.scroll(request))) //
@ -665,9 +751,7 @@ public class ReactiveElasticsearchTemplate implements ReactiveElasticsearchOpera
elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource()); elasticsearchQuery = new WrapperQueryBuilder(((StringQuery) query).getSource());
} else if (query instanceof NativeSearchQuery) { } else if (query instanceof NativeSearchQuery) {
elasticsearchQuery = ((NativeSearchQuery) query).getQuery(); elasticsearchQuery = ((NativeSearchQuery) query).getQuery();
} } else {
else {
throw new IllegalArgumentException(String.format("Unknown query type '%s'.", query.getClass())); throw new IllegalArgumentException(String.format("Unknown query type '%s'.", query.getClass()));
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More