Move R2DBC Docker Compose support into spring-boot-r2dbc

This commit is contained in:
Phillip Webb
2025-05-19 19:34:03 -07:00
parent 313e501345
commit 97c28f1123
58 changed files with 60 additions and 190 deletions

View File

@@ -1,71 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.clickhouse;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactoryOptions;
import reactor.core.publisher.Mono;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link ClickHouseR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Stephane Nicoll
*/
class ClickHouseR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "clickhouse-compose.yaml", image = TestImage.CLICKHOUSE)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
checkDatabaseAccess(connectionDetails);
}
@DockerComposeTest(composeFile = "clickhouse-bitnami-compose.yaml", image = TestImage.BITNAMI_CLICKHOUSE)
void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
// See https://github.com/bitnami/containers/issues/73550
// checkDatabaseAccess(connectionDetails);
}
private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=clickhouse",
"password=REDACTED", "user=myuser");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
private void checkDatabaseAccess(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
ConnectionFactory connectionFactory = ConnectionFactories.get(connectionFactoryOptions);
String sql = DatabaseDriver.CLICKHOUSE.getValidationQuery();
Integer result = Mono.from(connectionFactory.create())
.flatMapMany((connection) -> connection.createStatement(sql).execute())
.flatMap((r) -> r.map((row, rowMetadata) -> row.get(0, Integer.class)))
.blockFirst(Duration.ofSeconds(30));
assertThat(result).isEqualTo(1);
}
}

View File

@@ -1,54 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mariadb;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MariaDbR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MariaDbR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "mariadb-compose.yaml", image = TestImage.MARIADB)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
}
@DockerComposeTest(composeFile = "mariadb-bitnami-compose.yaml", image = TestImage.BITNAMI_MARIADB)
void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
}
private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mariadb",
"password=REDACTED", "user=myuser");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
}

View File

@@ -1,53 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mysql;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link MySqlR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class MySqlR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "mysql-compose.yaml", image = TestImage.MYSQL)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
}
@DockerComposeTest(composeFile = "mysql-bitnami-compose.yaml", image = TestImage.BITNAMI_MYSQL)
void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
}
private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=mydatabase", "driver=mysql",
"password=REDACTED", "user=myuser");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
}
}

View File

@@ -1,57 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleFreeR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
class OracleFreeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_FREE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=freepdb1", "driver=oracle",
"password=REDACTED", "user=app_user");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))
.isEqualTo("app_user_secret");
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
});
}
}

View File

@@ -1,61 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link OracleXeR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The Oracle image has no ARM support")
class OracleXeR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "oracle-compose.yaml", image = TestImage.ORACLE_XE)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("database=xepdb1", "driver=oracle",
"password=REDACTED", "user=app_user");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))
.isEqualTo("app_user_secret");
Awaitility.await().atMost(Duration.ofMinutes(1)).ignoreExceptions().untilAsserted(() -> {
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.ORACLE.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo("Hello");
});
}
}

View File

@@ -1,100 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link PostgresR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
* @author He Zean
*/
class PostgresR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "postgres-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
checkDatabaseAccess(connectionDetails);
}
@DockerComposeTest(composeFile = "postgres-with-trust-host-auth-method-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetailsThatCanAccessDatabaseWhenHostAuthMethodIsTrust(
R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.USER)).isEqualTo("myuser");
assertThat(connectionFactoryOptions.getValue(ConnectionFactoryOptions.PASSWORD)).isNull();
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.DATABASE))
.isEqualTo("mydatabase");
checkDatabaseAccess(connectionDetails);
}
@DockerComposeTest(composeFile = "postgres-bitnami-compose.yaml", image = TestImage.BITNAMI_POSTGRESQL)
void runWithBitnamiImageCreatesConnectionDetails(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
checkDatabaseAccess(connectionDetails);
}
@DockerComposeTest(composeFile = "postgres-application-name-compose.yaml", image = TestImage.POSTGRESQL)
void runCreatesConnectionDetailsApplicationName(R2dbcConnectionDetails connectionDetails) {
assertConnectionDetails(connectionDetails);
ConnectionFactoryOptions options = connectionDetails.getConnectionFactoryOptions();
assertThat(options.getValue(Option.valueOf("applicationName"))).isEqualTo("spring boot");
assertThat(executeQuery(connectionDetails, "select current_setting('application_name')", String.class))
.isEqualTo("spring boot");
}
private void assertConnectionDetails(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions options = connectionDetails.getConnectionFactoryOptions();
assertThat(options.getRequiredValue(ConnectionFactoryOptions.HOST)).isNotNull();
assertThat(options.getRequiredValue(ConnectionFactoryOptions.PORT)).isNotNull();
assertThat(options.getRequiredValue(ConnectionFactoryOptions.DATABASE)).isEqualTo("mydatabase");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.USER)).isEqualTo("myuser");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.DRIVER)).isEqualTo("postgresql");
}
private void checkDatabaseAccess(R2dbcConnectionDetails connectionDetails) {
assertThat(executeQuery(connectionDetails, DatabaseDriver.POSTGRESQL.getValidationQuery(), Integer.class))
.isEqualTo(1);
}
private <T> T executeQuery(R2dbcConnectionDetails connectionDetails, String sql, Class<T> resultClass) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
return DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(sql)
.mapValue(resultClass)
.first()
.block(Duration.ofSeconds(30));
}
}

View File

