From 077e3509c1eb86d6ad0376928e0e96110a2722c5 Mon Sep 17 00:00:00 2001 From: tvallin Date: Tue, 6 Feb 2024 15:44:04 +0100 Subject: [PATCH 1/2] Container test Signed-off-by: tvallin --- dependencies/pom.xml | 10 ++ examples/dbclient/jdbc/pom.xml | 29 +++++- .../dbclient/jdbc/JdbcExampleMain.java | 26 +++--- ...t.java => AbstractPokemonServiceTest.java} | 52 +++++++---- .../dbclient/jdbc/PokemonServiceH2IT.java | 58 ++++++++++++ .../dbclient/jdbc/PokemonServiceMySQLIT.java | 58 ++++++++++++ .../src/test/resources/application-test.yaml | 19 ---- examples/dbclient/pokemons/pom.xml | 20 ++++ .../pokemons/AbstractPokemonServiceTest.java | 6 +- .../dbclient/pokemons/PokemonServiceH2IT.java | 61 ++++++++++++ .../pokemons/PokemonServiceMySQLIT.java | 57 ++++++++++++ .../pokemons/PokemonServiceOracleIT.java | 57 ++++++++++++ examples/webserver/opentracing/pom.xml | 45 +++++++++ .../examples/webserver/opentracing/Main.java | 33 ++++--- .../webserver/opentracing/MainTest.java | 93 +++++++++++++++++++ 15 files changed, 551 insertions(+), 73 deletions(-) rename examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/{MainTest.java => AbstractPokemonServiceTest.java} (71%) create mode 100644 examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java create mode 100644 examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java delete mode 100644 examples/dbclient/jdbc/src/test/resources/application-test.yaml create mode 100644 examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java create mode 100644 examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java create mode 100644 examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java create mode 100644 examples/webserver/opentracing/src/test/java/io/helidon/examples/webserver/opentracing/MainTest.java diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 1af13e2b09b..853472ce826 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -1282,6 +1282,16 @@ mongodb ${version.lib.testcontainers} + + org.testcontainers + mysql + ${version.lib.testcontainers} + + + org.testcontainers + oracle-xe + ${version.lib.testcontainers} + org.apache.activemq activemq-kahadb-store diff --git a/examples/dbclient/jdbc/pom.xml b/examples/dbclient/jdbc/pom.xml index dc5ca6787ef..c542312577f 100644 --- a/examples/dbclient/jdbc/pom.xml +++ b/examples/dbclient/jdbc/pom.xml @@ -133,7 +133,22 @@ runtime - com.h2database + org.testcontainers + junit-jupiter + test + + + org.testcontainers + mysql + test + + + com.mysql + mysql-connector-j + test + + + io.helidon.integrations.db h2 test @@ -170,6 +185,18 @@ + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + diff --git a/examples/dbclient/jdbc/src/main/java/io/helidon/examples/dbclient/jdbc/JdbcExampleMain.java b/examples/dbclient/jdbc/src/main/java/io/helidon/examples/dbclient/jdbc/JdbcExampleMain.java index edaf977c45e..1f9caabb06e 100644 --- a/examples/dbclient/jdbc/src/main/java/io/helidon/examples/dbclient/jdbc/JdbcExampleMain.java +++ b/examples/dbclient/jdbc/src/main/java/io/helidon/examples/dbclient/jdbc/JdbcExampleMain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023 Oracle and/or its affiliates. + * Copyright (c) 2019, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import io.helidon.dbclient.health.DbClientHealthCheck; import io.helidon.logging.common.LogConfig; import io.helidon.webserver.WebServer; -import io.helidon.webserver.http.HttpRouting; +import io.helidon.webserver.WebServerConfig; import io.helidon.webserver.observe.ObserveFeature; import io.helidon.webserver.observe.health.HealthObserver; @@ -45,6 +45,13 @@ public static void main(String[] args) { // load logging configuration LogConfig.configureRuntime(); + // Prepare routing for the server + WebServer server = setupServer(WebServer.builder()); + + System.out.println("WEB server is up! http://localhost:" + server.port() + "/"); + } + + static WebServer setupServer(WebServerConfig.Builder builder) { // By default, this will pick up application.yaml from the classpath Config config = Config.global(); @@ -54,22 +61,15 @@ public static void main(String[] args) { ObserveFeature observe = ObserveFeature.builder() .config(config.get("server.features.observe")) .addObserver(HealthObserver.builder() - .addCheck(DbClientHealthCheck.create(dbClient, dbConfig.get("health-check"))) - .build()) + .addCheck(DbClientHealthCheck.create(dbClient, dbConfig.get("health-check"))) + .build()) .build(); - // Prepare routing for the server - WebServer server = WebServer.builder() + return builder .config(config.get("server")) .addFeature(observe) - .routing(routing -> routing(routing, dbClient)) + .routing(routing -> routing.register("/db", new PokemonService(dbClient))) .build() .start(); - - System.out.println("WEB server is up! http://localhost:" + server.port() + "/"); - } - - static void routing(HttpRouting.Builder routing, DbClient dbClient) { - routing.register("/db", new PokemonService(dbClient)); } } diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/MainTest.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/AbstractPokemonServiceTest.java similarity index 71% rename from examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/MainTest.java rename to examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/AbstractPokemonServiceTest.java index 2cd14d978f5..384e7daa133 100644 --- a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/MainTest.java +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/AbstractPokemonServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Oracle and/or its affiliates. + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,14 +19,11 @@ import java.util.List; import java.util.Map; -import io.helidon.config.Config; -import io.helidon.dbclient.DbClient; import io.helidon.http.Status; +import io.helidon.http.media.jsonp.JsonpSupport; import io.helidon.webclient.api.ClientResponseTyped; -import io.helidon.webclient.http1.Http1Client; -import io.helidon.webserver.http.HttpRouting; -import io.helidon.webserver.testing.junit5.ServerTest; -import io.helidon.webserver.testing.junit5.SetUpRoute; +import io.helidon.webclient.api.WebClient; +import io.helidon.webserver.WebServer; import jakarta.json.Json; import jakarta.json.JsonArray; @@ -37,19 +34,22 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; -@ServerTest -public class MainTest { +abstract class AbstractPokemonServiceTest { private static final JsonBuilderFactory JSON_FACTORY = Json.createBuilderFactory(Map.of()); - private final Http1Client client; + private static WebServer server; + private static WebClient client; - MainTest(Http1Client client) { - this.client = client; + static void beforeAll() { + server = JdbcExampleMain.setupServer(WebServer.builder()); + client = WebClient.create(config -> config.baseUri("http://localhost:" + server.port()) + .addMediaSupport(JsonpSupport.create())); } - @SetUpRoute - static void routing(HttpRouting.Builder routing) { - JdbcExampleMain.routing(routing, DbClient.create(Config.global().get("db"))); + static void afterAll() { + if (server != null && server.isRunning()) { + server.stop(); + } } @Test @@ -88,8 +88,8 @@ void testAddUpdateDeletePokemon() { // Get the new pokemon added jsonResponse = client.get("/db/Raticate").request(JsonObject.class); assertThat(jsonResponse.status(), is(Status.OK_200)); - assertThat(jsonResponse.entity().getString("NAME"), is("Raticate")); - assertThat(jsonResponse.entity().getString("TYPE"), is("1")); + assertThat(getName(jsonResponse.entity()), is("Raticate")); + assertThat(getType(jsonResponse.entity()), is("1")); // Update pokemon response = client.put("/db/Raticate/type/2").request(String.class); @@ -98,8 +98,8 @@ void testAddUpdateDeletePokemon() { // Verify updated pokemon jsonResponse = client.get("/db/Raticate").request(JsonObject.class); assertThat(jsonResponse.status(), is(Status.OK_200)); - assertThat(jsonResponse.entity().getString("NAME"), is("Raticate")); - assertThat(jsonResponse.entity().getString("TYPE"), is("2")); + assertThat(getName(jsonResponse.entity()), is("Raticate")); + assertThat(getType(jsonResponse.entity()), is("2")); // Delete Pokemon response = client.delete("/db/Raticate").request(String.class); @@ -113,6 +113,18 @@ void testAddUpdateDeletePokemon() { private List listAllPokemons() { ClientResponseTyped response = client.get("/db").request(JsonArray.class); assertThat(response.status(), is(Status.OK_200)); - return response.entity().stream().map(e -> e.asJsonObject().getString("NAME")).toList(); + return response.entity().stream().map(e -> getName(e.asJsonObject())).toList(); + } + + private String getName(JsonObject json) { + return json.containsKey("name") + ? json.getString("name") + : json.getString("NAME"); + } + + private String getType(JsonObject json) { + return json.containsKey("type") + ? json.getString("type") + : json.getString("TYPE"); } } diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java new file mode 100644 index 00000000000..6335d69d01b --- /dev/null +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.jdbc; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +@Testcontainers(disabledWithoutDocker = true) +class PokemonServiceH2IT extends AbstractPokemonServiceTest { + private static final DockerImageName H2_IMAGE = DockerImageName.parse("nemerosa/h2"); + + @Container + static GenericContainer container = new GenericContainer<>(H2_IMAGE) + .withExposedPorts(9082) + .waitingFor(Wait.forLogMessage("(.*)Web Console server running at(.*)", 1)); + + @BeforeAll + static void start() { + String url = String.format("jdbc:h2:tcp://localhost:%s/~./test", container.getMappedPort(9082)); + Config.global(Config.builder().addSource(ConfigSources.create( + Map.of("db.connection.url", url, + "db.connection.username", "sa", + "db.connection.password", "", + "db.connection.poolName", "h2"))) + .addSource(ConfigSources.create(Config.create())) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } +} diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java new file mode 100644 index 00000000000..b5ed7c2f353 --- /dev/null +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.jdbc; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers(disabledWithoutDocker = true) +class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { + + @Container + static MySQLContainer container = new MySQLContainer<>("mysql:8.0.36") + .withUsername("user") + .withPassword("password") + .withNetworkAliases("mysql") + .withDatabaseName("pokemon"); + + @BeforeAll + static void start() { + Config.global(Config.builder() + .addSource(ConfigSources.create( + Map.of("db.connection.url", container.getJdbcUrl(), + "db.connection.username", "user", + "db.connection.password", "password", + "db.connection.poolName", "mysql"))) + .addSource(ConfigSources.create(Config.create())) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } + +} diff --git a/examples/dbclient/jdbc/src/test/resources/application-test.yaml b/examples/dbclient/jdbc/src/test/resources/application-test.yaml deleted file mode 100644 index 94947bcb9fb..00000000000 --- a/examples/dbclient/jdbc/src/test/resources/application-test.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (c) 2023 Oracle and/or its affiliates. -# -# 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. -# - -db: - connection: - url: jdbc:h2:mem:test diff --git a/examples/dbclient/pokemons/pom.xml b/examples/dbclient/pokemons/pom.xml index ee6acc612c5..520fbe3facc 100644 --- a/examples/dbclient/pokemons/pom.xml +++ b/examples/dbclient/pokemons/pom.xml @@ -139,11 +139,26 @@ mongodb test + + org.testcontainers + mysql + test + + + org.testcontainers + oracle-xe + test + io.helidon.webclient helidon-webclient test + + com.mysql + mysql-connector-j + test + org.junit.jupiter junit-jupiter-api @@ -181,6 +196,11 @@ integration-test verify + + + false + + diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/AbstractPokemonServiceTest.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/AbstractPokemonServiceTest.java index fb36aa3135a..6f51f44de63 100644 --- a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/AbstractPokemonServiceTest.java +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/AbstractPokemonServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Oracle and/or its affiliates. + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,10 @@ import java.util.List; import java.util.Map; -import io.helidon.config.Config; import io.helidon.http.Status; import io.helidon.http.media.jsonp.JsonpSupport; import io.helidon.webclient.api.ClientResponseTyped; import io.helidon.webclient.api.WebClient; -import io.helidon.webclient.http1.Http1Client; import io.helidon.webserver.WebServer; import jakarta.json.Json; @@ -32,8 +30,6 @@ import jakarta.json.JsonObject; import jakarta.json.JsonReader; import jakarta.json.JsonValue; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java new file mode 100644 index 00000000000..262c39afc61 --- /dev/null +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.pokemons; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +/** + * Tests {@link io.helidon.examples.dbclient.pokemons.PokemonService}. + */ +@Testcontainers(disabledWithoutDocker = true) +class PokemonServiceH2IT extends AbstractPokemonServiceTest { + private static final DockerImageName H2_IMAGE = DockerImageName.parse("nemerosa/h2"); + + @Container + static GenericContainer container = new GenericContainer<>(H2_IMAGE) + .withExposedPorts(9082) + .waitingFor(Wait.forLogMessage("(.*)Web Console server running at(.*)", 1)); + + @BeforeAll + static void start() { + String url = String.format("jdbc:h2:tcp://localhost:%s/~./test", container.getMappedPort(9082)); + Config.global(Config.builder().addSource(ConfigSources.create( + Map.of("db.connection.url", url, + "db.connection.username", "sa", + "db.connection.password", "", + "db.connection.poolName", "h2", + "db.statements.health-check", "SELECT 0"))) + .addSource(ConfigSources.create(Config.create())) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } +} diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java new file mode 100644 index 00000000000..2449cff537b --- /dev/null +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023, 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.pokemons; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers(disabledWithoutDocker = true) +public class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { + + @Container + static MySQLContainer container = new MySQLContainer<>("mysql:8.0.36") + .withUsername("user") + .withPassword("password") + .withNetworkAliases("mysql") + .withDatabaseName("pokemon"); + + @BeforeAll + static void start() { + Config.global(Config.builder() + .addSource(ConfigSources.create( + Map.of("db.connection.url", container.getJdbcUrl(), + "db.connection.username", "user", + "db.connection.password", "password", + "db.connection.poolName", "mysql"))) + .addSource(ConfigSources.create(Config.create())) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } + +} diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java new file mode 100644 index 00000000000..7bffa0bc17f --- /dev/null +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.pokemons; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.OracleContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +@Testcontainers(disabledWithoutDocker = true) +public class PokemonServiceOracleIT extends AbstractPokemonServiceTest { + + private static final DockerImageName image = DockerImageName.parse("wnameless/oracle-xe-11g-r2") + .asCompatibleSubstituteFor("gvenzl/oracle-xe"); + + @Container + static OracleContainer container = new OracleContainer(image) + .withExposedPorts(1521, 8080) + .withDatabaseName("XE") + .usingSid() + .waitingFor(Wait.forListeningPorts(1521, 8080)); + + @BeforeAll + static void setup() { + Config.global(Config.builder().addSource(ConfigSources.create( + Map.of("db.connection.url", container.getJdbcUrl()))) + .addSource(ConfigSources.create(Config.create())) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } +} diff --git a/examples/webserver/opentracing/pom.xml b/examples/webserver/opentracing/pom.xml index 1fc175c4b2b..7165d693afb 100644 --- a/examples/webserver/opentracing/pom.xml +++ b/examples/webserver/opentracing/pom.xml @@ -61,6 +61,51 @@ io.helidon.tracing.providers helidon-tracing-providers-zipkin + + io.helidon.logging + helidon-logging-jul + runtime + + + org.testcontainers + junit-jupiter + test + + + org.junit.jupiter + junit-jupiter-api + test + + + io.helidon.webserver.testing.junit5 + helidon-webserver-testing-junit5 + test + + + io.helidon.webclient + helidon-webclient + test + + + org.hamcrest + hamcrest-all + test + + + jakarta.json + jakarta.json-api + test + + + io.helidon.common.testing + helidon-common-testing-junit5 + test + + + io.helidon.http.media + helidon-http-media-jsonp + test + diff --git a/examples/webserver/opentracing/src/main/java/io/helidon/examples/webserver/opentracing/Main.java b/examples/webserver/opentracing/src/main/java/io/helidon/examples/webserver/opentracing/Main.java index 73645237303..3282b3b7612 100644 --- a/examples/webserver/opentracing/src/main/java/io/helidon/examples/webserver/opentracing/Main.java +++ b/examples/webserver/opentracing/src/main/java/io/helidon/examples/webserver/opentracing/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023 Oracle and/or its affiliates. + * Copyright (c) 2017, 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,15 @@ package io.helidon.examples.webserver.opentracing; +import java.util.Map; + import io.helidon.config.Config; import io.helidon.config.ConfigSources; import io.helidon.logging.common.LogConfig; import io.helidon.tracing.Tracer; import io.helidon.tracing.TracerBuilder; import io.helidon.webserver.WebServer; +import io.helidon.webserver.WebServerConfig; import io.helidon.webserver.observe.ObserveFeature; import io.helidon.webserver.observe.tracing.TracingObserver; @@ -46,31 +49,31 @@ public static void main(String[] args) { // configure logging in order to not have the standard JVM defaults LogConfig.configureRuntime(); + WebServer server = setupServer(WebServerConfig.builder(), 9411); + + System.out.println("Started at http://localhost:" + server.port()); + } + + static WebServer setupServer(WebServerConfig.Builder builder, int port) { Config config = Config.builder() - .sources(ConfigSources.environmentVariables()) + .sources(ConfigSources.create(Map.of("host", "localhost", + "port", "8080"))) .build(); - Tracer tracer = TracerBuilder.create(config.get("tracing")) - .serviceName("demo-first") + Tracer tracer = TracerBuilder.create("demo-first") + .collectorPort(port) .registerGlobal(true) .build(); - WebServer server = WebServer.builder() + return builder + .config(config) .addFeature(ObserveFeature.builder() - .addObserver(TracingObserver.create(tracer)) - .build()) + .addObserver(TracingObserver.create(tracer)) + .build()) .routing(routing -> routing - .any((req, res) -> { - System.out.println("Received another request."); - res.next(); - }) .get("/test", (req, res) -> res.send("Hello World!")) .post("/hello", (req, res) -> res.send("Hello: " + req.content().as(String.class)))) - .port(8080) .build() .start(); - - System.out.println("Started at http://localhost:" + server.port()); } - } diff --git a/examples/webserver/opentracing/src/test/java/io/helidon/examples/webserver/opentracing/MainTest.java b/examples/webserver/opentracing/src/test/java/io/helidon/examples/webserver/opentracing/MainTest.java new file mode 100644 index 00000000000..9079fd48cc2 --- /dev/null +++ b/examples/webserver/opentracing/src/test/java/io/helidon/examples/webserver/opentracing/MainTest.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * 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.examples.webserver.opentracing; + +import io.helidon.http.Status; +import io.helidon.http.media.jsonp.JsonpSupport; +import io.helidon.webclient.api.HttpClientResponse; +import io.helidon.webclient.api.WebClient; +import io.helidon.webclient.http1.Http1Client; +import io.helidon.webclient.http1.Http1ClientResponse; +import io.helidon.webserver.WebServer; + +import jakarta.json.JsonArray; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import static io.helidon.common.testing.junit5.MatcherWithRetry.assertThatWithRetry; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@Testcontainers(disabledWithoutDocker = true) +public class MainTest { + private static WebClient client; + private static WebServer server; + private static Http1Client zipkinClient; + + @Container + private static final GenericContainer container = new GenericContainer<>("openzipkin/zipkin") + .withExposedPorts(9411) + .waitingFor(Wait.forHttp("/health").forPort(9411)); + + @BeforeAll + static void checkContainer() { + server = Main.setupServer(WebServer.builder(), container.getMappedPort(9411)); + client = WebClient.create(config -> config.baseUri("http://localhost:" + server.port()) + .addMediaSupport(JsonpSupport.create())); + zipkinClient = Http1Client.create(config -> config + .baseUri("http://localhost:" + container.getMappedPort(9411))); + } + + @AfterAll + static void close() { + if (server != null) { + server.stop(); + } + } + + @Test + void test() { + try (Http1ClientResponse response = zipkinClient.get("/zipkin/api/v2/traces").request()) { + JsonArray array = response.as(JsonArray.class); + assertThat(response.status(), is(Status.OK_200)); + assertThat(array.isEmpty(), is(true)); + } + + try (HttpClientResponse response = client.get("test").request()) { + assertThat(response.status(), is(Status.OK_200)); + assertThat(response.as(String.class), is("Hello World!")); + } + + assertThatWithRetry("Traces must contains service name", + MainTest::getZipkinTraces, containsString("demo-first")); + assertThatWithRetry("Traces must contains pinged endpoint", + MainTest::getZipkinTraces, containsString(client.get("test").uri().toString())); + } + + private static String getZipkinTraces() { + try (Http1ClientResponse response = zipkinClient.get("/zipkin/api/v2/traces").request()) { + assertThat(response.status(), is(Status.OK_200)); + return response.as(String.class); + } + } +} From b7093c7e66c4d64c3b001d791689f292336ec1ad Mon Sep 17 00:00:00 2001 From: tvallin Date: Thu, 8 Feb 2024 13:36:16 +0100 Subject: [PATCH 2/2] refactor tests Signed-off-by: tvallin --- examples/dbclient/jdbc/pom.xml | 9 ++ .../dbclient/jdbc/PokemonServiceH2IT.java | 11 +- .../dbclient/jdbc/PokemonServiceMySQLIT.java | 10 +- .../dbclient/jdbc/PokemonServiceOracleIT.java | 59 +++++++++ .../test/resources/application-h2-test.yaml | 72 +++++++++++ .../resources/application-mysql-test.yaml | 72 +++++++++++ .../resources/application-oracle-test.yaml | 74 ++++++++++++ .../dbclient/pokemons/PokemonServiceH2IT.java | 12 +- .../pokemons/PokemonServiceMongoIT.java | 12 +- .../pokemons/PokemonServiceMySQLIT.java | 10 +- .../pokemons/PokemonServiceOracleIT.java | 8 +- .../test/resources/application-h2-test.yaml | 59 +++++++++ .../resources/application-mongo-test.yaml | 113 ++++++++++++++++++ .../resources/application-mysql-test.yaml | 59 +++++++++ .../resources/application-oracle-test.yaml | 58 +++++++++ 15 files changed, 604 insertions(+), 34 deletions(-) create mode 100644 examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceOracleIT.java create mode 100644 examples/dbclient/jdbc/src/test/resources/application-h2-test.yaml create mode 100644 examples/dbclient/jdbc/src/test/resources/application-mysql-test.yaml create mode 100644 examples/dbclient/jdbc/src/test/resources/application-oracle-test.yaml create mode 100644 examples/dbclient/pokemons/src/test/resources/application-h2-test.yaml create mode 100644 examples/dbclient/pokemons/src/test/resources/application-mongo-test.yaml create mode 100644 examples/dbclient/pokemons/src/test/resources/application-mysql-test.yaml create mode 100644 examples/dbclient/pokemons/src/test/resources/application-oracle-test.yaml diff --git a/examples/dbclient/jdbc/pom.xml b/examples/dbclient/jdbc/pom.xml index c542312577f..c507293a418 100644 --- a/examples/dbclient/jdbc/pom.xml +++ b/examples/dbclient/jdbc/pom.xml @@ -142,6 +142,10 @@ mysql test + + org.testcontainers + oracle-xe + com.mysql mysql-connector-j @@ -194,6 +198,11 @@ integration-test verify + + + false + + diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java index 6335d69d01b..7f5c8dee143 100644 --- a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceH2IT.java @@ -29,6 +29,8 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +import static io.helidon.config.ConfigSources.classpath; + @Testcontainers(disabledWithoutDocker = true) class PokemonServiceH2IT extends AbstractPokemonServiceTest { private static final DockerImageName H2_IMAGE = DockerImageName.parse("nemerosa/h2"); @@ -41,12 +43,9 @@ class PokemonServiceH2IT extends AbstractPokemonServiceTest { @BeforeAll static void start() { String url = String.format("jdbc:h2:tcp://localhost:%s/~./test", container.getMappedPort(9082)); - Config.global(Config.builder().addSource(ConfigSources.create( - Map.of("db.connection.url", url, - "db.connection.username", "sa", - "db.connection.password", "", - "db.connection.poolName", "h2"))) - .addSource(ConfigSources.create(Config.create())) + Config.global(Config.builder() + .addSource(ConfigSources.create(Map.of("db.connection.url", url))) + .addSource(classpath("application-h2-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java index b5ed7c2f353..9326f8461d6 100644 --- a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceMySQLIT.java @@ -27,6 +27,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import static io.helidon.config.ConfigSources.classpath; + @Testcontainers(disabledWithoutDocker = true) class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { @@ -40,12 +42,8 @@ class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { @BeforeAll static void start() { Config.global(Config.builder() - .addSource(ConfigSources.create( - Map.of("db.connection.url", container.getJdbcUrl(), - "db.connection.username", "user", - "db.connection.password", "password", - "db.connection.poolName", "mysql"))) - .addSource(ConfigSources.create(Config.create())) + .addSource(ConfigSources.create(Map.of("db.connection.url", container.getJdbcUrl()))) + .addSource(classpath("application-mysql-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceOracleIT.java b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceOracleIT.java new file mode 100644 index 00000000000..a37525049f5 --- /dev/null +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/PokemonServiceOracleIT.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Oracle and/or its affiliates. + * + * 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.examples.dbclient.jdbc; + +import java.util.Map; + +import io.helidon.config.Config; +import io.helidon.config.ConfigSources; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.testcontainers.containers.OracleContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; +import org.testcontainers.utility.DockerImageName; + +import static io.helidon.config.ConfigSources.classpath; + +@Testcontainers(disabledWithoutDocker = true) +public class PokemonServiceOracleIT extends AbstractPokemonServiceTest { + + private static final DockerImageName image = DockerImageName.parse("wnameless/oracle-xe-11g-r2") + .asCompatibleSubstituteFor("gvenzl/oracle-xe"); + + @Container + static OracleContainer container = new OracleContainer(image) + .withExposedPorts(1521, 8080) + .withDatabaseName("XE") + .usingSid() + .waitingFor(Wait.forListeningPorts(1521, 8080)); + + @BeforeAll + static void start() { + Config.global(Config.builder() + .addSource(ConfigSources.create(Map.of("db.connection.url", container.getJdbcUrl()))) + .addSource(classpath("application-oracle-test.yaml")) + .build()); + beforeAll(); + } + + @AfterAll + static void stop() { + afterAll(); + } +} diff --git a/examples/dbclient/jdbc/src/test/resources/application-h2-test.yaml b/examples/dbclient/jdbc/src/test/resources/application-h2-test.yaml new file mode 100644 index 00000000000..f75ba554c40 --- /dev/null +++ b/examples/dbclient/jdbc/src/test/resources/application-h2-test.yaml @@ -0,0 +1,72 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8079 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +db: + source: jdbc + connection: + username: sa + password: + poolName: h2 + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + health-check: + type: "query" + statementName: "health-check" + services: + tracing: + # would trace all statement names that start with select- + - statement-names: ["select-.*"] + # would trace all delete statements + - statement-types: ["DELETE"] + metrics: + - type: TIMER + errors: false + statement-names: ["select-.*"] + description: "Timer for successful selects" + - type: COUNTER + errors: false + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + name-format: "db.counter.%s.success" + description: "Counter of successful DML statements" + - type: COUNTER + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + success: false + name-format: "db.counter.%s.error" + description: "Counter of failed DML statements" + statements: + health-check: "SELECT 0" + # Insert new pokemon + create-table: "CREATE TABLE pokemons (name VARCHAR(64) NOT NULL PRIMARY KEY, type VARCHAR(32))" + insert1: "INSERT INTO pokemons VALUES(?, ?)" + insert2: "INSERT INTO pokemons VALUES(:name, :type)" + select-by-type: "SELECT * FROM pokemons WHERE type = ?" + select-one: "SELECT * FROM pokemons WHERE name = ?" + select-all: "SELECT * FROM pokemons" + select-for-update: "SELECT * FROM pokemons WHERE name = :name for UPDATE" + update: "UPDATE pokemons SET type = :type WHERE name = :name" + delete: "DELETE FROM pokemons WHERE name = ?" diff --git a/examples/dbclient/jdbc/src/test/resources/application-mysql-test.yaml b/examples/dbclient/jdbc/src/test/resources/application-mysql-test.yaml new file mode 100644 index 00000000000..d271d1a30a4 --- /dev/null +++ b/examples/dbclient/jdbc/src/test/resources/application-mysql-test.yaml @@ -0,0 +1,72 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8079 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +db: + source: jdbc + connection: + username: user + password: password + poolName: mysql + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + health-check: + type: "query" + statementName: "health-check" + services: + tracing: + # would trace all statement names that start with select- + - statement-names: ["select-.*"] + # would trace all delete statements + - statement-types: ["DELETE"] + metrics: + - type: TIMER + errors: false + statement-names: ["select-.*"] + description: "Timer for successful selects" + - type: COUNTER + errors: false + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + name-format: "db.counter.%s.success" + description: "Counter of successful DML statements" + - type: COUNTER + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + success: false + name-format: "db.counter.%s.error" + description: "Counter of failed DML statements" + statements: + health-check: "SELECT 0" + # Insert new pokemon + create-table: "CREATE TABLE pokemons (name VARCHAR(64) NOT NULL PRIMARY KEY, type VARCHAR(32))" + insert1: "INSERT INTO pokemons VALUES(?, ?)" + insert2: "INSERT INTO pokemons VALUES(:name, :type)" + select-by-type: "SELECT * FROM pokemons WHERE type = ?" + select-one: "SELECT * FROM pokemons WHERE name = ?" + select-all: "SELECT * FROM pokemons" + select-for-update: "SELECT * FROM pokemons WHERE name = :name for UPDATE" + update: "UPDATE pokemons SET type = :type WHERE name = :name" + delete: "DELETE FROM pokemons WHERE name = ?" diff --git a/examples/dbclient/jdbc/src/test/resources/application-oracle-test.yaml b/examples/dbclient/jdbc/src/test/resources/application-oracle-test.yaml new file mode 100644 index 00000000000..dd713c0558d --- /dev/null +++ b/examples/dbclient/jdbc/src/test/resources/application-oracle-test.yaml @@ -0,0 +1,74 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8079 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +db: + source: jdbc + connection: + username: "system" + password: "oracle" + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + health-check: + type: "query" + statementName: "health-check" + services: + tracing: + # would trace all statement names that start with select- + - statement-names: ["select-.*"] + # would trace all delete statements + - statement-types: ["DELETE"] + metrics: + - type: TIMER + errors: false + statement-names: ["select-.*"] + description: "Timer for successful selects" + - type: COUNTER + errors: false + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + name-format: "db.counter.%s.success" + description: "Counter of successful DML statements" + - type: COUNTER + statement-types: ["DELETE", "UPDATE", "INSERT", "DML"] + success: false + name-format: "db.counter.%s.error" + description: "Counter of failed DML statements" + statements: + # Health check query statement for MySQL and H2 databases + # health-check: "SELECT 0" + # Health check query statement for Oracle database + health-check: "SELECT 1 FROM DUAL" + # Insert new pokemon + create-table: "CREATE TABLE pokemons (name VARCHAR(64) NOT NULL PRIMARY KEY, type VARCHAR(32))" + insert1: "INSERT INTO pokemons VALUES(?, ?)" + insert2: "INSERT INTO pokemons VALUES(:name, :type)" + select-by-type: "SELECT * FROM pokemons WHERE type = ?" + select-one: "SELECT * FROM pokemons WHERE name = ?" + select-all: "SELECT * FROM pokemons" + select-for-update: "SELECT * FROM pokemons WHERE name = :name for UPDATE" + update: "UPDATE pokemons SET type = :type WHERE name = :name" + delete: "DELETE FROM pokemons WHERE name = ?" diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java index 262c39afc61..25774f1744f 100644 --- a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceH2IT.java @@ -28,6 +28,8 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +import static io.helidon.config.ConfigSources.classpath; + /** * Tests {@link io.helidon.examples.dbclient.pokemons.PokemonService}. */ @@ -43,13 +45,9 @@ class PokemonServiceH2IT extends AbstractPokemonServiceTest { @BeforeAll static void start() { String url = String.format("jdbc:h2:tcp://localhost:%s/~./test", container.getMappedPort(9082)); - Config.global(Config.builder().addSource(ConfigSources.create( - Map.of("db.connection.url", url, - "db.connection.username", "sa", - "db.connection.password", "", - "db.connection.poolName", "h2", - "db.statements.health-check", "SELECT 0"))) - .addSource(ConfigSources.create(Config.create())) + Config.global(Config.builder() + .addSource(ConfigSources.create(Map.of("db.connection.url", url))) + .addSource(classpath("application-h2-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMongoIT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMongoIT.java index 1877eb54d6e..d0013d5657e 100644 --- a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMongoIT.java +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMongoIT.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Oracle and/or its affiliates. + * Copyright (c) 2024 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import static io.helidon.config.ConfigSources.classpath; + @Testcontainers(disabledWithoutDocker = true) public class PokemonServiceMongoIT extends AbstractPokemonServiceTest { @@ -36,11 +38,9 @@ public class PokemonServiceMongoIT extends AbstractPokemonServiceTest { @BeforeAll static void start() { String url = String.format("mongodb://127.0.0.1:%s/pokemon", container.getMappedPort(27017)); - //init-data is false because transactions are not supported - Config.global(Config.builder().addSource(ConfigSources.create( - Map.of("db.connection.url", url, - "db.init-data", "false"))) - .addSource(ConfigSources.classpath("mongo.yaml")) + Config.global(Config.builder() + .addSource(ConfigSources.create(Map.of("db.connection.url", url))) + .addSource(classpath("application-mongo-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java index 2449cff537b..fa79469b3d7 100644 --- a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceMySQLIT.java @@ -26,6 +26,8 @@ import org.testcontainers.junit.jupiter.Container; import org.testcontainers.junit.jupiter.Testcontainers; +import static io.helidon.config.ConfigSources.classpath; + @Testcontainers(disabledWithoutDocker = true) public class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { @@ -39,12 +41,8 @@ public class PokemonServiceMySQLIT extends AbstractPokemonServiceTest { @BeforeAll static void start() { Config.global(Config.builder() - .addSource(ConfigSources.create( - Map.of("db.connection.url", container.getJdbcUrl(), - "db.connection.username", "user", - "db.connection.password", "password", - "db.connection.poolName", "mysql"))) - .addSource(ConfigSources.create(Config.create())) + .addSource(ConfigSources.create(Map.of("db.connection.url", container.getJdbcUrl()))) + .addSource(classpath("application-mysql-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java index 7bffa0bc17f..cf2d4f6d916 100644 --- a/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java +++ b/examples/dbclient/pokemons/src/test/java/io/helidon/examples/dbclient/pokemons/PokemonServiceOracleIT.java @@ -28,6 +28,8 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.testcontainers.utility.DockerImageName; +import static io.helidon.config.ConfigSources.classpath; + @Testcontainers(disabledWithoutDocker = true) public class PokemonServiceOracleIT extends AbstractPokemonServiceTest { @@ -43,9 +45,9 @@ public class PokemonServiceOracleIT extends AbstractPokemonServiceTest { @BeforeAll static void setup() { - Config.global(Config.builder().addSource(ConfigSources.create( - Map.of("db.connection.url", container.getJdbcUrl()))) - .addSource(ConfigSources.create(Config.create())) + Config.global(Config.builder() + .addSource(ConfigSources.create(Map.of("db.connection.url", container.getJdbcUrl()))) + .addSource(classpath("application-oracle-test.yaml")) .build()); beforeAll(); } diff --git a/examples/dbclient/pokemons/src/test/resources/application-h2-test.yaml b/examples/dbclient/pokemons/src/test/resources/application-h2-test.yaml new file mode 100644 index 00000000000..daccc3736a0 --- /dev/null +++ b/examples/dbclient/pokemons/src/test/resources/application-h2-test.yaml @@ -0,0 +1,59 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8080 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +# see README.md for details how to run databases in docker +db: + source: jdbc + connection: + username: sa + password: "${EMPTY}" + poolName: h2 + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + services: + tracing: + - enabled: true + metrics: + - type: TIMER + health-check: + type: "query" + statementName: "health-check" + statements: + health-check: "SELECT 0" + create-types: "CREATE TABLE PokeTypes (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL)" + create-pokemons: "CREATE TABLE Pokemons (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL, id_type INTEGER NOT NULL REFERENCES PokeTypes(id))" + select-all-types: "SELECT id, name FROM PokeTypes" + select-all-pokemons: "SELECT id, name, id_type FROM Pokemons" + select-pokemon-by-id: "SELECT id, name, id_type FROM Pokemons WHERE id = :id" + select-pokemon-by-name: "SELECT id, name, id_type FROM Pokemons WHERE name = ?" + insert-type: "INSERT INTO PokeTypes(id, name) VALUES(?, ?)" + insert-pokemon: "INSERT INTO Pokemons(id, name, id_type) VALUES(?, ?, ?)" + update-pokemon-by-id: "UPDATE Pokemons SET name = :name, id_type = :idType WHERE id = :id" + delete-pokemon-by-id: "DELETE FROM Pokemons WHERE id = :id" + delete-all-types: "DELETE FROM PokeTypes" + delete-all-pokemons: "DELETE FROM Pokemons" diff --git a/examples/dbclient/pokemons/src/test/resources/application-mongo-test.yaml b/examples/dbclient/pokemons/src/test/resources/application-mongo-test.yaml new file mode 100644 index 00000000000..aee39d5e40b --- /dev/null +++ b/examples/dbclient/pokemons/src/test/resources/application-mongo-test.yaml @@ -0,0 +1,113 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8080 + host: 0.0.0.0 + +tracing: + service: mongo-db + +db: + source: "mongoDb" + init-schema: false + # Transactions are not supported + init-data: false + services: + tracing: + - enabled: true + health-check: + type: "query" + statementName: "health-check" + statements: + # Health check statement. HealthCheck statement type must be a query. + health-check: '{ + "operation": "command", + "query": { ping: 1 } + }' + ## Create database schema + # Select all types + select-all-types: '{ + "collection": "types", + "operation": "query", + "projection": { id: 1, name: 1, _id: 0 }, + "query": {} + }' + # Select all pokemons without type information + select-all-pokemons: '{ + "collection": "pokemons", + "operation": "query", + "projection": { id: 1, name: 1, id_type: 1, _id: 0 }, + "query": {} + }' + # Select pokemon by id + select-pokemon-by-id: '{ + "collection": "pokemons", + "operation": "query", + "projection": { id: 1, name: 1, id_type: 1, _id: 0 }, + "query": { id: $id } + }' + # Select pokemon by name + select-pokemon-by-name: '{ + "collection": "pokemons", + "operation": "query", + "projection": { id: 1, name: 1, id_type: 1, _id: 0 }, + "query": { name: ? } + }' + # Insert records into database + insert-type: '{ + "collection": "types", + "operation": "insert", + "value": { + "id": ?, + "name": ? + } + }' + insert-pokemon: '{ + "collection": "pokemons", + "operation": "insert", + "value": { + "id": ?, + "name": ?, + "id_type": ? + } + }' + # Update name of pokemon specified by id + update-pokemon-by-id: '{ + "collection": "pokemons", + "operation": "update", + "value":{ $set: { "name": $name, "id_type": $idType } }, + "query": { id: $id } + }' + # Delete pokemon by id + delete-pokemon-by-id: '{ + "collection": "pokemons", + "operation": "delete", + "query": { id: $id } + }' + # Delete all types + delete-all-types: '{ + "collection": "types", + "operation": "delete", + "query": { } + }' + # Delete all pokemons + delete-all-pokemons: '{ + "collection": "pokemons", + "operation": "delete", + "query": { } + }' + diff --git a/examples/dbclient/pokemons/src/test/resources/application-mysql-test.yaml b/examples/dbclient/pokemons/src/test/resources/application-mysql-test.yaml new file mode 100644 index 00000000000..0e67870a821 --- /dev/null +++ b/examples/dbclient/pokemons/src/test/resources/application-mysql-test.yaml @@ -0,0 +1,59 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8080 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +# see README.md for details how to run databases in docker +db: + source: jdbc + connection: + username: user + password: password + poolName: "mysql" + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + services: + tracing: + - enabled: true + metrics: + - type: TIMER + health-check: + type: "query" + statementName: "health-check" + statements: + health-check: "SELECT 0" + create-types: "CREATE TABLE PokeTypes (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL)" + create-pokemons: "CREATE TABLE Pokemons (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL, id_type INTEGER NOT NULL REFERENCES PokeTypes(id))" + select-all-types: "SELECT id, name FROM PokeTypes" + select-all-pokemons: "SELECT id, name, id_type FROM Pokemons" + select-pokemon-by-id: "SELECT id, name, id_type FROM Pokemons WHERE id = :id" + select-pokemon-by-name: "SELECT id, name, id_type FROM Pokemons WHERE name = ?" + insert-type: "INSERT INTO PokeTypes(id, name) VALUES(?, ?)" + insert-pokemon: "INSERT INTO Pokemons(id, name, id_type) VALUES(?, ?, ?)" + update-pokemon-by-id: "UPDATE Pokemons SET name = :name, id_type = :idType WHERE id = :id" + delete-pokemon-by-id: "DELETE FROM Pokemons WHERE id = :id" + delete-all-types: "DELETE FROM PokeTypes" + delete-all-pokemons: "DELETE FROM Pokemons" diff --git a/examples/dbclient/pokemons/src/test/resources/application-oracle-test.yaml b/examples/dbclient/pokemons/src/test/resources/application-oracle-test.yaml new file mode 100644 index 00000000000..66d62ec06d2 --- /dev/null +++ b/examples/dbclient/pokemons/src/test/resources/application-oracle-test.yaml @@ -0,0 +1,58 @@ +# +# Copyright (c) 2024 Oracle and/or its affiliates. +# +# 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. +# + +server: + port: 8080 + host: 0.0.0.0 + +tracing: + service: jdbc-db + +# see README.md for details how to run databases in docker +db: + source: jdbc + connection: + username: "system" + password: "oracle" + initializationFailTimeout: -1 + connectionTimeout: 2000 + helidon: + pool-metrics: + enabled: true + # name prefix defaults to "db.pool." - if you have more than one client within a JVM, you may want to distinguish between them + name-prefix: "hikari." + services: + tracing: + - enabled: true + metrics: + - type: TIMER + health-check: + type: "query" + statementName: "health-check" + statements: + health-check: "SELECT 1 FROM DUAL" + create-types: "CREATE TABLE PokeTypes (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL)" + create-pokemons: "CREATE TABLE Pokemons (id INTEGER NOT NULL PRIMARY KEY, name VARCHAR(64) NOT NULL, id_type INTEGER NOT NULL REFERENCES PokeTypes(id))" + select-all-types: "SELECT id, name FROM PokeTypes" + select-all-pokemons: "SELECT id, name, id_type FROM Pokemons" + select-pokemon-by-id: "SELECT id, name, id_type FROM Pokemons WHERE id = :id" + select-pokemon-by-name: "SELECT id, name, id_type FROM Pokemons WHERE name = ?" + insert-type: "INSERT INTO PokeTypes(id, name) VALUES(?, ?)" + insert-pokemon: "INSERT INTO Pokemons(id, name, id_type) VALUES(?, ?, ?)" + update-pokemon-by-id: "UPDATE Pokemons SET name = :name, id_type = :idType WHERE id = :id" + delete-pokemon-by-id: "DELETE FROM Pokemons WHERE id = :id" + delete-all-types: "DELETE FROM PokeTypes" + delete-all-pokemons: "DELETE FROM Pokemons"