diff --git a/build/container/amazon-opensearch-serverless.Dockerfile b/build/container/amazon-opensearch-serverless.Dockerfile
new file mode 100644
index 00000000000..dbce938321d
--- /dev/null
+++ b/build/container/amazon-opensearch-serverless.Dockerfile
@@ -0,0 +1,3 @@
+# OpenSearch
+# See https://hub.docker.com/r/opensearchproject/opensearch/tags
+FROM docker.io/opensearchproject/opensearch:2.11.0
\ No newline at end of file
diff --git a/build/container/elasticsearch.Dockerfile b/build/container/elastic.Dockerfile
similarity index 100%
rename from build/container/elasticsearch.Dockerfile
rename to build/container/elastic.Dockerfile
diff --git a/build/parents/build/pom.xml b/build/parents/build/pom.xml
index e559714d7cc..635d0e45a86 100644
--- a/build/parents/build/pom.xml
+++ b/build/parents/build/pom.xml
@@ -218,7 +218,6 @@
because we will be able to change the configuration without re-compiling the configuration file
(which is located in a dependency of the integration tests modules).
-->
- elastic
@@ -1196,10 +1195,9 @@
${project.version}
${test.performance.enable}
${test.elasticsearch.distribution}
- ${test.searchengine.run.image.name}
- ${test.searchengine.run.image.tag}
+ ${test.elasticsearch.version}
${test.database.run.kind}
- ${rootProject.directory}
+ ${rootProject.directory}
diff --git a/build/parents/integrationtest/pom.xml b/build/parents/integrationtest/pom.xml
index 9efd05a6a3d..4ef1694c541 100644
--- a/build/parents/integrationtest/pom.xml
+++ b/build/parents/integrationtest/pom.xml
@@ -96,31 +96,32 @@
-
+
- elasticsearch-run
+ search-container-do-not-start
-
+
- !test.elasticsearch.connection.uris
+ test.elasticsearch.connection.uris
- ${test.elasticsearch.run.elastic.image.name}
- ${test.elasticsearch.run.elastic.image.tag}
+ false
-
+
+
- elasticsearch-do-not-run
+ elasticsearch-test-skip
- test.elasticsearch.connection.uris
+ test.elasticsearch.skip
+ true
- false
+ true
@@ -143,20 +144,6 @@
-
- opensearch
-
-
- test.elasticsearch.distribution
- opensearch
-
-
-
- ${test.elasticsearch.run.opensearch.image.name}
- ${test.elasticsearch.run.opensearch.image.tag}
-
-
-
diff --git a/pom.xml b/pom.xml
index e1d25555b71..0d030026421 100644
--- a/pom.xml
+++ b/pom.xml
@@ -377,24 +377,14 @@
8.10.4
- ${version.org.elasticsearch.latest}
-
- true
- docker.io/elastic/elasticsearch
- ${test.elasticsearch.version}
-
- true
- docker.io/opensearchproject/opensearch
- ${test.elasticsearch.version}
+
+ elastic
h2
true
-
-
-
@@ -967,8 +957,14 @@
if ( isNotBlankString( '${test.database.run.kind}' ) && '${test.database.run.kind}' != 'h2') {
images += parseImage( './build/container/${test.database.run.kind}.Dockerfile' )
}
- if ( isTrueString( '${test.searchengine.run.image.pull}' ) && isNotBlankString( '${test.searchengine.run.image.name}' ) ) {
- images += '${test.searchengine.run.image.name}:${test.searchengine.run.image.tag}'
+ if ( isTrueString( '${test.searchengine.run.image.pull}' ) ) {
+ def fromFile = parseImage( './build/container/${test.elasticsearch.distribution}.Dockerfile')
+ def suppliedVersion = '${test.elasticsearch.version}'
+ if (isNotBlankString(suppliedVersion)) {
+ images += fromFile.substring(0, fromFile.lastIndexOf(':')+1) + suppliedVersion
+ } else {
+ images += fromFile
+ }
}
// Exclude images from non-dockerhub repositories
new File('${containerImagesListFile}').append( images.findAll{ref -> !(ref ==~ /^(?!((.*\.)?docker\.io))[\w\d\.]+\/[\w\d\.]+\/[\w\d\.]+(:.+)?$/)}.join('\n') + '\n' )
diff --git a/util/internal/integrationtest/backend/elasticsearch/src/main/java/org/hibernate/search/util/impl/integrationtest/backend/elasticsearch/SearchContainer.java b/util/internal/integrationtest/backend/elasticsearch/src/main/java/org/hibernate/search/util/impl/integrationtest/backend/elasticsearch/SearchContainer.java
index b1d6bb0411c..b67aa8f90c8 100644
--- a/util/internal/integrationtest/backend/elasticsearch/src/main/java/org/hibernate/search/util/impl/integrationtest/backend/elasticsearch/SearchContainer.java
+++ b/util/internal/integrationtest/backend/elasticsearch/src/main/java/org/hibernate/search/util/impl/integrationtest/backend/elasticsearch/SearchContainer.java
@@ -6,7 +6,12 @@
*/
package org.hibernate.search.util.impl.integrationtest.backend.elasticsearch;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.time.Duration;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.hibernate.search.backend.elasticsearch.ElasticsearchDistributionName;
import org.hibernate.search.backend.elasticsearch.ElasticsearchVersion;
@@ -23,12 +28,30 @@ private SearchContainer() {
private static final GenericContainer> SEARCH_CONTAINER;
static {
- String name = System.getProperty( "org.hibernate.search.integrationtest.backend.elasticsearch.name", "" );
- String tag = System.getProperty( "org.hibernate.search.integrationtest.backend.elasticsearch.tag" );
-
- SEARCH_CONTAINER = name.contains( "elastic" )
- ? elasticsearch( name, tag, ElasticsearchVersion.of( ElasticsearchDistributionName.ELASTIC, tag ) )
- : opensearch( name, tag );
+ ElasticsearchDistributionName distributionName = ElasticsearchDistributionName
+ .of( System.getProperty( "org.hibernate.search.integrationtest.backend.elasticsearch.distribution", "" ) );
+ String tag = System.getProperty( "org.hibernate.search.integrationtest.backend.elasticsearch.version" );
+ Path root = Path.of( System.getProperty( "org.hibernate.search.integrationtest.project.root.directory", "" ) );
+
+ try {
+ DockerImageName dockerImageName = parseDockerImageName( root.resolve( "build" ).resolve( "container" )
+ .resolve( distributionName.externalRepresentation() + ".Dockerfile" ), tag );
+ switch ( distributionName ) {
+ case ELASTIC:
+ SEARCH_CONTAINER = elasticsearch( dockerImageName );
+ break;
+ case OPENSEARCH:
+ case AMAZON_OPENSEARCH_SERVERLESS:
+ SEARCH_CONTAINER = opensearch( dockerImageName );
+ break;
+ default:
+ throw new IllegalStateException( "Unknown distribution " + distributionName );
+ }
+ }
+ catch (IOException e) {
+ throw new IllegalStateException(
+ "Unable to initialize a Search Engine container [" + distributionName + ", " + tag + ", " + root + "]", e );
+ }
}
public static int mappedPort(int port) {
@@ -60,8 +83,8 @@ private static void startIfNeeded() {
}
}
- private static GenericContainer> elasticsearch(String name, String tag, ElasticsearchVersion version) {
- GenericContainer> container = common( name, tag )
+ private static GenericContainer> elasticsearch(DockerImageName dockerImageName) {
+ GenericContainer> container = common( dockerImageName )
.withEnv( "logger.level", "WARN" )
.withEnv( "discovery.type", "single-node" )
// Older images require HTTP authentication for all requests;
@@ -79,6 +102,9 @@ private static GenericContainer> elasticsearch(String name, String tag, Elasti
// See https://www.elastic.co/guide/en/elasticsearch/reference/7.17/modules-cluster.html#disk-based-shard-allocation
.withEnv( "cluster.routing.allocation.disk.threshold_enabled", "false" );
+ ElasticsearchVersion version =
+ ElasticsearchVersion.of( ElasticsearchDistributionName.ELASTIC, dockerImageName.getVersionPart() );
+
if ( version.majorOptional().orElse( Integer.MIN_VALUE ) == 8 ) {
if ( version.minor().orElse( Integer.MAX_VALUE ) > 7 ) {
container.withEnv( "cluster.deprecation_indexing.enabled", "false" )
@@ -112,8 +138,8 @@ private static GenericContainer> elasticsearch(String name, String tag, Elasti
return container;
}
- private static GenericContainer> opensearch(String name, String tag) {
- return common( name, tag )
+ private static GenericContainer> opensearch(DockerImageName dockerImageName) {
+ return common( dockerImageName )
.withEnv( "logger.level", "WARN" )
.withEnv( "discovery.type", "single-node" )
// Prevent swapping
@@ -137,11 +163,30 @@ private static GenericContainer> opensearch(String name, String tag) {
* this resource in the end.
*/
@SuppressWarnings("resource")
- private static GenericContainer> common(String image, String tag) {
- return new GenericContainer<>( DockerImageName.parse( image ).withTag( tag ) )
+ private static GenericContainer> common(DockerImageName dockerImageName) {
+ return new GenericContainer<>( dockerImageName )
.withExposedPorts( 9200, 9300 )
.waitingFor( new HttpWaitStrategy().forPort( 9200 ).forStatusCode( 200 ) )
.withStartupTimeout( Duration.ofMinutes( 5 ) )
.withReuse( true );
}
+
+
+ private static DockerImageName parseDockerImageName(Path dockerfile, String tag) throws IOException {
+ Pattern DOCKERFILE_FROM_LINE_PATTERN = Pattern.compile( "FROM (.+)" );
+
+ DockerImageName dockerImageName = Files.lines( dockerfile )
+ .map( DOCKERFILE_FROM_LINE_PATTERN::matcher )
+ .filter( Matcher::matches )
+ .map( m -> m.group( 1 ) )
+ .map( DockerImageName::parse )
+ .findAny().orElseThrow( () -> new IllegalStateException(
+ "Dockerfile " + dockerfile + " has unexpected structure. It *must* contain a single FROM line." ) );
+
+ if ( tag != null && !tag.trim().isEmpty() ) {
+ return dockerImageName.withTag( tag );
+ }
+
+ return dockerImageName;
+ }
}
diff --git a/util/internal/integrationtest/mapper/orm/src/main/java/org/hibernate/search/util/impl/integrationtest/mapper/orm/DatabaseContainer.java b/util/internal/integrationtest/mapper/orm/src/main/java/org/hibernate/search/util/impl/integrationtest/mapper/orm/DatabaseContainer.java
index 7ab955dc4fe..04ea8974671 100644
--- a/util/internal/integrationtest/mapper/orm/src/main/java/org/hibernate/search/util/impl/integrationtest/mapper/orm/DatabaseContainer.java
+++ b/util/internal/integrationtest/mapper/orm/src/main/java/org/hibernate/search/util/impl/integrationtest/mapper/orm/DatabaseContainer.java
@@ -35,7 +35,7 @@ private DatabaseContainer() {
static {
String name = System.getProperty( "org.hibernate.search.integrationtest.orm.database.kind", "" );
- Path root = Path.of( System.getProperty( "org.hibernate.search.integrationtest.orm.project.root.directory", "" ) );
+ Path root = Path.of( System.getProperty( "org.hibernate.search.integrationtest.project.root.directory", "" ) );
DATABASE = SupportedDatabase.from( name );
DATABASE_CONTAINER = DATABASE.container(