@@ -1,57 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.sqlserver;
import java.time.Duration;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.junit.jupiter.api.condition.OS;
import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest;
import org.springframework.boot.jdbc.DatabaseDriver;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.boot.testsupport.container.TestImage;
import org.springframework.boot.testsupport.junit.DisabledOnOs;
import org.springframework.r2dbc.core.DatabaseClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link SqlServerR2dbcDockerComposeConnectionDetailsFactory}.
*
* @author Andy Wilkinson
*/
@DisabledOnOs(os = { OS.LINUX, OS.MAC }, architecture = "aarch64",
disabledReason = "The SQL server image has no ARM support")
class SqlServerR2dbcDockerComposeConnectionDetailsFactoryIntegrationTests {
@DockerComposeTest(composeFile = "mssqlserver-compose.yaml", image = TestImage.SQL_SERVER)
void runCreatesConnectionDetailsThatCanBeUsedToAccessDatabase(R2dbcConnectionDetails connectionDetails) {
ConnectionFactoryOptions connectionFactoryOptions = connectionDetails.getConnectionFactoryOptions();
assertThat(connectionFactoryOptions.toString()).contains("driver=mssql", "password=REDACTED", "user=SA");
assertThat(connectionFactoryOptions.getRequiredValue(ConnectionFactoryOptions.PASSWORD))
.isEqualTo("verYs3cret");
Object result = DatabaseClient.create(ConnectionFactories.get(connectionFactoryOptions))
.sql(DatabaseDriver.SQLSERVER.getValidationQuery())
.map((row, metadata) -> row.get(0))
.first()
.block(Duration.ofSeconds(30));
assertThat(result).isEqualTo(1);
}
}

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '8123'
environment:
- 'CLICKHOUSE_USER=myuser'
- 'CLICKHOUSE_PASSWORD=secret'
- 'CLICKHOUSE_DB=mydatabase'

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '8123'
environment:
- 'CLICKHOUSE_USER=myuser'
- 'CLICKHOUSE_PASSWORD=secret'
- 'CLICKHOUSE_DB=mydatabase'

View File

@@ -1,10 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MARIADB_ROOT_PASSWORD=verysecret'
- 'MARIADB_USER=myuser'
- 'MARIADB_PASSWORD=secret'
- 'MARIADB_DATABASE=mydatabase'

View File

@@ -1,11 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MARIADB_ROOT_PASSWORD=verysecret'
- 'MARIADB_USER=myuser'
- 'MARIADB_PASSWORD=secret'
- 'MARIADB_DATABASE=mydatabase'

View File

@@ -1,9 +0,0 @@
services:
mongo:
image: '{imageName}'
ports:
- '27017'
environment:
- 'MONGODB_ROOT_USERNAME=root'
- 'MONGODB_ROOT_PASSWORD=secret'
- 'MONGODB_DATABASE=testdb'

View File

@@ -1,9 +0,0 @@
services:
mongo:
image: '{imageName}'
ports:
- '27017'
environment:
MONGO_INITDB_ROOT_USERNAME: 'root'
MONGO_INITDB_ROOT_PASSWORD: 'secret'
MONGO_INITDB_DATABASE: 'mydatabase'

View File

@@ -1,10 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MYSQL_ROOT_PASSWORD=verysecret'
- 'MYSQL_USER=myuser'
- 'MYSQL_PASSWORD=secret'
- 'MYSQL_DATABASE=mydatabase'

View File

@@ -1,10 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '3306'
environment:
- 'MYSQL_ROOT_PASSWORD=verysecret'
- 'MYSQL_USER=myuser'
- 'MYSQL_PASSWORD=secret'
- 'MYSQL_DATABASE=mydatabase'

View File

@@ -1,15 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '1521'
environment:
- 'APP_USER=app_user'
- 'APP_USER_PASSWORD=app_user_secret'
- 'ORACLE_PASSWORD=secret'
healthcheck:
test: ["CMD-SHELL", "healthcheck.sh"]
interval: 10s
timeout: 5s
retries: 10

View File

@@ -1,12 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_PASSWORD=secret'
labels:
org.springframework.boot.jdbc.parameters: 'ApplicationName=spring+boot'
org.springframework.boot.r2dbc.parameters: 'applicationName=spring boot'

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRESQL_USERNAME=myuser'
- 'POSTGRESQL_DATABASE=mydatabase'
- 'POSTGRESQL_PASSWORD=secret'

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_PASSWORD=secret'

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '5432'
environment:
- 'POSTGRES_USER=myuser'
- 'POSTGRES_DB=mydatabase'
- 'POSTGRES_HOST_AUTH_METHOD=trust'

View File

@@ -1,9 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '1433'
environment:
- 'MSSQL_PID=express'
- 'MSSQL_SA_PASSWORD=verYs3cret'
- 'ACCEPT_EULA=yes'

View File

@@ -1,11 +0,0 @@
services:
database:
image: '{imageName}'
ports:
- '1433'
environment:
- 'MSSQL_PID=express'
- 'MSSQL_SA_PASSWORD=verYs3cret'
- 'ACCEPT_EULA=yes'
labels:
org.springframework.boot.jdbc.parameters: sendStringParametersAsUnicode=false

View File

