diff --git a/modules/postgresql/src/main/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainer.java b/modules/postgresql/src/main/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainer.java index d99d638b100..f27fccf5ba8 100644 --- a/modules/postgresql/src/main/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainer.java +++ b/modules/postgresql/src/main/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainer.java @@ -24,6 +24,24 @@ public static ConnectionFactoryOptions getOptions(PostgreSQLContainer container) return new PostgreSQLR2DBCDatabaseContainer(container).configure(options); } + /** + * Returns the R2DBC URL for connecting to the PostgreSQL database. + * + * @param container the PostgreSQL container instance + * @return the R2DBC URL in the format: r2dbc:postgresql://username:password@host:port/database + */ + public static String getR2dbcUrl(PostgreSQLContainer container) { + return String.format( + "r2dbc:%s://%s:%s@%s:%d/%s", + PostgresqlConnectionFactoryProvider.POSTGRESQL_DRIVER, + container.getUsername(), + container.getPassword(), + container.getHost(), + container.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT), + container.getDatabaseName() + ); + } + @Override public ConnectionFactoryOptions configure(ConnectionFactoryOptions options) { return options @@ -55,4 +73,9 @@ public void stop() { public void close() { this.container.close(); } + + @Override + public String getR2dbcUrl() { + return getR2dbcUrl(this.container); + } } diff --git a/modules/postgresql/src/test/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainerTest.java b/modules/postgresql/src/test/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainerTest.java index 4f5386d9f58..3f4a70915d3 100644 --- a/modules/postgresql/src/test/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainerTest.java +++ b/modules/postgresql/src/test/java/org/testcontainers/postgresql/PostgreSQLR2DBCDatabaseContainerTest.java @@ -1,10 +1,13 @@ package org.testcontainers.postgresql; import io.r2dbc.spi.ConnectionFactoryOptions; +import org.junit.jupiter.api.Test; import org.testcontainers.PostgreSQLTestImages; import org.testcontainers.r2dbc.AbstractR2DBCDatabaseContainerTest; -public class PostgreSQLR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest { +import static org.assertj.core.api.Assertions.assertThat; + +class PostgreSQLR2DBCDatabaseContainerTest extends AbstractR2DBCDatabaseContainerTest { @Override protected PostgreSQLContainer createContainer() { @@ -27,4 +30,40 @@ protected ConnectionFactoryOptions getOptions(PostgreSQLContainer container) { protected String createR2DBCUrl() { return "r2dbc:tc:postgresql:///db?TC_IMAGE_TAG=10-alpine"; } + + @Test + void testGetR2dbcUrl() { + try (PostgreSQLContainer container = createContainer()) { + container.start(); + + // Test static method + String r2dbcUrlStatic = PostgreSQLR2DBCDatabaseContainer.getR2dbcUrl(container); + + assertThat(r2dbcUrlStatic).isNotNull(); + assertThat(r2dbcUrlStatic).startsWith("r2dbc:postgresql://"); + assertThat(r2dbcUrlStatic).contains(container.getHost()); + assertThat(r2dbcUrlStatic).contains(String.valueOf(container.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT))); + assertThat(r2dbcUrlStatic).contains(container.getDatabaseName()); + assertThat(r2dbcUrlStatic).contains(container.getUsername()); + assertThat(r2dbcUrlStatic).contains(container.getPassword()); + + // Verify the format: r2dbc:postgresql://username:password@host:port/database + String expectedUrl = String.format( + "r2dbc:postgresql://%s:%s@%s:%d/%s", + container.getUsername(), + container.getPassword(), + container.getHost(), + container.getMappedPort(PostgreSQLContainer.POSTGRESQL_PORT), + container.getDatabaseName() + ); + assertThat(r2dbcUrlStatic).isEqualTo(expectedUrl); + + // Test instance method + try(PostgreSQLR2DBCDatabaseContainer r2dbcContainer = new PostgreSQLR2DBCDatabaseContainer(container)) { + String r2dbcUrlInstance = r2dbcContainer.getR2dbcUrl(); + + assertThat(r2dbcUrlInstance).isEqualTo(r2dbcUrlStatic); + } + } + } } diff --git a/modules/r2dbc/src/main/java/org/testcontainers/r2dbc/R2DBCDatabaseContainer.java b/modules/r2dbc/src/main/java/org/testcontainers/r2dbc/R2DBCDatabaseContainer.java index 8bf0401fe69..bed36e8a8f7 100644 --- a/modules/r2dbc/src/main/java/org/testcontainers/r2dbc/R2DBCDatabaseContainer.java +++ b/modules/r2dbc/src/main/java/org/testcontainers/r2dbc/R2DBCDatabaseContainer.java @@ -5,4 +5,17 @@ public interface R2DBCDatabaseContainer extends Startable { ConnectionFactoryOptions configure(ConnectionFactoryOptions options); + + /** + * Returns the R2DBC URL for connecting to the database. + *

+ * The default implementation throws {@link UnsupportedOperationException}. + * Implementations should override this method to provide the actual R2DBC URL. + * + * @return the R2DBC URL in the format: r2dbc:driver://username:password@host:port/database + * @throws UnsupportedOperationException if the implementation does not support R2DBC URLs + */ + default String getR2dbcUrl() { + throw new UnsupportedOperationException("R2DBC URL is not supported by this container"); + } }