From 5221dac7d21fcaa8fde174b2013f76bf63e66cae Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 15 Mar 2023 13:49:04 +0200 Subject: [PATCH 1/2] Fix incorrect generic type passed to MessageBodyWriter#writeTo Fixes: #31818 --- .../server/core/ServerSerialisers.java | 19 +++++++++++-------- .../simple/SimpleQuarkusRestResource.java | 6 ++++++ .../simple/SimpleQuarkusRestTestCase.java | 2 ++ .../server/vertx/test/simple/TestWriter.java | 6 +++++- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java index fc482e22001fd..5cd3502e727f4 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/core/ServerSerialisers.java @@ -202,16 +202,19 @@ public static boolean invokeWriter(ResteasyReactiveRequestContext context, Objec WriterInterceptor[] writerInterceptors = context.getWriterInterceptors(); boolean outputStreamSet = context.getOutputStream() != null; context.serverResponse().setPreCommitListener(HEADER_FUNCTION); + + RuntimeResource target = context.getTarget(); + Type genericType; + if (context.hasGenericReturnType()) { // make sure that when a Response with a GenericEntity was returned, we use it + genericType = context.getGenericReturnType(); + } else { + genericType = target == null ? null : target.getReturnType(); + } + try { if (writer instanceof ServerMessageBodyWriter && writerInterceptors == null && !outputStreamSet) { ServerMessageBodyWriter quarkusRestWriter = (ServerMessageBodyWriter) writer; - RuntimeResource target = context.getTarget(); - Type genericType; - if (context.hasGenericReturnType()) { // make sure that when a Response with a GenericEntity was returned, we use it - genericType = context.getGenericReturnType(); - } else { - genericType = target == null ? null : target.getReturnType(); - } + Class entityClass = entity.getClass(); if (quarkusRestWriter.isWriteable( entityClass, @@ -234,7 +237,7 @@ public static boolean invokeWriter(ResteasyReactiveRequestContext context, Objec context.setResponseContentType(mediaType); } if (writerInterceptors == null) { - writer.writeTo(entity, entity.getClass(), context.getGenericReturnType(), + writer.writeTo(entity, entity.getClass(), genericType, context.getAllAnnotations(), context.getResponseMediaType(), response.getHeaders(), context.getOrCreateOutputStream()); context.getOrCreateOutputStream().close(); diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java index 37c5be0667c4f..dd99dd9631a93 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestResource.java @@ -239,6 +239,12 @@ public TestClass writer() { return new TestClass(); } + @GET + @Path("uni-writer") + public Uni uniWriter() { + return Uni.createFrom().item(new TestClass()); + } + @GET @Path("fast-writer") @Produces("text/plain") diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java index 42d5ce328113c..4716148ca9c5e 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/SimpleQuarkusRestTestCase.java @@ -209,6 +209,8 @@ public void testWriter() { .then().body(Matchers.equalTo("OK")); RestAssured.get("/simple/writer") .then().body(Matchers.equalTo("WRITER")); + RestAssured.get("/simple/uni-writer") + .then().body(Matchers.equalTo("WRITER")); RestAssured.get("/simple/fast-writer") .then().body(Matchers.equalTo("OK")); diff --git a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java index bedb354add483..4e76104913783 100644 --- a/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java +++ b/independent-projects/resteasy-reactive/server/vertx/src/test/java/org/jboss/resteasy/reactive/server/vertx/test/simple/TestWriter.java @@ -26,7 +26,11 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat public void writeTo(TestClass t, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { - entityStream.write("WRITER".getBytes(StandardCharsets.UTF_8)); + if (genericType.getTypeName().equals(TestClass.class.getName())) { + entityStream.write("WRITER".getBytes(StandardCharsets.UTF_8)); + } else { + entityStream.write("INCORRECT GENERIC TYPE".getBytes(StandardCharsets.UTF_8)); + } } } From 304d30ec1c4ea4aac8d984b3d9b44439fab6f789 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 15 Mar 2023 13:54:45 +0200 Subject: [PATCH 2/2] Add logging to RequestDeserializeHandler This makes it easier to diagnose cases returned HTTP 415 --- .../reactive/server/handlers/RequestDeserializeHandler.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java index e6b3a0b7379e0..88bd9824402c5 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/handlers/RequestDeserializeHandler.java @@ -54,6 +54,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti try { effectiveRequestType = MediaType.valueOf((String) requestType); } catch (Exception e) { + log.debugv("Incorrect media type", e); throw new WebApplicationException(Response.status(Response.Status.BAD_REQUEST).build()); } @@ -70,6 +71,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti } List> readers = serialisers.findReaders(null, type, effectiveRequestType, RuntimeType.SERVER); if (readers.isEmpty()) { + log.debugv("No matching MessageBodyReader found for type {0} and media type {1}", type, effectiveRequestType); throw new NotSupportedException(); } for (MessageBodyReader reader : readers) { @@ -102,6 +104,7 @@ public void handle(ResteasyReactiveRequestContext requestContext) throws Excepti return; } } + log.debugv("No matching MessageBodyReader found for type {0} and media type {1}", type, effectiveRequestType); throw new NotSupportedException("No supported MessageBodyReader found"); }