diff --git a/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersMessageBodyWriter.java b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersMessageBodyWriter.java new file mode 100644 index 0000000000..f6fe4f5d9a --- /dev/null +++ b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersMessageBodyWriter.java @@ -0,0 +1,28 @@ +package io.quarkus.ts.http.advanced.reactive; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.Provider; + +@Provider +public class HeadersMessageBodyWriter implements MessageBodyWriter { + + @Override + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return String.class.isAssignableFrom(aClass) && MediaType.TEXT_PLAIN_TYPE.isCompatible(mediaType); + } + + @Override + public void writeTo(String s, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException { + final String content = "Headers response: " + s; + outputStream.write(content.getBytes()); + } +} diff --git a/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersResource.java b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersResource.java index 9856464872..6749b71e8e 100644 --- a/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersResource.java +++ b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/HeadersResource.java @@ -2,6 +2,8 @@ import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import io.smallrye.mutiny.Uni; @@ -28,4 +30,12 @@ public Uni headersOverride() { return Uni.createFrom().item(response); } + @GET + @Path("/no-accept") + @Produces(MediaType.TEXT_PLAIN) + public Uni okHeaders() { + final Response response = Response.ok("ok headers").build(); + return Uni.createFrom().item(response); + } + } diff --git a/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/YamlProvider.java b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/YamlProvider.java index b93169ee12..bca3472352 100644 --- a/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/YamlProvider.java +++ b/http/http-advanced-reactive/src/main/java/io/quarkus/ts/http/advanced/reactive/YamlProvider.java @@ -28,7 +28,7 @@ public class YamlProvider implements MessageBodyReader, MessageBody private final ObjectMapper mapper; public YamlProvider() { - System.out.println("calling YAMLPROVIDER"); + Log.info("Calling YamlProvider"); this.mapper = new ObjectMapper(new YAMLFactory()); } @@ -43,8 +43,6 @@ public CityListDTO readFrom(Class cityListDTOClass, Type type, Anno InputStream inputStream) { try { - Log.info("Parsing yaml input: " + inputStream.toString() + " TYPE " + type.getTypeName() + " MEDIATYPE " - + mediaType.getSubtype()); return this.mapper.readValue(inputStream, CityListDTO.class); } catch (Exception e) { Log.error("Error reading YAML input", e); @@ -61,8 +59,6 @@ public boolean isWriteable(Class type, Type genericType, Annotation[] annotat public void writeTo(CityListDTO cityListDTO, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, MultivaluedMap multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException { - Log.info("outputStream " + outputStream.toString() + " TYPE " + type.getTypeName() + " MEDIATYPE " - + mediaType.getSubtype()); mapper.writeValue(outputStream, cityListDTO); } diff --git a/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/HeadersIT.java b/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/HeadersIT.java index 5be721a992..3bc4820e02 100644 --- a/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/HeadersIT.java +++ b/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/HeadersIT.java @@ -16,12 +16,14 @@ import io.quarkus.test.bootstrap.RestService; import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.QuarkusApplication; +import io.restassured.http.Header; import io.restassured.response.ValidatableResponse; @QuarkusScenario public class HeadersIT { @QuarkusApplication(classes = { PathSpecificHeadersResource.class, + HeadersMessageBodyWriter.class, HeadersResource.class }, properties = "headers.properties") static RestService app = new RestService(); @@ -92,6 +94,19 @@ void testPathSpecificHeaderRulesOrder() { cacheControlMatches(response, "max-age=1"); } + @Test + @Tag("https://github.com/quarkusio/quarkus/pull/41411") + void testWithNoAcceptHeader() { + Header header = new Header("Accept", null); + given() + .when() + .header(header) + .get("/headers/no-accept") + .then() + .statusCode(200) + .body(is("Headers response: ok headers")); + } + private ValidatableResponse whenGet(String path) { return given() .get(path) diff --git a/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersMessageBodyWriter.java b/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersMessageBodyWriter.java new file mode 100644 index 0000000000..aea302497a --- /dev/null +++ b/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersMessageBodyWriter.java @@ -0,0 +1,28 @@ +package io.quarkus.ts.http.advanced; + +import java.io.IOException; +import java.io.OutputStream; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; +import jakarta.ws.rs.core.MultivaluedMap; +import jakarta.ws.rs.ext.MessageBodyWriter; +import jakarta.ws.rs.ext.Provider; + +@Provider +public class HeadersMessageBodyWriter implements MessageBodyWriter { + + @Override + public boolean isWriteable(Class aClass, Type type, Annotation[] annotations, MediaType mediaType) { + return String.class.isAssignableFrom(aClass) && MediaType.TEXT_PLAIN_TYPE.isCompatible(mediaType); + } + + @Override + public void writeTo(String s, Class aClass, Type type, Annotation[] annotations, MediaType mediaType, + MultivaluedMap multivaluedMap, OutputStream outputStream) throws IOException, WebApplicationException { + final String content = "Headers response: " + s; + outputStream.write(content.getBytes()); + } +} diff --git a/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersResource.java b/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersResource.java index 64d8aeadda..77f6f8e361 100644 --- a/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersResource.java +++ b/http/http-advanced/src/main/java/io/quarkus/ts/http/advanced/HeadersResource.java @@ -13,6 +13,12 @@ public String headers() { return "ok"; } + @GET + @Path("/no-accept") + public String noAcceptheaders() { + return "ok"; + } + @GET @Path("/pragma") public String pragmaHeaderMustBeSet() { diff --git a/http/http-advanced/src/test/java/io/quarkus/ts/http/advanced/HeadersIT.java b/http/http-advanced/src/test/java/io/quarkus/ts/http/advanced/HeadersIT.java index 741d94622e..69993e9971 100644 --- a/http/http-advanced/src/test/java/io/quarkus/ts/http/advanced/HeadersIT.java +++ b/http/http-advanced/src/test/java/io/quarkus/ts/http/advanced/HeadersIT.java @@ -16,12 +16,14 @@ import io.quarkus.test.bootstrap.RestService; import io.quarkus.test.scenarios.QuarkusScenario; import io.quarkus.test.services.QuarkusApplication; +import io.restassured.http.Header; import io.restassured.response.ValidatableResponse; @QuarkusScenario public class HeadersIT { @QuarkusApplication(classes = { PathSpecificHeadersResource.class, + HeadersMessageBodyWriter.class, HeadersResource.class }, properties = "headers.properties") static RestService app = new RestService(); @@ -93,6 +95,24 @@ void testPathSpecificHeaderRulesOrder() { cacheControlMatches(response, "max-age=1"); } + /* + * This test check 3.8.6 backport https://github.com/quarkusio/quarkus/pull/41411 will fails with quarkus-resteasy + * HeadersMessageBodyWriter just works with quarkus-rest and not with quarkus-resteasy + */ + @Test + @Tag("https://github.com/quarkusio/quarkus/pull/41411") + void testWithNoAcceptHeader() { + Header header = new Header("Accept", null); + given() + .when() + .header(header) + .get("/headers/no-accept") + .then() + .statusCode(200) + .body(not("Headers response: ok")) + .body(is("ok")); + } + private ValidatableResponse whenGet(String path) { return given() .get(path)