diff --git a/spring-boot-project/spring-boot-docker-compose/build.gradle b/spring-boot-project/spring-boot-docker-compose/build.gradle index be484f8b8dc..c1e95e62f84 100644 --- a/spring-boot-project/spring-boot-docker-compose/build.gradle +++ b/spring-boot-project/spring-boot-docker-compose/build.gradle @@ -20,6 +20,8 @@ dependencies { dockerTestRuntimeOnly("com.microsoft.sqlserver:mssql-jdbc") dockerTestRuntimeOnly("com.oracle.database.r2dbc:oracle-r2dbc") dockerTestRuntimeOnly("io.r2dbc:r2dbc-mssql") + dockerTestRuntimeOnly("org.postgresql:postgresql") + dockerTestRuntimeOnly("org.postgresql:r2dbc-postgresql") implementation("com.fasterxml.jackson.core:jackson-databind") implementation("com.fasterxml.jackson.module:jackson-module-parameter-names") diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index 0c8f16e9e02..ff1919d292d 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,15 @@ package org.springframework.boot.docker.compose.service.connection.postgres; +import java.sql.Driver; + import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.SimpleDriverDataSource; +import org.springframework.util.ClassUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -51,4 +57,21 @@ class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests { assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase"); } + private void checkDatabaseAccess(JdbcConnectionDetails connectionDetails) throws ClassNotFoundException { + assertThat(executeQuery(connectionDetails, DatabaseDriver.POSTGRESQL.getValidationQuery(), Integer.class)) + .isEqualTo(1); + } + + @SuppressWarnings("unchecked") + private T executeQuery(JdbcConnectionDetails connectionDetails, String sql, Class result) + throws ClassNotFoundException { + SimpleDriverDataSource dataSource = new SimpleDriverDataSource(); + dataSource.setUrl(connectionDetails.getJdbcUrl()); + dataSource.setUsername(connectionDetails.getUsername()); + dataSource.setPassword(connectionDetails.getPassword()); + dataSource.setDriverClass((Class) ClassUtils.forName(connectionDetails.getDriverClassName(), + getClass().getClassLoader())); + return new JdbcTemplate(dataSource).queryForObject(sql, result); + } + } diff --git a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java index d449b024b78..80f4f88c0de 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 the original author or authors. + * Copyright 2012-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,16 @@ package org.springframework.boot.docker.compose.service.connection.postgres; +import java.time.Duration; + +import io.r2dbc.spi.ConnectionFactories; import io.r2dbc.spi.ConnectionFactoryOptions; import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; +import org.springframework.boot.jdbc.DatabaseDriver; import org.springframework.boot.testsupport.container.TestImage; +import org.springframework.r2dbc.core.DatabaseClient; import static org.assertj.core.api.Assertions.assertThat; @@ -53,4 +58,18 @@ class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests { assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret"); } + private void checkDatabaseAccess(R2dbcConnectionDetails connectionDetails) { + assertThat(executeQuery(connectionDetails, DatabaseDriver.POSTGRESQL.getValidationQuery(), Integer.class)) + .isEqualTo(1); + } + + private T executeQuery(R2dbcConnectionDetails connectionDetails, String sql, Class result) { + ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions(); + return DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions)) + .sql(sql) + .mapValue(result) + .first() + .block(Duration.ofSeconds(30)); + } + } diff --git a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java index 0d560a5302c..3c69e87dce0 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java +++ b/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java @@ -32,12 +32,12 @@ import org.springframework.util.StringUtils; */ class PostgresEnvironment { - private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRES_USERNAME", - "POSTGRESQL_USER", "POSTGRESQL_USERNAME" }; + private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRESQL_USER", + "POSTGRESQL_USERNAME" }; private static final String DEFAULT_USERNAME = "postgres"; - private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRES_DATABASE", + private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRESQL_DB", "POSTGRESQL_DATABASE" }; private final String username; @@ -47,18 +47,18 @@ class PostgresEnvironment { private final String database; PostgresEnvironment(Map env) { - this.username = extractUsername(env); + this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME); this.password = extractPassword(env); - this.database = extractDatabase(env); + this.database = extract(env, DATABASE_KEYS, this.username); } - private String extractUsername(Map env) { - for (String key : USERNAME_KEYS) { + private String extract(Map env, String[] keys, String defaultValue) { + for (String key : keys) { if (env.containsKey(key)) { return env.get(key); } } - return DEFAULT_USERNAME; + return defaultValue; } private String extractPassword(Map env) { @@ -67,15 +67,6 @@ class PostgresEnvironment { return password; } - private String extractDatabase(Map env) { - for (String key : DATABASE_KEYS) { - if (env.containsKey(key)) { - return env.get(key); - } - } - return this.username; - } - String getUsername() { return this.username; } diff --git a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java index 7a8e5dab2c9..e79f89625f2 100644 --- a/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java +++ b/spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java @@ -67,13 +67,6 @@ class PostgresEnvironmentTests { assertThat(environment.getUsername()).isEqualTo("me"); } - @Test - void getUsernameWhenHasPostgresUsername() { - PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRES_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret")); - assertThat(environment.getUsername()).isEqualTo("me"); - } - @Test void getUsernameWhenHasPostgresqlUsername() { PostgresEnvironment environment = new PostgresEnvironment( @@ -134,9 +127,9 @@ class PostgresEnvironmentTests { } @Test - void getDatabaseWhenHasPostgresDatabase() { + void getDatabaseWhenHasPostgresqlDb() { PostgresEnvironment environment = new PostgresEnvironment( - Map.of("POSTGRES_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret")); + Map.of("POSTGRESQL_DB", "db", "POSTGRESQL_PASSWORD", "secret")); assertThat(environment.getDatabase()).isEqualTo("db"); }