From c56a7fdeeec71f7c6d8453d73e3d840e513a7047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Suszy=C5=84ski?= Date: Fri, 3 Mar 2023 16:29:50 +0100 Subject: [PATCH] Workaround for https://github.com/quarkusio/quarkus/issues/31587 and https://github.com/cloudevents/sdk-java/issues/533 --- .../knative/showcase/events/Endpoint.java | 75 ++++--------------- .../knative/showcase/events/Event.java | 61 +++++++++++++++ 2 files changed, 77 insertions(+), 59 deletions(-) create mode 100644 quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Event.java diff --git a/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Endpoint.java b/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Endpoint.java index 777c6fc..5bd6dd4 100644 --- a/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Endpoint.java +++ b/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Endpoint.java @@ -1,13 +1,7 @@ package com.redhat.openshift.knative.showcase.events; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.cloudevents.CloudEvent; -import io.cloudevents.core.builder.CloudEventBuilder; -import io.cloudevents.http.restful.ws.StructuredEncoding; import io.cloudevents.jackson.JsonFormat; -import io.quarkus.runtime.StartupEvent; import io.smallrye.mutiny.Multi; import org.eclipse.microprofile.openapi.annotations.Operation; import org.jboss.resteasy.reactive.RestStreamElementType; @@ -15,18 +9,13 @@ import org.slf4j.LoggerFactory; import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.event.Observes; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import java.net.URI; import java.util.ArrayList; import java.util.List; -import java.util.UUID; -import java.util.random.RandomGenerator; @Path("events") @ApplicationScoped @@ -35,64 +24,32 @@ class Endpoint { private static final Logger LOGGER = LoggerFactory.getLogger(Endpoint.class); private final List events = new ArrayList<>(); - void init(@Observes StartupEvent ignored, ObjectMapper om) - throws JsonProcessingException { - var rg = RandomGenerator.getDefault(); - for (int i = 0; i < 3; i++) { - var s = Score.random(rg); - events.add(CloudEventBuilder.v1() - .withId(String.valueOf(i)) - .withSource(URI.create("//localhost/dev")) - .withType(Endpoint.class.getName()) - .withData(MediaType.APPLICATION_JSON, om.writeValueAsBytes(s)) - .build()); - } - } - @GET @Operation(summary = "Retrieves all registered events as a JSON stream") - @RestStreamElementType(MediaType.APPLICATION_JSON) - @StructuredEncoding(JsonFormat.CONTENT_TYPE) - public Multi events() { - return Multi.createFrom().iterable(events); - } - - @GET - @Path("last") - @Produces(MediaType.APPLICATION_JSON) - @StructuredEncoding(JsonFormat.CONTENT_TYPE) - public CloudEvent last() { - return events.get(events.size() - 1); + @RestStreamElementType(JsonFormat.CONTENT_TYPE) + public Multi events() { + return Multi.createFrom() + .iterable(events) + .map(this::workaroundQuarkus31587); } @POST - @Consumes(MediaType.APPLICATION_JSON) + @Consumes({MediaType.APPLICATION_JSON, JsonFormat.CONTENT_TYPE}) @Operation(summary = "Receives a CloudEvent and stores it") public void receive(CloudEvent event) { events.add(event); - LOGGER.info("Received event: {}", event); + LOGGER.debug("Received event: {}", event); } - private static final class Score { - @JsonProperty - Play play; - @JsonProperty - int score; - - static Score random(RandomGenerator rg) { - var s = new Score(); - s.score = rg.nextInt(1_000); - s.play = new Play(); - s.play.id = new UUID(rg.nextLong(), rg.nextLong()).toString(); - s.play.game = rg.nextInt(300); - return s; - } + /** + * A workaround for + * quarkusio/quarkus#31587 + * and cloudevents/sdk-java#533. + * + * TODO: Remove this method once the above issues is fixed. + */ + private Event workaroundQuarkus31587(CloudEvent event) { + return Event.from(event, om); } - - private static class Play { - @JsonProperty - String id; - @JsonProperty - Integer game; } } diff --git a/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Event.java b/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Event.java new file mode 100644 index 0000000..6d16996 --- /dev/null +++ b/quarkus/src/main/java/com/redhat/openshift/knative/showcase/events/Event.java @@ -0,0 +1,61 @@ +package com.redhat.openshift.knative.showcase.events; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.cloudevents.CloudEvent; + +import javax.annotation.Nullable; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.Map; + +/** + * A workaround for + * quarkusio/quarkus#31587 + * and cloudevents/sdk-java#533. + * + * TODO: Remove this class once the above issues is fixed. + */ +class Event { + @JsonProperty + String id; + @JsonProperty + String source; + @JsonProperty + String type; + @JsonProperty("specversion") + String specVersion; + @JsonProperty("datacontenttype") + String dataContentType; + @JsonProperty + Map data; + + static Event from(CloudEvent event, ObjectMapper om) { + var e = new Event(); + e.id = event.getId(); + e.source = event.getSource().toString(); + e.type = event.getType(); + e.specVersion = event.getSpecVersion().toString(); + e.dataContentType = event.getDataContentType(); + e.data = dataToMap(event, om); + return e; + } + + @Nullable + private static Map dataToMap(CloudEvent event, ObjectMapper om) { + var data = event.getData(); + if (data == null) { + return null; + } + var mt = MediaType.valueOf(event.getDataContentType()); + if (mt.isCompatible(MediaType.APPLICATION_JSON_TYPE)) { + try { + return om.readValue(data.toBytes(), Map.class); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + throw new IllegalArgumentException("Unsupported media type: " + mt); + } + +}