Skip to content

Commit aa4ae89

Browse files
committed
Merge pull request #43783 from hezean
* gh-43783: Polish "Fix handling of env vars in Bitnami's Postgres image" Fix handling of env vars in Bitnami's Postgres image Closes gh-43783
2 parents 42ecda2 + d4f497d commit aa4ae89

File tree

6 files changed

+99
-10
lines changed

6 files changed

+99
-10
lines changed

spring-boot-project/spring-boot-docker-compose/build.gradle

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ dependencies {
2020
dockerTestRuntimeOnly("com.microsoft.sqlserver:mssql-jdbc")
2121
dockerTestRuntimeOnly("com.oracle.database.r2dbc:oracle-r2dbc")
2222
dockerTestRuntimeOnly("io.r2dbc:r2dbc-mssql")
23+
dockerTestRuntimeOnly("org.postgresql:postgresql")
24+
dockerTestRuntimeOnly("org.postgresql:r2dbc-postgresql")
2325

2426
implementation("com.fasterxml.jackson.core:jackson-databind")
2527
implementation("com.fasterxml.jackson.module:jackson-module-parameter-names")

spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests.java

+29-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,9 +16,15 @@
1616

1717
package org.springframework.boot.docker.compose.service.connection.postgres;
1818

19+
import java.sql.Driver;
20+
1921
import org.springframework.boot.autoconfigure.jdbc.JdbcConnectionDetails;
2022
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
23+
import org.springframework.boot.jdbc.DatabaseDriver;
2124
import org.springframework.boot.testsupport.container.TestImage;
25+
import org.springframework.jdbc.core.JdbcTemplate;
26+
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
27+
import org.springframework.util.ClassUtils;
2228

2329
import static org.assertj.core.api.Assertions.assertThat;
2430

@@ -33,13 +39,16 @@
3339
class PostgresJdbcDockerComposeConnectionDetailsFactoryIntegrationTests {
3440

3541
@DockerComposeTest(composeFile = "postgres-compose.yaml", image = TestImage.POSTGRESQL)
36-
void runCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) {
42+
void runCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) throws ClassNotFoundException {
3743
assertConnectionDetails(connectionDetails);
44+
checkDatabaseAccess(connectionDetails);
3845
}
3946

4047
@DockerComposeTest(composeFile = "postgres-bitnami-compose.yaml", image = TestImage.BITNAMI_POSTGRESQL)
41-
void runWithBitnamiImageCreatesConnectionDetails(JdbcConnectionDetails connectionDetails) {
48+
void runWithBitnamiImageCreatesConnectionDetails(JdbcConnectionDetails connectionDetails)
49+
throws ClassNotFoundException {
4250
assertConnectionDetails(connectionDetails);
51+
checkDatabaseAccess(connectionDetails);
4352
}
4453

4554
private void assertConnectionDetails(JdbcConnectionDetails connectionDetails) {
@@ -48,4 +57,21 @@ private void assertConnectionDetails(JdbcConnectionDetails connectionDetails) {
4857
assertThat(connectionDetails.getJdbcUrl()).startsWith("jdbc:postgresql://").endsWith("/mydatabase");
4958
}
5059

60+
private void checkDatabaseAccess(JdbcConnectionDetails connectionDetails) throws ClassNotFoundException {
61+
assertThat(executeQuery(connectionDetails, DatabaseDriver.POSTGRESQL.getValidationQuery(), Integer.class))
62+
.isEqualTo(1);
63+
}
64+
65+
@SuppressWarnings("unchecked")
66+
private <T> T executeQuery(JdbcConnectionDetails connectionDetails, String sql, Class<T> result)
67+
throws ClassNotFoundException {
68+
SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
69+
dataSource.setUrl(connectionDetails.getJdbcUrl());
70+
dataSource.setUsername(connectionDetails.getUsername());
71+
dataSource.setPassword(connectionDetails.getPassword());
72+
dataSource.setDriverClass((Class<? extends Driver>) ClassUtils.forName(connectionDetails.getDriverClassName(),
73+
getClass().getClassLoader()));
74+
return new JdbcTemplate(dataSource).queryForObject(sql, result);
75+
}
76+
5177
}

spring-boot-project/spring-boot-docker-compose/src/dockerTest/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests.java

+22-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,11 +16,16 @@
1616

1717
package org.springframework.boot.docker.compose.service.connection.postgres;
1818

19+
import java.time.Duration;
20+
21+
import io.r2dbc.spi.ConnectionFactories;
1922
import io.r2dbc.spi.ConnectionFactoryOptions;
2023

2124
import org.springframework.boot.autoconfigure.r2dbc.R2dbcConnectionDetails;
2225
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
26+
import org.springframework.boot.jdbc.DatabaseDriver;
2327
import org.springframework.boot.testsupport.container.TestImage;
28+
import org.springframework.r2dbc.core.DatabaseClient;
2429

2530
import static org.assertj.core.api.Assertions.assertThat;
2631

@@ -37,11 +42,13 @@ class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
3742
@DockerComposeTest(composeFile = "postgres-compose.yaml", image = TestImage.POSTGRESQL)
3843
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
3944
assertConnectionDetails(connectionDetails);
45+
checkDatabaseAccess(connectionDetails);
4046
}
4147

4248
@DockerComposeTest(composeFile = "postgres-bitnami-compose.yaml", image = TestImage.BITNAMI_POSTGRESQL)
4349
void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
4450
assertConnectionDetails(connectionDetails);
51+
checkDatabaseAccess(connectionDetails);
4552
}
4653

