Skip to content

Commit

Permalink
Provide a way to push container properties to database dev services
Browse files Browse the repository at this point in the history
  • Loading branch information
gsmet committed Jan 5, 2022
1 parent f7279c9 commit 0e772ad
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 18 deletions.
17 changes: 16 additions & 1 deletion docs/src/main/asciidoc/datasource.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,22 @@ mcr.microsoft.com/mssql/server:2017-CU12

[NOTE]
====
All services based on containers are ran using `testcontainers`. Even though extra URL properties can be set in your `application.properties` file, specific `testcontainers` properties such as `TC_INITSCRIPT`, `TC_INITFUNCTION`, `TC_DAEMON`, `TC_TMPFS` are not supported.
All services based on containers are run using Testcontainers but Quarkus is not using the Testcontainers JDBC driver.
Thus, even though extra JDBC URL properties can be set in your `application.properties` file,
specific properties supported by the Testcontainers JDBC driver such as `TC_INITSCRIPT`, `TC_INITFUNCTION`, `TC_DAEMON`, `TC_TMPFS` are not supported.
Quarkus can support specific properties sent to the container itself though and,
typically, this is the case for `TC_MY_CNF` which allows to override the MariaDB/MySQL configuration file.
Overriding the MariaDB/MySQL configuration would be done as follows:
[source,properties]
----
quarkus.datasource.devservices.container-properties.TC_MY_CNF=testcontainers/mysql-conf
----
This support is database specific and needs to be implemented in each dev service specifically.
====

=== JDBC datasource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ public interface DevServicesDatasourceProvider {

RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName,
Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> imageName,
Map<String, String> containerProperties,
Map<String, String> additionalJdbcUrlProperties,
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout);

