diff --git a/embedded-artifactory/README.adoc b/embedded-artifactory/README.adoc
index 82199d363..78effeab6 100644
--- a/embedded-artifactory/README.adoc
+++ b/embedded-artifactory/README.adoc
@@ -16,13 +16,32 @@
* `embedded.artifactory.enabled` `(true|false, default is true)`
* `embedded.artifactory.reuseContainer` `(true|false, default is false)`
-* `embedded.artifactory.dockerImage` `(default is 'releases-docker.jfrog.io/jfrog/artifactory-oss:7.77.12')`
+* `embedded.artifactory.dockerImage` `(default is 'releases-docker.jfrog.io/jfrog/artifactory-oss:7.98.9')`
** Release notes on https://www.jfrog.com/confluence/display/JFROG/Artifactory+Release+Notes[jfrog.com]
* `embedded.artifactory.networkAlias` `(default is 'artifactory')`
* `embedded.artifactory.username` `(default is 'admin')`
* `embedded.artifactory.password` `(default is 'password')`
* `embedded.toxiproxy.proxies.artifactory.enabled` Enables both creation of the container with ToxiProxy TCP proxy and a proxy to the `embedded-artifactory` container.
+==== PostgreSQL backing store
+
+Artifactory uses PostgreSQL as its backing database, provided by the `embedded-postgresql` module.
+Configure the database via `embedded.postgresql.*` properties:
+
+* `embedded.postgresql.user` `(default is 'postgresql')`
+* `embedded.postgresql.password` `(default is 'letmein')`
+* `embedded.postgresql.database` `(default is 'test_db')`
+* `embedded.postgresql.networkAlias` `(default is 'postgresql.testcontainer.docker')`
+* `embedded.postgresql.dockerImage` `(default is 'postgres:18-alpine')`
+
+Example override in `bootstrap.properties`:
+[source,properties]
+----
+embedded.postgresql.user=artifactory
+embedded.postgresql.password=artifactory
+embedded.postgresql.database=artifactory
+----
+
==== Produces
* `embedded.artifactory.host`
diff --git a/embedded-artifactory/pom.xml b/embedded-artifactory/pom.xml
index 34832c79c..70468786d 100644
--- a/embedded-artifactory/pom.xml
+++ b/embedded-artifactory/pom.xml
@@ -23,6 +23,10 @@
com.playtika.testcontainers
embedded-toxiproxy
+
+ com.playtika.testcontainers
+ embedded-postgresql
+
io.rest-assured
@@ -41,4 +45,4 @@
-
\ No newline at end of file
+
diff --git a/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/ArtifactoryProperties.java b/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/ArtifactoryProperties.java
index b34370d49..b750bc02d 100644
--- a/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/ArtifactoryProperties.java
+++ b/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/ArtifactoryProperties.java
@@ -20,13 +20,13 @@ public class ArtifactoryProperties extends CommonContainerProperties {
int generalPort = 8082;
public ArtifactoryProperties() {
- setWaitTimeoutInSeconds(120);
+ setWaitTimeoutInSeconds(300);
}
@Override
public String getDefaultDockerImage() {
// Please don`t remove this comment.
// renovate: datasource=docker
- return "releases-docker.jfrog.io/jfrog/artifactory-oss:7.77.12";
+ return "releases-docker.jfrog.io/jfrog/artifactory-oss:7.98.9";
}
}
diff --git a/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfiguration.java b/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfiguration.java
index bf93fa58c..b61ab4fca 100644
--- a/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfiguration.java
+++ b/embedded-artifactory/src/main/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfiguration.java
@@ -2,11 +2,14 @@
import com.playtika.testcontainer.common.spring.DockerPresenceBootstrapConfiguration;
import com.playtika.testcontainer.common.utils.ContainerUtils;
+import com.playtika.testcontainer.postgresql.EmbeddedPostgreSQLBootstrapConfiguration;
+import com.playtika.testcontainer.postgresql.PostgreSQLProperties;
import com.playtika.testcontainer.toxiproxy.ToxiproxyClientProxy;
import com.playtika.testcontainer.toxiproxy.ToxiproxyHelper;
import com.playtika.testcontainer.toxiproxy.condition.ConditionalOnToxiProxyEnabled;
import eu.rekawek.toxiproxy.ToxiproxyClient;
import lombok.extern.slf4j.Slf4j;
+import org.jspecify.annotations.NonNull;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@@ -21,24 +24,35 @@
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
+import org.testcontainers.images.builder.Transferable;
+import org.testcontainers.postgresql.PostgreSQLContainer;
import org.testcontainers.toxiproxy.ToxiproxyContainer;
+import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
-import java.util.Optional;
import static com.playtika.testcontainer.artifactory.ArtifactoryProperties.ARTIFACTORY_BEAN_NAME;
import static com.playtika.testcontainer.common.utils.ContainerUtils.configureCommonsAndStart;
+import static org.testcontainers.postgresql.PostgreSQLContainer.POSTGRESQL_PORT;
@Slf4j
@Configuration
@ConditionalOnExpression("${embedded.containers.enabled:true}")
-@AutoConfigureAfter(DockerPresenceBootstrapConfiguration.class)
+@AutoConfigureAfter({DockerPresenceBootstrapConfiguration.class, EmbeddedPostgreSQLBootstrapConfiguration.class})
@ConditionalOnProperty(name = "embedded.artifactory.enabled", matchIfMissing = true)
@EnableConfigurationProperties(ArtifactoryProperties.class)
public class EmbeddedArtifactoryBootstrapConfiguration {
private static final String ARTIFACTORY_NETWORK_ALIAS = "artifactory.testcontainer.docker";
+ @Bean
+ @ConditionalOnMissingBean(Network.class)
+ Network artifactoryNetwork() {
+ Network network = Network.newNetwork();
+ log.info("Created docker Network with id={}", network.getId());
+ return network;
+ }
+
@Bean
@ConditionalOnMissingBean(name = "artifactoryWaitStrategy")
public WaitStrategy artifactoryWaitStrategy(ArtifactoryProperties properties) {
@@ -70,17 +84,23 @@ ToxiproxyClientProxy artifactoryContainerProxy(ToxiproxyClient toxiproxyClient,
@Bean(name = ARTIFACTORY_BEAN_NAME, destroyMethod = "stop")
public GenericContainer> artifactory(ConfigurableEnvironment environment,
ArtifactoryProperties properties,
+ PostgreSQLContainer postgreSQLContainer,
+ PostgreSQLProperties postgresqlProperties,
WaitStrategy artifactoryWaitStrategy,
- Optional network) {
+ Network network) {
+
+ String systemYaml = getSystemYaml(postgresqlProperties, postgreSQLContainer);
GenericContainer> container =
new GenericContainer<>(ContainerUtils.getDockerImageName(properties))
.withExposedPorts(properties.getRestApiPort(), properties.getGeneralPort())
- .withNetwork(Network.SHARED)
+ .withNetwork(network)
.withNetworkAliases(properties.getNetworkAlias(), ARTIFACTORY_NETWORK_ALIAS)
+ .withCopyToContainer(
+ Transferable.of(systemYaml.getBytes(StandardCharsets.UTF_8), 0666),
+ "/opt/jfrog/artifactory/var/etc/system.yaml")
.waitingFor(artifactoryWaitStrategy);
- network.ifPresent(container::withNetwork);
configureCommonsAndStart(container, properties, log);
registerEnvironment(container, environment, properties);
@@ -88,6 +108,22 @@ public GenericContainer> artifactory(ConfigurableEnvironment environment,
return container;
}
+ static @NonNull String getSystemYaml(PostgreSQLProperties postgresqlProperties,
+ PostgreSQLContainer postgreSQLContainer) {
+ String jdbcUrl = "jdbc:postgresql://%s:%d/%s"
+ .formatted(postgresqlProperties.getNetworkAlias(), POSTGRESQL_PORT, postgresqlProperties.getDatabase());
+
+ return """
+ shared:
+ database:
+ type: "postgresql"
+ driver: "org.postgresql.Driver"
+ url: "%s"
+ username: "%s"
+ password: "%s"
+ """.formatted(jdbcUrl, postgreSQLContainer.getUsername(), postgreSQLContainer.getPassword());
+ }
+
private void registerEnvironment(GenericContainer> artifactory,
ConfigurableEnvironment environment,
ArtifactoryProperties properties) {
diff --git a/embedded-artifactory/src/test/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfigurationSystemYamlTest.java b/embedded-artifactory/src/test/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfigurationSystemYamlTest.java
new file mode 100644
index 000000000..3a2ae6ac1
--- /dev/null
+++ b/embedded-artifactory/src/test/java/com/playtika/testcontainer/artifactory/EmbeddedArtifactoryBootstrapConfigurationSystemYamlTest.java
@@ -0,0 +1,31 @@
+package com.playtika.testcontainer.artifactory;
+
+import com.playtika.testcontainer.postgresql.PostgreSQLProperties;
+import org.junit.jupiter.api.Test;
+import org.testcontainers.postgresql.PostgreSQLContainer;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class EmbeddedArtifactoryBootstrapConfigurationSystemYamlTest {
+
+ @Test
+ void shouldUseConfiguredPostgresqlNetworkAliasInSystemYaml() {
+ PostgreSQLProperties postgresqlProperties = new PostgreSQLProperties();
+ postgresqlProperties.setDatabase("artifactory");
+ postgresqlProperties.setNetworkAlias("postgresql.internal");
+
+ PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer("postgres:18-alpine")
+ .withNetworkAliases("postgresql.internal")
+ .withUsername("artifactory")
+ .withPassword("secret");
+
+ String systemYaml = EmbeddedArtifactoryBootstrapConfiguration.getSystemYaml(
+ postgresqlProperties,
+ postgreSQLContainer);
+
+ assertThat(systemYaml)
+ .contains("url: \"jdbc:postgresql://postgresql.internal:5432/artifactory\"")
+ .contains("username: \"artifactory\"")
+ .contains("password: \"secret\"");
+ }
+}
diff --git a/embedded-artifactory/src/test/resources/bootstrap.properties b/embedded-artifactory/src/test/resources/bootstrap.properties
new file mode 100644
index 000000000..3f07a7265
--- /dev/null
+++ b/embedded-artifactory/src/test/resources/bootstrap.properties
@@ -0,0 +1,3 @@
+embedded.postgresql.user=artifactory
+embedded.postgresql.password=artifactory
+embedded.postgresql.database=artifactory
diff --git a/embedded-postgresql/README.adoc b/embedded-postgresql/README.adoc
index 35b9ccf6c..1d5f19d88 100644
--- a/embedded-postgresql/README.adoc
+++ b/embedded-postgresql/README.adoc
@@ -22,6 +22,7 @@
* `embedded.postgresql.database`
* `embedded.postgresql.user`
* `embedded.postgresql.password`
+* `embedded.postgresql.networkAlias` `(default is 'postgresql.testcontainer.docker')`
* `embedded.postgresql.initScriptPath` `(default is null)`
* `embedded.postgresql.startupLogCheckRegex` `(default is null)`
* `embedded.postgresql.mountVolumes` `(default is empty list)`
diff --git a/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/EmbeddedPostgreSQLBootstrapConfiguration.java b/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/EmbeddedPostgreSQLBootstrapConfiguration.java
index c54728895..5b9d7eef5 100644
--- a/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/EmbeddedPostgreSQLBootstrapConfiguration.java
+++ b/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/EmbeddedPostgreSQLBootstrapConfiguration.java
@@ -18,9 +18,9 @@
import org.springframework.core.env.MapPropertySource;
import org.springframework.util.StringUtils;
import org.testcontainers.containers.Network;
-import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
import org.testcontainers.containers.wait.strategy.WaitStrategy;
+import org.testcontainers.postgresql.PostgreSQLContainer;
import org.testcontainers.toxiproxy.ToxiproxyContainer;
import java.util.LinkedHashMap;
@@ -37,8 +37,6 @@
@EnableConfigurationProperties(PostgreSQLProperties.class)
public class EmbeddedPostgreSQLBootstrapConfiguration {
- private static final String POSTGRESQL_NETWORK_ALIAS = "postgresql.testcontainer.docker";
-
@Bean
@ConditionalOnToxiProxyEnabled(module = "postgresql")
ToxiproxyClientProxy postgresqlContainerProxy(ToxiproxyClient toxiproxyClient,
@@ -63,12 +61,12 @@ public PostgreSQLContainer postgresql(ConfigurableEnvironment environment,
Optional network) {
PostgreSQLContainer postgresql =
- new PostgreSQLContainer<>(ContainerUtils.getDockerImageName(properties))
+ new PostgreSQLContainer(ContainerUtils.getDockerImageName(properties))
.withUsername(properties.getUser())
.withPassword(properties.getPassword())
.withDatabaseName(properties.getDatabase())
.withInitScript(properties.initScriptPath)
- .withNetworkAliases(POSTGRESQL_NETWORK_ALIAS);
+ .withNetworkAliases(properties.getNetworkAlias());
network.ifPresent(postgresql::withNetwork);
@@ -96,7 +94,7 @@ private void registerPostgresqlEnvironment(PostgreSQLContainer postgresql,
map.put("embedded.postgresql.schema", properties.getDatabase());
map.put("embedded.postgresql.user", properties.getUser());
map.put("embedded.postgresql.password", properties.getPassword());
- map.put("embedded.postgresql.networkAlias", POSTGRESQL_NETWORK_ALIAS);
+ map.put("embedded.postgresql.networkAlias", properties.getNetworkAlias());
map.put("embedded.postgresql.internalPort", PostgreSQLContainer.POSTGRESQL_PORT);
String jdbcURL = "jdbc:postgresql://{}:{}/{}";
diff --git a/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/PostgreSQLProperties.java b/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/PostgreSQLProperties.java
index 951bfcc06..e6436b75f 100644
--- a/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/PostgreSQLProperties.java
+++ b/embedded-postgresql/src/main/java/com/playtika/testcontainer/postgresql/PostgreSQLProperties.java
@@ -10,10 +10,12 @@
@ConfigurationProperties("embedded.postgresql")
public class PostgreSQLProperties extends CommonContainerProperties {
static final String BEAN_NAME_EMBEDDED_POSTGRESQL = "embeddedPostgreSql";
+ static final String DEFAULT_NETWORK_ALIAS = "postgresql.testcontainer.docker";
String user = "postgresql";
String password = "letmein";
String database = "test_db";
+ String networkAlias = DEFAULT_NETWORK_ALIAS;
String startupLogCheckRegex;
/**
* The SQL file path to execute after the container starts to initialize the database.
diff --git a/embedded-postgresql/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/embedded-postgresql/src/main/resources/META-INF/additional-spring-configuration-metadata.json
index dd067aaad..bfe1af239 100644
--- a/embedded-postgresql/src/main/resources/META-INF/additional-spring-configuration-metadata.json
+++ b/embedded-postgresql/src/main/resources/META-INF/additional-spring-configuration-metadata.json
@@ -17,6 +17,11 @@
"type": "java.lang.String",
"defaultValue": "null",
"description": "The SQL file path to execute after the container starts to initialize the database."
+ },
+ {
+ "name": "embedded.postgresql.network-alias",
+ "type": "java.lang.String",
+ "defaultValue": "postgresql.testcontainer.docker"
}
],
"hints": [
diff --git a/testcontainers-spring-boot-parent/pom.xml b/testcontainers-spring-boot-parent/pom.xml
index a622ab945..14181b76e 100644
--- a/testcontainers-spring-boot-parent/pom.xml
+++ b/testcontainers-spring-boot-parent/pom.xml
@@ -80,6 +80,11 @@
embedded-toxiproxy
${project.version}
+
+ com.playtika.testcontainers
+ embedded-postgresql
+ ${project.version}
+
com.playtika.testcontainers
embedded-aerospike