4754
private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
@@ -51,4 +58,18 @@ private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
5158
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
5259
}
5360

61+
private void checkDatabaseAccess(R2dbcConnectionDetails connectionDetails) {
62+
assertThat(executeQuery(connectionDetails, DatabaseDriver.POSTGRESQL.getValidationQuery(), Integer.class))
63+
.isEqualTo(1);
64+
}
65+
66+
private <T> T executeQuery(R2dbcConnectionDetails connectionDetails, String sql, Class<T> result) {
67+
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
68+
return DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
69+
.sql(sql)
70+
.mapValue(result)
71+
.first()
72+
.block(Duration.ofSeconds(30));
73+
}
74+
5475
}

spring-boot-project/spring-boot-docker-compose/src/dockerTest/resources/org/springframework/boot/docker/compose/service/connection/postgres/postgres-bitnami-compose.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ services:
44
ports:
55
- '5432'
66
environment:
7-
- 'POSTGRESQL_USER=myuser'
8-
- 'POSTGRESQL_DB=mydatabase'
7+
- 'POSTGRESQL_USERNAME=myuser'
8+
- 'POSTGRESQL_DATABASE=mydatabase'
99
- 'POSTGRESQL_PASSWORD=secret'

spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,19 +28,37 @@
2828
* @author Andy Wilkinson
2929
* @author Phillip Webb
3030
* @author Scott Frederick
31+
* @author He Zean
3132
*/
3233
class PostgresEnvironment {
3334

35+
private static final String[] USERNAME_KEYS = new String[] { "POSTGRES_USER", "POSTGRESQL_USER",
36+
"POSTGRESQL_USERNAME" };
37+
38+
private static final String DEFAULT_USERNAME = "postgres";
39+
40+
private static final String[] DATABASE_KEYS = new String[] { "POSTGRES_DB", "POSTGRESQL_DB",
41+
"POSTGRESQL_DATABASE" };
42+
3443
private final String username;
3544

3645
private final String password;
3746

3847
private final String database;
3948

4049
PostgresEnvironment(Map<String, String> env) {
41-
this.username = env.getOrDefault("POSTGRES_USER", env.getOrDefault("POSTGRESQL_USER", "postgres"));
50+
this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME);
4251
this.password = extractPassword(env);
43-
this.database = env.getOrDefault("POSTGRES_DB", env.getOrDefault("POSTGRESQL_DB", this.username));
52+
this.database = extract(env, DATABASE_KEYS, this.username);
53+
}
54+
55+
private String extract(Map<String, String> env, String[] keys, String defaultValue) {
56+
for (String key : keys) {
57+
if (env.containsKey(key)) {
58+
return env.get(key);
59+
}
60+
}
61+
return defaultValue;
4462
}
4563

4664
private String extractPassword(Map<String, String> env) {

spring-boot-project/spring-boot-docker-compose/src/test/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironmentTests.java

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2024 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
3131
* @author Andy Wilkinson
3232
* @author Phillip Webb
3333
* @author Scott Frederick
34+
* @author He Zean
3435
*/
3536
class PostgresEnvironmentTests {
3637

@@ -66,6 +67,13 @@ void getUsernameWhenHasPostgresqlUser() {
6667
assertThat(environment.getUsername()).isEqualTo("me");
6768
}
6869

70+
@Test
71+
void getUsernameWhenHasPostgresqlUsername() {
72+
PostgresEnvironment environment = new PostgresEnvironment(
73+
Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret"));
74+
assertThat(environment.getUsername()).isEqualTo("me");
75+
}
76+
6977
@Test
7078
void getPasswordWhenHasPostgresPassword() {
7179
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
@@ -104,6 +112,13 @@ void getDatabaseWhenNoPostgresqlDbAndPostgresUser() {
104112
assertThat(environment.getDatabase()).isEqualTo("me");
105113
}
106114

115+
@Test
116+
void getDatabaseWhenNoPostgresqlDatabaseAndPostgresqlUsername() {
117+
PostgresEnvironment environment = new PostgresEnvironment(
118+
Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret"));
119+
assertThat(environment.getDatabase()).isEqualTo("me");
120+
}
121+
107122
@Test
108123
void getDatabaseWhenHasPostgresDb() {
109124
PostgresEnvironment environment = new PostgresEnvironment(
@@ -118,4 +133,11 @@ void getDatabaseWhenHasPostgresqlDb() {
118133
assertThat(environment.getDatabase()).isEqualTo("db");
119134
}
120135

136+
@Test
137+
void getDatabaseWhenHasPostgresqlDatabase() {
138+
PostgresEnvironment environment = new PostgresEnvironment(
139+
Map.of("POSTGRESQL_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret"));
140+
assertThat(environment.getDatabase()).isEqualTo("db");
141+
}
142+
121143
}

0 commit comments

Comments
 (0)