From 50dd6c042f54bb5ee271c5b2ec360ff1ff969a44 Mon Sep 17 00:00:00 2001 From: Thibault Vallin Date: Wed, 13 Dec 2023 09:18:04 +0100 Subject: [PATCH] 4.x: Fix and add test to database SE example Signed-off-by: tvallin --- .../common/AbstractPokemonService.java | 3 +- examples/dbclient/jdbc/pom.xml | 30 +++++ .../jdbc/src/main/resources/application.yaml | 8 +- .../examples/dbclient/jdbc/MainTest.java | 118 ++++++++++++++++++ .../src/test/resources/application-test.yaml | 19 +++ examples/dbclient/pokemons/README.md | 4 +- 6 files changed, 172 insertions(+), 10 deletions(-) create mode 100644 examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/MainTest.java create mode 100644 examples/dbclient/jdbc/src/test/resources/application-test.yaml diff --git a/examples/dbclient/common/src/main/java/io/helidon/examples/dbclient/common/AbstractPokemonService.java b/examples/dbclient/common/src/main/java/io/helidon/examples/dbclient/common/AbstractPokemonService.java index eaf36eee554..e25db73468c 100644 --- a/examples/dbclient/common/src/main/java/io/helidon/examples/dbclient/common/AbstractPokemonService.java +++ b/examples/dbclient/common/src/main/java/io/helidon/examples/dbclient/common/AbstractPokemonService.java @@ -134,7 +134,8 @@ private void getPokemon(ServerRequest req, ServerResponse res) { private void listPokemons(ServerRequest req, ServerResponse res) { res.send(dbClient.execute() .namedQuery("select-all") - .map(it -> it.as(JsonObject.class))); + .map(it -> it.as(JsonObject.class)) + .toList()); } /** diff --git a/examples/dbclient/jdbc/pom.xml b/examples/dbclient/jdbc/pom.xml index aeefe4db30c..02a6ef8c9c9 100644 --- a/examples/dbclient/jdbc/pom.xml +++ b/examples/dbclient/jdbc/pom.xml @@ -34,6 +34,11 @@ + + io.helidon.logging + helidon-logging-jul + runtime + io.helidon.tracing helidon-tracing @@ -127,6 +132,31 @@ helidon-metrics-system-meters runtime + + com.h2database + h2 + test + + + io.helidon.webclient + helidon-webclient + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.hamcrest + hamcrest-all + test + + + io.helidon.webserver.testing.junit5 + helidon-webserver-testing-junit5 + test + diff --git a/examples/dbclient/jdbc/src/main/resources/application.yaml b/examples/dbclient/jdbc/src/main/resources/application.yaml index f187bc0a8ab..64cbce16324 100644 --- a/examples/dbclient/jdbc/src/main/resources/application.yaml +++ b/examples/dbclient/jdbc/src/main/resources/application.yaml @@ -59,7 +59,7 @@ db: # 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" + type: "query" statementName: "health-check" services: tracing: @@ -68,12 +68,6 @@ db: # would trace all delete statements - statement-types: ["DELETE"] metrics: - - type: METER - name-format: "db.meter.overall" - - type: METER - # meter per statement name (default name format) - - type: METER - name-format: "db.meter.%1$s" - type: TIMER errors: false statement-names: ["select-.*"] 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/MainTest.java new file mode 100644 index 00000000000..2cd14d978f5 --- /dev/null +++ b/examples/dbclient/jdbc/src/test/java/io/helidon/examples/dbclient/jdbc/MainTest.java @@ -0,0 +1,118 @@ +/* + * 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. + */ + +package io.helidon.examples.dbclient.jdbc; + +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.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 jakarta.json.Json; +import jakarta.json.JsonArray; +import jakarta.json.JsonBuilderFactory; +import jakarta.json.JsonObject; +import org.junit.jupiter.api.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +@ServerTest +public class MainTest { + private static final JsonBuilderFactory JSON_FACTORY = Json.createBuilderFactory(Map.of()); + + private final Http1Client client; + + MainTest(Http1Client client) { + this.client = client; + } + + @SetUpRoute + static void routing(HttpRouting.Builder routing) { + JdbcExampleMain.routing(routing, DbClient.create(Config.global().get("db"))); + } + + @Test + void testListAndDeleteAllPokemons() { + List names = listAllPokemons(); + assertThat(names.isEmpty(), is(true)); + + String endpoint = String.format("/db/%s/type/%s", "Raticate", 1); + ClientResponseTyped response = client.post(endpoint).request(String.class); + assertThat(response.status(), is(Status.OK_200)); + + names = listAllPokemons(); + assertThat(names.size(), is(1)); + assertThat(names.getFirst(), is("Raticate")); + + response = client.delete("/db").request(String.class); + assertThat(response.status(), is(Status.OK_200)); + + names = listAllPokemons(); + assertThat(names.isEmpty(), is(true)); + } + + @Test + void testAddUpdateDeletePokemon() { + ClientResponseTyped response; + ClientResponseTyped jsonResponse; + JsonObject pokemon = JSON_FACTORY.createObjectBuilder() + .add("type", 1) + .add("name", "Raticate") + .build(); + + // Add new pokemon + response = client.put("/db").submit(pokemon, String.class); + assertThat(response.entity(), is("Inserted: 1 values")); + + // 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")); + + // Update pokemon + response = client.put("/db/Raticate/type/2").request(String.class); + assertThat(response.status(), is(Status.OK_200)); + + // 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")); + + // Delete Pokemon + response = client.delete("/db/Raticate").request(String.class); + assertThat(response.status(), is(Status.OK_200)); + + // Verify pokemon is correctly deleted + response = client.get("/db/Raticate").request(String.class); + assertThat(response.status(), is(Status.NOT_FOUND_404)); + } + + 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(); + } +} diff --git a/examples/dbclient/jdbc/src/test/resources/application-test.yaml b/examples/dbclient/jdbc/src/test/resources/application-test.yaml new file mode 100644 index 00000000000..94947bcb9fb --- /dev/null +++ b/examples/dbclient/jdbc/src/test/resources/application-test.yaml @@ -0,0 +1,19 @@ +# +# 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/README.md b/examples/dbclient/pokemons/README.md index 1e6fa18ab06..a2ebdf2a817 100644 --- a/examples/dbclient/pokemons/README.md +++ b/examples/dbclient/pokemons/README.md @@ -120,10 +120,10 @@ curl http://localhost:8080/db/pokemon/2 curl http://localhost:8080/db/pokemon/name/Squirtle # Add a new Pokémon Rattata -curl -i -X POST -d '{"id":7,"name":"Rattata","idType":1}' http://localhost:8080/db/pokemon +curl -i -X POST -H 'Content-type: application/json' -d '{"id":7,"name":"Rattata","idType":1}' http://localhost:8080/db/pokemon # Rename Pokémon with id 7 to Raticate -curl -i -X PUT -d '{"id":7,"name":"Raticate","idType":2}' http://localhost:8080/db/pokemon +curl -i -X PUT -H 'Content-type: application/json' -d '{"id":7,"name":"Raticate","idType":2}' http://localhost:8080/db/pokemon # Delete Pokémon with id 7 curl -i -X DELETE http://localhost:8080/db/pokemon/7