From 1bfa629aa372edb43ad9d7c7efce2650a93c5728 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Mon, 13 Jul 2020 16:22:01 +0200 Subject: [PATCH] DATAJDBC-573 - Fixes the wait strategy for Oracle data sources. Oracle integration tests where failing when the docker container was freshly started, as it happens every time on CI. The reason was mainly a misuse of Awaitility.ignoreException(Class) which only ignores exception of exactly the class provided, not of subtypes. Apart from fixing this for Oracle the complete logic for verifying the connection was moved to DataSourceConfiguration so other database use it as well in a consistent manner. Original pull request: #237. --- .../jdbc/testing/DataSourceConfiguration.java | 33 ++++++++++++++++++- .../testing/Db2DataSourceConfiguration.java | 14 ++------ .../OracleDataSourceConfiguration.java | 22 ++----------- 3 files changed, 36 insertions(+), 33 deletions(-) diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java index ac5cff1ca..16730614d 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/DataSourceConfiguration.java @@ -17,15 +17,24 @@ package org.springframework.data.jdbc.testing; import javax.sql.DataSource; +import org.awaitility.Awaitility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.init.DataSourceInitializer; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import java.sql.Connection; +import java.util.concurrent.TimeUnit; + +import static org.awaitility.pollinterval.FibonacciPollInterval.*; + /** * Basic configuration expecting subclasses to provide a {@link DataSource} via {@link #createDataSource()} to be * exposed to the {@link ApplicationContext}. @@ -36,12 +45,17 @@ import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; @Configuration abstract class DataSourceConfiguration { + private static final Logger LOG = LoggerFactory.getLogger(DataSourceConfiguration.class); + + @Autowired Class testClass; @Autowired Environment environment; @Bean DataSource dataSource() { - return createDataSource(); + DataSource dataSource = createDataSource(); + verifyConnection(dataSource); + return dataSource; } @Bean @@ -76,4 +90,21 @@ abstract class DataSourceConfiguration { * @param populator will never be {@literal null}. */ protected void customizePopulator(ResourceDatabasePopulator populator) {} + + private void verifyConnection(DataSource dataSource) { + + Awaitility.await() // + .atMost(5L, TimeUnit.MINUTES) // + .pollInterval(fibonacci(TimeUnit.SECONDS)) // + .ignoreExceptions() // + .until(() -> { + + LOG.debug("connectivity verifying ..."); + try (Connection connection = dataSource.getConnection()) { + return true; + } + }); + + LOG.info("connectivity verified"); + } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/Db2DataSourceConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/Db2DataSourceConfiguration.java index 3dfa0d2de..28914b7d7 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/Db2DataSourceConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/Db2DataSourceConfiguration.java @@ -32,6 +32,8 @@ import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import org.testcontainers.containers.Db2Container; +import static org.awaitility.pollinterval.FibonacciPollInterval.*; + /** * {@link DataSource} setup for DB2. * @@ -66,18 +68,6 @@ class Db2DataSourceConfiguration extends DataSourceConfiguration { DriverManagerDataSource dataSource = new DriverManagerDataSource(DB_2_CONTAINER.getJdbcUrl(), DB_2_CONTAINER.getUsername(), DB_2_CONTAINER.getPassword()); - // DB2 container says its ready but it's like with a cat that denies service and still wants food although it had - // its food. Therefore, we make sure that we can properly establish a connection instead of trusting the cat - // ...err... DB2. - Awaitility.await().ignoreException(SQLException.class).until(() -> { - - try (Connection connection = dataSource.getConnection()) { - return true; - } - }); - - LOG.info("DB2 connectivity verified"); - return dataSource; } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/OracleDataSourceConfiguration.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/OracleDataSourceConfiguration.java index 83d19536f..001f088de 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/OracleDataSourceConfiguration.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/testing/OracleDataSourceConfiguration.java @@ -15,23 +15,14 @@ */ package org.springframework.data.jdbc.testing; -import static org.awaitility.pollinterval.FibonacciPollInterval.*; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.concurrent.TimeUnit; - import javax.sql.DataSource; -import org.awaitility.Awaitility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; - import org.testcontainers.containers.OracleContainer; /** @@ -61,8 +52,10 @@ public class OracleDataSourceConfiguration extends DataSourceConfiguration { if (ORACLE_CONTAINER == null) { + LOG.info("Oracle starting..."); OracleContainer container = new OracleContainer("springci/spring-data-oracle-xe-prebuild:18.4.0").withReuse(true); container.start(); + LOG.info("Oracle started"); ORACLE_CONTAINER = container; } @@ -72,17 +65,6 @@ public class OracleDataSourceConfiguration extends DataSourceConfiguration { DataSource dataSource = new DriverManagerDataSource(jdbcUrl, ORACLE_CONTAINER.getUsername(), ORACLE_CONTAINER.getPassword()); - // Oracle container says its ready but it's like with a cat that denies service and still wants food although it had - // its food. Therefore, we make sure that we can properly establish a connection instead of trusting the cat - // ...err... Oracle. - Awaitility.await().atMost(5L, TimeUnit.MINUTES).pollInterval(fibonacci(TimeUnit.SECONDS)) - .ignoreException(SQLException.class).until(() -> { - - try (Connection connection = dataSource.getConnection()) { - return true; - } - }); - return dataSource; }