Skip to content

Commit

Permalink
Add OperationHandler callback
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Edgar <[email protected]>
  • Loading branch information
MikeEdgar committed Oct 18, 2024
1 parent 70a85e5 commit 3a3c27c
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
38 changes: 38 additions & 0 deletions core/src/main/java/io/smallrye/openapi/api/OperationHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.smallrye.openapi.api;

import org.eclipse.microprofile.openapi.models.Operation;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.MethodInfo;

/**
* Handler interface for a platform integration layer to inspect or modify an operation.
*
* The resource method and class from which the operation was constructed are
* also provided.
*
* @since 4.0
*/
@FunctionalInterface
public interface OperationHandler {

static final OperationHandler DEFAULT = (o, c, m) -> {
};

/**
* Callback to allow modification to an {@link Operation operation},
* together with the associated resource class and resource method
* associated with the operation.
*
* @param operation
* the OpenAPI operation model created from the resource
* class/method
* @param resourceClass
* the resource class that hosts REST endpoint methods
* @param resourceMethod
* resource method for a REST request. The method's declaring
* class may differ from the resource class. For example it may
* have been declared in an abstract class or interface.
*/
void handleOperation(Operation operation, ClassInfo resourceClass, MethodInfo resourceMethod);

}
16 changes: 15 additions & 1 deletion core/src/main/java/io/smallrye/openapi/api/SmallRyeOpenAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ public static class Builder {
private boolean enableUnannotatedPathParameters = false;
private ClassLoader scannerClassLoader;
private Predicate<String> scannerFilter = n -> true;
private OperationHandler operationHandler = OperationHandler.DEFAULT;

private Function<Collection<ClassInfo>, String> contextRootResolver = apps -> null;
private UnaryOperator<Type> typeConverter = UnaryOperator.identity();
Expand Down Expand Up @@ -418,6 +419,19 @@ public Builder withScannerFilter(Predicate<String> scannerFilter) {
return this;
}

/**
* Provide an {@link OperationHandler} to be called for each operation discovered
* during annotation scanning.
*
* @param handler a non-null implementation of an {@link OperationHandler}
* @return this builder
*/
public Builder withOperationHandler(OperationHandler handler) {
removeContext();
this.operationHandler = Objects.requireNonNull(handler);
return this;
}

/**
* Provide a collection of OASFilter instances to apply to the final OpenAPI model. The
* filters will be executed in the same order as given in the collection.
Expand Down Expand Up @@ -585,7 +599,7 @@ protected <V, A extends V, O extends V, AB, OB> void buildAnnotationModel(BuildC
ctx.buildConfig.setAllowNakedPathParameter(enableUnannotatedPathParameters);
AnnotationScannerExtension ext = newExtension(ctx.modelIO);
AnnotationScannerContext scannerContext = new AnnotationScannerContext(ctx.filteredIndex, ctx.appClassLoader,
Collections.singletonList(ext), false, ctx.buildConfig, ctx.modelIO, new OpenAPIImpl());
Collections.singletonList(ext), false, ctx.buildConfig, operationHandler, new OpenAPIImpl());
ctx.modelIO.ioContext().scannerContext(scannerContext);
Supplier<Iterable<AnnotationScanner>> supplier = Optional.ofNullable(scannerClassLoader)
.map(AnnotationScannerFactory::new)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ default Optional<Operation> processOperation(final AnnotationScannerContext cont
operation.setOperationId(operationId);
}

context.getOperationHandler().handleOperation(operation, resourceClass, method);

// validate operationId
String operationId = operation.getOperationId();
if (operationId != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.UnaryOperator;
Expand All @@ -18,9 +19,9 @@
import org.jboss.jandex.Type;

import io.smallrye.openapi.api.OpenApiConfig;
import io.smallrye.openapi.api.OperationHandler;
import io.smallrye.openapi.api.models.OpenAPIImpl;
import io.smallrye.openapi.runtime.io.IOContext;
import io.smallrye.openapi.runtime.io.OpenAPIDefinitionIO;
import io.smallrye.openapi.runtime.scanner.AnnotationScannerExtension;
import io.smallrye.openapi.runtime.scanner.FilteredIndexView;
import io.smallrye.openapi.runtime.scanner.SchemaRegistry;
Expand All @@ -47,6 +48,7 @@ public class AnnotationScannerContext {
private final OpenApiConfig config;
private final UnaryOperator<String> propertyNameTranslator;
private final ClassLoader classLoader;
private final OperationHandler operationHandler;
private final OpenAPI openApi;
private final Deque<Type> scanStack = new ArrayDeque<>();
private Deque<TypeResolver> resolverStack = new ArrayDeque<>();
Expand All @@ -61,7 +63,6 @@ public class AnnotationScannerContext {
private final JavaSecurityProcessor javaSecurityProcessor;
private final Annotations annotations;
private final IOContext<?, ?, ?, ?, ?> ioContext;
private final OpenAPIDefinitionIO<?, ?, ?, ?, ?> modelIO;

private final Map<String, MethodInfo> operationIdMap = new HashMap<>();

Expand All @@ -70,21 +71,21 @@ public AnnotationScannerContext(FilteredIndexView index,
List<AnnotationScannerExtension> extensions,
boolean addDefaultExtension,
OpenApiConfig config,
OpenAPIDefinitionIO<?, ?, ?, ?, ?> modelIO,
OperationHandler operationHandler,
OpenAPI openApi) {
this.index = index;
this.augmentedIndex = AugmentedIndexView.augment(index);
this.ignoreResolver = new IgnoreResolver(this);
this.classLoader = classLoader;
this.config = config;
this.operationHandler = Objects.requireNonNullElse(operationHandler, OperationHandler.DEFAULT);
this.openApi = openApi;
this.propertyNameTranslator = PropertyNamingStrategyFactory.getStrategy(config.propertyNamingStrategy(), classLoader);
this.beanValidationScanner = config.scanBeanValidation() ? Optional.of(new BeanValidationScanner(this))
: Optional.empty();
this.javaSecurityProcessor = new JavaSecurityProcessor(this);
this.annotations = new Annotations(this);
this.ioContext = IOContext.forScanning(this);
this.modelIO = modelIO != null ? modelIO : new OpenAPIDefinitionIO<>(ioContext);
if (extensions.isEmpty()) {
this.extensions = AnnotationScannerExtension.defaultExtension(this);
} else {
Expand Down Expand Up @@ -129,6 +130,10 @@ public OpenApiConfig getConfig() {
return config;
}

public OperationHandler getOperationHandler() {
return operationHandler;
}

public UnaryOperator<String> getPropertyNameTranslator() {
return propertyNameTranslator;
}
Expand Down

0 comments on commit 3a3c27c

Please sign in to comment.