@@ -1,62 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.clickhouse;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* ClickHouse environment details.
*
* @author Stephane Nicoll
*/
class ClickHouseEnvironment {
private final String username;
private final String password;
private final String database;
ClickHouseEnvironment(Map<String, String> env) {
this.username = env.getOrDefault("CLICKHOUSE_USER", "default");
this.password = extractPassword(env);
this.database = env.getOrDefault("CLICKHOUSE_DB", "default");
}
private String extractPassword(Map<String, String> env) {
boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD");
String password = env.get("CLICKHOUSE_PASSWORD");
Assert.state(StringUtils.hasLength(password) || allowEmpty, "No ClickHouse password found");
return (password != null) ? password : "";
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
String getDatabase() {
return this.database;
}
}

View File

@@ -1,73 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.clickhouse;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for a {@code clickhouse} service.
*
* @author Stephane Nicoll
*/
class ClickHouseR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
private static final String[] CLICKHOUSE_CONTAINER_NAMES = { "clickhouse/clickhouse-server", "bitnami/clickhouse" };
ClickHouseR2dbcDockerComposeConnectionDetailsFactory() {
super(CLICKHOUSE_CONTAINER_NAMES, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new ClickhouseDbR2dbcDockerComposeConnectionDetails(source.getRunningService());
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code clickhouse}
* {@link RunningService}.
*/
static class ClickhouseDbR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"clickhouse", 8123);
private final ConnectionFactoryOptions connectionFactoryOptions;
ClickhouseDbR2dbcDockerComposeConnectionDetails(RunningService service) {
super(service);
ClickHouseEnvironment environment = new ClickHouseEnvironment(service.env());
this.connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service, environment.getDatabase(),
environment.getUsername(), environment.getPassword());
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose ClickHouse service connections.
*/
package org.springframework.boot.docker.compose.service.connection.clickhouse;

View File

@@ -1,84 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mariadb;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* MariaDB environment details.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MariaDbEnvironment {
private final String username;
private final String password;
private final String database;
MariaDbEnvironment(Map<String, String> env) {
this.username = extractUsername(env);
this.password = extractPassword(env);
this.database = extractDatabase(env);
}
private String extractUsername(Map<String, String> env) {
String user = env.get("MARIADB_USER");
return (user != null) ? user : env.getOrDefault("MYSQL_USER", "root");
}
private String extractPassword(Map<String, String> env) {
Assert.state(!env.containsKey("MARIADB_RANDOM_ROOT_PASSWORD"), "MARIADB_RANDOM_ROOT_PASSWORD is not supported");
Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported");
Assert.state(!env.containsKey("MARIADB_ROOT_PASSWORD_HASH"), "MARIADB_ROOT_PASSWORD_HASH is not supported");
boolean allowEmpty = env.containsKey("MARIADB_ALLOW_EMPTY_PASSWORD")
|| env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD");
String password = env.get("MARIADB_PASSWORD");
password = (password != null) ? password : env.get("MYSQL_PASSWORD");
password = (password != null) ? password : env.get("MARIADB_ROOT_PASSWORD");
password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD");
Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MariaDB password found");
return (password != null) ? password : "";
}
private String extractDatabase(Map<String, String> env) {
String database = env.get("MARIADB_DATABASE");
database = (database != null) ? database : env.get("MYSQL_DATABASE");
Assert.state(database != null, "No MARIADB_DATABASE defined");
return database;
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
String getDatabase() {
return this.database;
}
}

View File

@@ -1,75 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mariadb;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for a {@code mariadb} service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MariaDbR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
private static final String[] MARIADB_CONTAINER_NAMES = { "mariadb", "bitnami/mariadb" };
MariaDbR2dbcDockerComposeConnectionDetailsFactory() {
super(MARIADB_CONTAINER_NAMES, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new MariaDbR2dbcDockerComposeConnectionDetails(source.getRunningService());
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code mariadb} {@link RunningService}.
*/
static class MariaDbR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"mariadb", 3306);
private final ConnectionFactoryOptions connectionFactoryOptions;
MariaDbR2dbcDockerComposeConnectionDetails(RunningService service) {
super(service);
MariaDbEnvironment environment = new MariaDbEnvironment(service.env());
this.connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service, environment.getDatabase(),
environment.getUsername(), environment.getPassword());
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose MariaDB service connections.
*/
package org.springframework.boot.docker.compose.service.connection.mariadb;

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mysql;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* MySQL environment details.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MySqlEnvironment {
private final String username;
private final String password;
private final String database;
MySqlEnvironment(Map<String, String> env) {
this.username = env.getOrDefault("MYSQL_USER", "root");
this.password = extractPassword(env);
this.database = extractDatabase(env);
}
private String extractPassword(Map<String, String> env) {
Assert.state(!env.containsKey("MYSQL_RANDOM_ROOT_PASSWORD"), "MYSQL_RANDOM_ROOT_PASSWORD is not supported");
boolean allowEmpty = env.containsKey("MYSQL_ALLOW_EMPTY_PASSWORD") || env.containsKey("ALLOW_EMPTY_PASSWORD");
String password = env.get("MYSQL_PASSWORD");
password = (password != null) ? password : env.get("MYSQL_ROOT_PASSWORD");
Assert.state(StringUtils.hasLength(password) || allowEmpty, "No MySQL password found");
return (password != null) ? password : "";
}
private String extractDatabase(Map<String, String> env) {
String database = env.get("MYSQL_DATABASE");
Assert.state(database != null, "No MYSQL_DATABASE defined");
return database;
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
String getDatabase() {
return this.database;
}
}

View File

@@ -1,75 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mysql;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for a {@code mysql} service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class MySqlR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
private static final String[] MYSQL_CONTAINER_NAMES = { "mysql", "bitnami/mysql" };
MySqlR2dbcDockerComposeConnectionDetailsFactory() {
super(MYSQL_CONTAINER_NAMES, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new MySqlR2dbcDockerComposeConnectionDetails(source.getRunningService());
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code mysql} {@link RunningService}.
*/
static class MySqlR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"mysql", 3306);
private final ConnectionFactoryOptions connectionFactoryOptions;
MySqlR2dbcDockerComposeConnectionDetails(RunningService service) {
super(service);
MySqlEnvironment environment = new MySqlEnvironment(service.env());
this.connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service, environment.getDatabase(),
environment.getUsername(), environment.getPassword());
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose MySQL service connections.
*/
package org.springframework.boot.docker.compose.service.connection.mysql;

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
/**
* Enumeration of supported Oracle containers.
*
* @author Andy Wilkinson
*/
enum OracleContainer {
FREE("gvenzl/oracle-free", "freepdb1"),
XE("gvenzl/oracle-xe", "xepdb1");
private final String imageName;
private final String defaultDatabase;
OracleContainer(String imageName, String defaultDatabase) {
this.imageName = imageName;
this.defaultDatabase = defaultDatabase;
}
String getImageName() {
return this.imageName;
}
String getDefaultDatabase() {
return this.defaultDatabase;
}
}

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Oracle Database environment details.
*
* @author Andy Wilkinson
*/
class OracleEnvironment {
private final String username;
private final String password;
private final String database;
OracleEnvironment(Map<String, String> env, String defaultDatabase) {
this.username = env.getOrDefault("APP_USER", "system");
this.password = extractPassword(env);
this.database = env.getOrDefault("ORACLE_DATABASE", defaultDatabase);
}
private String extractPassword(Map<String, String> env) {
if (env.containsKey("APP_USER")) {
String password = env.get("APP_USER_PASSWORD");
Assert.state(StringUtils.hasLength(password), "No Oracle app password found");
return password;
}
Assert.state(!env.containsKey("ORACLE_RANDOM_PASSWORD"),
"ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD");
String password = env.get("ORACLE_PASSWORD");
Assert.state(StringUtils.hasLength(password), "No Oracle password found");
return password;
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
String getDatabase() {
return this.database;
}
}

View File

@@ -1,34 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for an {@link OracleContainer#FREE} service.
*
* @author Andy Wilkinson
*/
class OracleFreeR2dbcDockerComposeConnectionDetailsFactory extends OracleR2dbcDockerComposeConnectionDetailsFactory {
protected OracleFreeR2dbcDockerComposeConnectionDetailsFactory() {
super(OracleContainer.FREE);
}
}

View File

@@ -1,76 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* Base class for a {@link DockerComposeConnectionDetailsFactory} to create
* {@link R2dbcConnectionDetails} for an {@code oracle-free} or {@code oracle-xe} service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
abstract class OracleR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
private final String defaultDatabase;
OracleR2dbcDockerComposeConnectionDetailsFactory(OracleContainer container) {
super(container.getImageName(), "io.r2dbc.spi.ConnectionFactoryOptions");
this.defaultDatabase = container.getDefaultDatabase();
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new OracleDbR2dbcDockerComposeConnectionDetails(source.getRunningService(), this.defaultDatabase);
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code gvenzl/oracle-xe}
* {@link RunningService}.
*/
static class OracleDbR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"oracle", 1521);
private final ConnectionFactoryOptions connectionFactoryOptions;
OracleDbR2dbcDockerComposeConnectionDetails(RunningService service, String defaultDatabase) {
super(service);
OracleEnvironment environment = new OracleEnvironment(service.env(), defaultDatabase);
this.connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service, environment.getDatabase(),
environment.getUsername(), environment.getPassword());
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
}
}

View File

@@ -1,34 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for an {@link OracleContainer#XE} service.
*
* @author Andy Wilkinson
*/
class OracleXeR2dbcDockerComposeConnectionDetailsFactory extends OracleR2dbcDockerComposeConnectionDetailsFactory {
protected OracleXeR2dbcDockerComposeConnectionDetailsFactory() {
super(OracleContainer.XE);
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose MySQL service connections.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;

View File

@@ -1,92 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Postgres environment details.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
* @author Sidmar Theodoro
* @author He Zean
*/
class PostgresEnvironment {
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", "POSTGRESQL_DB",
"POSTGRESQL_DATABASE" };
private final String username;
private final String password;
private final String database;
PostgresEnvironment(Map<String, String> env) {
this.username = extract(env, USERNAME_KEYS, DEFAULT_USERNAME);
this.password = extractPassword(env);
this.database = extract(env, DATABASE_KEYS, this.username);
}
private String extract(Map<String, String> env, String[] keys, String defaultValue) {
for (String key : keys) {
if (env.containsKey(key)) {
return env.get(key);
}
}
return defaultValue;
}
private String extractPassword(Map<String, String> env) {
if (isUsingTrustHostAuthMethod(env)) {
return null;
}
String password = env.getOrDefault("POSTGRES_PASSWORD", env.get("POSTGRESQL_PASSWORD"));
boolean allowEmpty = env.containsKey("ALLOW_EMPTY_PASSWORD");
Assert.state(allowEmpty || StringUtils.hasLength(password), "No PostgreSQL password found");
return (password != null) ? password : "";
}
private boolean isUsingTrustHostAuthMethod(Map<String, String> env) {
String hostAuthMethod = env.get("POSTGRES_HOST_AUTH_METHOD");
return "trust".equals(hostAuthMethod);
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
String getDatabase() {
return this.database;
}
}

View File

@@ -1,98 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for a {@code postgres} service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
*/
class PostgresR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
private static final String[] POSTGRES_CONTAINER_NAMES = { "postgres", "bitnami/postgresql" };
PostgresR2dbcDockerComposeConnectionDetailsFactory() {
super(POSTGRES_CONTAINER_NAMES, "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new PostgresDbR2dbcDockerComposeConnectionDetails(source.getRunningService(), source.getEnvironment());
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code postgres} {@link RunningService}.
*/
static class PostgresDbR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final Option<String> APPLICATION_NAME = Option.valueOf("applicationName");
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"postgresql", 5432);
private final ConnectionFactoryOptions connectionFactoryOptions;
PostgresDbR2dbcDockerComposeConnectionDetails(RunningService service, Environment environment) {
super(service);
this.connectionFactoryOptions = getConnectionFactoryOptions(service, environment);
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
private static ConnectionFactoryOptions getConnectionFactoryOptions(RunningService service,
Environment environment) {
PostgresEnvironment env = new PostgresEnvironment(service.env());
ConnectionFactoryOptions connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service,
env.getDatabase(), env.getUsername(), env.getPassword());
return addApplicationNameIfNecessary(connectionFactoryOptions, environment);
}
private static ConnectionFactoryOptions addApplicationNameIfNecessary(
ConnectionFactoryOptions connectionFactoryOptions, Environment environment) {
if (connectionFactoryOptions.hasOption(APPLICATION_NAME)) {
return connectionFactoryOptions;
}
String applicationName = environment.getProperty("spring.application.name");
if (!StringUtils.hasText(applicationName)) {
return connectionFactoryOptions;
}
return connectionFactoryOptions.mutate().option(APPLICATION_NAME, applicationName).build();
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose Postgres service connections.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;

View File

@@ -1,99 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.r2dbc;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Utility used to build an R2DBC {@link ConnectionFactoryOptions} for a
* {@link RunningService}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @since 3.1.0
*/
public class ConnectionFactoryOptionsBuilder {
private static final String PARAMETERS_LABEL = "org.springframework.boot.r2dbc.parameters";
private final String driver;
private final int sourcePort;
/**
* Create a new {@link ConnectionFactoryOptionsBuilder} instance.
* @param driver the driver
* @param containerPort the source container port
*/
public ConnectionFactoryOptionsBuilder(String driver, int containerPort) {
Assert.notNull(driver, "'driver' must not be null");
this.driver = driver;
this.sourcePort = containerPort;
}
public ConnectionFactoryOptions build(RunningService service, String database, String user, String password) {
Assert.notNull(service, "'service' must not be null");
Assert.notNull(database, "'database' must not be null");
ConnectionFactoryOptions.Builder builder = ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DRIVER, this.driver)
.option(ConnectionFactoryOptions.HOST, service.host())
.option(ConnectionFactoryOptions.PORT, service.ports().get(this.sourcePort))
.option(ConnectionFactoryOptions.DATABASE, database);
if (StringUtils.hasLength(user)) {
builder.option(ConnectionFactoryOptions.USER, user);
}
if (StringUtils.hasLength(password)) {
builder.option(ConnectionFactoryOptions.PASSWORD, password);
}
applyParameters(service, builder);
return builder.build();
}
private void applyParameters(RunningService service, ConnectionFactoryOptions.Builder builder) {
String parameters = service.labels().get(PARAMETERS_LABEL);
try {
if (StringUtils.hasText(parameters)) {
parseParameters(parameters).forEach((name, value) -> builder.option(Option.valueOf(name), value));
}
}
catch (RuntimeException ex) {
throw new IllegalStateException(
"Unable to apply R2DBC label parameters '%s' defined on service %s".formatted(parameters, service));
}
}
private Map<String, String> parseParameters(String parameters) {
Map<String, String> result = new LinkedHashMap<>();
for (String parameter : StringUtils.commaDelimitedListToStringArray(parameters)) {
String[] parts = parameter.split("=");
Assert.state(parts.length == 2, () -> "'parameters' [%s] must cotain parsable value".formatted(parameter));
result.put(parts[0], parts[1]);
}
return Collections.unmodifiableMap(result);
}
}

View File

@@ -1,21 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Utilities to help when creating
* {@link org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails}.
*/
package org.springframework.boot.docker.compose.service.connection.r2dbc;

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.sqlserver;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* MS SQL Server environment details.
*
* @author Andy Wilkinson
*/
class SqlServerEnvironment {
private final String username = "SA";
private final String password;
SqlServerEnvironment(Map<String, String> env) {
this.password = extractPassword(env);
}
private String extractPassword(Map<String, String> env) {
String password = env.get("MSSQL_SA_PASSWORD");
password = (password != null) ? password : env.get("SA_PASSWORD");
Assert.state(StringUtils.hasLength(password), "No MSSQL password found");
return password;
}
String getUsername() {
return this.username;
}
String getPassword() {
return this.password;
}
}

View File

@@ -1,72 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.sqlserver;
import io.r2dbc.spi.ConnectionFactoryOptions;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory;
import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource;
import org.springframework.boot.docker.compose.service.connection.r2dbc.ConnectionFactoryOptionsBuilder;
import org.springframework.boot.r2dbc.autoconfigure.R2dbcConnectionDetails;
/**
* {@link DockerComposeConnectionDetailsFactory} to create {@link R2dbcConnectionDetails}
* for a {@code mssql} service.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class SqlServerR2dbcDockerComposeConnectionDetailsFactory
extends DockerComposeConnectionDetailsFactory<R2dbcConnectionDetails> {
SqlServerR2dbcDockerComposeConnectionDetailsFactory() {
super("mssql/server", "io.r2dbc.spi.ConnectionFactoryOptions");
}
@Override
protected R2dbcConnectionDetails getDockerComposeConnectionDetails(DockerComposeConnectionSource source) {
return new SqlServerR2dbcDockerComposeConnectionDetails(source.getRunningService());
}
/**
* {@link R2dbcConnectionDetails} backed by a {@code mssql} {@link RunningService}.
*/
static class SqlServerR2dbcDockerComposeConnectionDetails extends DockerComposeConnectionDetails
implements R2dbcConnectionDetails {
private static final ConnectionFactoryOptionsBuilder connectionFactoryOptionsBuilder = new ConnectionFactoryOptionsBuilder(
"mssql", 1433);
private final ConnectionFactoryOptions connectionFactoryOptions;
SqlServerR2dbcDockerComposeConnectionDetails(RunningService service) {
super(service);
SqlServerEnvironment environment = new SqlServerEnvironment(service.env());
this.connectionFactoryOptions = connectionFactoryOptionsBuilder.build(service, "",
environment.getUsername(), environment.getPassword());
}
@Override
public ConnectionFactoryOptions getConnectionFactoryOptions() {
return this.connectionFactoryOptions;
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Docker Compose MS SQL Server service connections.
*/
package org.springframework.boot.docker.compose.service.connection.sqlserver;

View File

@@ -1,14 +1,7 @@
# Connection Details Factories
org.springframework.boot.autoconfigure.service.connection.ConnectionDetailsFactory=\
org.springframework.boot.docker.compose.service.connection.clickhouse.ClickHouseR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.mariadb.MariaDbR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.mysql.MySqlR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.oracle.OracleFreeR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.oracle.OracleXeR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryLoggingDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryMetricsDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.otlp.OpenTelemetryTracingDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.postgres.PostgresR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.redis.RedisDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.sqlserver.SqlServerR2dbcDockerComposeConnectionDetailsFactory,\
org.springframework.boot.docker.compose.service.connection.zipkin.ZipkinDockerComposeConnectionDetailsFactory

View File

@@ -1,84 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.clickhouse;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link ClickHouseEnvironment}.
*
* @author Stephane Nicoll
*/
class ClickHouseEnvironmentTests {
@Test
void createWhenNoPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new ClickHouseEnvironment(Collections.emptyMap()))
.withMessage("No ClickHouse password found");
}
@Test
void getPasswordWhenHasPassword() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "true"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getPasswordWhenHasNoPasswordAndAllowEmptyPasswordIsYes() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getUsernameWhenNoUser() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("default");
}
@Test
void getUsernameWhenHasUser() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(
Map.of("CLICKHOUSE_USER", "me", "CLICKHOUSE_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("me");
}
@Test
void getDatabaseWhenNoDatabase() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(Map.of("CLICKHOUSE_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("default");
}
@Test
void getDatabaseWhenHasDatabase() {
ClickHouseEnvironment environment = new ClickHouseEnvironment(
Map.of("CLICKHOUSE_DB", "db", "CLICKHOUSE_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
}

View File

@@ -1,176 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mariadb;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link MariaDbEnvironment}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Jinseong Hwang
* @author Scott Frederick
*/
class MariaDbEnvironmentTests {
@Test
void createWhenHasMariadbRandomRootPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_RANDOM_ROOT_PASSWORD", "true")))
.withMessage("MARIADB_RANDOM_ROOT_PASSWORD is not supported");
}
@Test
void createWhenHasMysqlRandomRootPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true")))
.withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported");
}
@Test
void createWhenHasMariadbRootPasswordHashThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_ROOT_PASSWORD_HASH", "0FF")))
.withMessage("MARIADB_ROOT_PASSWORD_HASH is not supported");
}
@Test
void createWhenHasNoPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Collections.emptyMap()))
.withMessage("No MariaDB password found");
}
@Test
void createWhenHasNoDatabaseThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new MariaDbEnvironment(Map.of("MARIADB_PASSWORD", "secret")))
.withMessage("No MARIADB_DATABASE defined");
}
@Test
void getUsernameWhenHasMariadbUser() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("myself");
}
@Test
void getUsernameWhenHasMysqlUser() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MYSQL_USER", "myself", "MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("myself");
}
@Test
void getUsernameWhenHasMariadbUserAndMysqlUser() {
MariaDbEnvironment environment = new MariaDbEnvironment(Map.of("MARIADB_USER", "myself", "MYSQL_USER", "me",
"MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("myself");
}
@Test
void getUsernameWhenHasNoMariadbUserOrMysqlUser() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("root");
}
@Test
void getPasswordWhenHasMariadbPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMysqlPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MYSQL_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMysqlRootPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MYSQL_ROOT_PASSWORD", "secret", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMariadbPasswordAndMysqlPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_PASSWORD", "secret", "MYSQL_PASSWORD", "donttell", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMariadbPasswordAndMysqlRootPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_PASSWORD", "secret", "MYSQL_ROOT_PASSWORD", "donttell", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getPasswordWhenHasNoPasswordAndMariadbAllowEmptyPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getDatabaseWhenHasMariadbDatabase() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
@Test
void getDatabaseWhenHasMysqlDatabase() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
@Test
void getDatabaseWhenHasMariadbAndMysqlDatabase() {
MariaDbEnvironment environment = new MariaDbEnvironment(
Map.of("MARIADB_ALLOW_EMPTY_PASSWORD", "true", "MARIADB_DATABASE", "db", "MYSQL_DATABASE", "otherdb"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright 2012-2024 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.mysql;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link MySqlEnvironment}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Jinseong Hwang
* @author Scott Frederick
*/
class MySqlEnvironmentTests {
@Test
void createWhenHasMysqlRandomRootPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_RANDOM_ROOT_PASSWORD", "true")))
.withMessage("MYSQL_RANDOM_ROOT_PASSWORD is not supported");
}
@Test
void createWhenHasNoPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Collections.emptyMap()))
.withMessage("No MySQL password found");
}
@Test
void createWhenHasNoDatabaseThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret")))
.withMessage("No MYSQL_DATABASE defined");
}
@Test
void getUsernameWhenHasMysqlUser() {
MySqlEnvironment environment = new MySqlEnvironment(
Map.of("MYSQL_USER", "myself", "MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("myself");
}
@Test
void getUsernameWhenHasNoMysqlUser() {
MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
assertThat(environment.getUsername()).isEqualTo("root");
}
@Test
void getPasswordWhenHasMysqlPassword() {
MySqlEnvironment environment = new MySqlEnvironment(Map.of("MYSQL_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMysqlRootPassword() {
MySqlEnvironment environment = new MySqlEnvironment(
Map.of("MYSQL_ROOT_PASSWORD", "secret", "MYSQL_DATABASE", "db"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasNoPasswordAndMysqlAllowEmptyPassword() {
MySqlEnvironment environment = new MySqlEnvironment(
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() {
MySqlEnvironment environment = new MySqlEnvironment(
Map.of("ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getDatabaseWhenHasMysqlDatabase() {
MySqlEnvironment environment = new MySqlEnvironment(
Map.of("MYSQL_ALLOW_EMPTY_PASSWORD", "true", "MYSQL_DATABASE", "db"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
}

View File

@@ -1,115 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.oracle;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatNoException;
/**
* Tests for {@link OracleEnvironment}.
*
* @author Andy Wilkinson
*/
class OracleEnvironmentTests {
@Test
void getUsernameWhenHasAppUser() {
OracleEnvironment environment = new OracleEnvironment(
Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb");
assertThat(environment.getUsername()).isEqualTo("alice");
}
@Test
void getUsernameWhenHasNoAppUser() {
OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb");
assertThat(environment.getUsername()).isEqualTo("system");
}
@Test
void getPasswordWhenHasAppPassword() {
OracleEnvironment environment = new OracleEnvironment(
Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret"), "defaultDb");
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasOraclePassword() {
OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb");
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void createWhenRandomPasswordAndAppPasswordDoesNotThrow() {
assertThatNoException().isThrownBy(() -> new OracleEnvironment(
Map.of("APP_USER", "alice", "APP_USER_PASSWORD", "secret", "ORACLE_RANDOM_PASSWORD", "true"),
"defaultDb"));
}
@Test
void createWhenRandomPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_RANDOM_PASSWORD", "true"), "defaultDb"))
.withMessage("ORACLE_RANDOM_PASSWORD is not supported without APP_USER and APP_USER_PASSWORD");
}
@Test
void createWhenAppUserAndNoAppPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice"), "defaultDb"))
.withMessage("No Oracle app password found");
}
@Test
void createWhenAppUserAndEmptyAppPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new OracleEnvironment(Map.of("APP_USER", "alice", "APP_USER_PASSWORD", ""), "defaultDb"))
.withMessage("No Oracle app password found");
}
@Test
void createWhenHasNoPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new OracleEnvironment(Collections.emptyMap(), "defaultDb"))
.withMessage("No Oracle password found");
}
@Test
void createWhenHasEmptyPasswordThrowsException() {
assertThatIllegalStateException()
.isThrownBy(() -> new OracleEnvironment(Map.of("ORACLE_PASSWORD", ""), "defaultDb"))
.withMessage("No Oracle password found");
}
@Test
void getDatabaseWhenHasNoOracleDatabase() {
OracleEnvironment environment = new OracleEnvironment(Map.of("ORACLE_PASSWORD", "secret"), "defaultDb");
assertThat(environment.getDatabase()).isEqualTo("defaultDb");
}
@Test
void getDatabaseWhenHasOracleDatabase() {
OracleEnvironment environment = new OracleEnvironment(
Map.of("ORACLE_PASSWORD", "secret", "ORACLE_DATABASE", "db"), "defaultDb");
assertThat(environment.getDatabase()).isEqualTo("db");
}
}

View File

@@ -1,156 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link PostgresEnvironment}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
* @author Scott Frederick
* @author Sidmar Theodoro
* @author He Zean
*/
class PostgresEnvironmentTests {
@Test
void createWhenNoPostgresPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new PostgresEnvironment(Collections.emptyMap()))
.withMessage("No PostgreSQL password found");
}
@Test
void getUsernameWhenNoPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("postgres");
}
@Test
void getUsernameWhenNoPostgresqlUser() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("postgres");
}
@Test
void getUsernameWhenHasPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("me");
}
@Test
void getUsernameWhenHasPostgresqlUser() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("me");
}
@Test
void getUsernameWhenHasPostgresqlUsername() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("me");
}
@Test
void getPasswordWhenHasPostgresPassword() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasPostgresqlPassword() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasTrustHostAuthMethod() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_HOST_AUTH_METHOD", "trust"));
assertThat(environment.getPassword()).isNull();
}
@Test
void getPasswordWhenHasNoPasswordAndAllowEmptyPassword() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("ALLOW_EMPTY_PASSWORD", "yes"));
assertThat(environment.getPassword()).isEmpty();
}
@Test
void getDatabaseWhenNoPostgresDbOrPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRES_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("postgres");
}
@Test
void getDatabaseWhenNoPostgresqlDbOrPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(Map.of("POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("postgres");
}
@Test
void getDatabaseWhenNoPostgresDbAndPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRES_USER", "me", "POSTGRES_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("me");
}
@Test
void getDatabaseWhenNoPostgresqlDbAndPostgresUser() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_USER", "me", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("me");
}
@Test
void getDatabaseWhenNoPostgresqlDatabaseAndPostgresqlUsername() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_USERNAME", "me", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("me");
}
@Test
void getDatabaseWhenHasPostgresDb() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRES_DB", "db", "POSTGRES_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
@Test
void getDatabaseWhenHasPostgresqlDb() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_DB", "db", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
@Test
void getDatabaseWhenHasPostgresqlDatabase() {
PostgresEnvironment environment = new PostgresEnvironment(
Map.of("POSTGRESQL_DATABASE", "db", "POSTGRESQL_PASSWORD", "secret"));
assertThat(environment.getDatabase()).isEqualTo("db");
}
}

