From f5736ea5b286df0ffff7fc6865e3408b7103b8b7 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Wed, 5 May 2021 16:25:26 +0200 Subject: [PATCH] Allow defining a fixed port for datasource DevServices Fixes #16768 (cherry picked from commit ba938cecc2dc79b4f8f50b2f0314e8f1ec134ef4) --- .../spi/DevServicesDatasourceProvider.java | 4 +++- .../DevServicesDatasourceProcessor.java | 3 ++- .../runtime/DevServicesBuildTimeConfig.java | 9 +++++++++ .../deployment/DB2DevServicesProcessor.java | 20 ++++++++++++++----- .../deployment/DerbyDevServicesProcessor.java | 13 ++++++++---- .../deployment/H2DevServicesProcessor.java | 7 +++++-- .../MariaDBDevServicesProcessor.java | 20 ++++++++++++++----- .../deployment/MSSQLDevServicesProcessor.java | 16 ++++++++++++--- .../deployment/MySQLDevServicesProcessor.java | 20 ++++++++++++++----- .../PostgresqlDevServicesProcessor.java | 20 ++++++++++++++----- 10 files changed, 101 insertions(+), 31 deletions(-) diff --git a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceProvider.java b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceProvider.java index 2a320aa324f44..d75cc80c05cb5 100644 --- a/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceProvider.java +++ b/extensions/datasource/deployment-spi/src/main/java/io/quarkus/datasource/deployment/spi/DevServicesDatasourceProvider.java @@ -3,12 +3,14 @@ import java.io.Closeable; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; public interface DevServicesDatasourceProvider { RunningDevServicesDatasource startDatabase(Optional username, Optional password, Optional datasourceName, - Optional imageName, Map additionalProperties); + Optional imageName, Map additionalProperties, + OptionalInt port); class RunningDevServicesDatasource { diff --git a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java index 31ab21817b8a0..a6e04447276bc 100644 --- a/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java +++ b/extensions/datasource/deployment/src/main/java/io/quarkus/datasource/deployment/devservices/DevServicesDatasourceProcessor.java @@ -217,7 +217,8 @@ 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.properties); + dataSourceBuildTimeConfig.devservices.properties, + dataSourceBuildTimeConfig.devservices.port); closeableList.add(datasource.getCloseTask()); Map devDebProperties = new HashMap<>(); diff --git a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevServicesBuildTimeConfig.java b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevServicesBuildTimeConfig.java index f681c427eba6a..eaa93be6f7ae8 100644 --- a/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevServicesBuildTimeConfig.java +++ b/extensions/datasource/runtime/src/main/java/io/quarkus/datasource/runtime/DevServicesBuildTimeConfig.java @@ -2,6 +2,7 @@ import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import io.quarkus.runtime.annotations.ConfigGroup; import io.quarkus.runtime.annotations.ConfigItem; @@ -32,4 +33,12 @@ public class DevServicesBuildTimeConfig { */ @ConfigItem public Map properties; + + /** + * Optional fixed port the dev service will listen to. + *

