DATAES-914 - Use TestContainers.

This commit is contained in:
Peter-Josef Meisch 2020-08-25 16:35:42 +02:00
parent 79fdc449b8
commit 6361a1eefe
No known key found for this signature in database
GPG Key ID: DE108246970C7708
55 changed files with 790 additions and 1660 deletions

12
Jenkinsfile vendored
View File

@ -24,12 +24,16 @@ pipeline {
image 'adoptopenjdk/openjdk8:latest' image 'adoptopenjdk/openjdk8:latest'
label 'data' label 'data'
args '-v $HOME:/tmp/jenkins-home' args '-v $HOME:/tmp/jenkins-home'
args '-u root -v /var/run/docker.sock:/var/run/docker.sock'
} }
} }
options { timeout(time: 30, unit: 'MINUTES') } options { timeout(time: 30, unit: 'MINUTES') }
steps { steps {
sh 'mkdir -p /tmp/jenkins-home'
sh 'chown -R 1001:1001 .'
sh 'rm -rf ?' sh 'rm -rf ?'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw clean dependency:list test -Dsort -U -B'
sh 'chown -R 1001:1001 .'
} }
} }
@ -47,12 +51,16 @@ pipeline {
image 'adoptopenjdk/openjdk11:latest' image 'adoptopenjdk/openjdk11:latest'
label 'data' label 'data'
args '-v $HOME:/tmp/jenkins-home' args '-v $HOME:/tmp/jenkins-home'
args '-u root -v /var/run/docker.sock:/var/run/docker.sock'
} }
} }
options { timeout(time: 30, unit: 'MINUTES') } options { timeout(time: 30, unit: 'MINUTES') }
steps { steps {
sh 'mkdir -p /tmp/jenkins-home'
sh 'chown -R 1001:1001 .'
sh 'rm -rf ?' sh 'rm -rf ?'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B'
sh 'chown -R 1001:1001 .'
} }
} }
@ -62,12 +70,16 @@ pipeline {
image 'adoptopenjdk/openjdk12:latest' image 'adoptopenjdk/openjdk12:latest'
label 'data' label 'data'
args '-v $HOME:/tmp/jenkins-home' args '-v $HOME:/tmp/jenkins-home'
args '-u root -v /var/run/docker.sock:/var/run/docker.sock'
} }
} }
options { timeout(time: 30, unit: 'MINUTES') } options { timeout(time: 30, unit: 'MINUTES') }
steps { steps {
sh 'mkdir -p /tmp/jenkins-home'
sh 'chown -R 1001:1001 .'
sh 'rm -rf ?' sh 'rm -rf ?'
sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B' sh 'MAVEN_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home" ./mvnw -Pjava11 clean dependency:list test -Dsort -U -B'
sh 'chown -R 1001:1001 .'
} }
} }
} }

684
pom.xml
View File

@ -1,388 +1,396 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId> <artifactId>spring-data-elasticsearch</artifactId>
<version>4.1.0-SNAPSHOT</version> <version>4.1.0-DATAES-914-SNAPSHOT</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.4.0-SNAPSHOT</version> <version>2.4.0-SNAPSHOT</version>
</parent> </parent>
<name>Spring Data Elasticsearch</name> <name>Spring Data Elasticsearch</name>
<description>Spring Data Implementation for Elasticsearch</description> <description>Spring Data Implementation for Elasticsearch</description>
<url>https://github.com/spring-projects/spring-data-elasticsearch</url> <url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<properties> <properties>
<commonslang>2.6</commonslang> <commonslang>2.6</commonslang>
<elasticsearch>7.8.1</elasticsearch> <elasticsearch>7.8.1</elasticsearch>
<log4j>2.13.2</log4j> <log4j>2.13.3</log4j>
<springdata.commons>2.4.0-SNAPSHOT</springdata.commons> <netty>4.1.50.Final</netty>
<netty>4.1.50.Final</netty> <springdata.commons>2.4.0-SNAPSHOT</springdata.commons>
<java-module-name>spring.data.elasticsearch</java-module-name> <testcontainers>1.14.3</testcontainers>
</properties> <java-module-name>spring.data.elasticsearch</java-module-name>
</properties>
<developers> <developers>
<developer> <developer>
<id>biomedcentral</id> <id>biomedcentral</id>
<name>BioMed Central Development Team</name> <name>BioMed Central Development Team</name>
<timezone>+0</timezone> <timezone>+0</timezone>
</developer> </developer>
<developer> <developer>
<id>cstrobl</id> <id>cstrobl</id>
<name>Christoph Strobl</name> <name>Christoph Strobl</name>
<email>cstrobl at pivotal.io</email> <email>cstrobl at pivotal.io</email>
<organization>Pivotal</organization> <organization>Pivotal</organization>
<organizationUrl>https://www.pivotal.io</organizationUrl> <organizationUrl>https://www.pivotal.io</organizationUrl>
<roles> <roles>
<role>Developer</role> <role>Developer</role>
</roles> </roles>
<timezone>+1</timezone> <timezone>+1</timezone>
</developer> </developer>
<developer> <developer>
<id>mpaluch</id> <id>mpaluch</id>
<name>Mark Paluch</name> <name>Mark Paluch</name>
<email>mpaluch at pivotal.io</email> <email>mpaluch at pivotal.io</email>
<organization>Pivotal</organization> <organization>Pivotal</organization>
<organizationUrl>https://www.pivotal.io</organizationUrl> <organizationUrl>https://www.pivotal.io</organizationUrl>
<roles> <roles>
<role>Developer</role> <role>Developer</role>
</roles> </roles>
<timezone>+1</timezone> <timezone>+1</timezone>
</developer> </developer>
</developers> </developers>
<scm> <scm>
<url>https://github.com/spring-projects/spring-data-elasticsearch</url> <url>https://github.com/spring-projects/spring-data-elasticsearch</url>
<connection>scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git</connection> <connection>scm:git:git://github.com/spring-projects/spring-data-elasticsearch.git</connection>
<developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git <developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-data-elasticsearch.git
</developerConnection> </developerConnection>
</scm> </scm>
<ciManagement> <ciManagement>
<system>Bamboo</system> <system>Bamboo</system>
<url>https://build.spring.io/browse/SPRINGDATAES</url> <url>https://build.spring.io/browse/SPRINGDATAES</url>
</ciManagement> </ciManagement>
<issueManagement> <issueManagement>
<system>JIRA</system> <system>JIRA</system>
<url>https://jira.spring.io/browse/DATAES</url> <url>https://jira.spring.io/browse/DATAES</url>
</issueManagement> </issueManagement>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>io.netty</groupId> <groupId>io.netty</groupId>
<artifactId>netty-bom</artifactId> <artifactId>netty-bom</artifactId>
<version>${netty}</version> <version>${netty}</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
<dependencies> <dependencies>
<!-- Spring --> <!-- Spring -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId> <artifactId>spring-context</artifactId>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId> <artifactId>spring-tx</artifactId>
</dependency> </dependency>
<!-- SPRING DATA --> <!-- SPRING DATA -->
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId> <artifactId>spring-data-commons</artifactId>
<version>${springdata.commons}</version> <version>${springdata.commons}</version>
</dependency> </dependency>
<!-- Reactive Infrastructure --> <!-- Reactive Infrastructure -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId> <artifactId>spring-webflux</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.projectreactor.netty</groupId> <groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty-http</artifactId> <artifactId>reactor-netty-http</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>io.projectreactor</groupId> <groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId> <artifactId>reactor-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- APACHE --> <!-- APACHE -->
<dependency> <dependency>
<groupId>commons-lang</groupId> <groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId> <artifactId>commons-lang</artifactId>
<version>${commonslang}</version> <version>${commonslang}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- JODA Time --> <!-- JODA Time -->
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
<version>${jodatime}</version> <version>${jodatime}</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- Elasticsearch --> <!-- Elasticsearch -->
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId> <artifactId>transport</artifactId>
<version>${elasticsearch}</version> <version>${elasticsearch}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<!-- required by elasticsearch --> <!-- required by elasticsearch -->
<groupId>org.elasticsearch.plugin</groupId> <groupId>org.elasticsearch.plugin</groupId>
<artifactId>transport-netty4-client</artifactId> <artifactId>transport-netty4-client</artifactId>
<version>${elasticsearch}</version> <version>${elasticsearch}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.elasticsearch.client</groupId> <groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId> <artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>${elasticsearch}</version> <version>${elasticsearch}</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId> <artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j}</version> <version>${slf4j}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId> <artifactId>log4j-core</artifactId>
<version>${log4j}</version> <version>${log4j}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- Jackson JSON Mapper --> <!-- Jackson JSON Mapper -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId> <artifactId>jackson-core</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<!-- CDI --> <!-- CDI -->
<dependency> <dependency>
<groupId>javax.enterprise</groupId> <groupId>javax.enterprise</groupId>
<artifactId>cdi-api</artifactId> <artifactId>cdi-api</artifactId>
<version>${cdi}</version> <version>${cdi}</version>
<scope>provided</scope> <scope>provided</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<!-- Test --> <!-- Test -->
<dependency> <dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId> <artifactId>spring-test</artifactId>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.openwebbeans.test</groupId> <groupId>org.apache.openwebbeans.test</groupId>
<artifactId>cditest-owb</artifactId> <artifactId>cditest-owb</artifactId>
<version>1.2.8</version> <version>1.2.8</version>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.apache.geronimo.specs</groupId> <groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-jcdi_1.0_spec</artifactId> <artifactId>geronimo-jcdi_1.0_spec</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>org.apache.geronimo.specs</groupId> <groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-atinject_1.0_spec</artifactId> <artifactId>geronimo-atinject_1.0_spec</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.skyscreamer</groupId> <groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId> <artifactId>jsonassert</artifactId>
<version>1.5.0</version> <version>1.5.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.github.tomakehurst</groupId> <groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8</artifactId> <artifactId>wiremock-jre8</artifactId>
<version>2.26.3</version> <version>2.26.3</version>
<scope>test</scope> <scope>test</scope>
<exclusions> <exclusions>
<!-- these exclusions are needed because of Elasticsearch JarHell--> <!-- these exclusions are needed because of Elasticsearch JarHell-->
<exclusion> <exclusion>
<groupId>commons-logging</groupId> <groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId> <artifactId>commons-logging</artifactId>
</exclusion> </exclusion>
<exclusion> <exclusion>
<groupId>org.ow2.asm</groupId> <groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId> <artifactId>asm</artifactId>
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </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>
<artifactId>xbean-asm5-shaded</artifactId> <artifactId>xbean-asm5-shaded</artifactId>
<version>4.5</version> <version>4.5</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version> <version>3.1.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId> <artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito}</version> <version>${mockito}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> <dependency>
<groupId>org.testcontainers</groupId>
<artifactId>elasticsearch</artifactId>
<version>${testcontainers}</version>
<scope>test</scope>
</dependency>
<build> </dependencies>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/versions.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/versions.properties</exclude>
</excludes>
</resource>
</resources>
<plugins> <build>
<!-- <resources>
please do not remove this configuration for surefire - we need that to avoid issue with jar hell <resource>
--> <directory>src/main/resources</directory>
<plugin> <filtering>true</filtering>
<groupId>org.apache.maven.plugins</groupId> <includes>
<artifactId>maven-surefire-plugin</artifactId> <include>**/versions.properties</include>
<configuration> </includes>
<useSystemClassLoader>true</useSystemClassLoader> </resource>
<useFile>false</useFile> <resource>
<includes> <directory>src/main/resources</directory>
<include>**/*Tests.java</include> <filtering>false</filtering>
<include>**/*Test.java</include> <excludes>
</includes> <exclude>**/versions.properties</exclude>
<systemPropertyVariables> </excludes>
<es.set.netty.runtime.available.processors>false</es.set.netty.runtime.available.processors> </resource>
</systemPropertyVariables> </resources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<profiles> <plugins>
<profile> <!--
please do not remove this configuration for surefire - we need that to avoid issue with jar hell
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<useFile>false</useFile>
<includes>
<include>**/*Tests.java</include>
<include>**/*Test.java</include>
</includes>
<systemPropertyVariables>
<es.set.netty.runtime.available.processors>false</es.set.netty.runtime.available.processors>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<id>ci</id> <profiles>
<profile>
<build> <id>ci</id>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<checkstyleRules>
<module name="Checker">
<!-- Configure checker to use UTF-8 encoding --> <build>
<property name="charset" value="UTF-8"/> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<checkstyleRules>
<module name="Checker">
<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck"/> <!-- Configure checker to use UTF-8 encoding -->
</module> <property name="charset" value="UTF-8"/>
</checkstyleRules>
<includes>**/*</includes>
<excludes>.git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy</excludes>
<sourceDirectories>./</sourceDirectories>
</configuration>
</plugin>
</plugins>
</build>
</profile> <module name="io.spring.nohttp.checkstyle.check.NoHttpCheck"/>
</module>
</checkstyleRules>
<includes>**/*</includes>
<excludes>.git/**/*,target/**/*,**/target/**/*,.idea/**/*,**/spring.schemas,**/*.svg,mvnw,mvnw.cmd,**/*.policy</excludes>
<sourceDirectories>./</sourceDirectories>
</configuration>
</plugin>
</plugins>
</build>
</profiles> </profile>
<repositories> </profiles>
<repository>
<id>spring-libs-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
<pluginRepositories> <repositories>
<pluginRepository> <repository>
<id>spring-plugins-release</id> <id>spring-libs-snapshot</id>
<url>https://repo.spring.io/plugins-release</url> <url>https://repo.spring.io/libs-snapshot</url>
</pluginRepository> </repository>
</pluginRepositories> </repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-plugins-release</id>
<url>https://repo.spring.io/plugins-release</url>
</pluginRepository>
</pluginRepositories>
</project> </project>

