From a7137ce4de241d77417cfa26e72d43f0307f4df9 Mon Sep 17 00:00:00 2001 From: Martin Kouba Date: Fri, 12 Apr 2024 11:59:08 +0200 Subject: [PATCH] Qute: do not register TemplateInstance as non-blocking type by default - make it possible to enable the old behavior (for backrward compatibility) - deprecate NonBlockingReturnTypeBuildItem - resolves #39971 --- .../qute/deployment/RestQuteConfig.java | 22 +++++++++ .../ResteasyReactiveQuteProcessor.java | 7 ++- ...emplateInstanceNonBlockingEnabledTest.java | 48 +++++++++++++++++++ .../TemplateInstanceNonBlockingTest.java | 3 +- .../spi/NonBlockingReturnTypeBuildItem.java | 3 ++ 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/RestQuteConfig.java create mode 100644 extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingEnabledTest.java diff --git a/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/RestQuteConfig.java b/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/RestQuteConfig.java new file mode 100644 index 0000000000000..3649508cc5fc9 --- /dev/null +++ b/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/RestQuteConfig.java @@ -0,0 +1,22 @@ +package io.quarkus.resteasy.reactive.qute.deployment; + +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; +import io.smallrye.config.ConfigMapping; +import io.smallrye.config.WithDefault; + +@ConfigMapping(prefix = "quarkus.rest-qute") +@ConfigRoot(phase = ConfigPhase.BUILD_TIME) +public interface RestQuteConfig { + + /** + * If set to {@code true} then the {@link io.quarkus.qute.TemplateInstance} is registered as a non-blocking return type for + * JAX-RS resource methods. + * + * @deprecated This config item will be removed at some time after Quarkus 3.16 + */ + @Deprecated(forRemoval = true, since = "3.10") + @WithDefault("false") + boolean templateInstanceNonBlockingType(); + +} diff --git a/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/ResteasyReactiveQuteProcessor.java b/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/ResteasyReactiveQuteProcessor.java index 59d8213be71a3..137c39476022c 100644 --- a/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/ResteasyReactiveQuteProcessor.java +++ b/extensions/resteasy-reactive/rest-qute/deployment/src/main/java/io/quarkus/resteasy/reactive/qute/deployment/ResteasyReactiveQuteProcessor.java @@ -18,6 +18,7 @@ import org.jboss.resteasy.reactive.server.processor.scanning.MethodScanner; import io.quarkus.deployment.Feature; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyIgnoreWarningBuildItem; @@ -49,8 +50,10 @@ ReflectiveHierarchyIgnoreWarningBuildItem ignoreReflectiveWarning() { } @BuildStep - NonBlockingReturnTypeBuildItem nonBlockingTemplateInstance() { - return new NonBlockingReturnTypeBuildItem(TEMPLATE_INSTANCE); + void nonBlockingTemplateInstance(RestQuteConfig config, BuildProducer nonBlockingType) { + if (config.templateInstanceNonBlockingType()) { + nonBlockingType.produce(new NonBlockingReturnTypeBuildItem(TEMPLATE_INSTANCE)); + } } @BuildStep diff --git a/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingEnabledTest.java b/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingEnabledTest.java new file mode 100644 index 0000000000000..a4b9f0344cb63 --- /dev/null +++ b/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingEnabledTest.java @@ -0,0 +1,48 @@ +package io.quarkus.resteasy.reactive.qute.deployment; + +import static io.restassured.RestAssured.when; + +import jakarta.inject.Inject; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +import org.hamcrest.Matchers; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.qute.Template; +import io.quarkus.qute.TemplateInstance; +import io.quarkus.runtime.BlockingOperationControl; +import io.quarkus.test.QuarkusUnitTest; + +public class TemplateInstanceNonBlockingEnabledTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(TestResource.class) + .addAsResource(new StringAsset("quarkus.rest-qute.template-instance-non-blocking-type=true"), + "application.properties") + .addAsResource(new StringAsset("Blocking allowed: {blockingAllowed}"), "templates/item.txt")); + + @Test + public void test() { + when().get("/test").then().statusCode(200).body(Matchers.is("Blocking allowed: false")); + } + + @Path("test") + public static class TestResource { + + @Inject + Template item; + + @GET + @Produces(MediaType.TEXT_PLAIN) + public TemplateInstance get() { + return item.data("blockingAllowed", BlockingOperationControl.isBlockingAllowed()); + } + } +} diff --git a/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingTest.java b/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingTest.java index d1fb7c35fc321..80711c150c370 100644 --- a/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingTest.java +++ b/extensions/resteasy-reactive/rest-qute/deployment/src/test/java/io/quarkus/resteasy/reactive/qute/deployment/TemplateInstanceNonBlockingTest.java @@ -1,7 +1,6 @@ package io.quarkus.resteasy.reactive.qute.deployment; import static io.restassured.RestAssured.when; -import static org.hamcrest.Matchers.is; import jakarta.inject.Inject; import jakarta.ws.rs.GET; @@ -29,7 +28,7 @@ public class TemplateInstanceNonBlockingTest { @Test public void test() { - when().get("/test").then().statusCode(200).body(Matchers.is("Blocking allowed: false")); + when().get("/test").then().statusCode(200).body(Matchers.is("Blocking allowed: true")); } @Path("test") diff --git a/extensions/resteasy-reactive/rest/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/NonBlockingReturnTypeBuildItem.java b/extensions/resteasy-reactive/rest/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/NonBlockingReturnTypeBuildItem.java index 7faa3c03802a0..41f9c9fc409dd 100644 --- a/extensions/resteasy-reactive/rest/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/NonBlockingReturnTypeBuildItem.java +++ b/extensions/resteasy-reactive/rest/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/NonBlockingReturnTypeBuildItem.java @@ -6,7 +6,10 @@ /** * Register a type as non-blocking by default when used as a return type of JAX-RS Resource + * + * @deprecated This build item will be removed at some time after Quarkus 3.16 */ +@Deprecated(forRemoval = true, since = "3.10") public final class NonBlockingReturnTypeBuildItem extends MultiBuildItem { private final DotName type;