+ * If not defined, the port will be chosen randomly. + */ + @ConfigItem + public OptionalInt port; } diff --git a/extensions/devservices/db2/src/main/java/io/quarkus/devservices/db2/deployment/DB2DevServicesProcessor.java b/extensions/devservices/db2/src/main/java/io/quarkus/devservices/db2/deployment/DB2DevServicesProcessor.java index 4bcf2264dee6e..ca5711f07983c 100644 --- a/extensions/devservices/db2/src/main/java/io/quarkus/devservices/db2/deployment/DB2DevServicesProcessor.java +++ b/extensions/devservices/db2/src/main/java/io/quarkus/devservices/db2/deployment/DB2DevServicesProcessor.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.testcontainers.containers.Db2Container; import org.testcontainers.utility.DockerImageName; @@ -25,13 +26,22 @@ DevServicesDatasourceProviderBuildItem setupDB2() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DB2, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { Db2Container container = new Db2Container( DockerImageName.parse(imageName.orElse("ibmcom/db2:" + TAG)) - .asCompatibleSubstituteFor(DockerImageName.parse("ibmcom/db2"))) - .withPassword(password.orElse("quarkus")) - .withUsername(username.orElse("quarkus")) - .withDatabaseName(datasourceName.orElse("default")); + .asCompatibleSubstituteFor(DockerImageName.parse("ibmcom/db2"))) { + @Override + protected void configure() { + super.configure(); + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.getAsInt(), DB2_PORT); + } + }; + } + .withPassword(password.orElse("quarkus")) + .withUsername(username.orElse("quarkus")) + .withDatabaseName(datasourceName.orElse("default")); additionalProperties.forEach(container::withUrlParam); container.start(); return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(), diff --git a/extensions/devservices/derby/src/main/java/io/quarkus/devservices/postgresql/deployment/DerbyDevServicesProcessor.java b/extensions/devservices/derby/src/main/java/io/quarkus/devservices/postgresql/deployment/DerbyDevServicesProcessor.java index d6de868ab047d..dd5e8602ae21b 100644 --- a/extensions/devservices/derby/src/main/java/io/quarkus/devservices/postgresql/deployment/DerbyDevServicesProcessor.java +++ b/extensions/devservices/derby/src/main/java/io/quarkus/devservices/postgresql/deployment/DerbyDevServicesProcessor.java @@ -3,8 +3,10 @@ import java.io.Closeable; import java.io.IOException; import java.io.PrintWriter; +import java.net.InetAddress; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.apache.derby.drda.NetworkServerControl; @@ -23,9 +25,11 @@ DevServicesDatasourceProviderBuildItem setupDerby() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.DERBY, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { try { - NetworkServerControl server = new NetworkServerControl(); + int port = fixedExposedPort.isPresent() ? fixedExposedPort.getAsInt() : 1527; + NetworkServerControl server = new NetworkServerControl(InetAddress.getByName("localhost"), port); server.start(new PrintWriter(System.out)); for (int i = 1; i <= NUMBER_OF_PINGS; i++) { try { @@ -52,7 +56,7 @@ public RunningDevServicesDatasource startDatabase(Optional username, Opt additionalArgs.append(i.getValue()); } return new RunningDevServicesDatasource( - "jdbc:derby://localhost:1527/memory:" + datasourceName.orElse("quarkus") + ";create=true" + "jdbc:derby://localhost:" + port + "/memory:" + datasourceName.orElse("quarkus") + ";create=true" + additionalArgs.toString(), null, null, @@ -60,7 +64,8 @@ public RunningDevServicesDatasource startDatabase(Optional username, Opt @Override public void close() throws IOException { try { - NetworkServerControl server = new NetworkServerControl(); + NetworkServerControl server = new NetworkServerControl( + InetAddress.getByName("localhost"), port); server.shutdown(); System.out.println("[INFO] Derby database was shut down"); } catch (Exception e) { diff --git a/extensions/devservices/h2/src/main/java/io/quarkus/devservices/postgresql/deployment/H2DevServicesProcessor.java b/extensions/devservices/h2/src/main/java/io/quarkus/devservices/postgresql/deployment/H2DevServicesProcessor.java index 729e5fe190578..762e53492e1ac 100644 --- a/extensions/devservices/h2/src/main/java/io/quarkus/devservices/postgresql/deployment/H2DevServicesProcessor.java +++ b/extensions/devservices/h2/src/main/java/io/quarkus/devservices/postgresql/deployment/H2DevServicesProcessor.java @@ -8,6 +8,7 @@ import java.sql.Statement; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.h2.tools.Server; @@ -23,9 +24,11 @@ DevServicesDatasourceProviderBuildItem setupH2() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.H2, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt port) { try { - final Server tcpServer = Server.createTcpServer("-tcpPort", "0"); + final Server tcpServer = Server.createTcpServer("-tcpPort", + port.isPresent() ? String.valueOf(port.getAsInt()) : "0"); tcpServer.start(); StringBuilder additionalArgs = new StringBuilder(); diff --git a/extensions/devservices/mariadb/src/main/java/io/quarkus/devservices/postgresql/deployment/MariaDBDevServicesProcessor.java b/extensions/devservices/mariadb/src/main/java/io/quarkus/devservices/postgresql/deployment/MariaDBDevServicesProcessor.java index 88b61c87d69dc..cf993f100c76c 100644 --- a/extensions/devservices/mariadb/src/main/java/io/quarkus/devservices/postgresql/deployment/MariaDBDevServicesProcessor.java +++ b/extensions/devservices/mariadb/src/main/java/io/quarkus/devservices/postgresql/deployment/MariaDBDevServicesProcessor.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.testcontainers.containers.MariaDBContainer; import org.testcontainers.utility.DockerImageName; @@ -22,13 +23,22 @@ DevServicesDatasourceProviderBuildItem setupMariaDB() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MARIADB, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { MariaDBContainer container = new MariaDBContainer( DockerImageName.parse(imageName.orElse(MariaDBContainer.IMAGE + ":" + TAG)) - .asCompatibleSubstituteFor(DockerImageName.parse(MariaDBContainer.IMAGE))) - .withPassword(password.orElse("quarkus")) - .withUsername(username.orElse("quarkus")) - .withDatabaseName(datasourceName.orElse("default")); + .asCompatibleSubstituteFor(DockerImageName.parse(MariaDBContainer.IMAGE))) { + @Override + protected void configure() { + super.configure(); + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.getAsInt(), 3306); + } + }; + } + .withPassword(password.orElse("quarkus")) + .withUsername(username.orElse("quarkus")) + .withDatabaseName(datasourceName.orElse("default")); additionalProperties.forEach(container::withUrlParam); container.start(); return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(), diff --git a/extensions/devservices/mssql/src/main/java/io/quarkus/devservices/mssql/deployment/MSSQLDevServicesProcessor.java b/extensions/devservices/mssql/src/main/java/io/quarkus/devservices/mssql/deployment/MSSQLDevServicesProcessor.java index ba53402f3e52c..4973c4cc4642c 100644 --- a/extensions/devservices/mssql/src/main/java/io/quarkus/devservices/mssql/deployment/MSSQLDevServicesProcessor.java +++ b/extensions/devservices/mssql/src/main/java/io/quarkus/devservices/mssql/deployment/MSSQLDevServicesProcessor.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.testcontainers.containers.JdbcDatabaseContainer; import org.testcontainers.containers.MSSQLServerContainer; @@ -26,12 +27,21 @@ DevServicesDatasourceProviderBuildItem setupMSSQL() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MSSQL, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { JdbcDatabaseContainer container = new MSSQLServerContainer( DockerImageName .parse(imageName.orElse(MSSQLServerContainer.IMAGE + ":" + TAG)) - .asCompatibleSubstituteFor(MSSQLServerContainer.IMAGE)) - .withPassword(password.orElse("Quarkuspassword1")); + .asCompatibleSubstituteFor(MSSQLServerContainer.IMAGE)) { + @Override + protected void configure() { + super.configure(); + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.getAsInt(), MSSQLServerContainer.MS_SQL_SERVER_PORT); + } + }; + } + .withPassword(password.orElse("Quarkuspassword1")); additionalProperties.forEach(container::withUrlParam); container.start(); return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(), diff --git a/extensions/devservices/mysql/src/main/java/io/quarkus/devservices/postgresql/deployment/MySQLDevServicesProcessor.java b/extensions/devservices/mysql/src/main/java/io/quarkus/devservices/postgresql/deployment/MySQLDevServicesProcessor.java index e1827d0689b4f..706eed8940553 100644 --- a/extensions/devservices/mysql/src/main/java/io/quarkus/devservices/postgresql/deployment/MySQLDevServicesProcessor.java +++ b/extensions/devservices/mysql/src/main/java/io/quarkus/devservices/postgresql/deployment/MySQLDevServicesProcessor.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.testcontainers.containers.MySQLContainer; import org.testcontainers.utility.DockerImageName; @@ -22,13 +23,22 @@ DevServicesDatasourceProviderBuildItem setupMysql() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.MYSQL, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { MySQLContainer container = new MySQLContainer( DockerImageName.parse(imageName.orElse(MySQLContainer.IMAGE + ":" + TAG)) - .asCompatibleSubstituteFor(DockerImageName.parse(MySQLContainer.IMAGE))) - .withPassword(password.orElse("quarkus")) - .withUsername(username.orElse("quarkus")) - .withDatabaseName(datasourceName.orElse("default")); + .asCompatibleSubstituteFor(DockerImageName.parse(MySQLContainer.IMAGE))) { + @Override + protected void configure() { + super.configure(); + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.getAsInt(), MySQLContainer.MYSQL_PORT); + } + }; + } + .withPassword(password.orElse("quarkus")) + .withUsername(username.orElse("quarkus")) + .withDatabaseName(datasourceName.orElse("default")); additionalProperties.forEach(container::withUrlParam); container.start(); return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(), diff --git a/extensions/devservices/postgresql/src/main/java/io/quarkus/devservices/postgresql/deployment/PostgresqlDevServicesProcessor.java b/extensions/devservices/postgresql/src/main/java/io/quarkus/devservices/postgresql/deployment/PostgresqlDevServicesProcessor.java index 674c2e9e687c3..6eee877e897b1 100644 --- a/extensions/devservices/postgresql/src/main/java/io/quarkus/devservices/postgresql/deployment/PostgresqlDevServicesProcessor.java +++ b/extensions/devservices/postgresql/src/main/java/io/quarkus/devservices/postgresql/deployment/PostgresqlDevServicesProcessor.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Map; import java.util.Optional; +import java.util.OptionalInt; import org.testcontainers.containers.PostgreSQLContainer; import org.testcontainers.utility.DockerImageName; @@ -22,13 +23,22 @@ DevServicesDatasourceProviderBuildItem setupPostgres() { return new DevServicesDatasourceProviderBuildItem(DatabaseKind.POSTGRESQL, new DevServicesDatasourceProvider() { @Override public RunningDevServicesDatasource startDatabase(Optional username, Optional password, - Optional datasourceName, Optional imageName, Map additionalProperties) { + Optional datasourceName, Optional imageName, Map additionalProperties, + OptionalInt fixedExposedPort) { PostgreSQLContainer container = new PostgreSQLContainer( DockerImageName.parse(imageName.orElse(PostgreSQLContainer.IMAGE + ":" + TAG)) - .asCompatibleSubstituteFor(DockerImageName.parse(PostgreSQLContainer.IMAGE))) - .withPassword(password.orElse("quarkus")) - .withUsername(username.orElse("quarkus")) - .withDatabaseName(datasourceName.orElse("default")); + .asCompatibleSubstituteFor(DockerImageName.parse(PostgreSQLContainer.IMAGE))) { + @Override + protected void configure() { + super.configure(); + if (fixedExposedPort.isPresent()) { + addFixedExposedPort(fixedExposedPort.getAsInt(), PostgreSQLContainer.POSTGRESQL_PORT); + } + }; + } + .withPassword(password.orElse("quarkus")) + .withUsername(username.orElse("quarkus")) + .withDatabaseName(datasourceName.orElse("default")); additionalProperties.forEach(container::withUrlParam); container.start(); return new RunningDevServicesDatasource(container.getJdbcUrl(), container.getUsername(),