Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
import io.quarkus.vertx.http.runtime.security.SecurityHandlerPriorities;
import io.smallrye.openapi.api.OpenApiConfig;
import io.smallrye.openapi.api.OpenApiDocument;
import io.smallrye.openapi.api.OperationHandler;
import io.smallrye.openapi.api.SmallRyeOpenAPI;
import io.smallrye.openapi.api.constants.SecurityConstants;
import io.smallrye.openapi.api.util.MergeUtil;
Expand Down Expand Up @@ -881,7 +882,13 @@ private void registerReflectionForApiResponseSchemaSerialization(BuildProducer<R
}
}

private void handleOperation(Operation operation, ClassInfo classInfo, MethodInfo method) {
/**
* Callback invoked by the smallrye-open-api annotation scanner for each discovered API
* operation. We use this to set a (private) extension in the OpenAPI model which is then
* used by the {@link OperationFilter} to match operations with the security and
* tag information discovered earlier in the build by this class.
*/
private void addMethodReferenceExtension(Operation operation, ClassInfo classInfo, MethodInfo method) {
String methodRef = createUniqueMethodReference(classInfo, method);
operation.addExtension(OperationFilter.EXT_METHOD_REF, methodRef);
}
Expand All @@ -906,6 +913,16 @@ public void build(BuildProducer<GeneratedResourceBuildItem> resourceBuildItemBui
.map(IgnoreStaticDocumentBuildItem::getUrlIgnorePattern)
.toList();

/*
* Only add method references if the OperationFilter is enabled. Otherwise,
* they are not needed.
*/
OperationHandler operationHandler = openAPIBuildItems.stream()
.map(AddToOpenAPIDefinitionBuildItem::getOASFilter)
.anyMatch(OperationFilter.class::isInstance)
? this::addMethodReferenceExtension
: OperationHandler.DEFAULT;

SmallRyeOpenAPI.Builder builder = SmallRyeOpenAPI.builder()
.withConfig(config)
.withIndex(index)
Expand All @@ -926,7 +943,7 @@ public void build(BuildProducer<GeneratedResourceBuildItem> resourceBuildItemBui
.withScannerFilter(getScannerFilter(capabilities, index))
.withContextRootResolver(getContextRootResolver(config, capabilities, httpRootPathBuildItem))
.withTypeConverter(getTypeConverter(index, capabilities))
.withOperationHandler(this::handleOperation)
.withOperationHandler(operationHandler)
.enableUnannotatedPathParameters(capabilities.isPresent(Capability.RESTEASY_REACTIVE))
.enableStandardFilter(false)
.withFilters(openAPIBuildItems.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package io.quarkus.smallrye.openapi.test.jaxrs;

import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.not;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.smallrye.openapi.deployment.filter.OperationFilter;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

/**
* Verify that method reference extensions are not added to the OpenAPI model when the
* {@link OperationFilter} is not in use (disabled via several configuration properties).
*/
class DisabledOperationFilterTestCase {
@RegisterExtension
static QuarkusUnitTest runner = new QuarkusUnitTest()
.withApplicationRoot(jar -> jar
.addClasses(Endpoint.class)
.add(new StringAsset("""
quarkus.smallrye-openapi.auto-add-operation-summary=false
quarkus.smallrye-openapi.auto-add-tags=false
quarkus.smallrye-openapi.auto-add-security-requirement=false
"""), "application.properties"));

@Path("/api")
public static class Endpoint {
@Path("/op1")
@GET
public String op1() {
return null;
}

@Path("/op2")
@GET
public String op2() {
return null;
}
}

@Test
void testMethodRefExtensionsAbsent() {
RestAssured.given().header("Accept", "application/json")
.when().get("/q/openapi")
.then()
.log().ifValidationFails()
.body("paths.\"/api/op1\".get", not(hasKey(OperationFilter.EXT_METHOD_REF)))
.body("paths.\"/api/op2\".get", not(hasKey(OperationFilter.EXT_METHOD_REF)));
}
}
Loading