diff --git a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java index 96b5a7d3bad69..caa4d1c7d521f 100644 --- a/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java +++ b/extensions/arc/deployment/src/main/java/io/quarkus/arc/deployment/BuildTimeEnabledProcessor.java @@ -52,6 +52,9 @@ public class BuildTimeEnabledProcessor { private static final DotName UNLESS_BUILD_PROPERTY_CONTAINER = DotName .createSimple(UnlessBuildProperty.List.class.getName()); + public static final Set BUILD_TIME_ENABLED_BEAN_ANNOTATIONS = Set.of(IF_BUILD_PROFILE, UNLESS_BUILD_PROFILE, + IF_BUILD_PROPERTY, IF_BUILD_PROPERTY_CONTAINER, UNLESS_BUILD_PROPERTY, UNLESS_BUILD_PROPERTY_CONTAINER); + @BuildStep void ifBuildProfile(CombinedIndexBuildItem index, BuildProducer producer) { Collection annotationInstances = index.getIndex().getAnnotations(IF_BUILD_PROFILE); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveScanningProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveScanningProcessor.java index 8c28403d2b25b..32f47b768d25a 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveScanningProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveScanningProcessor.java @@ -47,6 +47,7 @@ import io.quarkus.arc.ArcUndeclaredThrowableException; import io.quarkus.arc.Unremovable; import io.quarkus.arc.deployment.AdditionalBeanBuildItem; +import io.quarkus.arc.deployment.BuildTimeEnabledProcessor; import io.quarkus.arc.deployment.GeneratedBeanBuildItem; import io.quarkus.arc.deployment.GeneratedBeanGizmoAdaptor; import io.quarkus.arc.processor.DotNames; @@ -310,7 +311,16 @@ public void handleCustomAnnotatedMethods( } List generatedFilters = FilterGeneration.generate(index, - Set.of(HTTP_SERVER_REQUEST, HTTP_SERVER_RESPONSE, ROUTING_CONTEXT), Set.of(Unremovable.class.getName())); + Set.of(HTTP_SERVER_REQUEST, HTTP_SERVER_RESPONSE, ROUTING_CONTEXT), Set.of(Unremovable.class.getName()), + (methodInfo -> { + List classAnnotations = methodInfo.declaringClass().declaredAnnotations(); + for (AnnotationInstance classAnnotation : classAnnotations) { + if (BuildTimeEnabledProcessor.BUILD_TIME_ENABLED_BEAN_ANNOTATIONS.contains(classAnnotation.name())) { + return true; + } + } + return false; + })); for (var generated : generatedFilters) { for (var i : generated.getGeneratedClasses()) { generatedBean.produce(new GeneratedBeanBuildItem(i.getName(), i.getData())); diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/customproviders/ConditionalBeanFiltersTest.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/customproviders/ConditionalBeanFiltersTest.java new file mode 100644 index 0000000000000..847c460533056 --- /dev/null +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/test/java/io/quarkus/resteasy/reactive/server/test/customproviders/ConditionalBeanFiltersTest.java @@ -0,0 +1,149 @@ +package io.quarkus.resteasy.reactive.server.test.customproviders; + +import static io.restassured.RestAssured.*; +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.List; +import java.util.Optional; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Priorities; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; + +import org.hamcrest.Matchers; +import org.jboss.resteasy.reactive.server.ServerRequestFilter; +import org.jboss.resteasy.reactive.server.ServerResponseFilter; +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.arc.profile.IfBuildProfile; +import io.quarkus.arc.properties.IfBuildProperty; +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.http.Header; +import io.smallrye.mutiny.Uni; + +public class ConditionalBeanFiltersTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .setArchiveProducer(new Supplier<>() { + @Override + public JavaArchive get() { + return ShrinkWrap.create(JavaArchive.class) + .addClasses(WontBeEnabledFilter.class, WillBeEnabledFilter.class, AlwaysEnabledFilter.class, + TestResource.class); + } + }); + + @Test + public void testExpectedFilters() { + List responseFiltersValues = get("/test/filters") + .then().statusCode(200) + .body(Matchers.is("void-on,response-on,uni-on,always")) + .extract() + .headers() + .getList("response-filters") + .stream() + .map(Header::getValue) + .collect(Collectors.toList()); + assertThat(responseFiltersValues).containsOnly("always", "void-on", "uni-on"); + } + + @Path("test") + public static class TestResource { + + @Path("filters") + @GET + public String filters(HttpHeaders headers) { + return String.join(",", headers.getRequestHeader("request-filters")); + } + } + + @IfBuildProperty(name = "notexistingproperty", stringValue = "true") + public static class WontBeEnabledFilter { + + @ServerRequestFilter(priority = Priorities.USER + 1) + public void voidRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "void-off"); + } + + @ServerRequestFilter(priority = Priorities.USER + 2) + public Response responseTypeRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "response-off"); + return null; + } + + @ServerRequestFilter(priority = Priorities.USER + 3) + public Uni uniRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "uni-off"); + return Uni.createFrom().nullItem(); + } + + // if any of the following were to be executed, they would fail, thrown an exception and result in an HTTP 500 + + @ServerResponseFilter + public void voidResponseFilter(ContainerResponseContext ctx) { + assertFalse(true); + } + + @ServerResponseFilter + public Uni uniResponseFilter(ContainerResponseContext ctx) { + assertFalse(true); + return Uni.createFrom().nullItem(); + } + } + + @IfBuildProfile("test") + public static class WillBeEnabledFilter { + + @ServerRequestFilter(priority = Priorities.USER + 4) + public void voidRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "void-on"); + } + + @ServerRequestFilter(priority = Priorities.USER + 5) + public Optional responseTypeRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "response-on"); + return Optional.empty(); + } + + @ServerRequestFilter(priority = Priorities.USER + 6) + public Uni uniRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "uni-on"); + return Uni.createFrom().nullItem(); + } + + @ServerResponseFilter(priority = Priorities.USER + 4) + public void voidResponseFilter(ContainerResponseContext ctx) { + ctx.getHeaders().add("response-filters", "void-on"); + } + + @ServerResponseFilter(priority = Priorities.USER + 6) + public Uni uniResponseFilter(ContainerResponseContext ctx) { + ctx.getHeaders().add("response-filters", "uni-on"); + return Uni.createFrom().nullItem(); + } + } + + public static class AlwaysEnabledFilter { + + @ServerRequestFilter(priority = Priorities.USER + 100) + public void alwaysRequestFilter(ContainerRequestContext requestContext) { + requestContext.getHeaders().add("request-filters", "always"); + } + + @ServerResponseFilter(priority = Priorities.USER + 100) + public void voidResponseFilter(ContainerResponseContext ctx) { + ctx.getHeaders().add("response-filters", "always"); + } + } +} diff --git a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java index 734804776609a..f6c131328b41a 100644 --- a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java +++ b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/CustomFilterGenerator.java @@ -17,9 +17,11 @@ import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.function.Predicate; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.RequestScoped; +import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.container.ContainerRequestContext; @@ -56,6 +58,7 @@ import io.quarkus.gizmo.AssignableResultHandle; import io.quarkus.gizmo.BranchResult; +import io.quarkus.gizmo.BytecodeCreator; import io.quarkus.gizmo.ClassCreator; import io.quarkus.gizmo.ClassOutput; import io.quarkus.gizmo.FieldDescriptor; @@ -75,21 +78,25 @@ final class CustomFilterGenerator { private final Set unwrappableTypes; private final Set additionalBeanAnnotations; + private final Predicate isOptionalFilter; - CustomFilterGenerator(Set unwrappableTypes, Set additionalBeanAnnotations) { + CustomFilterGenerator(Set unwrappableTypes, Set additionalBeanAnnotations, + Predicate isOptionalFilter) { this.unwrappableTypes = unwrappableTypes; this.additionalBeanAnnotations = additionalBeanAnnotations; + this.isOptionalFilter = isOptionalFilter; } String generateContainerRequestFilter(MethodInfo targetMethod, ClassOutput classOutput) { checkModifiers(targetMethod, ResteasyReactiveServerDotNames.SERVER_REQUEST_FILTER); if (KotlinUtils.isSuspendMethod(targetMethod)) { - return generateRequestFilterForSuspendedMethod(targetMethod, classOutput); + return generateRequestFilterForSuspendedMethod(targetMethod, classOutput, isOptionalFilter.test(targetMethod)); } - return generateStandardRequestFilter(targetMethod, classOutput); + return generateStandardRequestFilter(targetMethod, classOutput, isOptionalFilter.test(targetMethod)); } - private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, ClassOutput classOutput) { + private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, ClassOutput classOutput, + boolean checkForOptionalBean) { DotName returnDotName = determineReturnDotNameOfSuspendMethod(targetMethod); ReturnType returnType; if (returnDotName.equals(VOID)) { @@ -112,14 +119,21 @@ private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, .superClass(ABSTRACT_SUSPENDED_REQ_FILTER) .build()) { FieldDescriptor delegateField = generateConstructorAndDelegateField(cc, declaringClass, - ABSTRACT_SUSPENDED_REQ_FILTER, additionalBeanAnnotations); + ABSTRACT_SUSPENDED_REQ_FILTER, additionalBeanAnnotations, checkForOptionalBean); // generate the implementation of the 'doFilter' method MethodCreator doFilterMethod = cc.getMethodCreator("doFilter", Object.class.getName(), ResteasyReactiveContainerRequestContext.class.getName(), ResteasyReactiveDotNames.CONTINUATION.toString()); + ResultHandle delegate = doFilterMethod.readInstanceField(delegateField, doFilterMethod.getThis()); + + if (checkForOptionalBean) { + // if the delegate is null (because there was no bean of the target type, just return), + doFilterMethod.ifNull(delegate).trueBranch().returnNull(); + } + // call the target method ResultHandle resultHandle = doFilterMethod.invokeVirtualMethod(targetMethod, - doFilterMethod.readInstanceField(delegateField, doFilterMethod.getThis()), + delegate, getRequestFilterResultHandles(targetMethod, declaringClassName, doFilterMethod, 2, getRRReqCtxHandle(doFilterMethod, getRRContainerReqCtxHandle(doFilterMethod, 0)))); doFilterMethod.returnValue(resultHandle); @@ -151,7 +165,7 @@ private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, Uni.class, ResteasyReactiveContainerRequestContext.class), handleResultMethod.getMethodParam(1), getRRContainerReqCtxHandle(handleResultMethod, 0)); - handleResultMethod.returnValue(null); + handleResultMethod.returnNull(); } return generatedClassName; @@ -186,7 +200,8 @@ private String generateRequestFilterForSuspendedMethod(MethodInfo targetMethod, * * */ - private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutput classOutput) { + private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutput classOutput, + boolean checkForOptionalBean) { ReturnType returnType = determineRequestFilterReturnType(targetMethod); String generatedClassName = getGeneratedClassName(targetMethod, ResteasyReactiveServerDotNames.SERVER_REQUEST_FILTER); ClassInfo declaringClass = targetMethod.declaringClass(); @@ -196,7 +211,7 @@ private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutpu .interfaces(determineRequestInterfaceType(returnType)) .build()) { FieldDescriptor delegateField = generateConstructorAndDelegateField(cc, declaringClass, - Object.class.getName(), additionalBeanAnnotations); + Object.class.getName(), additionalBeanAnnotations, checkForOptionalBean); if (returnType == ReturnType.VOID || returnType == ReturnType.OPTIONAL_RESPONSE @@ -205,10 +220,23 @@ private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutpu || returnType == ReturnType.REST_RESPONSE) { // generate the implementation of the filter method MethodCreator filterMethod = cc.getMethodCreator("filter", void.class, ContainerRequestContext.class); + ResultHandle delegate = filterMethod.readInstanceField(delegateField, filterMethod.getThis()); + + if (checkForOptionalBean) { + // if the delegate is null (because there was no bean of the target type, just return), + BytecodeCreator delegateIsNull = filterMethod.ifNull(delegate).trueBranch(); + if (returnType == ReturnType.VOID) { + delegateIsNull.returnVoid(); + } else { + delegateIsNull.returnNull(); + } + } + ResultHandle rrContainerReqCtxHandle = getRRContainerReqCtxHandle(filterMethod, 0); // call the target method + ResultHandle resultHandle = filterMethod.invokeVirtualMethod(targetMethod, - filterMethod.readInstanceField(delegateField, filterMethod.getThis()), + delegate, getRequestFilterResultHandles(targetMethod, declaringClassName, filterMethod, 1, getRRReqCtxHandle(filterMethod, rrContainerReqCtxHandle))); if (returnType == ReturnType.OPTIONAL_RESPONSE) { @@ -241,6 +269,13 @@ private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutpu // generate the implementation of the filter method MethodCreator filterMethod = cc.getMethodCreator("filter", void.class, ResteasyReactiveContainerRequestContext.class); + + if (checkForOptionalBean) { + // if the delegate is null (because there was no bean of the target type, just return), + filterMethod.ifNull(filterMethod.readInstanceField(delegateField, filterMethod.getThis())).trueBranch() + .returnNull(); + } + // call the target method ResultHandle rrContainerReqCtxHandle = getRRContainerReqCtxHandle(filterMethod, 0); ResultHandle uniHandle = filterMethod.invokeVirtualMethod(targetMethod, @@ -270,7 +305,7 @@ private String generateStandardRequestFilter(MethodInfo targetMethod, ClassOutpu void.class, Uni.class, ResteasyReactiveContainerRequestContext.class), uniHandle, rrContainerReqCtxHandle); - filterMethod.returnValue(null); + filterMethod.returnNull(); } else { throw new IllegalStateException("ReturnType: '" + returnType + "' is not supported, in method " + targetMethod.declaringClass() + "." + targetMethod.name()); @@ -332,12 +367,13 @@ private ResultHandle[] getRequestFilterResultHandles(MethodInfo targetMethod, Do String generateContainerResponseFilter(MethodInfo targetMethod, ClassOutput classOutput) { checkModifiers(targetMethod, ResteasyReactiveServerDotNames.SERVER_RESPONSE_FILTER); if (KotlinUtils.isSuspendMethod(targetMethod)) { - return generateResponseFilterForSuspendedMethod(targetMethod, classOutput); + return generateResponseFilterForSuspendedMethod(targetMethod, classOutput, isOptionalFilter.test(targetMethod)); } - return generateStandardContainerResponseFilter(targetMethod, classOutput); + return generateStandardContainerResponseFilter(targetMethod, classOutput, isOptionalFilter.test(targetMethod)); } - private String generateResponseFilterForSuspendedMethod(MethodInfo targetMethod, ClassOutput classOutput) { + private String generateResponseFilterForSuspendedMethod(MethodInfo targetMethod, ClassOutput classOutput, + boolean checkForOptionalBean) { DotName returnDotName = determineReturnDotNameOfSuspendMethod(targetMethod); if (!returnDotName.equals(VOID)) { throw new RuntimeException("Suspend method '" + targetMethod.name() + " of class '" @@ -352,7 +388,7 @@ private String generateResponseFilterForSuspendedMethod(MethodInfo targetMethod, .superClass(ABSTRACT_SUSPENDED_RES_FILTER) .build()) { FieldDescriptor delegateField = generateConstructorAndDelegateField(cc, declaringClass, - ABSTRACT_SUSPENDED_RES_FILTER, additionalBeanAnnotations); + ABSTRACT_SUSPENDED_RES_FILTER, additionalBeanAnnotations, checkForOptionalBean); // generate the implementation of the filter method MethodCreator doFilterMethod = cc.getMethodCreator("doFilter", Object.class.getName(), @@ -401,7 +437,8 @@ private String generateResponseFilterForSuspendedMethod(MethodInfo targetMethod, * * */ - private String generateStandardContainerResponseFilter(MethodInfo targetMethod, ClassOutput classOutput) { + private String generateStandardContainerResponseFilter(MethodInfo targetMethod, ClassOutput classOutput, + boolean checkForOptionalBean) { ReturnType returnType = determineResponseFilterReturnType(targetMethod); String generatedClassName = getGeneratedClassName(targetMethod, ResteasyReactiveServerDotNames.SERVER_RESPONSE_FILTER); ClassInfo declaringClassInfo = targetMethod.declaringClass(); @@ -411,13 +448,18 @@ private String generateStandardContainerResponseFilter(MethodInfo targetMethod, .interfaces(determineResponseInterfaceType(returnType)) .build()) { FieldDescriptor delegateField = generateConstructorAndDelegateField(cc, declaringClassInfo, - Object.class.getName(), additionalBeanAnnotations); + Object.class.getName(), additionalBeanAnnotations, checkForOptionalBean); if (returnType == ReturnType.VOID) { // generate the implementation of the filter method MethodCreator filterMethod = cc.getMethodCreator("filter", void.class, ContainerRequestContext.class, ContainerResponseContext.class); + if (checkForOptionalBean) { + filterMethod.ifNull(filterMethod.readInstanceField(delegateField, filterMethod.getThis())).trueBranch() + .returnVoid(); + } + ResultHandle rrContainerReqCtxHandle = getRRContainerReqCtxHandle(filterMethod, 0); ResultHandle rrReqCtxHandle = getRRReqCtxHandle(filterMethod, rrContainerReqCtxHandle); @@ -433,6 +475,11 @@ private String generateStandardContainerResponseFilter(MethodInfo targetMethod, ResteasyReactiveContainerRequestContext.class, ContainerResponseContext.class); + if (checkForOptionalBean) { + filterMethod.ifNull(filterMethod.readInstanceField(delegateField, filterMethod.getThis())).trueBranch() + .returnNull(); + } + ResultHandle rrContainerReqCtxHandle = getRRContainerReqCtxHandle(filterMethod, 0); ResultHandle rrReqCtxHandle = getRRReqCtxHandle(filterMethod, rrContainerReqCtxHandle); @@ -454,7 +501,8 @@ private String generateStandardContainerResponseFilter(MethodInfo targetMethod, } private FieldDescriptor generateConstructorAndDelegateField(ClassCreator cc, ClassInfo declaringClass, - String superClassName, Set additionalBeanAnnotations) { + String superClassName, Set additionalBeanAnnotations, + boolean checkForOptionalBean) { String declaringClassName = declaringClass.toString(); ScopeInspectionResult scopeInspectionResult = inspectScope(declaringClass); @@ -470,14 +518,35 @@ private FieldDescriptor generateConstructorAndDelegateField(ClassCreator cc, Cla .setModifiers(Modifier.PRIVATE | Modifier.FINAL) .getFieldDescriptor(); - // generate a constructor that takes the target class as an argument - this class is a CDI bean so Arc will be able to inject into the generated class - MethodCreator ctor = cc.getMethodCreator("", void.class, declaringClassName); + MethodCreator ctor; + if (checkForOptionalBean) { + // generate a constructor that takes the Instance as an argument + ctor = cc.getMethodCreator("", void.class, Instance.class).setSignature( + String.format("(Ljavax/enterprise/inject/Instance;)V", declaringClassName.replace('.', '/'))); + } else { + // generate a constructor that takes the target class as an argument - this class is a CDI bean so Arc will be able to inject into the generated class + ctor = cc.getMethodCreator("", void.class, declaringClassName); + } ctor.setModifiers(Modifier.PUBLIC); ctor.addAnnotation(Inject.class); ctor.invokeSpecialMethod(MethodDescriptor.ofConstructor(superClassName), ctor.getThis()); ResultHandle self = ctor.getThis(); - ResultHandle delegate = ctor.getMethodParam(0); - ctor.writeInstanceField(delegateField, self, delegate); + if (checkForOptionalBean) { + ResultHandle instance = ctor.getMethodParam(0); + ResultHandle isResolvable = ctor + .invokeInterfaceMethod(MethodDescriptor.ofMethod(Instance.class, "isResolvable", boolean.class), instance); + BranchResult isResolvableBranch = ctor.ifTrue(isResolvable); + + BytecodeCreator isResolvableTrue = isResolvableBranch.trueBranch(); + isResolvableTrue.writeInstanceField(delegateField, self, isResolvableTrue + .invokeInterfaceMethod(MethodDescriptor.ofMethod(Instance.class, "get", Object.class), instance)); + + BytecodeCreator isResolvableFalse = isResolvableBranch.falseBranch(); + isResolvableFalse.writeInstanceField(delegateField, self, isResolvableFalse.loadNull()); + } else { + ctor.writeInstanceField(delegateField, self, ctor.getMethodParam(0)); + } + ctor.returnValue(null); if (scopeInspectionResult.needsProxy) { diff --git a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterFeature.java b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterFeature.java index 9ab190b5315eb..afdbe40f27d42 100644 --- a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterFeature.java +++ b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterFeature.java @@ -34,7 +34,7 @@ public FilterFeature(Set unwrappableTypes, Set additionalBeanAn public FeatureScanResult integrate(IndexView application, ScannedApplication scannedApplication) { List generatedClasses = new ArrayList<>(); List result = FilterGeneration.generate(application, unwrappableTypes, - additionalBeanAnnotations); + additionalBeanAnnotations, (m) -> false); for (var i : result) { generatedClasses.addAll(i.getGeneratedClasses()); if (i.isRequestFilter()) { diff --git a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterGeneration.java b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterGeneration.java index 3935127456de6..9d07114902225 100644 --- a/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterGeneration.java +++ b/independent-projects/resteasy-reactive/server/processor/src/main/java/org/jboss/resteasy/reactive/server/processor/generation/filters/FilterGeneration.java @@ -7,6 +7,7 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Predicate; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; @@ -21,7 +22,7 @@ public class FilterGeneration { public static List generate(IndexView index, Set unwrappableTypes, - Set additionalBeanAnnotations) { + Set additionalBeanAnnotations, Predicate isOptionalFilter) { List ret = new ArrayList<>(); for (AnnotationInstance instance : index .getAnnotations(SERVER_REQUEST_FILTER)) { @@ -30,7 +31,7 @@ public static List generate(IndexView index, Set unwra } MethodInfo methodInfo = instance.target().asMethod(); GeneratedClassOutput output = new GeneratedClassOutput(); - String generatedClassName = new CustomFilterGenerator(unwrappableTypes, additionalBeanAnnotations) + String generatedClassName = new CustomFilterGenerator(unwrappableTypes, additionalBeanAnnotations, isOptionalFilter) .generateContainerRequestFilter(methodInfo, output); Integer priority = null; boolean preMatching = false; @@ -88,7 +89,8 @@ public static List generate(IndexView index, Set unwra Integer priority = null; Set nameBindingNames = new HashSet<>(); GeneratedClassOutput output = new GeneratedClassOutput(); - String generatedClassName = new CustomFilterGenerator(unwrappableTypes, additionalBeanAnnotations) + String generatedClassName = new CustomFilterGenerator(unwrappableTypes, additionalBeanAnnotations, + isOptionalFilter) .generateContainerResponseFilter(methodInfo, output); AnnotationValue priorityValue = instance.value("priority");