View File

@@ -1,119 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.postgres;
import java.util.LinkedHashMap;
import java.util.Map;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.junit.jupiter.api.Test;
import org.springframework.boot.docker.compose.core.ConnectionPorts;
import org.springframework.boot.docker.compose.core.RunningService;
import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for
* {@link PostgresR2dbcDockerComposeConnectionDetailsFactory.PostgresDbR2dbcDockerComposeConnectionDetails}.
*
* @author Dmytro Nosan
*/
class PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests {
private static final Option<String> APPLICATION_NAME = Option.valueOf("applicationName");
private final RunningService service = mock(RunningService.class);
private final MockEnvironment environment = new MockEnvironment();
private final Map<String, String> labels = new LinkedHashMap<>();
PostgresR2dbcDockerComposeConnectionDetailsFactoryConnectionDetailsTests() {
given(this.service.env())
.willReturn(Map.of("POSTGRES_USER", "myuser", "POSTGRES_PASSWORD", "secret", "POSTGRES_DB", "mydatabase"));
given(this.service.labels()).willReturn(this.labels);
ConnectionPorts connectionPorts = mock(ConnectionPorts.class);
given(this.service.ports()).willReturn(connectionPorts);
given(this.service.host()).willReturn("localhost");
given(connectionPorts.get(5432)).willReturn(30001);
}
@Test
void createConnectionDetails() {
ConnectionFactoryOptions options = getConnectionFactoryOptions();
assertConnectionFactoryOptions(options);
assertThat(options.getValue(APPLICATION_NAME)).isNull();
}
@Test
void createConnectionDetailsWithLabels() {
this.labels.put("org.springframework.boot.r2dbc.parameters",
"connectTimeout=PT15S,applicationName=spring-boot");
ConnectionFactoryOptions options = getConnectionFactoryOptions();
assertConnectionFactoryOptions(options);
assertThat(options.getRequiredValue(ConnectionFactoryOptions.CONNECT_TIMEOUT)).isEqualTo("PT15S");
assertThat(options.getRequiredValue(APPLICATION_NAME)).isEqualTo("spring-boot");
}
@Test
void createConnectionDetailsWithApplicationNameLabelTakesPrecedence() {
this.labels.put("org.springframework.boot.r2dbc.parameters", "applicationName=spring-boot");
this.environment.setProperty("spring.application.name", "my-app");
ConnectionFactoryOptions options = getConnectionFactoryOptions();
assertConnectionFactoryOptions(options);
assertThat(options.getRequiredValue(APPLICATION_NAME)).isEqualTo("spring-boot");
}
@Test
void createConnectionDetailsWithSpringApplicationName() {
this.environment.setProperty("spring.application.name", "spring boot");
ConnectionFactoryOptions options = getConnectionFactoryOptions();
assertConnectionFactoryOptions(options);
assertThat(options.getRequiredValue(APPLICATION_NAME)).isEqualTo("spring boot");
}
@Test
void createConnectionDetailsAppendSpringApplicationName() {
this.labels.put("org.springframework.boot.r2dbc.parameters", "connectTimeout=PT15S");
this.environment.setProperty("spring.application.name", "my-app");
ConnectionFactoryOptions options = getConnectionFactoryOptions();
assertConnectionFactoryOptions(options);
assertThat(options.getRequiredValue(ConnectionFactoryOptions.CONNECT_TIMEOUT)).isEqualTo("PT15S");
assertThat(options.getRequiredValue(APPLICATION_NAME)).isEqualTo("my-app");
}
private void assertConnectionFactoryOptions(ConnectionFactoryOptions options) {
assertThat(options.getRequiredValue(ConnectionFactoryOptions.HOST)).isEqualTo("localhost");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.PORT)).isEqualTo(30001);
assertThat(options.getRequiredValue(ConnectionFactoryOptions.DATABASE)).isEqualTo("mydatabase");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.USER)).isEqualTo("myuser");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.PASSWORD)).isEqualTo("secret");
assertThat(options.getRequiredValue(ConnectionFactoryOptions.DRIVER)).isEqualTo("postgresql");
}
private ConnectionFactoryOptions getConnectionFactoryOptions() {
return new PostgresR2dbcDockerComposeConnectionDetailsFactory.PostgresDbR2dbcDockerComposeConnectionDetails(
this.service, this.environment)
.getConnectionFactoryOptions();
}
}