default boolean isDockerRequired() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ private DevServicesDatasourceResultBuildItem.DbResult startDevDb(String dbName,
.startDatabase(ConfigProvider.getConfig().getOptionalValue(prefix + "username", String.class),
ConfigProvider.getConfig().getOptionalValue(prefix + "password", String.class),
Optional.ofNullable(dbName), dataSourceBuildTimeConfig.devservices.imageName,
dataSourceBuildTimeConfig.devservices.containerProperties,
dataSourceBuildTimeConfig.devservices.properties,
dataSourceBuildTimeConfig.devservices.port, launchMode, globalDevServicesConfig.timeout);
closeableList.add(datasource.getCloseTask());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ public class DevServicesBuildTimeConfig {
@ConfigItem
public Optional<String> imageName;

/**
* Generic properties that are passed for additional container configuration.
* <p>
* Properties defined here are database specific and are interpreted specifically in each database dev service
* implementation.
*/
@ConfigItem
public Map<String, String> containerProperties;

/**
* Generic properties that are added to the database connection URL.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,16 @@ DevServicesDatasourceProviderBuildItem setupDB2(
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DB2, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusDb2Container container = new QuarkusDb2Container(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);
additionalJdbcUrlProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for IBM Db2 started.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ DevServicesDatasourceProviderBuildItem setupDerby() {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DERBY, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
int port = fixedExposedPort.isPresent() ? fixedExposedPort.getAsInt()
Expand All @@ -57,7 +58,7 @@ public RunningDevServicesDatasource startDatabase(Optional<String> username, Opt
LOG.info("Dev Services for Derby started.");

StringBuilder additionalArgs = new StringBuilder();
for (Map.Entry<String, String> i : additionalProperties.entrySet()) {
for (Map.Entry<String, String> i : additionalJdbcUrlProperties.entrySet()) {
additionalArgs.append(";");
additionalArgs.append(i.getKey());
additionalArgs.append("=");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ DevServicesDatasourceProviderBuildItem setupH2() {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.H2, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt port, LaunchMode launchMode, Optional<Duration> startupTimeout) {
try {
final Server tcpServer = Server.createTcpServer("-tcpPort",
port.isPresent() ? String.valueOf(port.getAsInt()) : "0");
tcpServer.start();

StringBuilder additionalArgs = new StringBuilder();
for (Map.Entry<String, String> i : additionalProperties.entrySet()) {
for (Map.Entry<String, String> i : additionalJdbcUrlProperties.entrySet()) {
additionalArgs.append(";");
additionalArgs.append(i.getKey());
additionalArgs.append("=");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,29 @@ public class MariaDBDevServicesProcessor {

public static final String TAG = "10.5.9";
public static final Integer PORT = 3306;
public static final String MY_CNF_CONFIG_OVERRIDE_PARAM_NAME = "TC_MY_CNF";

@BuildStep
DevServicesDatasourceProviderBuildItem setupMariaDB(
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MARIADB, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusMariaDBContainer container = new QuarkusMariaDBContainer(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);

if (containerProperties.containsKey(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME)) {
container.withConfigurationOverride(containerProperties.get(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME));
}

additionalJdbcUrlProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for MariaDB started.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ DevServicesDatasourceProviderBuildItem setupMSSQL(
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MSSQL, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusMSSQLServerContainer container = new QuarkusMSSQLServerContainer(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("Quarkuspassword1"));
additionalProperties.forEach(container::withUrlParam);
additionalJdbcUrlProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for Microsoft SQL Server started.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,30 @@ public class MySQLDevServicesProcessor {
private static final Logger LOG = Logger.getLogger(MySQLDevServicesProcessor.class);

public static final String TAG = "8.0.24";
public static final String MY_CNF_CONFIG_OVERRIDE_PARAM_NAME = "TC_MY_CNF";

@BuildStep
DevServicesDatasourceProviderBuildItem setupMysql(
List<DevServicesSharedNetworkBuildItem> devServicesSharedNetworkBuildItem) {
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MYSQL, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusMySQLContainer container = new QuarkusMySQLContainer(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);

if (containerProperties.containsKey(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME)) {
container.withConfigurationOverride(containerProperties.get(MY_CNF_CONFIG_OVERRIDE_PARAM_NAME));
}

additionalJdbcUrlProperties.forEach(container::withUrlParam);

container.start();

LOG.info("Dev Services for MySQL started.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,16 @@ DevServicesDatasourceProviderBuildItem setupOracle(
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.ORACLE, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusOracleServerContainer container = new QuarkusOracleServerContainer(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withUsername(username.orElse(DEFAULT_DATABASE_USER))
.withPassword(password.orElse(DEFAULT_DATABASE_PASSWORD))
.withDatabaseName(datasourceName.orElse(DEFAULT_DATABASE_NAME));
additionalProperties.forEach(container::withUrlParam);
additionalJdbcUrlProperties.forEach(container::withUrlParam);
container.start();

LOG.info("Dev Services for Oracle started.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,16 @@ DevServicesDatasourceProviderBuildItem setupPostgres(
return new DevServicesDatasourceProviderBuildItem(DatabaseKind.POSTGRESQL, new DevServicesDatasourceProvider() {
@Override
public RunningDevServicesDatasource startDatabase(Optional<String> username, Optional<String> password,
Optional<String> datasourceName, Optional<String> imageName, Map<String, String> additionalProperties,
Optional<String> datasourceName, Optional<String> imageName,
Map<String, String> containerProperties, Map<String, String> additionalJdbcUrlProperties,
OptionalInt fixedExposedPort, LaunchMode launchMode, Optional<Duration> startupTimeout) {
QuarkusPostgreSQLContainer container = new QuarkusPostgreSQLContainer(imageName, fixedExposedPort,
!devServicesSharedNetworkBuildItem.isEmpty());
startupTimeout.ifPresent(container::withStartupTimeout);
container.withPassword(password.orElse("quarkus"))
.withUsername(username.orElse("quarkus"))
.withDatabaseName(datasourceName.orElse("default"));
additionalProperties.forEach(container::withUrlParam);
additionalJdbcUrlProperties.forEach(container::withUrlParam);

container.start();

Expand Down

0 comments on commit 0e772ad

Please sign in to comment.