From 488cb208166b442f82962a01d6deaf30cf96357d Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Wed, 9 Mar 2022 11:06:54 +0200 Subject: [PATCH] Allow injection of Lambda types into JAX-RS methods via @Context in RESTEasy Reactive Fixes: #24181 --- .../amazon-lambda-http/deployment/pom.xml | 6 ++++- .../deployment/AmazonLambdaHttpProcessor.java | 18 +++++++++++++++ .../deployment/ResteasyReactiveProcessor.java | 17 +++++++++++++- .../server/spi/ContextTypeBuildItem.java | 23 +++++++++++++++++++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 extensions/resteasy-reactive/quarkus-resteasy-reactive/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/ContextTypeBuildItem.java diff --git a/extensions/amazon-lambda-http/deployment/pom.xml b/extensions/amazon-lambda-http/deployment/pom.xml index d14d4ce408f31..f3b04e2293f73 100644 --- a/extensions/amazon-lambda-http/deployment/pom.xml +++ b/extensions/amazon-lambda-http/deployment/pom.xml @@ -39,6 +39,10 @@ io.quarkus quarkus-amazon-lambda-http-event-server + + io.quarkus + quarkus-resteasy-reactive-server-spi-deployment + @@ -56,4 +60,4 @@ - \ No newline at end of file + diff --git a/extensions/amazon-lambda-http/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java b/extensions/amazon-lambda-http/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java index 45dd863768a1b..57ebac086db28 100644 --- a/extensions/amazon-lambda-http/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java +++ b/extensions/amazon-lambda-http/deployment/src/main/java/io/quarkus/amazon/lambda/http/deployment/AmazonLambdaHttpProcessor.java @@ -2,8 +2,10 @@ import static io.vertx.core.file.impl.FileResolverImpl.CACHE_DIR_BASE_PROP_NAME; +import org.jboss.jandex.DotName; import org.jboss.logging.Logger; +import com.amazonaws.services.lambda.runtime.Context; import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPEvent; import com.amazonaws.services.lambda.runtime.events.APIGatewayV2HTTPResponse; @@ -16,16 +18,22 @@ import io.quarkus.amazon.lambda.http.model.Headers; import io.quarkus.amazon.lambda.http.model.MultiValuedTreeMap; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.deployment.UnremovableBeanBuildItem; import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.builditem.SystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.pkg.builditem.ArtifactResultBuildItem; import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; +import io.quarkus.resteasy.reactive.server.spi.ContextTypeBuildItem; import io.quarkus.vertx.http.deployment.RequireVirtualHttpBuildItem; public class AmazonLambdaHttpProcessor { private static final Logger log = Logger.getLogger(AmazonLambdaHttpProcessor.class); + public static final DotName CONTEXT = DotName.createSimple(Context.class.getName()); + public static final DotName API_GATEWAY_HTTP_EVENT = DotName.createSimple(APIGatewayV2HTTPEvent.class.getName()); + public static final DotName REQUEST_CONTEXT = DotName.createSimple( + APIGatewayV2HTTPEvent.RequestContext.class.getName()); @BuildStep public void setupCDI(BuildProducer additionalBeans) { @@ -96,4 +104,14 @@ public void generateScripts(OutputTargetBuildItem target, LambdaUtil.writeFile(target, "sam.native.yaml", output); } + @BuildStep + public void resteasyReactiveIntegration(BuildProducer contextTypeProducer, + BuildProducer unremovableBeanProducer) { + contextTypeProducer.produce(new ContextTypeBuildItem(CONTEXT)); + contextTypeProducer.produce(new ContextTypeBuildItem(API_GATEWAY_HTTP_EVENT)); + contextTypeProducer.produce(new ContextTypeBuildItem(REQUEST_CONTEXT)); + + unremovableBeanProducer.produce(UnremovableBeanBuildItem.beanTypes(CONTEXT, API_GATEWAY_HTTP_EVENT, REQUEST_CONTEXT)); + } + } 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 3c3efd132d1f3..919843ec99b10 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 @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.Deque; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -142,6 +143,7 @@ import io.quarkus.resteasy.reactive.server.runtime.security.EagerSecurityHandler; import io.quarkus.resteasy.reactive.server.runtime.security.SecurityContextOverrideHandler; import io.quarkus.resteasy.reactive.server.spi.AnnotationsTransformerBuildItem; +import io.quarkus.resteasy.reactive.server.spi.ContextTypeBuildItem; import io.quarkus.resteasy.reactive.server.spi.MethodScannerBuildItem; import io.quarkus.resteasy.reactive.server.spi.NonBlockingReturnTypeBuildItem; import io.quarkus.resteasy.reactive.spi.CustomExceptionMapperBuildItem; @@ -355,6 +357,7 @@ public void setupEndpoints(ApplicationIndexBuildItem applicationIndexBuildItem, List applicationClassPredicateBuildItems, List methodScanners, List annotationTransformerBuildItems, + List contextTypeBuildItems, Capabilities capabilities) throws NoSuchMethodException { @@ -412,7 +415,7 @@ public void setupEndpoints(ApplicationIndexBuildItem applicationIndexBuildItem, methodScanners.stream().map(MethodScannerBuildItem::getMethodScanner).collect(toList())) .setIndex(index) .setApplicationIndex(applicationIndexBuildItem.getIndex()) - .addContextTypes(CONTEXT_TYPES) + .addContextTypes(additionalContextTypes(contextTypeBuildItems)) .setFactoryCreator(new QuarkusFactoryCreator(recorder, beanContainerBuildItem.getValue())) .setEndpointInvokerFactory( new QuarkusInvokerFactory(generatedClassBuildItemBuildProducer, recorder)) @@ -601,6 +604,18 @@ private boolean hasAnnotation(MethodInfo method, short paramPosition, DotName an handleDateFormatReflection(reflectiveClass, index); } + private Collection additionalContextTypes(List contextTypeBuildItems) { + if (contextTypeBuildItems.isEmpty()) { + return CONTEXT_TYPES; + } + Set contextTypes = new HashSet<>(CONTEXT_TYPES.size() + contextTypeBuildItems.size()); + contextTypes.addAll(CONTEXT_TYPES); + for (ContextTypeBuildItem bi : contextTypeBuildItems) { + contextTypes.add(bi.getType()); + } + return contextTypes; + } + private void handleDateFormatReflection(BuildProducer reflectiveClass, IndexView index) { Collection dateFormatInstances = index.getAnnotations(DATE_FORMAT); if (dateFormatInstances.isEmpty()) { diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/ContextTypeBuildItem.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/ContextTypeBuildItem.java new file mode 100644 index 0000000000000..cfea09343a228 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/spi-deployment/src/main/java/io/quarkus/resteasy/reactive/server/spi/ContextTypeBuildItem.java @@ -0,0 +1,23 @@ +package io.quarkus.resteasy.reactive.server.spi; + +import javax.ws.rs.core.Context; + +import org.jboss.jandex.DotName; + +import io.quarkus.builder.item.MultiBuildItem; + +/** + * Register types that should be available for injection into JAX-RS methods via {@link Context} + */ +public final class ContextTypeBuildItem extends MultiBuildItem { + + private final DotName type; + + public ContextTypeBuildItem(DotName className) { + this.type = className; + } + + public DotName getType() { + return type; + } +}