View File

@@ -1,107 +0,0 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.r2dbc;
import java.util.Collections;
import java.util.Map;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.Option;
import org.junit.jupiter.api.Test;
import org.springframework.boot.docker.compose.core.ConnectionPorts;
import org.springframework.boot.docker.compose.core.RunningService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ConnectionFactoryOptionsBuilder}.
*
* @author Moritz Halbritter
* @author Andy Wilkinson
* @author Phillip Webb
*/
class ConnectionFactoryOptionsBuilderTests {
private ConnectionFactoryOptionsBuilder builder = new ConnectionFactoryOptionsBuilder("mydb", 1234);
@Test
void createWhenDriverProtocolIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> new ConnectionFactoryOptionsBuilder(null, 123))
.withMessage("'driver' must not be null");
}
@Test
void buildBuildsOptions() {
RunningService service = mockService(456);
ConnectionFactoryOptions options = this.builder.build(service, "mydb", "user", "pass");
assertThat(options).isEqualTo(ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DATABASE, "mydb")
.option(ConnectionFactoryOptions.HOST, "myhost")
.option(ConnectionFactoryOptions.PORT, 456)
.option(ConnectionFactoryOptions.DRIVER, "mydb")
.option(ConnectionFactoryOptions.PASSWORD, "pass")
.option(ConnectionFactoryOptions.USER, "user")
.build());
}
@Test
void buildWhenHasParamsLabelBuildsOptions() {
RunningService service = mockService(456, Map.of("org.springframework.boot.r2dbc.parameters", "foo=bar"));
ConnectionFactoryOptions options = this.builder.build(service, "mydb", "user", "pass");
assertThat(options).isEqualTo(ConnectionFactoryOptions.builder()
.option(ConnectionFactoryOptions.DATABASE, "mydb")
.option(ConnectionFactoryOptions.HOST, "myhost")
.option(ConnectionFactoryOptions.PORT, 456)
.option(ConnectionFactoryOptions.DRIVER, "mydb")
.option(ConnectionFactoryOptions.PASSWORD, "pass")
.option(ConnectionFactoryOptions.USER, "user")
.option(Option.valueOf("foo"), "bar")
.build());
}
@Test
void buildWhenServiceIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() -> this.builder.build(null, "mydb", "user", "pass"))
.withMessage("'service' must not be null");
}
@Test
void buildWhenDatabaseIsNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.builder.build(mockService(456), null, "user", "pass"))
.withMessage("'database' must not be null");
}
private RunningService mockService(int mappedPort) {
return mockService(mappedPort, Collections.emptyMap());
}
private RunningService mockService(int mappedPort, Map<String, String> labels) {
RunningService service = mock(RunningService.class);
ConnectionPorts ports = mock(ConnectionPorts.class);
given(ports.get(1234)).willReturn(mappedPort);
given(service.host()).willReturn("myhost");
given(service.ports()).willReturn(ports);
given(service.labels()).willReturn(labels);
return service;
}
}

View File

@@ -1,65 +0,0 @@
/*
* Copyright 2012-2023 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.docker.compose.service.connection.sqlserver;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link SqlServerEnvironment}.
*
* @author Andy Wilkinson
*/
class SqlServerEnvironmentTests {
@Test
void createWhenHasNoPasswordThrowsException() {
assertThatIllegalStateException().isThrownBy(() -> new SqlServerEnvironment(Collections.emptyMap()))
.withMessage("No MSSQL password found");
}
@Test
void getUsernameWhenHasNoMsSqlUser() {
SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret"));
assertThat(environment.getUsername()).isEqualTo("SA");
}
@Test
void getPasswordWhenHasMsSqlSaPassword() {
SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("MSSQL_SA_PASSWORD", "secret"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasSaPassword() {
SqlServerEnvironment environment = new SqlServerEnvironment(Map.of("SA_PASSWORD", "secret"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
@Test
void getPasswordWhenHasMsSqlSaPasswordAndSaPasswordPrefersMsSqlSaPassword() {
SqlServerEnvironment environment = new SqlServerEnvironment(
Map.of("MSSQL_SA_PASSWORD", "secret", "SA_PASSWORD", "not used"));
assertThat(environment.getPassword()).isEqualTo("secret");
}
}