diff --git a/dbclient/dbclient/src/main/java/io/helidon/dbclient/DbClient.java b/dbclient/dbclient/src/main/java/io/helidon/dbclient/DbClient.java index 64e9bbd35..87f98477a 100644 --- a/dbclient/dbclient/src/main/java/io/helidon/dbclient/DbClient.java +++ b/dbclient/dbclient/src/main/java/io/helidon/dbclient/DbClient.java @@ -57,10 +57,17 @@ public interface DbClient { */ > T execute(Function executor); + /** + * Name of the named statement used in database health checks. + */ + String PING_STATEMENT_NAME = "ping"; + /** * Pings the database, completes when DB is up and ready, completes exceptionally if not. + * Executes simple SQL query defined as {@code db.statements.ping} configuration property. * * @return stage that completes when the ping finished + * @deprecated Use {@code io.helidon.dbclient.health.DbClientHealthCheck} instead. */ Single ping(); diff --git a/dbclient/health/src/main/java/io/helidon/dbclient/health/DbClientHealthCheck.java b/dbclient/health/src/main/java/io/helidon/dbclient/health/DbClientHealthCheck.java index 7ad22e00a..d97579a48 100644 --- a/dbclient/health/src/main/java/io/helidon/dbclient/health/DbClientHealthCheck.java +++ b/dbclient/health/src/main/java/io/helidon/dbclient/health/DbClientHealthCheck.java @@ -16,7 +16,10 @@ package io.helidon.dbclient.health; import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import io.helidon.common.reactive.Awaitable; import io.helidon.dbclient.DbClient; import org.eclipse.microprofile.health.HealthCheck; @@ -26,18 +29,16 @@ import org.eclipse.microprofile.health.HealthCheckResponseBuilder; /** * Database health check. */ -public final class DbClientHealthCheck implements HealthCheck { +public abstract class DbClientHealthCheck implements HealthCheck { - private final DbClient dbClient; - private final String name; - - private DbClientHealthCheck(Builder builder) { - this.dbClient = builder.database; - this.name = builder.name; - } + /* Local logger instance. */ + private static final Logger LOGGER = Logger.getLogger(DbClientHealthCheck.class.getName()); + /* Default hHealth check timeout in seconds (to wait for statement execution response). */ + private static final int DEFAULT_TIMEOUT_SECONDS = 10; /** - * Create a health check for the database. + * Create a health check with default settings for the database. + * This health check will execute DML statement named {@code ping} to verify database status. * * @param dbClient A database that implements {@link io.helidon.dbclient.DbClient#ping()} * @return health check that can be used with @@ -58,39 +59,220 @@ public final class DbClientHealthCheck implements HealthCheck { return new Builder(dbClient); } + /* Helidon database client. */ + private final DbClient dbClient; + /* Health check name. */ + private final String name; + /* Health check timeout length (to wait for statement execution response). */ + private final long timeoutDuration; + /* Health check timeout units (to wait for statement execution response). */ + private final TimeUnit timeoutUnit; + + private DbClientHealthCheck(Builder builder) { + this.dbClient = builder.database; + this.name = builder.name; + this.timeoutDuration = builder.timeoutDuration; + this.timeoutUnit = builder.timeoutUnit; + } + + /** + * Execute the ping statement. + * + * @return {@code Awaitable} instance to wait for + */ + protected abstract Awaitable execPing(); + @Override public HealthCheckResponse call() { - HealthCheckResponseBuilder builder = HealthCheckResponse.builder() - .name(name); + HealthCheckResponseBuilder builder = HealthCheckResponse.builder().name(name); try { - dbClient.ping().await(10, TimeUnit.SECONDS); + execPing().await(timeoutDuration, timeoutUnit); builder.up(); } catch (Throwable e) { builder.down(); builder.withData("ErrorMessage", e.getMessage()); builder.withData("ErrorClass", e.getClass().getName()); - e.printStackTrace(); + LOGGER.log(Level.FINER, e, () -> String.format( + "Database %s is not responding: %s", dbClient.dbType(), e.getMessage())); } return builder.build(); } + protected DbClient dbClient() { + return dbClient; + } + + /** + * Database health check which calls default DBClient's {@code ping} method. + */ + private static final class DbClientHealthCheckAsPing extends DbClientHealthCheck { + + private DbClientHealthCheckAsPing(Builder builder) { + super(builder); + LOGGER.finest("Created an instance of DbClientHealthCheckAsPing"); + } + + @Override + protected Awaitable execPing() { + return dbClient().ping(); + } + + } + + /** + * Database health check which calls DBClient's {@code namedDml} method. + */ + private static final class DbClientHealthCheckAsNamedDml extends DbClientHealthCheck { + + /* Name of the statement. */ + private final String statementName; + + private DbClientHealthCheckAsNamedDml(Builder builder) { + super(builder); + this.statementName = builder.statementName; + LOGGER.finest("Created an instance of DbClientHealthCheckAsNamedDml"); + } + + @Override + protected Awaitable execPing() { + return dbClient().execute(exec -> exec.namedDml(statementName)); + } + + } + + /** + * Database health check which calls DBClient's {@code dml} method. + */ + private static final class DbClientHealthCheckAsDml extends DbClientHealthCheck { + + /* Custom statement. */ + private final String statement; + + private DbClientHealthCheckAsDml(Builder builder) { + super(builder); + this.statement = builder.statement; + LOGGER.finest("Created an instance of DbClientHealthCheckAsDml"); + } + + @Override + protected Awaitable execPing() { + return dbClient().execute(exec -> exec.dml(statement)); + } + + } + + /** + * Database health check which calls DBClient's {@code namedQuery} method. + */ + private static final class DbClientHealthCheckAsNamedQuery extends DbClientHealthCheck { + + /* Name of the statement. */ + private final String statementName; + + private DbClientHealthCheckAsNamedQuery(Builder builder) { + super(builder); + this.statementName = builder.statementName; + LOGGER.finest("Created an instance of DbClientHealthCheckAsNamedQuery"); + } + + @Override + protected Awaitable execPing() { + return dbClient() + .execute(exec -> exec.namedQuery(statementName).forEach(it -> {})); + } + + } + + /** + * Database health check which calls DBClient's {@code query} method. + */ + private static final class DbClientHealthCheckAsQuery extends DbClientHealthCheck { + + /* Custom statement. */ + private final String statement; + + private DbClientHealthCheckAsQuery(Builder builder) { + super(builder); + this.statement = builder.statement; + LOGGER.finest("Created an instance of DbClientHealthCheckAsQuery"); + } + + @Override + protected Awaitable execPing() { + return dbClient() + .execute(exec -> exec.query(statement).forEach(it -> {})); + } + + } + /** * Fluent API builder for {@link DbClientHealthCheck}. + * Default health check setup will call named DML statement with name {@code ping}. + * This named DML statement shall be configured in {@code statements} section + * of the DBClient configuration file. */ public static final class Builder implements io.helidon.common.Builder { + + /* Helidon database client. */ private final DbClient database; + /* Health check name. */ private String name; + /* Health check timeout length (to wait for statement execution response). */ + private long timeoutDuration; + /* Health check timeout units (to wait for statement execution response). */ + private TimeUnit timeoutUnit; + + // Those two boolean variables define 4 ways of query execution: + // + // +-----------+----------+--------+------------+-------+ + // | DbExecute | namedDML | dml | namedQuery | query | + // +-----------+----------+--------+------------+-------+ + // | isDML | true | true | false | false | + // | named | true | faslse | true | false | + // +-----------+----------+--------+------------+-------+ + // The best performance optimized solution seems to be polymorphysm for part of check method. + + /* Health check statement is DML when {@code true} and query when {@code false}. */ + private boolean isDML; + /* Whether to use named statement or statement passed as an argument. */ + private boolean isNamedstatement; + + /** Name of the statement. */ + private String statementName; + /** Custom statement. */ + private String statement; private Builder(DbClient database) { this.database = database; this.name = database.dbType(); + this.timeoutDuration = DEFAULT_TIMEOUT_SECONDS; + this.timeoutUnit = TimeUnit.SECONDS; + this.isDML = true; + this.isNamedstatement = true; + this.statementName = null; + this.statement = null; } + // Defines polymorphysm for ping statement execution based on isDML and isNamedstatement values. + // Default health check is to call DBClient's ping method (when no customization is set). @Override public DbClientHealthCheck build() { - return new DbClientHealthCheck(this); + if (isDML) { + if (isNamedstatement) { + return statementName == null + ? new DbClientHealthCheckAsPing(this) : new DbClientHealthCheckAsNamedDml(this); + } else { + return new DbClientHealthCheckAsDml(this); + } + } else { + if (isNamedstatement && statementName == null) { + statementName = DbClient.PING_STATEMENT_NAME; + } + return isNamedstatement + ? new DbClientHealthCheckAsNamedQuery(this) : new DbClientHealthCheckAsQuery(this); + } } /** @@ -104,6 +286,66 @@ public final class DbClientHealthCheck implements HealthCheck { this.name = name; return this; } + + /** + * Set health check statement type to query. + * Default health check statement type is DML. + * + * @return updated builder instance + */ + public Builder query() { + this.isDML = false; + this.isNamedstatement = true; + return this; + } + + /** + * Set custom statement name. + * Default statement name value is {@code ping}. + * + * @param name custom statement name. + * @return updated builder instance + */ + public Builder statementName(String name) { + if (statement != null) { + throw new UnsupportedOperationException( + "Can't use both statementName and statement methods in a single builder instance!"); + } + this.isNamedstatement = true; + this.statementName = name; + return this; + } + + /** + * Set custom statement. + * + * @param statement custom statement name. + * @return updated builder instance + */ + public Builder statement(String statement) { + if (statementName != null) { + throw new UnsupportedOperationException( + "Can't use both statementName and statement methods in a single builder instance!"); + } + this.isNamedstatement = false; + this.statement = statement; + return this; + } + + /** + * Set custom timeout to wait for statement execution response. + * Default value is {@code 10} seconds. + * + * @param duration the maximum time to wait for statement execution response + * @param timeUnit the time unit of the timeout argument + * @return updated builder instance + */ + public Builder timeout(long duration, TimeUnit timeUnit) { + this.timeoutDuration = duration; + this.timeoutUnit = timeUnit; + return this; + } + } } diff --git a/dbclient/jdbc/src/main/java/io/helidon/dbclient/jdbc/JdbcDbClient.java b/dbclient/jdbc/src/main/java/io/helidon/dbclient/jdbc/JdbcDbClient.java index 98f511188..9a0930cb9 100644 --- a/dbclient/jdbc/src/main/java/io/helidon/dbclient/jdbc/JdbcDbClient.java +++ b/dbclient/jdbc/src/main/java/io/helidon/dbclient/jdbc/JdbcDbClient.java @@ -149,12 +149,12 @@ class JdbcDbClient implements DbClient { @Override public T apply(Throwable t) { LOGGER.log(level, - String.format("Transaction rollback: %s", t.getMessage()), - t); + t, + () -> String.format("Transaction rollback: %s", t.getMessage())); execute.doRollback().exceptionally(t2 -> { LOGGER.log(level, - String.format("Transaction rollback failed: %s", t2.getMessage()), - t2); + t2, + () -> String.format("Transaction rollback failed: %s", t2.getMessage())); return null; }); return null; @@ -190,8 +190,8 @@ class JdbcDbClient implements DbClient { execute.close(); }).exceptionally(throwable -> { LOGGER.log(Level.WARNING, - String.format("Execution failed: %s", throwable.getMessage()), - throwable); + throwable, + () -> String.format("Execution failed: %s", throwable.getMessage())); execute.close(); return null; }); @@ -199,8 +199,8 @@ class JdbcDbClient implements DbClient { result = result.onError(throwable -> { LOGGER.log(Level.FINEST, - String.format("Execution failed: %s", throwable.getMessage()), - throwable); + throwable, + () -> String.format("Execution failed: %s", throwable.getMessage())); execute.close(); }); @@ -209,7 +209,7 @@ class JdbcDbClient implements DbClient { @Override public Single ping() { - return execute(exec -> exec.namedUpdate("ping")) + return execute(exec -> exec.namedUpdate(PING_STATEMENT_NAME)) .flatMapSingle(it -> Single.empty()); } @@ -372,7 +372,7 @@ class JdbcDbClient implements DbClient { try { conn.close(); } catch (SQLException e) { - LOGGER.log(Level.WARNING, String.format("Could not close connection: %s", e.getMessage()), e); + LOGGER.log(Level.WARNING, e, () -> String.format("Could not close connection: %s", e.getMessage())); } }); } diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 28cf8d10c..b04b53245 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -79,6 +79,7 @@ 1.1.6 5.6.2 4.12 + 2.6.2 2.10 1.4 2.2 @@ -93,6 +94,7 @@ 1.0.1 2.23.4 1.11.0 + 8.4.1.jre8 19.3.0.0 8.0.11 5.9.3.Final @@ -103,6 +105,7 @@ 0.2.1 0.1.8 2.2.3 + 42.2.16 0.9.0 1.0.3 1.7.26 @@ -782,6 +785,21 @@ mysql-connector-java ${version.lib.mysql-connector-java} + + org.mariadb.jdbc + mariadb-java-client + ${version.lib.mariadb-java-client} + + + org.postgresql + postgresql + ${version.lib.postgresql} + + + com.microsoft.sqlserver + mssql-jdbc + ${version.lib.mssql-jdbc} + com.oracle.oci.sdk oci-java-sdk-objectstorage diff --git a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/AbstractIT.java b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/AbstractIT.java index 3ad47dd35..1cf1560ed 100644 --- a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/AbstractIT.java +++ b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/AbstractIT.java @@ -1,5 +1,3 @@ -package io.helidon.tests.integration.dbclient.common; - /* * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. * @@ -15,11 +13,13 @@ package io.helidon.tests.integration.dbclient.common; * See the License for the specific language governing permissions and * limitations under the License. */ +package io.helidon.tests.integration.dbclient.common; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.logging.Logger; import io.helidon.config.Config; @@ -36,10 +36,15 @@ public abstract class AbstractIT { /** Local logger instance. */ private static final Logger LOGGER = Logger.getLogger(AbstractIT.class.getName()); - public static final Config CONFIG = Config.create(ConfigSources.classpath("test.yaml")); + public static final Config CONFIG = Config.create(ConfigSources.classpath(ConfigIT.configFile())); public static final DbClient DB_CLIENT = initDbClient(); + /** + * Initialize database client. + * + * @return database client instance + */ public static DbClient initDbClient() { Config dbConfig = CONFIG.get("db"); return DbClient.builder(dbConfig).build(); diff --git a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/ConfigIT.java b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/ConfigIT.java new file mode 100644 index 000000000..39dc5d669 --- /dev/null +++ b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/ConfigIT.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. + * + * 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 + * + * http://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 io.helidon.tests.integration.dbclient.common; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Configuration utilities. + */ +public class ConfigIT { + + /** Local logger instance. */ + private static final Logger LOGGER = Logger.getLogger(ConfigIT.class.getName()); + + private static final String CONFIG_PROPERTY_NAME="io.helidon.tests.integration.dbclient.config"; + + private static final String DEFAULT_CONFIG_FILE="test.yaml"; + + /** + * Retrieve configuration file from {@code io.helidon.tests.integration.dbclient.config} + * property if exists. + * Default {@code test.yaml} value is used when no property is set. + * + * @return tests configuration file name + */ + public static String configFile() { + String configFile = System.getProperty(CONFIG_PROPERTY_NAME, DEFAULT_CONFIG_FILE); + LOGGER.info(() -> String.format("Configuration file: %s", configFile)); + return configFile; + } + +} diff --git a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/HealthCheckIT.java b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/HealthCheckIT.java index a9b68405b..fd9a04197 100644 --- a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/HealthCheckIT.java +++ b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/HealthCheckIT.java @@ -15,13 +15,20 @@ */ package io.helidon.tests.integration.dbclient.common.tests.health; +import java.util.logging.Level; +import java.util.logging.Logger; + +import io.helidon.config.Config; import io.helidon.dbclient.health.DbClientHealthCheck; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import static io.helidon.tests.integration.dbclient.common.AbstractIT.CONFIG; import static io.helidon.tests.integration.dbclient.common.AbstractIT.DB_CLIENT; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; @@ -30,12 +37,31 @@ import static org.hamcrest.Matchers.equalTo; */ public class HealthCheckIT { + /** Local logger instance. */ + private static final Logger LOGGER = Logger.getLogger(HealthCheckIT.class.getName()); + + private static boolean pingDml = true; + + @BeforeAll + public static void setup() { + Config cfgPingDml = CONFIG.get("test.ping-dml"); + pingDml = cfgPingDml.exists() ? cfgPingDml.asBoolean().get() : true; + } + /** - * Verify health BASIC check implementation. + * Verify health check implementation with default settings. */ @Test public void testHealthCheck() { - HealthCheck check = DbClientHealthCheck.create(DB_CLIENT); + LOGGER.log(Level.INFO, "Running test testHealthCheck"); + HealthCheck check; + if (!pingDml) { + LOGGER.log(Level.INFO, () -> String.format("Database %s does not support DML ping, using query", DB_CLIENT.dbType())); + check = DbClientHealthCheck.builder(DB_CLIENT).query().build(); + } else { + LOGGER.log(Level.INFO, () -> String.format("Database %s supports DML ping, using default method", DB_CLIENT.dbType())); + check = DbClientHealthCheck.create(DB_CLIENT); + } HealthCheckResponse response = check.call(); HealthCheckResponse.State state = response.getState(); assertThat("Healthcheck failed, response: " + response.getData(), state, equalTo(HealthCheckResponse.State.UP)); @@ -46,8 +72,16 @@ public class HealthCheckIT { */ @Test public void testHealthCheckWithName() { + LOGGER.log(Level.INFO, "Running test testHealthCheckWithName"); final String hcName = "TestHC"; - HealthCheck check = DbClientHealthCheck.builder(DB_CLIENT).name(hcName).build(); + HealthCheck check; + if (!pingDml) { + LOGGER.log(Level.INFO, () -> String.format("Database %s does not support DML ping, using query", DB_CLIENT.dbType())); + check = DbClientHealthCheck.builder(DB_CLIENT).name(hcName).query().build(); + } else { + LOGGER.log(Level.INFO, () -> String.format("Database %s supports DML ping, using default method", DB_CLIENT.dbType())); + check = DbClientHealthCheck.builder(DB_CLIENT).name(hcName).build(); + } HealthCheckResponse response = check.call(); String name = response.getName(); HealthCheckResponse.State state = response.getState(); @@ -55,4 +89,71 @@ public class HealthCheckIT { assertThat(state, equalTo(HealthCheckResponse.State.UP)); } + /** + * Verify health check implementation using custom DML named statement. + */ + @Test + public void testHealthCheckWithCustomNamedDML() { + LOGGER.log(Level.INFO, "Running test testHealthCheckWithCustomNamedDML"); + if (!pingDml) { + LOGGER.log(Level.INFO, () -> String.format("Database %s does not support DML ping, skipping this test", DB_CLIENT.dbType())); + return; + } + HealthCheck check = DbClientHealthCheck.builder(DB_CLIENT).statementName("ping-dml").build(); + HealthCheckResponse response = check.call(); + HealthCheckResponse.State state = response.getState(); + assertThat("Healthcheck failed, response: " + response.getData(), state, equalTo(HealthCheckResponse.State.UP)); + } + + /** + * Verify health check implementation using custom DML statement. + */ + @Test + public void testHealthCheckWithCustomDML() { + LOGGER.log(Level.INFO, "Running test testHealthCheckWithCustomDML"); + if (!pingDml) { + LOGGER.log(Level.INFO, () -> String.format("Database %s does not support DML ping, skipping this test", DB_CLIENT.dbType())); + return; + } + Config cfgStatement = CONFIG.get("db.statements.ping-dml"); + assertThat("Missing ping-dml statement in database configuration!", cfgStatement.exists(), equalTo(true)); + String statement = cfgStatement.asString().get(); + assertThat("Missing ping-dml statement String in database configuration!", statement, is(notNullValue())); + LOGGER.log(Level.INFO, () -> String.format("Using db.statements.ping-dml value %s", statement)); + HealthCheck check = DbClientHealthCheck.builder(DB_CLIENT).statement(statement).build(); + HealthCheckResponse response = check.call(); + HealthCheckResponse.State state = response.getState(); + assertThat("Healthcheck failed, response: " + response.getData(), state, equalTo(HealthCheckResponse.State.UP)); + } + + /** + * Verify health check implementation using custom query named statement. + */ + @Test + public void testHealthCheckWithCustomNamedQuery() { + LOGGER.log(Level.INFO, "Running test testHealthCheckWithCustomNamedQuery"); + HealthCheck check = DbClientHealthCheck.builder(DB_CLIENT).query().statementName("ping-query").build(); + HealthCheckResponse response = check.call(); + HealthCheckResponse.State state = response.getState(); + assertThat("Healthcheck failed, response: " + response.getData(), state, equalTo(HealthCheckResponse.State.UP)); + } + + /** + * Verify health check implementation using custom query statement. + */ + @Test + public void testHealthCheckWithCustomQuery() { + LOGGER.log(Level.INFO, "Running test testHealthCheckWithCustomQuery"); + Config cfgStatement = CONFIG.get("db.statements.ping-query"); + assertThat("Missing ping-query statement in database configuration!", cfgStatement.exists(), equalTo(true)); + String statement = cfgStatement.asString().get(); + assertThat("Missing ping-query statement String in database configuration!", statement, is(notNullValue())); + LOGGER.log(Level.INFO, () -> String.format("Using db.statements.ping-query value %s", statement)); + HealthCheck check = DbClientHealthCheck.builder(DB_CLIENT).query().statement(statement).build(); + HealthCheckResponse response = check.call(); + HealthCheckResponse.State state = response.getState(); + assertThat("Healthcheck failed, response: " + response.getData(), state, equalTo(HealthCheckResponse.State.UP)); + } + + } diff --git a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/ServerHealthCheckIT.java b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/ServerHealthCheckIT.java index 53654fac3..5717240cb 100644 --- a/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/ServerHealthCheckIT.java +++ b/tests/integration/dbclient/common/src/main/java/io/helidon/tests/integration/dbclient/common/tests/health/ServerHealthCheckIT.java @@ -34,12 +34,14 @@ import javax.json.JsonValue; import javax.json.stream.JsonParsingException; import io.helidon.common.reactive.Multi; +import io.helidon.config.Config; import io.helidon.dbclient.DbRow; import io.helidon.dbclient.health.DbClientHealthCheck; import io.helidon.health.HealthSupport; import io.helidon.webserver.Routing; import io.helidon.webserver.WebServer; +import org.eclipse.microprofile.health.HealthCheck; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -63,8 +65,13 @@ public class ServerHealthCheckIT { private static String URL; private static Routing createRouting() { + Config cfgPingDml = CONFIG.get("test.ping-dml"); + boolean pingDml = cfgPingDml.exists() ? cfgPingDml.asBoolean().get() : true; + HealthCheck check = pingDml + ? DbClientHealthCheck.create(DB_CLIENT) + : DbClientHealthCheck.builder(DB_CLIENT).query().build(); final HealthSupport health = HealthSupport.builder() - .addLiveness(DbClientHealthCheck.create(DB_CLIENT)) + .addLiveness(check) .build(); return Routing.builder() .register(health) // Health at "/health" diff --git a/tests/integration/dbclient/jdbc/pom.xml b/tests/integration/dbclient/jdbc/pom.xml index 98f4442ee..36465cbae 100644 --- a/tests/integration/dbclient/jdbc/pom.xml +++ b/tests/integration/dbclient/jdbc/pom.xml @@ -32,12 +32,6 @@ Integration Tests: DB Client JDBC - 3306 - 127.0.0.1 - pokemon - user - password - root @@ -72,11 +66,6 @@ slf4j-jdk14 test - - mysql - mysql-connector-java - test - org.junit.jupiter junit-jupiter-api @@ -97,12 +86,31 @@ + + + + io.fabric8 + docker-maven-plugin + 0.33.0 + + + org.apache.maven.plugins + maven-surefire-plugin + ${version.plugin.surefire} + + + org.apache.maven.plugins + maven-failsafe-plugin + ${version.plugin.surefire} + + + + org.apache.maven.plugins maven-surefire-plugin - ${version.plugin.surefire} true @@ -111,7 +119,6 @@ org.apache.maven.plugins maven-failsafe-plugin - ${version.plugin.surefire} methods 10 @@ -126,7 +133,8 @@ - io.helidon.tests.integration.dbclient.jdbc.init.*IT + io.helidon.tests.integration.dbclient.jdbc.init.CheckIT + io.helidon.tests.integration.dbclient.jdbc.init.InitIT @@ -174,6 +182,315 @@ + + mysql + + + mysql + + + + 3306 + 127.0.0.1 + pokemon + user + password + root + + + + mysql + mysql-connector-java + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + mysql.yaml + + + + + io.fabric8 + docker-maven-plugin + + + + mysql:8 + mysql + + + ${db.user} + ${db.password} + ${db.roootpw} + ${db.database} + + ${db.host} + + ${db.host}:${db.port}:3306 + + + MySQL server is up an running + + 127.0.0.1 + + ${db.port} + + + + + + + + true + false + + + + + + + mariadb + + + mariadb + + + + 3306 + 127.0.0.1 + pokemon + user + password + root + + + + org.mariadb.jdbc + mariadb-java-client + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + mariadb.yaml + + + + + io.fabric8 + docker-maven-plugin + + + + mariadb + mariadb + + + ${db.user} + ${db.password} + ${db.roootpw} + ${db.database} + + ${db.host} + + ${db.host}:${db.port}:3306 + + + MySQL server is up an running + + 127.0.0.1 + + ${db.port} + + + + + + + + true + false + + + + + + + pgsql + + + pgsql + + + + 5432 + 127.0.0.1 + pokemon + user + password + + + + org.postgresql + postgresql + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + pgsql.yaml + + + + + io.fabric8 + docker-maven-plugin + + + + postgres + postgres + + + ${db.user} + ${db.password} + ${db.database} + + ${db.host} + + ${db.host}:${db.port}:5432 + + + MySQL server is up an running + + 127.0.0.1 + + ${db.port} + + + + + + + + true + false + + + + + + + mssql + + + mssql + + + + Y + MsH4sN0r00t + 1433 + 127.0.0.1 + pokemon + test_user + P4ss_W0rd + + + + com.microsoft.sqlserver + mssql-jdbc + test + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + mssql.yaml + + + + + io.fabric8 + docker-maven-plugin + + + + mcr.microsoft.com/mssql/server:2017-latest + mssql + + + ${accept.eula} + ${db.sa.password} + + ${db.host} + + ${db.host}:${db.port}:1433 + + + SQL server is up an running + + 127.0.0.1 + + ${db.port} + + + + + + + + true + false + + + + org.apache.maven.plugins + maven-failsafe-plugin + + methods + 10 + + + + + init + integration-test + + integration-test + + + + io.helidon.tests.integration.dbclient.jdbc.init.CheckMsSqlIT + io.helidon.tests.integration.dbclient.jdbc.init.InitIT + + + + + + + +