From 399fd88c9ad80ff47ac13d477f5e1717c8a830c1 Mon Sep 17 00:00:00 2001 From: Jacek Date: Tue, 13 Dec 2022 09:26:22 +0100 Subject: [PATCH] SONAR-17762 Allow customization of HikariCP configuration --- .../java/org/sonar/db/DefaultDatabase.java | 16 +++++++- .../org/sonar/db/DefaultDatabaseTest.java | 40 +++++++++++++++---- .../org/sonar/process/ProcessProperties.java | 5 +++ 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java b/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java index 0b1bd78451c..95edd8b312a 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/DefaultDatabase.java @@ -44,10 +44,14 @@ import org.sonar.process.logging.LogbackHelper; import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; import static org.sonar.process.ProcessProperties.Property.JDBC_EMBEDDED_PORT; +import static org.sonar.process.ProcessProperties.Property.JDBC_MAX_IDLE_TIMEOUT; +import static org.sonar.process.ProcessProperties.Property.JDBC_MAX_KEEP_ALIVE_TIME; +import static org.sonar.process.ProcessProperties.Property.JDBC_MAX_LIFETIME; import static org.sonar.process.ProcessProperties.Property.JDBC_MIN_IDLE; import static org.sonar.process.ProcessProperties.Property.JDBC_PASSWORD; import static org.sonar.process.ProcessProperties.Property.JDBC_URL; import static org.sonar.process.ProcessProperties.Property.JDBC_USERNAME; +import static org.sonar.process.ProcessProperties.Property.JDBC_VALIDATION_TIMEOUT; /** * @since 2.12 @@ -76,6 +80,7 @@ public class DefaultDatabase implements Database { SONAR_JDBC_MAX_WAIT, SONAR_JDBC_MAX_ACTIVE, // allowed hikari cp direct properties + // see: https://github.com/brettwooldridge/HikariCP#frequently-used SONAR_JDBC_DRIVER, "sonar.jdbc.dataSource.user", "sonar.jdbc.dataSource.password", @@ -83,7 +88,16 @@ public class DefaultDatabase implements Database { "sonar.jdbc.jdbcUrl", "sonar.jdbc.connectionTimeout", "sonar.jdbc.maximumPoolSize", - "sonar.jdbc.minimumIdle"); + "sonar.jdbc.minimumIdle", + "sonar.jdbc.schema", + JDBC_VALIDATION_TIMEOUT.getKey(), + "sonar.jdbc.catalog", + "sonar.jdbc.initializationFailTimeout", + JDBC_MAX_LIFETIME.getKey(), + "sonar.jdbc.leakDetectionThreshold", + JDBC_MAX_KEEP_ALIVE_TIME.getKey(), + JDBC_MAX_IDLE_TIMEOUT.getKey() + ); private static final Map SONAR_JDBC_TO_HIKARI_PROPERTY_MAPPINGS = Map.of( JDBC_USERNAME.getKey(), "dataSource.user", diff --git a/server/sonar-db-core/src/test/java/org/sonar/db/DefaultDatabaseTest.java b/server/sonar-db-core/src/test/java/org/sonar/db/DefaultDatabaseTest.java index 07488e08e90..46f09ce12ff 100644 --- a/server/sonar-db-core/src/test/java/org/sonar/db/DefaultDatabaseTest.java +++ b/server/sonar-db-core/src/test/java/org/sonar/db/DefaultDatabaseTest.java @@ -62,15 +62,39 @@ public class DefaultDatabaseTest { Properties props = new Properties(); props.setProperty("sonar.jdbc.driverClassName", "my.Driver"); props.setProperty("sonar.jdbc.username", "me"); - props.setProperty("sonar.jdbc.maximumPoolSize", "5"); - props.setProperty("sonar.jdbc.connectionTimeout", "5000"); + props.setProperty("sonar.jdbc.dataSource.password", "my_password"); + props.setProperty("sonar.jdbc.dataSource.portNumber", "9999"); + props.setProperty("sonar.jdbc.connectionTimeout", "8000"); + props.setProperty("sonar.jdbc.maximumPoolSize", "80"); + props.setProperty("sonar.jdbc.minimumIdle", "10"); + props.setProperty("sonar.jdbc.schema", "db-schema"); + props.setProperty("sonar.jdbc.validationTimeout", "5000"); + props.setProperty("sonar.jdbc.catalog", "db-catalog"); + props.setProperty("sonar.jdbc.initializationFailTimeout", "5000"); + props.setProperty("sonar.jdbc.maxLifetime", "1800000"); + props.setProperty("sonar.jdbc.leakDetectionThreshold", "0"); + props.setProperty("sonar.jdbc.keepaliveTime", "30000"); + props.setProperty("sonar.jdbc.idleTimeout", "600000"); Properties hikariProps = DefaultDatabase.extractCommonsHikariProperties(props); - assertThat(hikariProps.getProperty("dataSource.user")).isEqualTo("me"); + assertThat(hikariProps).hasSize(15); assertThat(hikariProps.getProperty("driverClassName")).isEqualTo("my.Driver"); - assertThat(hikariProps.getProperty("maximumPoolSize")).isEqualTo("5"); - assertThat(hikariProps.getProperty("connectionTimeout")).isEqualTo("5000"); + assertThat(hikariProps.getProperty("dataSource.user")).isEqualTo("me"); + assertThat(hikariProps.getProperty("dataSource.password")).isEqualTo("my_password"); + assertThat(hikariProps.getProperty("dataSource.portNumber")).isEqualTo("9999"); + assertThat(hikariProps.getProperty("connectionTimeout")).isEqualTo("8000"); + assertThat(hikariProps.getProperty("maximumPoolSize")).isEqualTo("80"); + assertThat(hikariProps.getProperty("minimumIdle")).isEqualTo("10"); + assertThat(hikariProps.getProperty("schema")).isEqualTo("db-schema"); + assertThat(hikariProps.getProperty("validationTimeout")).isEqualTo("5000"); + assertThat(hikariProps.getProperty("catalog")).isEqualTo("db-catalog"); + assertThat(hikariProps.getProperty("initializationFailTimeout")).isEqualTo("5000"); + assertThat(hikariProps.getProperty("maxLifetime")).isEqualTo("1800000"); + assertThat(hikariProps.getProperty("leakDetectionThreshold")).isEqualTo("0"); + assertThat(hikariProps.getProperty("keepaliveTime")).isEqualTo("30000"); + assertThat(hikariProps.getProperty("idleTimeout")).isEqualTo("600000"); + } @Test @@ -91,7 +115,7 @@ public class DefaultDatabaseTest { } @Test - @UseDataProvider("sonarJdbcAndDbcpProperties") + @UseDataProvider("sonarJdbcAndHikariProperties") public void shouldExtractCommonsDbcpPropertiesIfDuplicatedPropertiesWithSameValue(String jdbcProperty, String dbcpProperty) { Properties props = new Properties(); props.setProperty(jdbcProperty, "100"); @@ -103,7 +127,7 @@ public class DefaultDatabaseTest { } @Test - @UseDataProvider("sonarJdbcAndDbcpProperties") + @UseDataProvider("sonarJdbcAndHikariProperties") public void shouldThrowISEIfDuplicatedResolvedPropertiesWithDifferentValue(String jdbcProperty, String hikariProperty) { Properties props = new Properties(); props.setProperty(jdbcProperty, "100"); @@ -171,7 +195,7 @@ public class DefaultDatabaseTest { } @DataProvider - public static Object[][] sonarJdbcAndDbcpProperties() { + public static Object[][] sonarJdbcAndHikariProperties() { return new Object[][] { {"sonar.jdbc.maxWait", "sonar.jdbc.connectionTimeout"}, {"sonar.jdbc.maxActive", "sonar.jdbc.maximumPoolSize"} diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java index bf712591eae..d575396319f 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java +++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java @@ -57,6 +57,11 @@ public class ProcessProperties { JDBC_MAX_ACTIVE("sonar.jdbc.maxActive", "60"), JDBC_MIN_IDLE("sonar.jdbc.minIdle", "10"), JDBC_MAX_WAIT("sonar.jdbc.maxWait", "8000"), + JDBC_MAX_IDLE_TIMEOUT("sonar.jdbc.idleTimeout", "600000"), + JDBC_MAX_KEEP_ALIVE_TIME("sonar.jdbc.keepaliveTime", "300000"), + JDBC_MAX_LIFETIME("sonar.jdbc.maxLifetime", "1800000"), + JDBC_VALIDATION_TIMEOUT("sonar.jdbc.validationTimeout", "5000"), + JDBC_EMBEDDED_PORT("sonar.embeddedDatabase.port"), PATH_DATA("sonar.path.data", "data"), -- 2.39.5