Skip to content

Add RouterOperationCustomizer #1706

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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 @@ -84,6 +84,7 @@
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springdoc.core.customizers.OpenApiLocaleCustomizer;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springdoc.core.customizers.RouterOperationCustomizer;
import org.springdoc.core.filters.OpenApiMethodFilter;
import org.springdoc.core.fn.AbstractRouterFunctionVisitor;
import org.springdoc.core.fn.RouterFunctionData;
Expand Down Expand Up @@ -119,6 +120,7 @@
* The type Abstract open api resource.
* @author bnasslahsen
* @author kevinraddatz
* @author hyeonisism
*/
public abstract class AbstractOpenApiResource extends SpecFilter {

Expand Down Expand Up @@ -177,6 +179,11 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
*/
private final Optional<List<OperationCustomizer>> operationCustomizers;

/**
* The RouterOperation customizers.
*/
private final Optional<List<RouterOperationCustomizer>> routerOperationCustomizers;

/**
* The method filters to use.
*/
Expand Down Expand Up @@ -216,6 +223,7 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
* @param operationParser the operation parser
* @param operationCustomizers the operation customizers
* @param openApiCustomisers the open api customisers
* @param routerOperationCustomizers the router operation customisers
* @param methodFilters the method filters
* @param springDocConfigProperties the spring doc config properties
* @param springDocProviders the spring doc providers
Expand All @@ -225,6 +233,7 @@ protected AbstractOpenApiResource(String groupName, ObjectFactory<OpenAPIService
GenericResponseService responseBuilder, OperationService operationParser,
Optional<List<OperationCustomizer>> operationCustomizers,
Optional<List<OpenApiCustomiser>> openApiCustomisers,
Optional<List<RouterOperationCustomizer>> routerOperationCustomizers,
Optional<List<OpenApiMethodFilter>> methodFilters,
SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
super();
Expand All @@ -235,6 +244,7 @@ protected AbstractOpenApiResource(String groupName, ObjectFactory<OpenAPIService
this.responseBuilder = responseBuilder;
this.operationParser = operationParser;
this.openApiCustomisers = openApiCustomisers;
this.routerOperationCustomizers = routerOperationCustomizers;
this.methodFilters = methodFilters;
this.springDocProviders = springDocProviders;
//add the default customizers
Expand Down Expand Up @@ -381,6 +391,9 @@ protected synchronized OpenAPI getOpenApi(Locale locale) {
*/
protected void calculatePath(HandlerMethod handlerMethod,
RouterOperation routerOperation, Locale locale, OpenAPI openAPI) {

routerOperation = customiseRouterOperation(routerOperation, handlerMethod);

String operationPath = routerOperation.getPath();
Set<RequestMethod> requestMethods = new HashSet<>(Arrays.asList(routerOperation.getMethods()));
io.swagger.v3.oas.annotations.Operation apiOperation = routerOperation.getOperation();
Expand Down Expand Up @@ -608,12 +621,15 @@ protected void calculatePath(RouterOperation routerOperation, Locale locale, Ope
* @param consumes the consumes
* @param produces the produces
* @param headers the headers
* @param params the params
* @param locale the locale
* @param openAPI the open api
*/
protected void calculatePath(HandlerMethod handlerMethod, String operationPath,
Set<RequestMethod> requestMethods, String[] consumes, String[] produces, String[] headers, Locale locale, OpenAPI openAPI) {
this.calculatePath(handlerMethod, new RouterOperation(operationPath, requestMethods.toArray(new RequestMethod[requestMethods.size()]), consumes, produces, headers), locale, openAPI);
Set<RequestMethod> requestMethods, String[] consumes, String[] produces, String[] headers, String[] params, Locale locale, OpenAPI openAPI) {
this.calculatePath(handlerMethod,
new RouterOperation(operationPath, requestMethods.toArray(new RequestMethod[requestMethods.size()]), consumes, produces, headers, params),
locale, openAPI);
}

/**
Expand Down Expand Up @@ -794,7 +810,6 @@ public static boolean containsResponseBody(HandlerMethod handlerMethod) {
return responseBodyAnnotation != null;
}


/**
* Is rest controller boolean.
*
Expand Down Expand Up @@ -849,6 +864,22 @@ protected Operation customiseOperation(Operation operation, HandlerMethod handle
return operation;
}

/**
* Customise router operation
* @param routerOperation
* @param handlerMethod
* @return the router operation
*/
protected RouterOperation customiseRouterOperation(RouterOperation routerOperation, HandlerMethod handlerMethod) {
if (routerOperationCustomizers.isPresent()) {
List<RouterOperationCustomizer> routerOperationCustomizerList = routerOperationCustomizers.get();
for (RouterOperationCustomizer routerOperationCustomizer : routerOperationCustomizerList) {
routerOperation = routerOperationCustomizer.customize(routerOperation, handlerMethod);
}
}
return routerOperation;
}

/**
* Merge routers.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springdoc.core.customizers.RouterOperationCustomizer;
import org.springdoc.core.filters.OpenApiMethodFilter;

import org.springframework.util.CollectionUtils;
Expand Down Expand Up @@ -58,6 +59,11 @@ public class GroupedOpenApi {
*/
private List<OperationCustomizer> operationCustomizers;

/**
* The Router Operation customizers.
*/
private List<RouterOperationCustomizer> routerOperationCustomizers;

/**
* The Paths to match.
*/
Expand Down Expand Up @@ -120,6 +126,7 @@ private GroupedOpenApi(Builder builder) {
this.displayName = StringUtils.defaultIfEmpty(builder.displayName, this.group);
this.openApiCustomisers = Objects.requireNonNull(builder.openApiCustomisers);
this.operationCustomizers = Objects.requireNonNull(builder.operationCustomizers);
this.routerOperationCustomizers = Objects.requireNonNull(builder.routerOperationCustomizers);
this.openApiMethodFilters = Objects.requireNonNull(builder.methodFilters);
if (CollectionUtils.isEmpty(this.pathsToMatch)
&& CollectionUtils.isEmpty(this.packagesToScan)
Expand Down Expand Up @@ -242,6 +249,15 @@ public List<OpenApiMethodFilter> getOpenApiMethodFilters() {
return openApiMethodFilters;
}

/**
* Gets router operation customizers.
*
* @return the router operation customizers
*/
public List<RouterOperationCustomizer> getRouterOperationCustomizers() {
return routerOperationCustomizers;
}

/**
* Gets display name.
*
Expand All @@ -266,6 +282,11 @@ public static class Builder {
*/
private final List<OperationCustomizer> operationCustomizers = new ArrayList<>();

/**
* The Router Operation customizers.
*/
private final List<RouterOperationCustomizer> routerOperationCustomizers = new ArrayList<>();

/**
* The methods filters to apply.
*/
Expand Down Expand Up @@ -433,6 +454,17 @@ public Builder addOperationCustomizer(OperationCustomizer operationCustomizer) {
return this;
}

/**
* Add router operation customizer builder
*
* @param routerOperationCustomizer the router operation customizer
* @return the builder
*/
public Builder addRouterOperationCustomizer(RouterOperationCustomizer routerOperationCustomizer) {
this.routerOperationCustomizers.add(routerOperationCustomizer);
return this;
}

/**
* Add method filter.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*
* @author bnasslahsen
*/
@Target({ ElementType.TYPE, ElementType.METHOD})
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RouterOperation {
Expand Down Expand Up @@ -95,6 +95,14 @@
*/
String[] headers() default {};

/**
* The parameters of the mapped request, narrowing the primary mapping.
* Same format for any environment: a sequence of "myParam=myValue" style expressions,
* with a request only mapped if each such parameter is found to have the given value.
* @return the string [ ]
*/
String[] params() default {};

/**
* The class of the Handler bean.
* @return the class of the Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.springdoc.core.customizers;

import org.springdoc.core.fn.RouterOperation;

import org.springframework.web.method.HandlerMethod;

/**
* Implement and register a bean of type {@link RouterOperationCustomizer} to customize an router operation
* based on the handler method input on default OpenAPI descriptions but not groups
*
* @author hyeonisism
*/
@FunctionalInterface
public interface RouterOperationCustomizer {

/**
* Customize router operation.
*
* @param routerOperation input operation
* @param handlerMethod original handler method
* @return customized router operation
*/
RouterOperation customize(RouterOperation routerOperation, HandlerMethod handlerMethod);

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ public class RouterFunctionData {
*/
private List<String> headers = new ArrayList<>();

/**
* The Params.
*/
private List<String> params = new ArrayList<>();

/**
* The Query params.
*/
Expand Down Expand Up @@ -93,6 +98,7 @@ public RouterFunctionData(String nestedOrPath, RouterFunctionData functionData)
this.consumes = Arrays.asList(functionData.getConsumes());
this.produces = Arrays.asList(functionData.getProduces());
this.headers = Arrays.asList(functionData.getHeaders());
this.params = Arrays.asList(functionData.getParams());
this.queryParams = functionData.getQueryParams();
this.methods = functionData.getMethods();
this.attributes = functionData.getAttributes();
Expand Down Expand Up @@ -181,6 +187,20 @@ public String[] getConsumes() {
return consumes.toArray(new String[consumes.size()]);
}

/**
* Get params string [ ].
*
* @return the string [ ]
*/
public String[] getParams() { return params.toArray(new String[params.size()]); }

/**
* Add params.
*
* @param params the params
*/
public void addParams(String params) { if(StringUtils.isNotBlank(params)) this.params.add(params); }

/**
* Add consumes.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
/**
* The type Router operation.
* @author bnasslahsen
* @author hyeonisism
*/
public class RouterOperation implements Comparable<RouterOperation> {

Expand Down Expand Up @@ -66,6 +67,11 @@ public class RouterOperation implements Comparable<RouterOperation> {
*/
private String[] headers;

/**
* The Params.
*/
private String[] params;

/**
* The Bean class.
*/
Expand Down Expand Up @@ -116,6 +122,7 @@ public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOper
this.parameterTypes = routerOperationAnnotation.parameterTypes();
this.operation = routerOperationAnnotation.operation();
this.headers = routerOperationAnnotation.headers();
this.params = routerOperationAnnotation.params();
}

/**
Expand All @@ -134,6 +141,7 @@ public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOper
this.parameterTypes = routerOperationAnnotation.parameterTypes();
this.operation = routerOperationAnnotation.operation();
this.headers = ArrayUtils.isEmpty(routerOperationAnnotation.headers()) ? routerFunctionData.getHeaders() : routerOperationAnnotation.headers();
this.params = routerOperationAnnotation.params();
this.queryParams = routerFunctionData.getQueryParams();
}

Expand All @@ -146,12 +154,13 @@ public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOper
* @param produces the produces
* @param headers the headers
*/
public RouterOperation(String path, RequestMethod[] methods,String[] consumes, String[] produces, String[] headers) {
public RouterOperation(String path, RequestMethod[] methods, String[] consumes, String[] produces, String[] headers, String[] params) {
this.path = path;
this.methods = methods;
this.consumes=consumes;
this.produces=produces;
this.headers=headers;
this.consumes = consumes;
this.produces = produces;
this.headers = headers;
this.params = params;
}

/**
Expand All @@ -165,6 +174,7 @@ public RouterOperation(RouterFunctionData routerFunctionData) {
this.consumes = routerFunctionData.getConsumes();
this.produces = routerFunctionData.getProduces();
this.headers = routerFunctionData.getHeaders();
this.params = routerFunctionData.getParams();
this.queryParams = routerFunctionData.getQueryParams();

Map<String, Object> attributes = routerFunctionData.getAttributes();
Expand Down Expand Up @@ -369,6 +379,24 @@ public void setQueryParams(Map<String, String> queryParams) {
this.queryParams = queryParams;
}

/**
* Gets params.
*
* @return the params
*/
public String[] getParams() {
return this.params;
}

/**
* Sets params.
*
* @param params
*/
public void setParams(String[] params) {
this.params = params;
}

/**
* Gets operation model.
*
Expand Down
Loading