From fe3129c8347842948c429ecd8eed66d591991231 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Mon, 19 Feb 2024 11:34:15 +0200 Subject: [PATCH] Add configuration option for resuming on 404 This is a useful (albeit advanced) option for users that want to use custom routes to handle cases where RESTEasy Reactive does not match the URL path. Closes: #38840 --- .../runtime/ResteasyReactiveConfig.java | 8 ++ .../deployment/ResteasyReactiveProcessor.java | 4 +- .../server/test/ResumeOn404ConfigTest.java | 73 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/ResumeOn404ConfigTest.java diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ResteasyReactiveConfig.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ResteasyReactiveConfig.java index 611d0ccd64fb7..efd5cdedfa0d8 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ResteasyReactiveConfig.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/src/main/java/io/quarkus/resteasy/reactive/common/runtime/ResteasyReactiveConfig.java @@ -67,4 +67,12 @@ public interface ResteasyReactiveConfig { */ @WithDefault("true") boolean failOnDuplicate(); + + /** + * An advanced option that can be set when they RESTEasy Reactive should NOT reply with 404 when it does not match the URL + * path + * and instead just pass control onto the next Vert.x handler (if any) + */ + @WithDefault("false") + boolean resumeOn404(); } diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java index c82aeca8fe561..ef97ce8b74dff 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java @@ -1281,10 +1281,12 @@ public void setupDeployment(BeanContainerBuildItem beanContainerBuildItem, servletPresent = true; } + boolean resumeOn404 = servletPresent || !resumeOn404Items.isEmpty() || config.resumeOn404(); + RuntimeValue deployment = recorder.createDeployment(deploymentInfo, beanContainerBuildItem.getValue(), shutdownContext, vertxConfig, requestContextFactoryBuildItem.map(RequestContextFactoryBuildItem::getFactory).orElse(null), - initClassFactory, launchModeBuildItem.getLaunchMode(), servletPresent || !resumeOn404Items.isEmpty()); + initClassFactory, launchModeBuildItem.getLaunchMode(), resumeOn404); quarkusRestDeploymentBuildItemBuildProducer .produce(new ResteasyReactiveDeploymentBuildItem(deployment, deploymentPath)); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/ResumeOn404ConfigTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/ResumeOn404ConfigTest.java new file mode 100644 index 0000000000000..94d9d95800693 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/ResumeOn404ConfigTest.java @@ -0,0 +1,73 @@ +package io.quarkus.resteasy.reactive.server.test; + +import static io.restassured.RestAssured.get; + +import java.util.function.Supplier; + +import jakarta.enterprise.context.RequestScoped; +import jakarta.enterprise.event.Observes; +import jakarta.ws.rs.GET; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.Produces; +import jakarta.ws.rs.core.MediaType; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.vertx.ext.web.Router; + +public class ResumeOn404ConfigTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(Resource.class, CustomRoute.class); + } + }) + .overrideRuntimeConfigKey("quarkus.resteasy-reactive.resume-on-404", "true"); + + @Test + public void matchingFromResteasyReactive() { + get("/test") + .then() + .statusCode(200); + } + + @Test + public void matchingFromCustomRoute() { + get("/main") + .then() + .statusCode(200); + } + + @Test + public void missing() { + get("/dummy") + .then() + .statusCode(404); + } + + @Path("/test") + @RequestScoped + public static class Resource { + @GET + @Produces(MediaType.TEXT_PLAIN) + public String hello() { + return "test"; + } + + } + + public static class CustomRoute { + + public void initMain(@Observes Router router) { + router.get("/main").handler(rc -> rc.response().end("main")); + } + } +}