View File

@ -44,7 +44,9 @@ import org.springframework.util.StringUtils;
* @author Mohsin Husen * @author Mohsin Husen
* @author Ilkang Na * @author Ilkang Na
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
* @deprecated since 4.1, we're not supporting embedded Node clients anymore, use the REST client
*/ */
@Deprecated
public class NodeClientFactoryBean implements FactoryBean<Client>, InitializingBean, DisposableBean { public class NodeClientFactoryBean implements FactoryBean<Client>, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(NodeClientFactoryBean.class); private static final Logger logger = LoggerFactory.getLogger(NodeClientFactoryBean.class);

View File

@ -173,7 +173,12 @@ class RequestFactory {
} }
public GetAliasesRequest getAliasesRequest(@Nullable String[] aliasNames, @Nullable String[] indexNames) { public GetAliasesRequest getAliasesRequest(@Nullable String[] aliasNames, @Nullable String[] indexNames) {
return new GetAliasesRequest(aliasNames).indices(indexNames); GetAliasesRequest getAliasesRequest = new GetAliasesRequest(aliasNames);
if (indexNames != null) {
getAliasesRequest.indices(indexNames);
}
return getAliasesRequest;
} }
public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) { public IndicesAliasesRequest indicesAddAliasesRequest(AliasQuery query, IndexCoordinates index) {

View File

@ -36,7 +36,10 @@ public final class VersionInfo {
private static final Logger LOG = LoggerFactory.getLogger(VersionInfo.class); private static final Logger LOG = LoggerFactory.getLogger(VersionInfo.class);
private static final AtomicBoolean initialized = new AtomicBoolean(false); private static final AtomicBoolean initialized = new AtomicBoolean(false);
private static String VERSION_PROPERTIES = "versions.properties";
private static final String VERSION_PROPERTIES = "versions.properties";
public static final String VERSION_SPRING_DATA_ELASTICSEARCH = "version.spring-data-elasticsearch";
public static final String VERSION_ELASTICSEARCH_CLIENT = "version.elasticsearch-client";
/** /**
* logs the relevant version info the first time it is called. Does nothing after the first call * logs the relevant version info the first time it is called. Does nothing after the first call
@ -51,8 +54,8 @@ public final class VersionInfo {
Properties properties = new Properties(); Properties properties = new Properties();
properties.load(resource); properties.load(resource);
String versionSpringDataElasticsearch = properties.getProperty("version.spring-data-elasticsearch"); String versionSpringDataElasticsearch = properties.getProperty(VERSION_SPRING_DATA_ELASTICSEARCH);
Version versionESBuilt = Version.fromString(properties.getProperty("version.elasticsearch-client")); Version versionESBuilt = Version.fromString(properties.getProperty(VERSION_ELASTICSEARCH_CLIENT));
Version versionESUsed = Version.CURRENT; Version versionESUsed = Version.CURRENT;
Version versionESCluster = clusterVersion != null ? Version.fromString(clusterVersion) : null; Version versionESCluster = clusterVersion != null ? Version.fromString(clusterVersion) : null;
@ -83,6 +86,22 @@ public final class VersionInfo {
} }
} }
public static Properties versionProperties() throws Exception {
try {
InputStream resource = VersionInfo.class.getClassLoader().getResourceAsStream(VERSION_PROPERTIES);
if (resource != null) {
Properties properties = new Properties();
properties.load(resource);
return properties;
} else {
throw new IllegalStateException("Resource not found");
}
} catch (Exception e) {
LOG.error("Could not load {}", VERSION_PROPERTIES, e);
throw e;
}
}
private static boolean differInMajorOrMinor(Version version1, Version version2) { private static boolean differInMajorOrMinor(Version version1, Version version2) {
return version1.major != version2.major || version1.minor != version2.minor; return version1.major != version2.major || version1.minor != version2.minor;
} }

View File

@ -1,49 +0,0 @@
/*
* Copyright 2019-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
import org.elasticsearch.client.Client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverter;
import org.springframework.data.elasticsearch.junit.junit4.TestNodeResource;
/**
* configuration class for the classic ElasticsearchTemplate. Needs a {@link TestNodeResource} bean that should be set
* up in the test as ClassRule and exported as bean.
*
* @author Peter-Josef Meisch
*/
@Configuration
public class ElasticsearchTestConfiguration extends ElasticsearchConfigurationSupport {
@Autowired private TestNodeResource testNodeResource;
@Bean
public Client elasticsearchClient() {
return testNodeResource.client();
}
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })
public ElasticsearchTemplate elasticsearchTemplate(Client elasticsearchClient,
ElasticsearchConverter elasticsearchConverter) {
return new ElasticsearchTemplate(elasticsearchClient, elasticsearchConverter);
}
}

View File

@ -1,34 +0,0 @@
/*
* Copyright 2019-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
/**
* @author Peter-Josef Meisch
*/
@Configuration
public class RestElasticsearchTestConfiguration extends AbstractElasticsearchConfiguration {
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
return TestUtils.restHighLevelClient();
}
}

View File

