diff --git a/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonEndpoint.java b/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonEndpoint.java index c8052f728476a..e2330472a2eba 100644 --- a/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonEndpoint.java +++ b/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonEndpoint.java @@ -27,6 +27,20 @@ public JsonObject jsonObject(JsonObject input) { return result; } + @POST + @Path("jsonObjectWrapper") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public JsonObjectWrapper jsonObjectWrapper(JsonObjectWrapper wrapper) { + var payload = wrapper.payload; + JsonObject result = new JsonObject(); + result.put("name", payload.getString("name")); + result.put("age", 50); + result.put("nested", new JsonObject(Collections.singletonMap("foo", "bar"))); + result.put("bools", new JsonArray().add(true)); + return new JsonObjectWrapper(result); + } + @POST @Path("jsonArray") @Produces(MediaType.APPLICATION_JSON) @@ -36,4 +50,22 @@ public JsonArray jsonArray(JsonArray input) { result.add("last"); return result; } + + @POST + @Path("jsonArrayWrapper") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public JsonArrayWrapper jsonArrayWrapper(JsonArrayWrapper wrapper) { + var payload = wrapper.payload; + JsonArray result = payload.copy(); + result.add("last"); + return new JsonArrayWrapper(result); + } + + public record JsonObjectWrapper(JsonObject payload) { + } + + public record JsonArrayWrapper(JsonArray payload) { + + } } diff --git a/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonTest.java b/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonTest.java index a62fe11749f18..9756d7c3144ed 100644 --- a/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonTest.java +++ b/extensions/resteasy-reactive/rest-jackson/deployment/src/test/java/io/quarkus/resteasy/reactive/jackson/deployment/test/VertxJsonTest.java @@ -38,6 +38,21 @@ public void testJsonObject() { .body("bools[0]", Matchers.equalTo(true)); } + @Test + public void testJsonObjectWrapper() { + RestAssured.with() + .body("{\"payload\": {\"name\": \"Bob\"}}") + .contentType("application/json") + .post("/vertx/jsonObjectWrapper") + .then() + .statusCode(200) + .contentType("application/json") + .body("payload.name", Matchers.equalTo("Bob")) + .body("payload.age", Matchers.equalTo(50)) + .body("payload.nested.foo", Matchers.equalTo("bar")) + .body("payload.bools[0]", Matchers.equalTo(true)); + } + @Test public void testJsonArray() { RestAssured.with() @@ -51,4 +66,17 @@ public void testJsonArray() { .body("[1]", Matchers.equalTo("last")); } + @Test + public void testJsonArrayWrapper() { + RestAssured.with() + .body("{\"payload\": [\"first\"]}") + .contentType("application/json") + .post("/vertx/jsonArrayWrapper") + .then() + .statusCode(200) + .contentType("application/json") + .body("payload[0]", Matchers.equalTo("first")) + .body("payload[1]", Matchers.equalTo("last")); + } + } diff --git a/extensions/vertx/deployment/pom.xml b/extensions/vertx/deployment/pom.xml index aad294e6680e0..fd96dfafdae57 100644 --- a/extensions/vertx/deployment/pom.xml +++ b/extensions/vertx/deployment/pom.xml @@ -33,6 +33,10 @@ io.quarkus quarkus-mutiny-deployment + + io.quarkus + quarkus-jackson-spi + io.quarkus quarkus-junit5-internal diff --git a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java index cbecc141c135e..2708d6d25c976 100644 --- a/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java +++ b/extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxJsonProcessor.java @@ -6,6 +6,13 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; +import io.quarkus.jackson.spi.JacksonModuleBuildItem; +import io.quarkus.vertx.runtime.jackson.JsonArrayDeserializer; +import io.quarkus.vertx.runtime.jackson.JsonArraySerializer; +import io.quarkus.vertx.runtime.jackson.JsonObjectDeserializer; +import io.quarkus.vertx.runtime.jackson.JsonObjectSerializer; +import io.vertx.core.json.JsonArray; +import io.vertx.core.json.JsonObject; import io.vertx.core.spi.JsonFactory; public class VertxJsonProcessor { @@ -24,4 +31,16 @@ void nativeSupport(List reinitializeVertxJson, serviceProviderBuildItemBuildProducer .produce(ServiceProviderBuildItem.allProvidersFromClassPath(JsonFactory.class.getName())); } + + @BuildStep + JacksonModuleBuildItem registerJacksonSerDeser() { + return new JacksonModuleBuildItem.Builder("VertxTypes") + .add(JsonArraySerializer.class.getName(), + JsonArrayDeserializer.class.getName(), + JsonArray.class.getName()) + .add(JsonObjectSerializer.class.getName(), + JsonObjectDeserializer.class.getName(), + JsonObject.class.getName()) + .build(); + } } diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferDeserializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferDeserializer.java index 696f7182feeab..1ae4c81345b74 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferDeserializer.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferDeserializer.java @@ -25,7 +25,7 @@ /** * Copied from {@code io.vertx.core.json.jackson.BufferDeserializer} as that class is package private */ -class BufferDeserializer extends JsonDeserializer { +public class BufferDeserializer extends JsonDeserializer { @Override public Buffer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferSerializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferSerializer.java index 508c59083d911..364fbd71eeb31 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferSerializer.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/BufferSerializer.java @@ -23,7 +23,7 @@ /** * Copied from {@code io.vertx.core.json.jackson.BufferSerializer} as that class is package private */ -class BufferSerializer extends JsonSerializer { +public class BufferSerializer extends JsonSerializer { @Override public void serialize(Buffer value, JsonGenerator jgen, SerializerProvider provider) throws IOException { diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArrayDeserializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArrayDeserializer.java new file mode 100644 index 0000000000000..59dc87c0097a2 --- /dev/null +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArrayDeserializer.java @@ -0,0 +1,30 @@ +package io.quarkus.vertx.runtime.jackson; + +import java.util.List; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer; +import com.fasterxml.jackson.databind.util.Converter; +import com.fasterxml.jackson.databind.util.StdConverter; + +import io.vertx.core.json.JsonArray; + +public class JsonArrayDeserializer extends StdDelegatingDeserializer { + + public JsonArrayDeserializer() { + super(new StdConverter, JsonArray>() { + @Override + public JsonArray convert(List list) { + return new JsonArray(list); + } + }); + } + + @Override + protected StdDelegatingDeserializer withDelegate(Converter converter, + JavaType delegateType, + JsonDeserializer delegateDeserializer) { + return new StdDelegatingDeserializer<>(converter, delegateType, delegateDeserializer); + } +} diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArraySerializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArraySerializer.java index dc2053b32530b..1c3575152df1e 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArraySerializer.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonArraySerializer.java @@ -22,7 +22,7 @@ /** * Copied from {@code io.vertx.core.json.jackson.JsonArraySerializer} as that class is package private */ -class JsonArraySerializer extends JsonSerializer { +public class JsonArraySerializer extends JsonSerializer { @Override public void serialize(JsonArray value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeObject(value.getList()); diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectDeserializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectDeserializer.java new file mode 100644 index 0000000000000..8dfba6c2c181b --- /dev/null +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectDeserializer.java @@ -0,0 +1,30 @@ +package io.quarkus.vertx.runtime.jackson; + +import java.util.Map; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.deser.std.StdDelegatingDeserializer; +import com.fasterxml.jackson.databind.util.Converter; +import com.fasterxml.jackson.databind.util.StdConverter; + +import io.vertx.core.json.JsonObject; + +public class JsonObjectDeserializer extends StdDelegatingDeserializer { + + public JsonObjectDeserializer() { + super(new StdConverter, JsonObject>() { + @Override + public JsonObject convert(Map map) { + return new JsonObject(map); + } + }); + } + + @Override + protected StdDelegatingDeserializer withDelegate(Converter converter, + JavaType delegateType, + JsonDeserializer delegateDeserializer) { + return new StdDelegatingDeserializer<>(converter, delegateType, delegateDeserializer); + } +} diff --git a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectSerializer.java b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectSerializer.java index 07bfed2083ede..e276b09bc36b1 100644 --- a/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectSerializer.java +++ b/extensions/vertx/runtime/src/main/java/io/quarkus/vertx/runtime/jackson/JsonObjectSerializer.java @@ -21,7 +21,7 @@ /** * Copied from {@code io.vertx.core.json.jackson.JsonObjectSerializer} as that class is package private */ -class JsonObjectSerializer extends JsonSerializer { +public class JsonObjectSerializer extends JsonSerializer { @Override public void serialize(JsonObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeObject(value.getMap()); diff --git a/integration-tests/jpa-postgresql/src/test/resources/image-metrics/23.1/image-metrics.properties b/integration-tests/jpa-postgresql/src/test/resources/image-metrics/23.1/image-metrics.properties index 6315f449e1bf9..507eb65104e09 100644 --- a/integration-tests/jpa-postgresql/src/test/resources/image-metrics/23.1/image-metrics.properties +++ b/integration-tests/jpa-postgresql/src/test/resources/image-metrics/23.1/image-metrics.properties @@ -7,7 +7,7 @@ analysis_results.methods.reachable=96465 analysis_results.methods.reachable.tolerance=3 analysis_results.fields.reachable=27025 analysis_results.fields.reachable.tolerance=3 -analysis_results.types.reflection=6048 +analysis_results.types.reflection=6100 analysis_results.types.reflection.tolerance=3 analysis_results.methods.reflection=4707 analysis_results.methods.reflection.tolerance=3