From 8afa8d17bd2a5fdd0c09f435a92fbb872d75359f Mon Sep 17 00:00:00 2001 From: Ivan Vakhrushev Date: Thu, 28 Nov 2024 23:17:36 +0400 Subject: [PATCH] Support Testcontainers URL --- ...DatabaseStructureHealthAutoConfiguration.java | 9 ++++++++- .../spring/DatabaseStructureHealthCondition.java | 15 ++++++++++++++- ...baseStructureHealthAutoConfigurationTest.java | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfiguration.java b/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfiguration.java index 2da41a47..db099501 100644 --- a/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfiguration.java +++ b/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfiguration.java @@ -30,6 +30,7 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Objects; +import javax.annotation.Nullable; import javax.sql.DataSource; /** @@ -58,7 +59,7 @@ public class DatabaseStructureHealthAutoConfiguration { public PgConnection pgConnection(@Qualifier("dataSource") final DataSource dataSource, @Value("${spring.datasource.url:#{null}}") final String databaseUrl) { final PgHost host; - if (Objects.isNull(databaseUrl) || databaseUrl.isBlank()) { + if (needToGetUrlFromMetaData(databaseUrl)) { try (Connection connection = dataSource.getConnection()) { host = PgHostImpl.ofUrl(connection.getMetaData().getURL()); } catch (SQLException ex) { @@ -69,4 +70,10 @@ public PgConnection pgConnection(@Qualifier("dataSource") final DataSource dataS } return PgConnectionImpl.of(dataSource, host); } + + private static boolean needToGetUrlFromMetaData(@Nullable final String databaseUrl) { + return Objects.isNull(databaseUrl) || + databaseUrl.isBlank() || + databaseUrl.startsWith(DatabaseStructureHealthCondition.TESTCONTAINERS_PG_URL_PREFIX); + } } diff --git a/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthCondition.java b/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthCondition.java index d3c25ad3..3e812ed9 100644 --- a/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthCondition.java +++ b/spring-boot-integration/pg-index-health-test-starter/src/main/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthCondition.java @@ -24,6 +24,19 @@ */ public class DatabaseStructureHealthCondition extends SpringBootCondition { + /** + * The URL prefix used in Testcontainers to initialize PostgreSQL containers. + *

+ * Testcontainers provides a special JDBC URL format that allows for on-the-fly creation and management + * of PostgreSQL database containers during tests. This prefix is part of the JDBC URL and signals + * Testcontainers to handle the lifecycle of the container automatically. + *

+ * + * @see Testcontainers JDBC Support + */ + static final String TESTCONTAINERS_PG_URL_PREFIX = "jdbc:tc:postgresql:"; + + private static final String ORIGINAL_PG_URL_PREFIX = "jdbc:postgresql://"; private static final String PROPERTY_NAME = "spring.datasource.url"; /** @@ -34,7 +47,7 @@ public ConditionOutcome getMatchOutcome(final ConditionContext context, final An final ConditionMessage.Builder message = ConditionMessage.forCondition("pg.index.health.test PostgreSQL condition"); final String jdbcUrl = getJdbcUrl(context); if (jdbcUrl != null && !jdbcUrl.isBlank()) { - if (jdbcUrl.startsWith("jdbc:postgresql://")) { + if (jdbcUrl.startsWith(ORIGINAL_PG_URL_PREFIX) || jdbcUrl.startsWith(TESTCONTAINERS_PG_URL_PREFIX)) { return ConditionOutcome.match(message.foundExactly("found PostgreSQL connection " + jdbcUrl)); } return ConditionOutcome.noMatch(message.notAvailable("not PostgreSQL connection")); diff --git a/spring-boot-integration/pg-index-health-test-starter/src/test/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfigurationTest.java b/spring-boot-integration/pg-index-health-test-starter/src/test/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfigurationTest.java index e1c99d42..f3810b19 100644 --- a/spring-boot-integration/pg-index-health-test-starter/src/test/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfigurationTest.java +++ b/spring-boot-integration/pg-index-health-test-starter/src/test/java/io/github/mfvanek/pg/spring/DatabaseStructureHealthAutoConfigurationTest.java @@ -101,6 +101,22 @@ void withDataSourceAndWrongConnectionString() { }); } + @Test + void withDataSourceAndTestcontainersConnectionString() throws SQLException { + try (Connection connectionMock = Mockito.mock(Connection.class)) { + setMocks(connectionMock); + + assertWithTestConfig() + .withPropertyValues("spring.datasource.url=jdbc:tc:postgresql:17.2:///test") + .withInitializer(AutoConfigurationTestBase::initialize) + .run(context -> { + assertThatBeansPresent(context); + assertThatBeansAreNotNullBean(context); + assertThatPgConnectionIsValid(context); + }); + } + } + @Test void shouldNotCreateAutoConfigurationWithDisabledProperty() { assertWithTestConfig()