From 3964f21398b468677f7e876a1e68d7f0d61d2626 Mon Sep 17 00:00:00 2001 From: brunobat Date: Wed, 11 Oct 2023 10:51:10 +0100 Subject: [PATCH] resteasy reactive in legumes --- pom.xml | 2 +- .../pom.xml | 19 +++- .../com/brunobat/rest/LegumeRepository.java | 29 +++-- .../com/brunobat/rest/resource/LegumeApi.java | 11 +- .../rest/resource/LegumeResource.java | 106 ++++++++++-------- .../src/main/resources/application.properties | 2 +- .../com/brunobat/rest/LegumeResourceTest.java | 5 +- .../src/test/resources/application.properties | 10 +- .../src/main/resources/application.properties | 2 + 9 files changed, 108 insertions(+), 78 deletions(-) diff --git a/pom.xml b/pom.xml index b7b35ea..e22e02c 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ 3.0.0 2.2.0 1.18.26 - 5.3.0 + 5.3.2 true 3.0.0 diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/pom.xml b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/pom.xml index f51ad86..b5a34e8 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/pom.xml +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/pom.xml @@ -34,24 +34,35 @@ io.quarkus - quarkus-resteasy-jackson + quarkus-resteasy-reactive-jackson + + + io.quarkus + quarkus-hibernate-validator io.quarkus quarkus-smallrye-openapi + io.quarkus - quarkus-hibernate-orm-panache + quarkus-hibernate-reactive-panache + + io.quarkus - quarkus-opentelemetry + quarkus-reactive-pg-client io.quarkus - quarkus-jdbc-postgresql + quarkus-opentelemetry + + + + io.quarkus quarkus-arc diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/LegumeRepository.java b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/LegumeRepository.java index c0b18a8..65ba48f 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/LegumeRepository.java +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/LegumeRepository.java @@ -1,30 +1,29 @@ package com.brunobat.rest; -import com.brunobat.rest.data.LegumeItem; import com.brunobat.rest.model.Legume; -import io.quarkus.hibernate.orm.panache.PanacheRepository; - +import io.quarkus.hibernate.reactive.panache.PanacheRepository; +import io.quarkus.hibernate.reactive.panache.common.WithSession; +import io.smallrye.mutiny.Uni; import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import jakarta.persistence.EntityManager; + import java.util.List; -import java.util.stream.Stream; @ApplicationScoped public class LegumeRepository implements PanacheRepository { - @Inject - EntityManager manager; - - public Stream listLegumes(int pageIndex) { - return find("SELECT h FROM Legume h").page(pageIndex, 16).stream(); + @WithSession + public Uni> listLegumes(int pageIndex) { + return find("SELECT h FROM Legume h").page(pageIndex, 16).list(); } - public void remove(final LegumeItem legume) { - manager.remove(legume); + public void removeLegume(final String legumeId) { + find("SELECT h FROM Legume h WHERE h.id=?1", legumeId).firstResult().onItem().transform(legume -> { + delete(legume); + return legume; + }); } - public Legume merge(final Legume legumeToAdd) { - return manager.merge(legumeToAdd); + public Uni createLegume(final Legume legumeToAdd) { + return persist(legumeToAdd); } } diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeApi.java b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeApi.java index ecc1bea..ffcd848 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeApi.java +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeApi.java @@ -2,13 +2,14 @@ import com.brunobat.rest.data.LegumeItem; import com.brunobat.rest.data.LegumeNew; +import io.smallrye.mutiny.Uni; +import jakarta.ws.rs.PathParam; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.media.Content; import org.eclipse.microprofile.openapi.annotations.media.Schema; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.parameters.RequestBody; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.jboss.resteasy.annotations.jaxrs.PathParam; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; @@ -51,7 +52,7 @@ public interface LegumeApi { responseCode = "500", description = "Internal Server Error" ) - Response provision(); + Uni provision(); @POST @Operation( @@ -87,7 +88,7 @@ public interface LegumeApi { responseCode = "500", description = "Internal Server Error" ) - public Response add(@Valid final LegumeNew legume); + public Uni add(@Valid final LegumeNew legume); @DELETE @Path("{id}") @@ -109,7 +110,7 @@ public interface LegumeApi { responseCode = "500", description = "Internal Server Error" ) - Response delete( + Uni delete( @Parameter(name = "id", description = "Id of the Legume to delete", required = true, @@ -137,7 +138,7 @@ Response delete( description = "Internal Server Error" ) @GET - List list( + Uni> list( @Parameter(name = "pageIndex", required = false) @QueryParam("pageIndex") final int pageIndex); diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeResource.java b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeResource.java index 775eabb..828fef4 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeResource.java +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/java/com/brunobat/rest/resource/LegumeResource.java @@ -6,19 +6,19 @@ import com.brunobat.rest.data.LegumeNew; import com.brunobat.rest.message.MessageSender; import com.brunobat.rest.model.Legume; -import lombok.extern.slf4j.Slf4j; - +import io.quarkus.hibernate.reactive.panache.common.WithTransaction; +import io.smallrye.mutiny.Uni; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; -import jakarta.transaction.Transactional; import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.ws.rs.core.Response; + +import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; -import static java.util.Arrays.asList; import static jakarta.ws.rs.core.Response.Status.CREATED; import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; import static jakarta.ws.rs.core.Response.Status.NO_CONTENT; @@ -33,68 +33,84 @@ public class LegumeResource implements LegumeApi { @Inject MessageSender messageSender; - @Transactional - public Response provision() { + @WithTransaction + public Uni provision() { final LegumeNew carrot = LegumeNew.builder() - .name("Carrot") - .description("Root vegetable, usually orange") - .build(); + .name("Carrot") + .description("Root vegetable, usually orange") + .build(); final LegumeNew zucchini = LegumeNew.builder() - .name("Zucchini") - .description("Summer squash") - .build(); - return Response.status(CREATED).entity(asList( - addLegume(carrot), - addLegume(zucchini))).build(); + .name("Zucchini") + .description("Summer squash") + .build(); + + return Uni.combine().all().unis( + addLegume(carrot), + addLegume(zucchini)) + .asTuple() + .onItem().transform(tuple -> { + List resultList = new ArrayList<>(); + resultList.add(tuple.getItem1()); + resultList.add(tuple.getItem2()); + return Response.status(CREATED).entity(resultList).build(); + }); } - @Transactional - public Response add(@Valid final LegumeNew legumeNew) { - return Response.status(CREATED).entity(addLegume(legumeNew)).build(); + @WithTransaction + public Uni add(@Valid final LegumeNew legumeNew) { + return addLegume(legumeNew) + .onItem().transform(legumeItem -> Response + .status(CREATED) + .entity(legumeItem) + .build()); } - @Transactional - public Response delete(@NotEmpty final String legumeId) { + @WithTransaction + public Uni delete(@NotEmpty final String legumeId) { return find(legumeId) - .map(legume -> { - repository.remove(legume); - return Response.status(NO_CONTENT).build(); - }) - .orElse(Response.status(NOT_FOUND).build()); + .onItem().transform(legumeOpt -> legumeOpt + .map(legume -> { + repository.removeLegume(legume.getId()); + return Response.status(NO_CONTENT).build(); + }) + .orElse(Response.status(NOT_FOUND).build())); } - public List list(int pageIndex) { + public Uni> list(int pageIndex) { // log.info("someone asked for a list for index: " + pageIndex); return repository.listLegumes(pageIndex) - .map(this::getLegumeItem) - .collect(Collectors.toList()); + .onItem().transform(legumes -> legumes.stream() + .map(this::getLegumeItem) + .collect(Collectors.toList())); } - private Optional find(final String legumeId) { - return repository.find("id", legumeId).stream() - .map(this::getLegumeItem) - .findFirst(); + private Uni> find(final String legumeId) { + return repository.find("id", legumeId).list() + .onItem().transform(legumes -> legumes.stream() + .map(this::getLegumeItem) + .findFirst()); } - private LegumeItem addLegume(final @Valid LegumeNew legumeNew) { + private Uni addLegume(final LegumeNew legumeNew) { final Legume legumeToAdd = Legume.builder() - .name(legumeNew.getName()) - .description((legumeNew.getDescription())) - .build(); - - final Legume addedLegume = repository.merge(legumeToAdd); - final LegumeItem legumeItem = getLegumeItem(addedLegume); + .name(legumeNew.getName()) + .description((legumeNew.getDescription())) + .build(); - messageSender.send(legumeItem.getName()); + final Uni addedLegume = repository.createLegume(legumeToAdd); - return legumeItem; + return addedLegume.onItem().transform(legume -> { + LegumeItem legumeItem = getLegumeItem(legume); + messageSender.send(legumeItem.getName()); + return legumeItem; + }); } private LegumeItem getLegumeItem(final Legume addedLegume) { return LegumeItem.builder() - .id(addedLegume.getId()) - .name(addedLegume.getName()) - .description(addedLegume.getDescription()) - .build(); + .id(addedLegume.getId()) + .name(addedLegume.getName()) + .description(addedLegume.getDescription()) + .build(); } } diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/resources/application.properties b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/resources/application.properties index 5a80316..a944fa5 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/resources/application.properties +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/main/resources/application.properties @@ -1,7 +1,7 @@ # DB quarkus.datasource.db-kind=postgresql -quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/test?current_schema=public +quarkus.datasource.reactive.url=postgresql://localhost:5432/test?current_schema=public quarkus.datasource.username: pguser quarkus.datasource.password: changeit quarkus.datasource.jdbc.max-size=50 diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/java/com/brunobat/rest/LegumeResourceTest.java b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/java/com/brunobat/rest/LegumeResourceTest.java index fc006aa..619ba2b 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/java/com/brunobat/rest/LegumeResourceTest.java +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/java/com/brunobat/rest/LegumeResourceTest.java @@ -16,11 +16,14 @@ public class LegumeResourceTest { public void testProvisionAndList() { given() .header("Content-Type", "application/json; encoding=utf8; charset=utf8") + .header("Accept", "application/json; encoding=utf8; charset=utf8") .when().post("/legumes/init") .then() .statusCode(201); given() + .header("Content-Type", "application/json; encoding=utf8; charset=utf8") + .header("Accept", "application/json; encoding=utf8; charset=utf8") .when().get("/legumes") .then() .log().all() @@ -28,7 +31,5 @@ public void testProvisionAndList() { .body("$.size()", is(2), "name", containsInAnyOrder("Carrot", "Zucchini"), "description", containsInAnyOrder("Root vegetable, usually orange", "Summer squash")); - - } } diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/resources/application.properties b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/resources/application.properties index 7cdd842..8d2cb2c 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/resources/application.properties +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-legume/src/test/resources/application.properties @@ -1,9 +1,9 @@ ## configure your datasource -quarkus.datasource.db-kind=h2 -quarkus.datasource.jdbc.url=jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1 -quarkus.datasource.username: sa -quarkus.datasource.password: -quarkus.datasource.jdbc.max-size: 20 +#quarkus.datasource.db-kind=h2 +#quarkus.datasource.reactive.url=h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1 +#quarkus.datasource.username: sa +#quarkus.datasource.password: +#quarkus.datasource.jdbc.max-size: 20 # drop and create the database at startup (use `update` to only update the schema) #quarkus.hibernate-orm.dialect=org.hibernate.dialect.H2Dialect quarkus.hibernate-orm.database.generation=drop-and-create diff --git a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-superhero/src/main/resources/application.properties b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-superhero/src/main/resources/application.properties index 788463d..9d68a12 100644 --- a/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-superhero/src/main/resources/application.properties +++ b/quarkus-observability-demo-activemq/quarkus-observability-demo-activemq-superhero/src/main/resources/application.properties @@ -23,6 +23,8 @@ quarkus.log.console.format=%d{HH:mm:ss} %-5p traceId=%X{traceId}, parentId=%X{pa #quarkus.otel.bsp.max.export.batch.size=64 #quarkus.otel.bsp.schedule.delay=500ms otel.metrics.exporter=none +quarkus.otel.traces.sampler=traceidratio +quarkus.otel.traces.sampler.arg=0.1 # Configures the Artemis properties. quarkus.artemis.url=tcp://localhost:61616