@ -1,137 +0,0 @@
/*
* Copyright 2018-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
import lombok.SneakyThrows;
import java.time.Duration;
import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
import org.springframework.data.elasticsearch.support.SearchHitsUtil;
import org.springframework.data.util.Version;
import org.springframework.util.ObjectUtils;
/**
* @author Christoph Strobl
* @author Mark Paluch
* @currentRead Fool's Fate - Robin Hobb
*/
public final class TestUtils {
private TestUtils() {}
private static final ClientConfiguration CONFIG = ClientConfiguration.builder().connectedToLocalhost()
.withConnectTimeout(Duration.ofSeconds(5)).withSocketTimeout(Duration.ofSeconds(3)).build();
public static RestHighLevelClient restHighLevelClient() {
return RestClients.create(CONFIG).rest();
}
public static ReactiveElasticsearchClient reactiveClient() {
return ReactiveRestClients.create(CONFIG);
}
public static Version serverVersion() {
try (RestHighLevelClient client = restHighLevelClient()) {
org.elasticsearch.Version version = org.elasticsearch.Version
.fromString(client.info(RequestOptions.DEFAULT).getVersion().getNumber());
return new Version(version.major, version.minor, version.revision);
} catch (Exception e) {
return new Version(0, 0, 0);
}
}
@SneakyThrows
public static void deleteIndex(String... indexes) {
if (ObjectUtils.isEmpty(indexes)) {
return;
}
try (RestHighLevelClient client = restHighLevelClient()) {
for (String index : indexes) {
try {
client.indices().delete(new DeleteIndexRequest(index), RequestOptions.DEFAULT);
} catch (ElasticsearchStatusException ex) {
// just ignore it
}
}
}
}
@SneakyThrows
public static boolean isEmptyIndex(String indexName) {
try (RestHighLevelClient client = restHighLevelClient()) {
return 0L == SearchHitsUtil.getTotalCount(client
.search(new SearchRequest(indexName)
.source(SearchSourceBuilder.searchSource().query(QueryBuilders.matchAllQuery())), RequestOptions.DEFAULT)
.getHits());
}
}
public static OfType documentWithId(String id) {
return new DocumentLookup(id);
}
public interface ExistsIn {
boolean existsIn(String index);
}
public interface OfType extends ExistsIn {
ExistsIn ofType(String type);
}
private static class DocumentLookup implements OfType {
private String id;
public DocumentLookup(String id) {
this.id = id;
}
@Override
@SneakyThrows
public boolean existsIn(String index) {
GetRequest request = new GetRequest(index).id(id);
try (RestHighLevelClient client = restHighLevelClient()) {
return client.get(request, RequestOptions.DEFAULT).isExists();
}
}
@Override
public ExistsIn ofType(String type) {
return this;
}
}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2015-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch;
import java.util.Arrays;
import java.util.UUID;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.join.ParentJoinPlugin;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeValidationException;
import org.elasticsearch.transport.Netty4Plugin;
import org.springframework.data.elasticsearch.client.NodeClientFactoryBean;
/**
* @author Mohsin Husen
* @author Artur Konczak
* @author Ilkang Na
* @author Peter-Josef Meisch
* @author Roman Puchkovskiy
* @author Subhobrata Dey
*/
public class Utils {
public static Node getNode() {
String pathHome = "src/test/resources/test-home-dir";
String pathData = "target/elasticsearchTestData";
String clusterName = UUID.randomUUID().toString();
return new NodeClientFactoryBean.TestNode( //
Settings.builder() //
.put("transport.type", "netty4") //
.put("http.type", "netty4") //
.put("path.home", pathHome) //
.put("path.data", pathData) //
.put("cluster.name", clusterName) //
.put("node.max_local_storage_nodes", 100)//
// the following 3 settings are needed to avoid problems on big, but
// almost full filesystems, see DATAES-741
.put("cluster.routing.allocation.disk.watermark.low", "1gb")//
.put("cluster.routing.allocation.disk.watermark.high", "1gb")//
.put("cluster.routing.allocation.disk.watermark.flood_stage", "1gb")//
.build(), //
Arrays.asList(Netty4Plugin.class, ParentJoinPlugin.class));
}
public static Client getNodeClient() throws NodeValidationException {
return getNode().start().client();
}
}

View File

@ -18,9 +18,9 @@ package org.springframework.data.elasticsearch.client.reactive;
import static org.assertj.core.api.Assertions.*; import static org.assertj.core.api.Assertions.*;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
import java.io.IOException;
import java.time.Duration; import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -39,11 +39,6 @@ import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy; import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.PutMappingRequest;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.get.GetResult; import org.elasticsearch.index.get.GetResult;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
@ -58,13 +53,17 @@ import org.elasticsearch.search.suggest.completion.CompletionSuggestionBuilder;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.data.elasticsearch.TestUtils; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.core.ReactiveIndexOperations;
import org.springframework.data.elasticsearch.core.document.Document;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.lang.Nullable;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
/** /**
@ -76,21 +75,27 @@ import org.springframework.test.context.ContextConfiguration;
* @author Thomas Geese * @author Thomas Geese
*/ */
@SpringIntegrationTest @SpringIntegrationTest
@ContextConfiguration(classes = { ElasticsearchRestTemplateConfiguration.class }) @ContextConfiguration(classes = { ReactiveElasticsearchClientTests.Config.class })
public class ReactiveElasticsearchClientTests { public class ReactiveElasticsearchClientTests {
@Configuration
static class Config extends ReactiveElasticsearchRestTemplateConfiguration {
@Override
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
return super.reactiveElasticsearchClient();
}
}
static final String INDEX_I = "idx-1-reactive-client-tests"; static final String INDEX_I = "idx-1-reactive-client-tests";
static final String INDEX_II = "idx-2-reactive-client-tests"; static final String INDEX_II = "idx-2-reactive-client-tests";
static final String TYPE_I = "doc-type-1";
static final String TYPE_II = "doc-type-2";
// must be <String, Object> and not <String, String>, otherwise UpdateRequest.doc() will use the overload with // must be <String, Object> and not <String, String>, otherwise UpdateRequest.doc() will use the overload with
// (Object...) // (Object...)
static final Map<String, Object> DOC_SOURCE; static final Map<String, Object> DOC_SOURCE;
RestHighLevelClient syncClient; @Autowired ReactiveElasticsearchClient client;
ReactiveElasticsearchClient client; @Autowired ReactiveElasticsearchOperations operations;
static { static {
@ -103,19 +108,14 @@ public class ReactiveElasticsearchClientTests {
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
operations.indexOps(IndexCoordinates.of(INDEX_I)).delete().block();
syncClient = TestUtils.restHighLevelClient(); operations.indexOps(IndexCoordinates.of(INDEX_II)).delete().block();
client = TestUtils.reactiveClient();
TestUtils.deleteIndex(INDEX_I, INDEX_II);
} }
@AfterEach @AfterEach
public void after() throws IOException { public void after() {
operations.indexOps(IndexCoordinates.of(INDEX_I)).delete().block();
TestUtils.deleteIndex(INDEX_I, INDEX_II); operations.indexOps(IndexCoordinates.of(INDEX_II)).delete().block();
syncClient.close();
} }
@Test // DATAES-488 @Test // DATAES-488
@ -157,7 +157,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void getShouldFetchDocumentById() { public void getShouldFetchDocumentById() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
client.get(new GetRequest(INDEX_I, id)) // client.get(new GetRequest(INDEX_I, id)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -172,7 +172,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void getShouldCompleteForNonExistingDocuments() { public void getShouldCompleteForNonExistingDocuments() {
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
String id = "this-one-does-not-exist"; String id = "this-one-does-not-exist";
client.get(new GetRequest(INDEX_I, id)) // client.get(new GetRequest(INDEX_I, id)) //
@ -183,8 +183,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void multiGetShouldReturnAllDocumentsFromSameCollection() { public void multiGetShouldReturnAllDocumentsFromSameCollection() {
String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id1 = addSourceDocument().to(INDEX_I);
String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id2 = addSourceDocument().to(INDEX_I);
MultiGetRequest request = new MultiGetRequest() // MultiGetRequest request = new MultiGetRequest() //
.add(INDEX_I, id1) // .add(INDEX_I, id1) //
@ -200,8 +200,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void multiGetShouldReturnAllExistingDocumentsFromSameCollection() { public void multiGetShouldReturnAllExistingDocumentsFromSameCollection() {
String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id1 = addSourceDocument().to(INDEX_I);
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
MultiGetRequest request = new MultiGetRequest() // MultiGetRequest request = new MultiGetRequest() //
.add(INDEX_I, id1) // .add(INDEX_I, id1) //
@ -216,8 +216,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void multiGetShouldSkipNonExistingDocuments() { public void multiGetShouldSkipNonExistingDocuments() {
String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id1 = addSourceDocument().to(INDEX_I);
String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id2 = addSourceDocument().to(INDEX_I);
MultiGetRequest request = new MultiGetRequest() // MultiGetRequest request = new MultiGetRequest() //
.add(INDEX_I, id1) // .add(INDEX_I, id1) //
@ -234,8 +234,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void multiGetShouldCompleteIfNothingFound() { public void multiGetShouldCompleteIfNothingFound() {
String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id1 = addSourceDocument().to(INDEX_I);
String id2 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id2 = addSourceDocument().to(INDEX_I);
client.multiGet(new MultiGetRequest() // client.multiGet(new MultiGetRequest() //
.add(INDEX_II, id1).add(INDEX_II, id2)) // .add(INDEX_II, id1).add(INDEX_II, id2)) //
@ -246,8 +246,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void multiGetShouldReturnAllExistingDocumentsFromDifferentCollection() { public void multiGetShouldReturnAllExistingDocumentsFromDifferentCollection() {
String id1 = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id1 = addSourceDocument().to(INDEX_I);
String id2 = addSourceDocument().ofType(TYPE_II).to(INDEX_II); String id2 = addSourceDocument().to(INDEX_II);
MultiGetRequest request = new MultiGetRequest() // MultiGetRequest request = new MultiGetRequest() //
.add(INDEX_I, id1) // .add(INDEX_I, id1) //
@ -263,7 +263,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void existsReturnsTrueForExistingDocuments() { public void existsReturnsTrueForExistingDocuments() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
client.exists(new GetRequest(INDEX_I, id)) // client.exists(new GetRequest(INDEX_I, id)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -274,7 +274,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void existsReturnsFalseForNonExistingDocuments() { public void existsReturnsFalseForNonExistingDocuments() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
client.exists(new GetRequest(INDEX_II, id)) // client.exists(new GetRequest(INDEX_II, id)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -285,7 +285,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void indexShouldAddDocument() { public void indexShouldAddDocument() {
IndexRequest request = indexRequest(DOC_SOURCE, INDEX_I, TYPE_I); IndexRequest request = indexRequest();
client.index(request) // client.index(request) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -300,9 +300,9 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void indexShouldErrorForExistingDocuments() { public void indexShouldErrorForExistingDocuments() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
IndexRequest request = indexRequest(DOC_SOURCE, INDEX_I, TYPE_I)// IndexRequest request = indexRequest()//
.id(id); .id(id);
client.index(request) // client.index(request) //
@ -331,7 +331,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void updateShouldUpdateExistingDocument() { public void updateShouldUpdateExistingDocument() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
UpdateRequest request = new UpdateRequest(INDEX_I, id) // UpdateRequest request = new UpdateRequest(INDEX_I, id) //
.doc(Collections.singletonMap("dutiful", "farseer")); .doc(Collections.singletonMap("dutiful", "farseer"));
@ -362,7 +362,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void deleteShouldRemoveExistingDocument() { public void deleteShouldRemoveExistingDocument() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
DeleteRequest request = new DeleteRequest(INDEX_I, id); DeleteRequest request = new DeleteRequest(INDEX_I, id);
@ -375,7 +375,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void deleteShouldReturnNotFoundForNonExistingDocument() { public void deleteShouldReturnNotFoundForNonExistingDocument() {
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
DeleteRequest request = new DeleteRequest(INDEX_I, "this-one-does-not-exist"); DeleteRequest request = new DeleteRequest(INDEX_I, "this-one-does-not-exist");
@ -388,8 +388,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-488 @Test // DATAES-488
public void searchShouldFindExistingDocuments() { public void searchShouldFindExistingDocuments() {
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
SearchRequest request = new SearchRequest(INDEX_I) // SearchRequest request = new SearchRequest(INDEX_I) //
.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
@ -401,9 +401,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-488 @Test // DATAES-488
public void searchShouldCompleteIfNothingFound() throws IOException { public void searchShouldCompleteIfNothingFound() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
SearchRequest request = new SearchRequest(INDEX_I) // SearchRequest request = new SearchRequest(INDEX_I) //
.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
@ -414,10 +414,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-488 @Test // DATAES-488
@ElasticsearchVersion(asOf = "6.5.0")
public void deleteByShouldRemoveExistingDocument() { public void deleteByShouldRemoveExistingDocument() {
String id = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String id = addSourceDocument().to(INDEX_I);
DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) //
.setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", id))); .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", id)));
@ -430,10 +429,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-488 @Test // DATAES-488
@ElasticsearchVersion(asOf = "6.5.0")
public void deleteByEmitResultWhenNothingRemoved() { public void deleteByEmitResultWhenNothingRemoved() {
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) // DeleteByQueryRequest request = new DeleteByQueryRequest(INDEX_I) //
.setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", "it-was-not-me"))); .setQuery(QueryBuilders.boolQuery().must(QueryBuilders.termQuery("_id", "it-was-not-me")));
@ -448,7 +446,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-510 @Test // DATAES-510
public void scrollShouldReadWhileEndNotReached() { public void scrollShouldReadWhileEndNotReached() {
IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).to(INDEX_I));
SearchRequest request = new SearchRequest(INDEX_I) // SearchRequest request = new SearchRequest(INDEX_I) //
.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
@ -464,7 +462,7 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-510 @Test // DATAES-510
public void scrollShouldReadWhileTakeNotReached() { public void scrollShouldReadWhileTakeNotReached() {
IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).ofType(TYPE_I).to(INDEX_I)); IntStream.range(0, 100).forEach(it -> add(Collections.singletonMap(it + "-foo", "bar")).to(INDEX_I));
SearchRequest request = new SearchRequest(INDEX_I) // SearchRequest request = new SearchRequest(INDEX_I) //
.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery())); .source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
@ -479,9 +477,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void indexExistsShouldReturnTrueIfSo() throws IOException { public void indexExistsShouldReturnTrueIfSo() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().existsIndex(request -> request.indices(INDEX_I)) // client.indices().existsIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -490,9 +488,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void indexExistsShouldReturnFalseIfNot() throws IOException { public void indexExistsShouldReturnFalseIfNot() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().existsIndex(request -> request.indices(INDEX_II)) // client.indices().existsIndex(request -> request.indices(INDEX_II)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -501,20 +499,23 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569, DATAES-678 @Test // DATAES-569, DATAES-678
public void createIndex() throws IOException { public void createIndex() {
client.indices().createIndex(request -> request.index(INDEX_I)) // client.indices().createIndex(request -> request.index(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectNext(true) // .expectNext(true) //
.verifyComplete(); .verifyComplete();
assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isTrue(); operations.indexOps(IndexCoordinates.of(INDEX_I)).exists() //
.as(StepVerifier::create) //
.expectNext(true) //
.verifyComplete();
} }
@Test // DATAES-569 @Test // DATAES-569
public void createExistingIndexErrors() throws IOException { public void createExistingIndexErrors() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().createIndex(request -> request.index(INDEX_I)) // client.indices().createIndex(request -> request.index(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -522,16 +523,20 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569, DATAES-678 @Test // DATAES-569, DATAES-678
public void deleteExistingIndex() throws IOException { public void deleteExistingIndex() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().deleteIndex(request -> request.indices(INDEX_I)) // client.indices().deleteIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectNext(true) // .expectNext(true) //
.verifyComplete(); .verifyComplete();
assertThat(syncClient.indices().exists(new GetIndexRequest(INDEX_I), RequestOptions.DEFAULT)).isFalse(); operations.indexOps(IndexCoordinates.of(INDEX_I)) //
.exists() //
.as(StepVerifier::create) //
.expectNext(false) //
.verifyComplete();
} }
@Test // DATAES-569, DATAES-767 @Test // DATAES-569, DATAES-767
@ -543,9 +548,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void openExistingIndex() throws IOException { public void openExistingIndex() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().openIndex(request -> request.indices(INDEX_I)) // client.indices().openIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -561,9 +566,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void closeExistingIndex() throws IOException { public void closeExistingIndex() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().openIndex(request -> request.indices(INDEX_I)) // client.indices().openIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -579,9 +584,9 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void refreshIndex() throws IOException { public void refreshIndex() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().refreshIndex(request -> request.indices(INDEX_I)) // client.indices().refreshIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -597,14 +602,14 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-569 @Test // DATAES-569
public void updateMapping() throws IOException { public void updateMapping() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
Map<String, Object> jsonMap = Collections.singletonMap("properties", Map<String, Object> jsonMap = Collections.singletonMap("properties",
Collections.singletonMap("message", Collections.singletonMap("type", "text"))); Collections.singletonMap("message", Collections.singletonMap("type", "text")));
client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // client.indices().updateMapping(request -> request.indices(INDEX_I).source(jsonMap)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectNext(true) // .expectNext(true) //
.verifyComplete(); .verifyComplete();
@ -616,15 +621,15 @@ public class ReactiveElasticsearchClientTests {
Map<String, Object> jsonMap = Collections.singletonMap("properties", Map<String, Object> jsonMap = Collections.singletonMap("properties",
Collections.singletonMap("message", Collections.singletonMap("type", "text"))); Collections.singletonMap("message", Collections.singletonMap("type", "text")));
client.indices().updateMapping(request -> request.indices(INDEX_I).type(TYPE_I).source(jsonMap)) // client.indices().updateMapping(request -> request.indices(INDEX_I).source(jsonMap)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.verifyError(ElasticsearchStatusException.class); .verifyError(ElasticsearchStatusException.class);
} }
@Test // DATAES-569 @Test // DATAES-569
public void flushIndex() throws IOException { public void flushIndex() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); operations.indexOps(IndexCoordinates.of(INDEX_I)).create().block();
client.indices().flushIndex(request -> request.indices(INDEX_I)) // client.indices().flushIndex(request -> request.indices(INDEX_I)) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -641,8 +646,8 @@ public class ReactiveElasticsearchClientTests {
@Test // DATAES-684 @Test // DATAES-684
public void bulkShouldUpdateExistingDocument() { public void bulkShouldUpdateExistingDocument() {
String idFirstDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String idFirstDoc = addSourceDocument().to(INDEX_I);
String idSecondDoc = addSourceDocument().ofType(TYPE_I).to(INDEX_I); String idSecondDoc = addSourceDocument().to(INDEX_I);
UpdateRequest requestFirstDoc = new UpdateRequest(INDEX_I, idFirstDoc) // UpdateRequest requestFirstDoc = new UpdateRequest(INDEX_I, idFirstDoc) //
.doc(Collections.singletonMap("dutiful", "farseer")); .doc(Collections.singletonMap("dutiful", "farseer"));
@ -666,13 +671,15 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-567 @Test // DATAES-567
public void aggregateReturnsAggregationResults() throws IOException { public void aggregateReturnsAggregationResults() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(INDEX_I));
indexOps.create().block();
Map<String, Object> jsonMap = Collections.singletonMap("properties", Map<String, Object> jsonMap = Collections.singletonMap("properties",
Collections.singletonMap("firstname", Collections.singletonMap("type", "keyword"))); Collections.singletonMap("firstname", Collections.singletonMap("type", "keyword")));
syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); indexOps.putMapping(Mono.just(Document.from(jsonMap))).block();
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
searchSourceBuilder.aggregation(AggregationBuilders.terms("terms").field("firstname")); searchSourceBuilder.aggregation(AggregationBuilders.terms("terms").field("firstname"));
@ -685,13 +692,14 @@ public class ReactiveElasticsearchClientTests {
} }
@Test // DATAES-866 @Test // DATAES-866
public void suggestReturnsSuggestionResults() throws IOException { public void suggestReturnsSuggestionResults() {
syncClient.indices().create(new CreateIndexRequest(INDEX_I), RequestOptions.DEFAULT); ReactiveIndexOperations indexOps = operations.indexOps(IndexCoordinates.of(INDEX_I));
indexOps.create().block();
Map<String, Object> jsonMap = Collections.singletonMap("properties", Map<String, Object> jsonMap = Collections.singletonMap("properties",
Collections.singletonMap("firstname", Collections.singletonMap("type", "completion"))); Collections.singletonMap("firstname", Collections.singletonMap("type", "completion")));
syncClient.indices().putMapping(new PutMappingRequest(INDEX_I).source(jsonMap), RequestOptions.DEFAULT); indexOps.putMapping(Mono.just(Document.from(jsonMap))).block();
addSourceDocument().ofType(TYPE_I).to(INDEX_I); addSourceDocument().to(INDEX_I);
SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("firstname", SuggestBuilder suggestBuilder = new SuggestBuilder().addSuggestion("firstname",
new CompletionSuggestionBuilder("firstname").prefix("ch")); new CompletionSuggestionBuilder("firstname").prefix("ch"));
@ -708,55 +716,43 @@ public class ReactiveElasticsearchClientTests {
.verifyComplete(); .verifyComplete();
} }
private AddToIndexOfType addSourceDocument() { private AddToIndex addSourceDocument() {
return add(DOC_SOURCE); return add(DOC_SOURCE);
} }
private AddToIndexOfType add(Map<String, ?> source) { private AddToIndex add(Map<String, ?> source) {
return new AddDocument(source); return new AddDocument(source);
} }
private IndexRequest indexRequest(Map source, String index, String type) { private IndexRequest indexRequest() {
return new IndexRequest(index) // return new IndexRequest(ReactiveElasticsearchClientTests.INDEX_I) //
.id(UUID.randomUUID().toString()) // .id(UUID.randomUUID().toString()) //
.source(source) // .source(ReactiveElasticsearchClientTests.DOC_SOURCE) //
.setRefreshPolicy(RefreshPolicy.IMMEDIATE) // .setRefreshPolicy(RefreshPolicy.IMMEDIATE) //
.create(true); .create(true);
} }
@SneakyThrows @SneakyThrows
private String doIndex(Map<?, ?> source, String index, String type) { private String doIndex(Map<String, ?> source, String index) {
return syncClient.index(indexRequest(source, index, type), RequestOptions.DEFAULT).getId(); return operations.save(source, IndexCoordinates.of(index)).block().get("id").toString();
}
interface AddToIndexOfType extends AddToIndex {
AddToIndex ofType(String type);
} }
interface AddToIndex { interface AddToIndex {
String to(String index); String to(String index);
} }
class AddDocument implements AddToIndexOfType { class AddDocument implements AddToIndex {
Map<String, ?> source; Map<String, ?> source;
@Nullable String type;
AddDocument(Map<String, ?> source) { AddDocument(Map<String, ?> source) {
this.source = source; this.source = source;
} }
@Override
public AddToIndex ofType(String type) {
this.type = type;
return this;
}
@Override @Override
public String to(String index) { public String to(String index) {
return doIndex(new LinkedHashMap<>(source), index, type); return doIndex(new LinkedHashMap<>(source), index);
} }
} }

View File

@ -28,6 +28,7 @@ import lombok.NoArgsConstructor;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
import java.lang.Boolean;
import java.lang.Long; import java.lang.Long;
import java.lang.Object; import java.lang.Object;
import java.net.ConnectException; import java.net.ConnectException;
@ -49,6 +50,9 @@ import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.dao.DataAccessResourceFailureException; import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
@ -56,7 +60,6 @@ import org.springframework.data.annotation.Version;
import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.UncategorizedElasticsearchException; import org.springframework.data.elasticsearch.UncategorizedElasticsearchException;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Field;
@ -64,7 +67,7 @@ import org.springframework.data.elasticsearch.annotations.Score;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.*; import org.springframework.data.elasticsearch.core.query.*;
import org.springframework.data.elasticsearch.junit.junit4.ElasticsearchVersion; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -83,25 +86,26 @@ import org.springframework.util.StringUtils;
@SpringIntegrationTest @SpringIntegrationTest
public class ReactiveElasticsearchTemplateTests { public class ReactiveElasticsearchTemplateTests {
@Configuration
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
static class Config {}
static final String DEFAULT_INDEX = "reactive-template-test-index"; static final String DEFAULT_INDEX = "reactive-template-test-index";
static final String ALTERNATE_INDEX = "reactive-template-tests-alternate-index"; static final String ALTERNATE_INDEX = "reactive-template-tests-alternate-index";
private ElasticsearchRestTemplate restTemplate; @Autowired private ReactiveElasticsearchTemplate template;
private ReactiveElasticsearchTemplate template; private ReactiveIndexOperations indexOperations;
private IndexOperations indexOperations;
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
restTemplate = new ElasticsearchRestTemplate(TestUtils.restHighLevelClient()); indexOperations = template.indexOps(SampleEntity.class);
indexOperations = restTemplate.indexOps(SampleEntity.class);
deleteIndices(); deleteIndices();
indexOperations.create(); indexOperations.create() //
indexOperations.putMapping(SampleEntity.class); .then(indexOperations.putMapping(SampleEntity.class)) //
indexOperations.refresh(); .then(indexOperations.refresh()) //
.block(); //
template = new ReactiveElasticsearchTemplate(TestUtils.reactiveClient(), restTemplate.getElasticsearchConverter());
} }
@AfterEach @AfterEach
@ -110,9 +114,13 @@ public class ReactiveElasticsearchTemplateTests {
} }
private void deleteIndices() { private void deleteIndices() {
TestUtils.deleteIndex(DEFAULT_INDEX, ALTERNATE_INDEX, "rx-template-test-index-this", "rx-template-test-index-that", template.indexOps(IndexCoordinates.of(DEFAULT_INDEX)).delete().block();
"test-index-reactive-optimistic-entity-template", template.indexOps(IndexCoordinates.of(ALTERNATE_INDEX)).delete().block();
"test-index-reactive-optimistic-and-versioned-entity-template"); template.indexOps(IndexCoordinates.of("rx-template-test-index-this")).delete().block();
template.indexOps(IndexCoordinates.of("rx-template-test-index-that")).delete().block();
template.indexOps(IndexCoordinates.of("test-index-reactive-optimistic-entity-template")).delete().block();
template.indexOps(IndexCoordinates.of("test-index-reactive-optimistic-and-versioned-entity-template")).delete()
.block();
} }
@Test // DATAES-504 @Test // DATAES-504
@ -147,10 +155,12 @@ public class ReactiveElasticsearchTemplateTests {
indexOperations.refresh(); indexOperations.refresh();
SearchHits<SampleEntity> result = restTemplate.search( template
new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class, .search(new CriteriaQuery(Criteria.where("message").is(sampleEntity.getMessage())), SampleEntity.class,
IndexCoordinates.of(DEFAULT_INDEX)); IndexCoordinates.of(DEFAULT_INDEX)) //
assertThat(result).hasSize(1); .as(StepVerifier::create) //
.expectNextCount(1) //
.verifyComplete();
} }
@Test // DATAES-504 @Test // DATAES-504
@ -159,17 +169,17 @@ public class ReactiveElasticsearchTemplateTests {
SampleEntity sampleEntity = SampleEntity.builder().message("wohoo").build(); SampleEntity sampleEntity = SampleEntity.builder().message("wohoo").build();
template.save(sampleEntity) // template.save(sampleEntity) //
.as(StepVerifier::create) // .map(SampleEntity::getId) //
.consumeNextWith(it -> { .flatMap(id -> indexOperations.refresh().thenReturn(id)) //
.flatMap(id -> documentWithIdExistsInIndex(id, DEFAULT_INDEX)).as(StepVerifier::create) //
assertThat(it.getId()).isNotNull(); .expectNext(true) //
indexOperations.refresh();
assertThat(TestUtils.documentWithId(it.getId()).existsIn(DEFAULT_INDEX)).isTrue();
}) //
.verifyComplete(); .verifyComplete();
} }
private Mono<Boolean> documentWithIdExistsInIndex(String id, String index) {
return template.exists(id, IndexCoordinates.of(index));
}
@Test // DATAES-504 @Test // DATAES-504
public void insertWithExplicitIndexNameShouldOverwriteMetadata() { public void insertWithExplicitIndexNameShouldOverwriteMetadata() {
@ -181,11 +191,11 @@ public class ReactiveElasticsearchTemplateTests {
.expectNextCount(1)// .expectNextCount(1)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(IndexCoordinates.of(DEFAULT_INDEX)); template.indexOps(IndexCoordinates.of(DEFAULT_INDEX)).refresh().block();
restTemplate.refresh(alternateIndex); template.indexOps(alternateIndex).refresh().block();
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(DEFAULT_INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex(sampleEntity.getId(), DEFAULT_INDEX).block()).isFalse();
assertThat(TestUtils.documentWithId(sampleEntity.getId()).existsIn(ALTERNATE_INDEX)).isTrue(); assertThat(documentWithIdExistsInIndex(sampleEntity.getId(), ALTERNATE_INDEX).block()).isTrue();
} }
@Test // DATAES-504 @Test // DATAES-504
@ -266,16 +276,14 @@ public class ReactiveElasticsearchTemplateTests {
SampleEntity sampleEntity = randomEntity("some message"); SampleEntity sampleEntity = randomEntity("some message");
IndexQuery indexQuery = getIndexQuery(sampleEntity);
IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX); IndexCoordinates defaultIndex = IndexCoordinates.of(DEFAULT_INDEX);
IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX); IndexCoordinates alternateIndex = IndexCoordinates.of(ALTERNATE_INDEX);
restTemplate.index(indexQuery, alternateIndex); template.save(sampleEntity, alternateIndex) //
indexOperations.refresh(); .then(indexOperations.refresh()) //
.then(template.indexOps(defaultIndex).refresh()) //
restTemplate.indexOps(defaultIndex).refresh(); .then(template.indexOps(alternateIndex).refresh()) //
restTemplate.indexOps(alternateIndex).refresh(); .block();
template.get(sampleEntity.getId(), SampleEntity.class, defaultIndex) // template.get(sampleEntity.getId(), SampleEntity.class, defaultIndex) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -612,7 +620,6 @@ public class ReactiveElasticsearchTemplateTests {
} }
@Test // DATAES-519 @Test // DATAES-519
@ElasticsearchVersion(asOf = "6.5.0")
public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() { public void deleteByQueryShouldReturnZeroWhenIndexDoesNotExist() {
CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test")); CriteriaQuery query = new CriteriaQuery(new Criteria("message").contains("test"));
@ -624,7 +631,6 @@ public class ReactiveElasticsearchTemplateTests {
} }
@Test // DATAES-547 @Test // DATAES-547
@ElasticsearchVersion(asOf = "6.5.0")
public void shouldDeleteAcrossIndex() { public void shouldDeleteAcrossIndex() {
String indexPrefix = "rx-template-test-index"; String indexPrefix = "rx-template-test-index";
@ -637,8 +643,7 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)// .as(StepVerifier::create)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(thisIndex); template.indexOps(thisIndex).refresh().then(template.indexOps(thatIndex).refresh()).block();
restTemplate.refresh(thatIndex);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "test")) // .withQuery(termQuery("message", "test")) //
@ -649,11 +654,10 @@ public class ReactiveElasticsearchTemplateTests {
.expectNext(2L) // .expectNext(2L) //
.verifyComplete(); .verifyComplete();
TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); template.indexOps(thisIndex).delete().then(template.indexOps(thatIndex).delete()).block();
} }
@Test // DATAES-547 @Test // DATAES-547
@ElasticsearchVersion(asOf = "6.5.0")
public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() { public void shouldDeleteAcrossIndexWhenNoMatchingDataPresent() {
String indexPrefix = "rx-template-test-index"; String indexPrefix = "rx-template-test-index";
@ -666,8 +670,7 @@ public class ReactiveElasticsearchTemplateTests {
.as(StepVerifier::create)// .as(StepVerifier::create)//
.verifyComplete(); .verifyComplete();
restTemplate.refresh(thisIndex); template.indexOps(thisIndex).refresh().then(template.indexOps(thatIndex).refresh()).block();
restTemplate.refresh(thatIndex);
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() // NativeSearchQuery searchQuery = new NativeSearchQueryBuilder() //
.withQuery(termQuery("message", "negative")) // .withQuery(termQuery("message", "negative")) //
@ -678,11 +681,10 @@ public class ReactiveElasticsearchTemplateTests {
.expectNext(0L) // .expectNext(0L) //
.verifyComplete(); .verifyComplete();
TestUtils.deleteIndex(thisIndex.getIndexName(), thatIndex.getIndexName()); template.indexOps(thisIndex).delete().then(template.indexOps(thatIndex).delete()).block();
} }
@Test // DATAES-504 @Test // DATAES-504
@ElasticsearchVersion(asOf = "6.5.0")
public void deleteByQueryShouldReturnNumberOfDeletedDocuments() { public void deleteByQueryShouldReturnNumberOfDeletedDocuments() {
index(randomEntity("test message"), randomEntity("test test"), randomEntity("some message")); index(randomEntity("test message"), randomEntity("test test"), randomEntity("some message"));
@ -696,7 +698,6 @@ public class ReactiveElasticsearchTemplateTests {
} }
@Test // DATAES-504 @Test // DATAES-504
@ElasticsearchVersion(asOf = "6.5.0")
public void deleteByQueryShouldReturnZeroIfNothingDeleted() { public void deleteByQueryShouldReturnZeroIfNothingDeleted() {
index(randomEntity("test message")); index(randomEntity("test message"));
@ -896,7 +897,8 @@ public class ReactiveElasticsearchTemplateTests {
OptimisticEntity original = new OptimisticEntity(); OptimisticEntity original = new OptimisticEntity();
original.setMessage("It's fine"); original.setMessage("It's fine");
OptimisticEntity saved = template.save(original).block(); OptimisticEntity saved = template.save(original).block();
restTemplate.refresh(OptimisticEntity.class);
template.indexOps(OptimisticEntity.class).refresh().block();
template template
.search(searchQueryForOne(saved.getId()), OptimisticEntity.class, .search(searchQueryForOne(saved.getId()), OptimisticEntity.class,
@ -1050,12 +1052,10 @@ public class ReactiveElasticsearchTemplateTests {
IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX); IndexCoordinates indexCoordinates = IndexCoordinates.of(DEFAULT_INDEX);
if (entities.length == 1) { if (entities.length == 1) {
restTemplate.index(getIndexQuery(entities[0]), indexCoordinates); template.save(entities[0], indexCoordinates).then(indexOperations.refresh()).block();
} else { } else {
restTemplate.bulkIndex(getIndexQueries(entities), indexCoordinates); template.saveAll(Mono.just(Arrays.asList(entities)), indexCoordinates).then(indexOperations.refresh()).block();
} }
indexOperations.refresh();
} }
@Data @Data

View File

@ -1,45 +0,0 @@
/*
* Copyright 2018-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.junit.junit4;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Christoph Strobl
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ElasticsearchVersion {
/**
* Inclusive lower bound of Elasticsearch server range.
*
* @return {@code 0.0.0} by default.
*/
String asOf() default "0.0.0";
/**
* Exclusive upper bound of Elasticsearch server range.
*
* @return {@code 9999.9999.9999} by default.
*/
String until() default "9999.9999.9999";
}

View File

@ -1,132 +0,0 @@
/*
* Copyright 2018-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.junit.junit4;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.AssumptionViolatedException;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.util.Version;
/**
* @author Christoph Strobl
*/
public class ElasticsearchVersionRule implements TestRule {
private static final Logger logger = LoggerFactory.getLogger(ElasticsearchVersionRule.class);
private static final Version ANY = new Version(9999, 9999, 9999);
private static final Version DEFAULT_HIGH = ANY;
private static final Version DEFAULT_LOW = new Version(0, 0, 0);
private final static AtomicReference<Version> currentVersion = new AtomicReference<>(null);
private final Version minVersion;
private final Version maxVersion;
public ElasticsearchVersionRule(Version min, Version max) {
this.minVersion = min;
this.maxVersion = max;
}
public static ElasticsearchVersionRule any() {
return new ElasticsearchVersionRule(ANY, ANY);
}
public static ElasticsearchVersionRule atLeast(Version minVersion) {
return new ElasticsearchVersionRule(minVersion, DEFAULT_HIGH);
}
public static ElasticsearchVersionRule atMost(Version maxVersion) {
return new ElasticsearchVersionRule(DEFAULT_LOW, maxVersion);
}
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
if (!getCurrentVersion().equals(ANY)) {
Version minVersion = ElasticsearchVersionRule.this.minVersion.equals(ANY) ? DEFAULT_LOW
: ElasticsearchVersionRule.this.minVersion;
Version maxVersion = ElasticsearchVersionRule.this.maxVersion.equals(ANY) ? DEFAULT_HIGH
: ElasticsearchVersionRule.this.maxVersion;
if (description.getAnnotation(ElasticsearchVersion.class) != null) {
ElasticsearchVersion version = description.getAnnotation(ElasticsearchVersion.class);
if (version != null) {
Version expectedMinVersion = Version.parse(version.asOf());
if (!expectedMinVersion.equals(ANY) && !expectedMinVersion.equals(DEFAULT_LOW)) {
minVersion = expectedMinVersion;
}
Version expectedMaxVersion = Version.parse(version.until());
if (!expectedMaxVersion.equals(ANY) && !expectedMaxVersion.equals(DEFAULT_HIGH)) {
maxVersion = expectedMaxVersion;
}
}
}
validateVersion(minVersion, maxVersion);
}
base.evaluate();
}
};
}
private void validateVersion(Version min, Version max) {
if (getCurrentVersion().isLessThan(min) || getCurrentVersion().isGreaterThanOrEqualTo(max)) {
throw new AssumptionViolatedException(String
.format("Expected Elasticsearch server to be in range (%s, %s] but found %s", min, max, currentVersion));
}
}
private Version getCurrentVersion() {
if (currentVersion.get() == null) {
Version current = fetchCurrentVersion();
if (currentVersion.compareAndSet(null, current)) {
logger.info("Running Elasticsearch " + current);
}
}
return currentVersion.get();
}
private Version fetchCurrentVersion() {
return TestUtils.serverVersion();
}
@Override
public String toString() {
return getCurrentVersion().toString();
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2019-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.elasticsearch.junit.junit4;
import java.io.IOException;
import org.elasticsearch.client.Client;
import org.elasticsearch.node.Node;
import org.junit.rules.ExternalResource;
import org.springframework.data.elasticsearch.Utils;
import org.springframework.util.Assert;
/**
* JUnit4 Rule that sets up and tears down a local Elasticsearch node.
*
* @author Peter-Josef Meisch
*/
public class TestNodeResource extends ExternalResource {
private Node node;
@Override
protected void before() throws Throwable {
node = Utils.getNode();
node.start();
}
@Override
protected void after() {
if (node != null) {
try {
node.close();
} catch (IOException ignored) {}
}
}
public Client client() {
Assert.notNull(node, "node is not initialized");
return node.client();
}
}

View File

@ -1,5 +0,0 @@
/**
* interfaces, annotations and classes related to JUnit 4 test handling.
*/
@org.springframework.lang.NonNullApi
package org.springframework.data.elasticsearch.junit.junit4;

View File

@ -15,42 +15,44 @@
*/ */
package org.springframework.data.elasticsearch.junit.jupiter; package org.springframework.data.elasticsearch.junit.jupiter;
import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeValidationException;
import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtensionContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.data.elasticsearch.Utils; import org.springframework.data.elasticsearch.support.VersionInfo;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
/** /**
* This class manages the connection to an Elasticsearch Cluster, starting a local one if necessary. The information * This class manages the connection to an Elasticsearch Cluster, starting a containerized one if necessary. The
* about the ClusterConnection is stored both as a variable in the instance for direct access from JUnit 5 and in a * information about the ClusterConnection is stored both as a variable in the instance for direct access from JUnit 5
* static ThreadLocal<ClusterConnectionInfo> accessible with the {@link ClusterConnection#clusterConnectionInfo()} * and in a static ThreadLocal<ClusterConnectionInfo> accessible with the
* method to be integrated in the Spring setup * {@link ClusterConnection#clusterConnectionInfo()} method to be integrated in the Spring setup
* *
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
*/ */
class ClusterConnection implements ExtensionContext.Store.CloseableResource { public class ClusterConnection implements ExtensionContext.Store.CloseableResource {
private static final Logger LOGGER = LoggerFactory.getLogger(ClusterConnection.class); private static final Logger LOGGER = LoggerFactory.getLogger(ClusterConnection.class);
private static final int ELASTICSEARCH_DEFAULT_PORT = 9200;
private static final int ELASTICSEARCH_DEFAULT_TRANSPORT_PORT = 9300;
private static final String ELASTICSEARCH_DEFAULT_IMAGE = "docker.elastic.co/elasticsearch/elasticsearch";
private static final ThreadLocal<ClusterConnectionInfo> clusterConnectionInfoThreadLocal = new ThreadLocal<>(); private static final ThreadLocal<ClusterConnectionInfo> clusterConnectionInfoThreadLocal = new ThreadLocal<>();
private Node node; @Nullable private final ClusterConnectionInfo clusterConnectionInfo;
private final ClusterConnectionInfo clusterConnectionInfo;
/** /**
* creates the ClusterConnection, starting a local node if necessary. * creates the ClusterConnection, starting a container if necessary.
* *
* @param clusterUrl if null or empty a local cluster is tarted * @param clusterUrl if null or empty a local cluster is tarted
*/ */
public ClusterConnection(@Nullable String clusterUrl) { public ClusterConnection(@Nullable String clusterUrl) {
clusterConnectionInfo = StringUtils.isEmpty(clusterUrl) ? startLocalNode() : parseUrl(clusterUrl); clusterConnectionInfo = StringUtils.isEmpty(clusterUrl) ? startElasticsearchContainer() : parseUrl(clusterUrl);
if (clusterConnectionInfo != null) { if (clusterConnectionInfo != null) {
LOGGER.debug(clusterConnectionInfo.toString()); LOGGER.debug(clusterConnectionInfo.toString());
@ -68,6 +70,7 @@ class ClusterConnection implements ExtensionContext.Store.CloseableResource {
return clusterConnectionInfoThreadLocal.get(); return clusterConnectionInfoThreadLocal.get();
} }
@Nullable
public ClusterConnectionInfo getClusterConnectionInfo() { public ClusterConnectionInfo getClusterConnectionInfo() {
return clusterConnectionInfo; return clusterConnectionInfo;
} }
@ -94,18 +97,27 @@ class ClusterConnection implements ExtensionContext.Store.CloseableResource {
} }
private @Nullable ClusterConnectionInfo startLocalNode() { @Nullable
LOGGER.debug("starting local node"); private ClusterConnectionInfo startElasticsearchContainer() {
LOGGER.debug("Starting Elasticsearch Container");
try { try {
node = Utils.getNode(); String elasticsearchVersion = VersionInfo.versionProperties()
node.start(); .getProperty(VersionInfo.VERSION_ELASTICSEARCH_CLIENT);
String dockerImageName = ELASTICSEARCH_DEFAULT_IMAGE + ':' + elasticsearchVersion;
LOGGER.debug("Docker image: {}", dockerImageName);
ElasticsearchContainer elasticsearchContainer = new ElasticsearchContainer(dockerImageName);
elasticsearchContainer.start();
return ClusterConnectionInfo.builder() // return ClusterConnectionInfo.builder() //
.withHostAndPort("localhost", 9200) // .withHostAndPort(elasticsearchContainer.getHost(),
.withClient(node.client()) // elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_PORT)) //
.withTransportPort(elasticsearchContainer.getMappedPort(ELASTICSEARCH_DEFAULT_TRANSPORT_PORT)) //
.withElasticsearchContainer(elasticsearchContainer) //
.build(); .build();
} catch (NodeValidationException e) { } catch (Exception e) {
LOGGER.error("could not start local node", e); LOGGER.error("Could not start Elasticsearch container", e);
} }
return null; return null;
@ -114,12 +126,11 @@ class ClusterConnection implements ExtensionContext.Store.CloseableResource {
@Override @Override
public void close() { public void close() {
if (node != null) { if (clusterConnectionInfo != null && clusterConnectionInfo.getElasticsearchContainer() != null) {
LOGGER.debug("closing node"); LOGGER.debug("Stopping container");
try { clusterConnectionInfo.getElasticsearchContainer().stop();
node.close();
} catch (IOException ignored) {}
} }
LOGGER.debug("closed"); LOGGER.debug("closed");
} }
} }

View File

@ -15,16 +15,15 @@
*/ */
package org.springframework.data.elasticsearch.junit.jupiter; package org.springframework.data.elasticsearch.junit.jupiter;
import org.elasticsearch.client.Client;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.testcontainers.elasticsearch.ElasticsearchContainer;
/** /**
* The information about the ClusterConnection. the {@link #client} field is only set if a local node is started, * The information about the ClusterConnection.<br/>
* otherwise it is null. <br/>
* The {@link #host}, {@link #httpPort} and {@link #useSsl} values specify the values needed to connect to the cluster * The {@link #host}, {@link #httpPort} and {@link #useSsl} values specify the values needed to connect to the cluster
* with a rest client for both a local started cluster and for one defined by the cluster URL when creating the * with a rest client for both a local started cluster and for one defined by the cluster URL when creating the
* {@link ClusterConnection}. <br/> * {@link ClusterConnection}.<br/>
* The object must be created by using a {@link ClusterConnectionInfo.Builder}. * The object must be created by using a {@link ClusterConnectionInfo.Builder}.
* *
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
@ -33,23 +32,32 @@ public final class ClusterConnectionInfo {
private final boolean useSsl; private final boolean useSsl;
private final String host; private final String host;
private final int httpPort; private final int httpPort;
private final Client client; private final int transportPort;
private final String clusterName;
@Nullable private final ElasticsearchContainer elasticsearchContainer;
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
private ClusterConnectionInfo(String host, int httpPort, boolean useSsl, Client client) { private ClusterConnectionInfo(String host, int httpPort, boolean useSsl, int transportPort,
@Nullable ElasticsearchContainer elasticsearchContainer) {
this.host = host; this.host = host;
this.httpPort = httpPort; this.httpPort = httpPort;
this.useSsl = useSsl; this.useSsl = useSsl;
this.client = client; this.transportPort = transportPort;
this.elasticsearchContainer = elasticsearchContainer;
this.clusterName = "docker-cluster";
} }
@Override @Override
public String toString() { public String toString() {
return "ClusterConnectionInfo{" + "useSsl=" + useSsl + ", host='" + host + '\'' + ", httpPort=" + httpPort return "ClusterConnectionInfo{" + //
+ ", client=" + client + '}'; "useSsl=" + useSsl + //
", host='" + host + '\'' + //
", httpPort=" + httpPort + //
", transportPort=" + transportPort + //
'}'; //
} }
public String getHost() { public String getHost() {
@ -60,20 +68,29 @@ public final class ClusterConnectionInfo {
return httpPort; return httpPort;
} }
public int getTransportPort() {
return transportPort;
}
public String getClusterName() {
return clusterName;
}
public boolean isUseSsl() { public boolean isUseSsl() {
return useSsl; return useSsl;
} }
@Nullable @Nullable
public Client getClient() { public ElasticsearchContainer getElasticsearchContainer() {
return client; return elasticsearchContainer;
} }
public static class Builder { public static class Builder {
boolean useSsl = false; boolean useSsl = false;
private String host; private String host;
private int httpPort; private int httpPort;
private Client client = null; private int transportPort;
@Nullable private ElasticsearchContainer elasticsearchContainer;
public Builder withHostAndPort(String host, int httpPort) { public Builder withHostAndPort(String host, int httpPort) {
Assert.hasLength(host, "host must not be empty"); Assert.hasLength(host, "host must not be empty");
@ -87,13 +104,18 @@ public final class ClusterConnectionInfo {
return this; return this;
} }
public Builder withClient(Client client) { public Builder withTransportPort(int transportPort) {
this.client = client; this.transportPort = transportPort;
return this;
}
public Builder withElasticsearchContainer(ElasticsearchContainer elasticsearchContainer) {
this.elasticsearchContainer = elasticsearchContainer;
return this; return this;
} }
public ClusterConnectionInfo build() { public ClusterConnectionInfo build() {
return new ClusterConnectionInfo(host, httpPort, useSsl, client); return new ClusterConnectionInfo(host, httpPort, useSsl, transportPort, elasticsearchContainer);
} }
} }
} }

View File

@ -15,7 +15,14 @@
*/ */
package org.springframework.data.elasticsearch.junit.jupiter; package org.springframework.data.elasticsearch.junit.jupiter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.elasticsearch.client.Client; import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport; import org.springframework.data.elasticsearch.config.ElasticsearchConfigurationSupport;
@ -32,8 +39,14 @@ import org.springframework.data.elasticsearch.core.convert.ElasticsearchConverte
public class ElasticsearchTemplateConfiguration extends ElasticsearchConfigurationSupport { public class ElasticsearchTemplateConfiguration extends ElasticsearchConfigurationSupport {
@Bean @Bean
public Client elasticsearchClient(ClusterConnectionInfo clusterConnectionInfo) { public Client elasticsearchClient(ClusterConnectionInfo clusterConnectionInfo) throws UnknownHostException {
return clusterConnectionInfo.getClient();
Settings settings = Settings.builder().put("cluster.name", clusterConnectionInfo.getClusterName()).build();
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new TransportAddress(InetAddress.getByName(clusterConnectionInfo.getHost()),
clusterConnectionInfo.getTransportPort()));
return client;
} }
@Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" }) @Bean(name = { "elasticsearchOperations", "elasticsearchTemplate" })

View File

@ -35,12 +35,14 @@ import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.data.elasticsearch.annotations.FieldType;
import org.springframework.data.elasticsearch.annotations.InnerField; import org.springframework.data.elasticsearch.annotations.InnerField;
import org.springframework.data.elasticsearch.annotations.MultiField; import org.springframework.data.elasticsearch.annotations.MultiField;
import org.springframework.data.elasticsearch.junit.jupiter.SpringDataElasticsearchExtension;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
/** /**
@ -49,6 +51,7 @@ import org.springframework.lang.Nullable;
* @author Christoph Strobl * @author Christoph Strobl
* @author Peter-Josef Meisch * @author Peter-Josef Meisch
*/ */
@ExtendWith(SpringDataElasticsearchExtension.class)
public class CdiRepositoryTests { public class CdiRepositoryTests {
@Nullable private static CdiTestContainer cdiContainer; @Nullable private static CdiTestContainer cdiContainer;

View File

@ -19,33 +19,31 @@ import javax.annotation.PreDestroy;
import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces; import javax.enterprise.inject.Produces;
import org.elasticsearch.client.Client; import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.node.NodeValidationException; import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.Utils; import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations; import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnection;
import org.springframework.data.elasticsearch.junit.jupiter.ClusterConnectionInfo;
/** /**
* @author Mohsin Husen * @author Mohsin Husen
* @author Peter-Josef Meisch
*/ */
@ApplicationScoped @ApplicationScoped
class ElasticsearchTemplateProducer { class ElasticsearchOperationsProducer {
@Produces @Produces
public Client createNodeClient() throws NodeValidationException { public ElasticsearchOperations createElasticsearchTemplate(RestHighLevelClient restHighLevelClient) {
return Utils.getNodeClient(); return new ElasticsearchRestTemplate(restHighLevelClient);
}
@Produces
public ElasticsearchOperations createElasticsearchTemplate(Client client) {
return new ElasticsearchTemplate(client);
} }
@Produces @Produces
@OtherQualifier @OtherQualifier
@PersonDB @PersonDB
public ElasticsearchOperations createQualifiedElasticsearchTemplate(Client client) { public ElasticsearchOperations createQualifiedElasticsearchTemplate(RestHighLevelClient restHighLevelClient) {
return new ElasticsearchTemplate(client); return new ElasticsearchRestTemplate(restHighLevelClient);
} }
@PreDestroy @PreDestroy
@ -53,4 +51,15 @@ class ElasticsearchTemplateProducer {
// remove everything to avoid conflicts with other tests in case server not shut down properly // remove everything to avoid conflicts with other tests in case server not shut down properly
} }
@Produces
public RestHighLevelClient elasticsearchClient() {
// we rely on the tests being run with the SpringDataElasticsearchExtension class that sets up a containerized ES.
ClusterConnectionInfo connectionInfo = ClusterConnection.clusterConnectionInfo();
ClientConfiguration clientConfiguration = ClientConfiguration.builder() //
.connectedTo(connectionInfo.getHost() + ':' + connectionInfo.getHttpPort()) //
.build();
return RestClients.create(clientConfiguration).rest();
}
} }

View File

@ -26,13 +26,12 @@ import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchTemplate; import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository; import org.springframework.data.elasticsearch.repository.ReactiveElasticsearchRepository;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
@ -46,14 +45,9 @@ import org.springframework.test.context.ContextConfiguration;
public class ReactiveElasticsearchRepositoriesRegistrarTests { public class ReactiveElasticsearchRepositoriesRegistrarTests {
@Configuration @Configuration
@Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
@EnableReactiveElasticsearchRepositories(considerNestedRepositories = true) @EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
static class Config { static class Config {}
@Bean
public ReactiveElasticsearchTemplate reactiveElasticsearchTemplate() {
return new ReactiveElasticsearchTemplate(TestUtils.reactiveClient());
}
}
@Autowired ReactiveSampleEntityRepository repository; @Autowired ReactiveSampleEntityRepository repository;
@Autowired ApplicationContext context; @Autowired ApplicationContext context;
@ -72,8 +66,7 @@ public class ReactiveElasticsearchRepositoriesRegistrarTests {
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@Builder @Builder
@Document(indexName = "test-index-sample-reactive-repositories-registrar", @Document(indexName = "test-index-sample-reactive-repositories-registrar", replicas = 0, refreshInterval = "-1")
replicas = 0, refreshInterval = "-1")
static class SampleEntity { static class SampleEntity {
@Id private String id; @Id private String id;

View File

@ -27,23 +27,13 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
import java.io.IOException;
import java.lang.Boolean; import java.lang.Boolean;
import java.lang.Long; import java.lang.Long;
import java.lang.Object;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.ElasticsearchStatusException;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -57,22 +47,19 @@ import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Order; import org.springframework.data.domain.Sort.Order;
import org.springframework.data.elasticsearch.TestUtils;
import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field; import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.Highlight; import org.springframework.data.elasticsearch.annotations.Highlight;
import org.springframework.data.elasticsearch.annotations.HighlightField; import org.springframework.data.elasticsearch.annotations.HighlightField;
import org.springframework.data.elasticsearch.annotations.Query; import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.annotations.Score; import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient;
import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.junit.jupiter.ElasticsearchRestTemplateConfiguration; import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.junit.jupiter.ReactiveElasticsearchRestTemplateConfiguration;
import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest; import org.springframework.data.elasticsearch.junit.jupiter.SpringIntegrationTest;
import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories; import org.springframework.data.elasticsearch.repository.config.EnableReactiveElasticsearchRepositories;
import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.data.repository.reactive.ReactiveCrudRepository;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.util.StringUtils;
/** /**
* @author Christoph Strobl * @author Christoph Strobl
@ -83,38 +70,37 @@ import org.springframework.util.StringUtils;
public class SimpleReactiveElasticsearchRepositoryTests { public class SimpleReactiveElasticsearchRepositoryTests {
@Configuration @Configuration
@Import({ ElasticsearchRestTemplateConfiguration.class }) @Import({ ReactiveElasticsearchRestTemplateConfiguration.class })
@EnableReactiveElasticsearchRepositories(considerNestedRepositories = true) @EnableReactiveElasticsearchRepositories(considerNestedRepositories = true)
static class Config extends AbstractReactiveElasticsearchConfiguration { static class Config {}
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
return TestUtils.reactiveClient();
}
}
static final String INDEX = "test-index-sample-simple-reactive"; static final String INDEX = "test-index-sample-simple-reactive";
static final String TYPE = "test-type";
@Autowired ReactiveSampleEntityRepository repository; @Autowired ReactiveElasticsearchOperations operations;
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @Autowired ReactiveSampleEntityRepository repository;
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
TestUtils.deleteIndex(INDEX); operations.indexOps(IndexCoordinates.of(INDEX)).delete().block();
} }
@AfterEach @AfterEach
void after() { void after() {
TestUtils.deleteIndex(INDEX); operations.indexOps(IndexCoordinates.of(INDEX)).delete().block();
} }
@Test // DATAES-519 @Test // DATAES-519
public void saveShouldSaveSingleEntity() { public void saveShouldSaveSingleEntity() {
repository.save(SampleEntity.builder().build()) // repository.save(SampleEntity.builder().build()) //
.map(SampleEntity::getId) //
.flatMap(this::documentWithIdExistsInIndex) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .expectNext(true).verifyComplete();
.verifyComplete(); }
private Mono<Boolean> documentWithIdExistsInIndex(String id) {
return operations.exists(id, IndexCoordinates.of(INDEX));
} }
@Test // DATAES-519 @Test // DATAES-519
@ -123,10 +109,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
repository repository
.saveAll(Arrays.asList(SampleEntity.builder().build(), SampleEntity.builder().build(), .saveAll(Arrays.asList(SampleEntity.builder().build(), SampleEntity.builder().build(),
SampleEntity.builder().build())) // SampleEntity.builder().build())) //
.map(SampleEntity::getId) //
.flatMap(this::documentWithIdExistsInIndex) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .expectNext(true) //
.consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .expectNext(true) //
.consumeNextWith(it -> assertThat(TestUtils.documentWithId(it.getId()).existsIn(INDEX)).isTrue()) // .expectNext(true) //
.verifyComplete(); .verifyComplete();
} }
@ -138,11 +126,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void findShouldRetrieveSingleEntityById() throws IOException { public void findShouldRetrieveSingleEntityById() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-two").build(), //
SampleEntity.builder().id("id-three").build()); SampleEntity.builder().id("id-three").build()) //
.block();
repository.findById("id-two").as(StepVerifier::create)// repository.findById("id-two").as(StepVerifier::create)//
.consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-two")) // .consumeNextWith(it -> assertThat(it.getId()).isEqualTo("id-two")) //
@ -150,23 +139,25 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void findByIdShouldCompleteIfNothingFound() throws IOException { public void findByIdShouldCompleteIfNothingFound() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-two").build(), //
SampleEntity.builder().id("id-three").build()); SampleEntity.builder().id("id-three").build()) //
.block();
repository.findById("does-not-exist").as(StepVerifier::create) // repository.findById("does-not-exist").as(StepVerifier::create) //
.verifyComplete(); .verifyComplete();
} }
@Test // DATAES-720 @Test // DATAES-720
public void findAllShouldReturnAllElements() throws IOException { public void findAllShouldReturnAllElements() {
// make sure to be above the default page size of the Query interface // make sure to be above the default page size of the Query interface
int count = DEFAULT_PAGE_SIZE * 2; int count = DEFAULT_PAGE_SIZE * 2;
bulkIndex(IntStream.range(1, count + 1) // bulkIndex(IntStream.range(1, count + 1) //
.mapToObj(it -> SampleEntity.builder().id(String.valueOf(it)).build()) // .mapToObj(it -> SampleEntity.builder().id(String.valueOf(it)).build()) //
.toArray(SampleEntity[]::new)); .toArray(SampleEntity[]::new)) //
.block();
repository.findAll() // repository.findAll() //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -180,11 +171,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void findAllByIdShouldRetrieveMatchingDocuments() throws IOException { public void findAllByIdShouldRetrieveMatchingDocuments() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-two").build(), //
SampleEntity.builder().id("id-three").build()); SampleEntity.builder().id("id-three").build()) //
.block();
repository.findAllById(Arrays.asList("id-one", "id-two")) // repository.findAllById(Arrays.asList("id-one", "id-two")) //
.as(StepVerifier::create)// .as(StepVerifier::create)//
@ -194,11 +186,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void findAllByIdShouldCompleteWhenNothingFound() throws IOException { public void findAllByIdShouldCompleteWhenNothingFound() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-two").build(), //
SampleEntity.builder().id("id-three").build()); SampleEntity.builder().id("id-three").build()) //
.block();
repository.findAllById(Arrays.asList("can't", "touch", "this")) // repository.findAllById(Arrays.asList("can't", "touch", "this")) //
.as(StepVerifier::create)// .as(StepVerifier::create)//
@ -206,11 +199,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-717 @Test // DATAES-717
void shouldReturnFluxOfSearchHit() throws IOException { void shouldReturnFluxOfSearchHit() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), //
SampleEntity.builder().id("id-three").message("message").build()); SampleEntity.builder().id("id-three").message("message").build()) //
.block();
repository.queryAllByMessage("message") // repository.queryAllByMessage("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -220,11 +214,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-717 @Test // DATAES-717
void shouldReturnFluxOfSearchHitForStringQuery() throws IOException { void shouldReturnFluxOfSearchHitForStringQuery() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), //
SampleEntity.builder().id("id-three").message("message").build()); SampleEntity.builder().id("id-three").message("message").build()) //
.block();
repository.queryByMessageWithString("message") // repository.queryByMessageWithString("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -234,11 +229,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-372 @Test // DATAES-372
void shouldReturnHighlightsOnAnnotatedMethod() throws IOException { void shouldReturnHighlightsOnAnnotatedMethod() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), //
SampleEntity.builder().id("id-three").message("message").build()); SampleEntity.builder().id("id-three").message("message").build()) //
.block();
repository.queryAllByMessage("message") // repository.queryAllByMessage("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -251,11 +247,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-372 @Test // DATAES-372
void shouldReturnHighlightsOnAnnotatedStringQueryMethod() throws IOException { void shouldReturnHighlightsOnAnnotatedStringQueryMethod() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("message").build(), // SampleEntity.builder().id("id-two").message("message").build(), //
SampleEntity.builder().id("id-three").message("message").build()); SampleEntity.builder().id("id-three").message("message").build()) //
.block();
repository.queryByMessageWithString("message") // repository.queryByMessageWithString("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -275,20 +272,22 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void countShouldCountDocuments() throws IOException { public void countShouldCountDocuments() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build()); SampleEntity.builder().id("id-two").build()) //
.block();
repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete(); repository.count().as(StepVerifier::create).expectNext(2L).verifyComplete();
} }
@Test // DATAES-519 @Test // DATAES-519
public void existsByIdShouldReturnTrueIfExists() throws IOException { public void existsByIdShouldReturnTrueIfExists() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.existsById("id-two") // repository.existsById("id-two") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -297,11 +296,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void existsByIdShouldReturnFalseIfNotExists() throws IOException { public void existsByIdShouldReturnFalseIfNotExists() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.existsById("wrecking ball") // repository.existsById("wrecking ball") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -310,11 +310,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void countShouldCountMatchingDocuments() throws IOException { public void countShouldCountMatchingDocuments() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.countAllByMessage("test") // repository.countAllByMessage("test") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -323,11 +324,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void existsShouldReturnTrueIfExists() throws IOException { public void existsShouldReturnTrueIfExists() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.existsAllByMessage("message") // repository.existsAllByMessage("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -336,11 +338,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void existsShouldReturnFalseIfNotExists() throws IOException { public void existsShouldReturnFalseIfNotExists() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.existsAllByMessage("these days") // repository.existsAllByMessage("these days") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -349,10 +352,11 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void deleteByIdShouldCompleteIfNothingDeleted() throws IOException { public void deleteByIdShouldCompleteIfNothingDeleted() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build()); SampleEntity.builder().id("id-two").build()) //
.block();
repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete(); repository.deleteById("does-not-exist").as(StepVerifier::create).verifyComplete();
} }
@ -365,61 +369,69 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void deleteByIdShouldDeleteEntry() throws IOException { public void deleteByIdShouldDeleteEntry() {
SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build();
bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted) //
.block();
repository.deleteById(toBeDeleted.getId()).as(StepVerifier::create).verifyComplete(); repository.deleteById(toBeDeleted.getId()).as(StepVerifier::create).verifyComplete();
assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
} }
@Test // DATAES-519 @Test // DATAES-519
public void deleteShouldDeleteEntry() throws IOException { public void deleteShouldDeleteEntry() {
SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build(); SampleEntity toBeDeleted = SampleEntity.builder().id("id-two").build();
bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted); bulkIndex(SampleEntity.builder().id("id-one").build(), toBeDeleted) //
.block();
repository.delete(toBeDeleted).as(StepVerifier::create).verifyComplete(); repository.delete(toBeDeleted).as(StepVerifier::create).verifyComplete();
assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
} }
@Test // DATAES-519 @Test // DATAES-519
public void deleteAllShouldDeleteGivenEntries() throws IOException { public void deleteAllShouldDeleteGivenEntries() {
SampleEntity toBeDeleted = SampleEntity.builder().id("id-one").build(); SampleEntity toBeDeleted = SampleEntity.builder().id("id-one").build();
SampleEntity hangInThere = SampleEntity.builder().id("id-two").build(); SampleEntity hangInThere = SampleEntity.builder().id("id-two").build();
SampleEntity toBeDeleted2 = SampleEntity.builder().id("id-three").build(); SampleEntity toBeDeleted2 = SampleEntity.builder().id("id-three").build();
bulkIndex(toBeDeleted, hangInThere, toBeDeleted2); bulkIndex(toBeDeleted, hangInThere, toBeDeleted2) //
.block();
repository.deleteAll(Arrays.asList(toBeDeleted, toBeDeleted2)).as(StepVerifier::create).verifyComplete(); repository.deleteAll(Arrays.asList(toBeDeleted, toBeDeleted2)).as(StepVerifier::create).verifyComplete();
assertThat(TestUtils.documentWithId(toBeDeleted.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted.getId()).block()).isFalse();
assertThat(TestUtils.documentWithId(toBeDeleted2.getId()).ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex(toBeDeleted2.getId()).block()).isFalse();
assertThat(TestUtils.documentWithId(hangInThere.getId()).ofType(TYPE).existsIn(INDEX)).isTrue(); assertThat(documentWithIdExistsInIndex(hangInThere.getId()).block()).isTrue();
} }
@Test // DATAES-519 @Test // DATAES-519
public void deleteAllShouldDeleteAllEntries() throws IOException { public void deleteAllShouldDeleteAllEntries() {
bulkIndex(SampleEntity.builder().id("id-one").build(), // bulkIndex(SampleEntity.builder().id("id-one").build(), //
SampleEntity.builder().id("id-two").build(), // SampleEntity.builder().id("id-two").build(), //
SampleEntity.builder().id("id-three").build()); SampleEntity.builder().id("id-three").build()) //
.block();
repository.deleteAll().as(StepVerifier::create).verifyComplete(); repository.deleteAll().as(StepVerifier::create).verifyComplete();
assertThat(TestUtils.isEmptyIndex(INDEX)).isTrue(); repository.count() //
.as(StepVerifier::create) //
.expectNext(0L) //
.verifyComplete();
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderMethodShouldBeExecutedCorrectly() throws IOException { public void derivedFinderMethodShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.findAllByMessageLike("test") // repository.findAllByMessageLike("test") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -428,11 +440,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() throws IOException { public void derivedFinderMethodShouldBeExecutedCorrectlyWhenGivenPublisher() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.findAllByMessage(Mono.just("test")) // repository.findAllByMessage(Mono.just("test")) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -441,11 +454,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() throws IOException { public void derivedFinderWithDerivedSortMethodShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), //
SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), //
SampleEntity.builder().id("id-three").message("test test").rate(2).build()); SampleEntity.builder().id("id-three").message("test test").rate(2).build()) //
.block();
repository.findAllByMessageLikeOrderByRate("test") // repository.findAllByMessageLikeOrderByRate("test") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -456,11 +470,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() throws IOException { public void derivedFinderMethodWithSortParameterShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), //
SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), //
SampleEntity.builder().id("id-three").message("test test").rate(2).build()); SampleEntity.builder().id("id-three").message("test test").rate(2).build()) //
.block();
repository.findAllByMessage("test", Sort.by(Order.asc("rate"))) // repository.findAllByMessage("test", Sort.by(Order.asc("rate"))) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -471,11 +486,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() throws IOException { public void derivedFinderMethodWithPageableParameterShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), // bulkIndex(SampleEntity.builder().id("id-one").message("test").rate(3).build(), //
SampleEntity.builder().id("id-two").message("test test").rate(1).build(), // SampleEntity.builder().id("id-two").message("test test").rate(1).build(), //
SampleEntity.builder().id("id-three").message("test test").rate(2).build()); SampleEntity.builder().id("id-three").message("test test").rate(2).build()) //
.block();
repository.findAllByMessage("test", PageRequest.of(0, 2, Sort.by(Order.asc("rate")))) // repository.findAllByMessage("test", PageRequest.of(0, 2, Sort.by(Order.asc("rate")))) //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -485,11 +501,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() throws IOException { public void derivedFinderMethodReturningMonoShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.findFirstByMessageLike("test") // repository.findFirstByMessageLike("test") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -498,11 +515,12 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void annotatedFinderMethodShouldBeExecutedCorrectly() throws IOException { public void annotatedFinderMethodShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.findAllViaAnnotatedQueryByMessageLike("test") // repository.findAllViaAnnotatedQueryByMessageLike("test") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
@ -511,60 +529,25 @@ public class SimpleReactiveElasticsearchRepositoryTests {
} }
@Test // DATAES-519 @Test // DATAES-519
public void derivedDeleteMethodShouldBeExecutedCorrectly() throws IOException { public void derivedDeleteMethodShouldBeExecutedCorrectly() {
bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), // bulkIndex(SampleEntity.builder().id("id-one").message("message").build(), //
SampleEntity.builder().id("id-two").message("test message").build(), // SampleEntity.builder().id("id-two").message("test message").build(), //
SampleEntity.builder().id("id-three").message("test test").build()); SampleEntity.builder().id("id-three").message("test test").build()) //
.block();
repository.deleteAllByMessage("message") // repository.deleteAllByMessage("message") //
.as(StepVerifier::create) // .as(StepVerifier::create) //
.expectNext(2L) // .expectNext(2L) //
.verifyComplete(); .verifyComplete();
assertThat(TestUtils.documentWithId("id-one").ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex("id-one").block()).isFalse();
assertThat(TestUtils.documentWithId("id-two").ofType(TYPE).existsIn(INDEX)).isFalse(); assertThat(documentWithIdExistsInIndex("id-two").block()).isFalse();
assertThat(TestUtils.documentWithId("id-three").ofType(TYPE).existsIn(INDEX)).isTrue(); assertThat(documentWithIdExistsInIndex("id-three").block()).isTrue();
} }
private IndexRequest indexRequest(Map<String, ?> source, String index) { Mono<Void> bulkIndex(SampleEntity... entities) {
return operations.saveAll(Arrays.asList(entities), IndexCoordinates.of(INDEX)).then();
return new IndexRequest(index) //
.id(source.containsKey("id") ? source.get("id").toString() : UUID.randomUUID().toString()) //
.source(source) //
.create(true);
}
private IndexRequest indexRequestFrom(SampleEntity entity) {
Map<String, Object> target = new LinkedHashMap<>();
if (StringUtils.hasText(entity.getId())) {
target.put("id", entity.getId());
}
if (StringUtils.hasText(entity.getType())) {
target.put("type", entity.getType());
}
if (StringUtils.hasText(entity.getMessage())) {
target.put("message", entity.getMessage());
}
target.put("rate", entity.getRate());
target.put("available", entity.isAvailable());
return indexRequest(target, INDEX);
}
void bulkIndex(SampleEntity... entities) throws IOException {
BulkRequest request = new BulkRequest();
Arrays.stream(entities).forEach(it -> request.add(indexRequestFrom(it)));
try (RestHighLevelClient client = TestUtils.restHighLevelClient()) {
client.bulk(request.setRefreshPolicy(RefreshPolicy.IMMEDIATE), RequestOptions.DEFAULT);
}
} }
interface ReactiveSampleEntityRepository extends ReactiveCrudRepository<SampleEntity, String> { interface ReactiveSampleEntityRepository extends ReactiveCrudRepository<SampleEntity, String> {
@ -617,7 +600,6 @@ public class SimpleReactiveElasticsearchRepositoryTests {
private int rate; private int rate;
private boolean available; private boolean available;
@Version private Long version; @Version private Long version;
@Score private float score;
} }
} }

View File

@ -16,4 +16,7 @@
<appender-ref ref="console"/> <appender-ref ref="console"/>
</root> </root>
<logger name="org.testcontainers" level="INFO"/>
<logger name="com.github.dockerjava" level="WARN"/>
</configuration> </configuration>

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=Adds "built in" analyzers to Elasticsearch.
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=analysis-common
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.analysis.common.CommonAnalysisPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=lang-painless
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=Module for ingest processors that do not require additional security permissions or have large dependencies and resources
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=ingest-common
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.ingest.common.IngestCommonPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=lang-painless
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=Lucene expressions integration for Elasticsearch
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=lang-expression
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.script.expression.ExpressionPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,32 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
grant {
// needed to generate runtime classes
permission java.lang.RuntimePermission "createClassLoader";
// expression runtime
permission org.elasticsearch.script.ClassPermission "java.lang.String";
permission org.elasticsearch.script.ClassPermission "org.apache.lucene.expressions.Expression";
permission org.elasticsearch.script.ClassPermission "org.apache.lucene.search.DoubleValues";
// available functions
permission org.elasticsearch.script.ClassPermission "java.lang.Math";
permission org.elasticsearch.script.ClassPermission "org.apache.lucene.util.MathUtil";
permission org.elasticsearch.script.ClassPermission "org.apache.lucene.util.SloppyMath";
};

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=An easy, safe and fast scripting language for Elasticsearch
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=lang-painless
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.painless.PainlessPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,26 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
grant {
// needed to generate runtime classes
permission java.lang.RuntimePermission "createClassLoader";
// needed to find the classloader to load whitelisted classes from
permission java.lang.RuntimePermission "getClassLoader";
};

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=Adds advanced field mappers
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=mapper-extras
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.index.mapper.MapperExtrasPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=The Reindex module adds APIs to reindex from one index to another or update documents in place.
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=reindex
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.index.reindex.ReindexPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,33 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
grant {
// reindex opens socket connections using the rest client
permission java.net.SocketPermission "*", "connect";
};
grant codeBase "${codebase.elasticsearch-rest-client}" {
// rest client uses system properties which gets the default proxy
permission java.net.NetPermission "getProxySelector";
};
grant codeBase "${codebase.httpasyncclient}" {
// rest client uses system properties which gets the default proxy
permission java.net.NetPermission "getProxySelector";
};

View File

@ -1,45 +0,0 @@
# Elasticsearch plugin descriptor file
# This file must exist as 'plugin-descriptor.properties' inside a plugin.
#
### example plugin for "foo"
#
# foo.zip <-- zip file for the plugin, with this structure:
# |____ <arbitrary name1>.jar <-- classes, resources, dependencies
# |____ <arbitrary nameN>.jar <-- any number of jars
# |____ plugin-descriptor.properties <-- example contents below:
#
# classname=foo.bar.BazPlugin
# description=My cool plugin
# version=6.0
# elasticsearch.version=6.0
# java.version=1.8
#
### mandatory elements for all plugins:
#
# 'description': simple summary of the plugin
description=Module for URL repository
#
# 'version': plugin's version
version=7.8.1
#
# 'name': the plugin name
name=repository-url
#
# 'classname': the name of the class to load, fully-qualified.
classname=org.elasticsearch.plugin.repository.url.URLRepositoryPlugin
#
# 'java.version': version of java the code is built against
# use the system property java.specification.version
# version string must be a sequence of nonnegative decimal integers
# separated by "."'s and may have leading zeros
java.version=1.8
#
# 'elasticsearch.version': version of elasticsearch compiled against
elasticsearch.version=7.8.1
### optional elements for plugins:
#
# 'extended.plugins': other plugins this plugin extends through SPI
extended.plugins=
#
# 'has.native.controller': whether or not the plugin has a native controller
has.native.controller=false

View File

@ -1,22 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
grant {
permission java.net.SocketPermission "*", "connect";
};