Repository: springdoc/springdoc-openapi
Pull request #1651 (2022-05-07 09:21:56)

Ease group declaration through code or properties with actuators
Ease group declaration through code or properties with actuators by making actuator customizers global.

That way, actuator may be used the same way they already are on Default OpenAPI description.
```
springdoc:
  show-actuator: true
  group-configs:
    - group: all
      paths-to-match: /**
    - group: person
      paths-to-match: /person/**
    - group: x-actuator
      paths-to-match: ${management.endpoints.web.base-path:/actuator}/**
```

```
@Bean
public GroupedOpenApi allGroupedOpenApi() {
	return GroupedOpenApi.builder()
		.group("all")
		.pathsToMatch("/**")
		.build();
	}
}
@Bean
public GroupedOpenApi personGroupedOpenApi() {
	return GroupedOpenApi.builder()
		.group("person")
		.pathsToMatch("/person/**")
		.build();
	}
}
@Bean
public GroupedOpenApi xActuatorGroupedOpenApi(WebEndpointProperties endpointProperties) {
	return GroupedOpenApi.builder()
		.group(Constants.ACTUATOR_DEFAULT_GROUP)
		.pathsToMatch(endpointProperties.getBasePath() + Constants.ALL_PATTERN)
		.build();
	}
}
```


The PR is composed by 2 commits that are more easy to review one by one :
1. Ease group declaration through code or properties with actuators (Global actuator customizers)
1. Switch from statefull to stateless actuator customizers (otherwise, operationId depends on the order in which groups are requested). Actuator operation ids should be unique across each OpenAPI definition not across all OpenAPI definitions. Statefull cutomizer beans seems odd.


Patch:
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index c6943d733..a19504692 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,2 @@
-open_collective: springdoc
+open_collective: springdoc-openapi
 github: springdoc
diff --git a/README.md b/README.md
index 55dcaa6be..6c7ce3506 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,9 @@
-![Octocat](https://springdoc.org/img/banner-logo.svg)
+![Octocat](https://springdoc.org/images/springdoc-openapi.png)
 [![Build Status](http://129.159.254.115:8686/buildStatus/icon?job=springdoc-openapi-IC)](http://129.159.254.115:8686/view/springdoc-openapi/job/springdoc-openapi-IC/)
 [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=springdoc_springdoc-openapi&metric=alert_status)](https://sonarcloud.io/dashboard?id=springdoc_springdoc-openapi)
 [![Known Vulnerabilities](https://snyk.io/test/github/springdoc/springdoc-openapi.git/badge.svg)](https://snyk.io/test/github/springdoc/springdoc-openapi.git)
 [![Stack Exchange questions](https://img.shields.io/stackexchange/stackoverflow/t/springdoc)](https://stackoverflow.com/questions/tagged/springdoc?tab=Votes)
 
-`springdoc-openapi` is on [Open Collective](https://opencollective.com/springdoc).
-If you ❤️ this project consider becoming a [sponsor](https://github.com/sponsors/springdoc).
-
-This project is sponsored by
-
-<p align="center">
-<a href="https://opensource.mercedes-benz.com/" target="_blank">
-    <img src="https://springdoc.org/img/mercedes-benz.png" height="10%" width="10%" />
-</a>
-&nbsp;&nbsp;
-<a href="https://www.dm-jobs.com/dmTECH/?locale=de_DE&wt_mc=.display.github.sponsoring.logo" target="_blank">
-     <img src="https://springdoc.org/img/dmTECH_Logo.jpg" height="10%" width="10%" />
-</a>
-</p>
-
 # Table of Contents
 - [Full documentation](#full-documentation)
 - [**Introduction**](#introduction)
@@ -96,7 +81,7 @@ springdoc.swagger-ui.path=/swagger-ui.html
 ### [Demo Spring Boot 2 WebFlux with Functional endpoints OpenAPI 3](http://158.101.191.70:8084/).
 ### [Demo Spring Boot 2 and Spring Hateoas with OpenAPI 3](http://158.101.191.70:8085/).
 
-![Branching](https://springdoc.org/img/pets.png)
+![Branching](https://springdoc.org/images/pets.png)
 
 ## Integration of the library in a Spring Boot 2.x.x project without the swagger-ui:
 *   Documentation will be available at the following url for json format: http://server:port/context-path/v3/api-docs
@@ -177,4 +162,4 @@ Thanks you all for your support!
 * [Spring Team](https://spring.io/team) - Thanks for their support by sharing all relevant resources around Spring projects.
 * [JetBrains](https://www.jetbrains.com/?from=springdoc-openapi) - Thanks a lot for supporting springdoc-openapi project.
 
-![JenBrains logo](https://springdoc.org/img/jetbrains.svg)
+![JenBrains logo](https://springdoc.org/images/jetbrains.svg)
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
index 228fa3351..61add17a1 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java
@@ -136,12 +136,12 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	/**
 	 * The constant ADDITIONAL_REST_CONTROLLERS.
 	 */
-	private static final List<Class<?>> ADDITIONAL_REST_CONTROLLERS = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> ADDITIONAL_REST_CONTROLLERS = new ArrayList<>();
 
 	/**
 	 * The constant HIDDEN_REST_CONTROLLERS.
 	 */
-	private static final List<Class<?>> HIDDEN_REST_CONTROLLERS = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> HIDDEN_REST_CONTROLLERS = new ArrayList<>();
 
 	/**
 	 * The Open api builder.
@@ -304,11 +304,11 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 * @return the open api
 	 */
 	protected synchronized OpenAPI getOpenApi(Locale locale) {
-		OpenAPI openAPI;
+		OpenAPI openApi;
 		final Locale finalLocale = locale == null ? Locale.getDefault() : locale;
 		if (openAPIService.getCachedOpenAPI(finalLocale) == null || springDocConfigProperties.isCacheDisabled()) {
 			Instant start = Instant.now();
-			openAPI = openAPIService.build(finalLocale);
+			openAPIService.build(finalLocale);
 			Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream()
 					.filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(),
 							Hidden.class) == null))
@@ -316,32 +316,34 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 					.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1));
 
 			Map<String, Object> findControllerAdvice = openAPIService.getControllerAdviceMap();
+			// calculate generic responses
+			openApi = openAPIService.getCalculatedOpenAPI();
 			if (OpenApiVersion.OPENAPI_3_1 == springDocConfigProperties.getApiDocs().getVersion())
-				openAPI.openapi(OpenApiVersion.OPENAPI_3_1.getVersion());
+				openApi.openapi(OpenApiVersion.OPENAPI_3_1.getVersion());
 			if (springDocConfigProperties.isDefaultOverrideWithGenericResponse()) {
 				if (!CollectionUtils.isEmpty(mappingsMap))
 					findControllerAdvice.putAll(mappingsMap);
-				responseBuilder.buildGenericResponse(openAPI.getComponents(), findControllerAdvice, finalLocale);
+				responseBuilder.buildGenericResponse(openApi.getComponents(), findControllerAdvice, finalLocale);
 			}
-			getPaths(mappingsMap, finalLocale, openAPI);
+			getPaths(mappingsMap, finalLocale);
 
 			Optional<CloudFunctionProvider> cloudFunctionProviderOptional = springDocProviders.getSpringCloudFunctionProvider();
 			cloudFunctionProviderOptional.ifPresent(cloudFunctionProvider -> {
-						List<RouterOperation> routerOperationList = cloudFunctionProvider.getRouterOperations(openAPI);
+						List<RouterOperation> routerOperationList = cloudFunctionProvider.getRouterOperations(openApi);
 						if (!CollectionUtils.isEmpty(routerOperationList))
-							this.calculatePath(routerOperationList, locale, openAPI);
+							this.calculatePath(routerOperationList, locale);
 					}
 			);
 
-			if (!CollectionUtils.isEmpty(openAPI.getServers()))
+			if (!CollectionUtils.isEmpty(openApi.getServers()))
 				openAPIService.setServersPresent(true);
-			openAPIService.updateServers(openAPI);
+			openAPIService.updateServers(openApi);
 
 			if (springDocConfigProperties.isRemoveBrokenReferenceDefinitions())
-				this.removeBrokenReferenceDefinitions(openAPI);
+				this.removeBrokenReferenceDefinitions(openApi);
 
 			// run the optional customisers
-			List<Server> servers = openAPI.getServers();
+			List<Server> servers = openApi.getServers();
 			List<Server> serversCopy = null;
 			try {
 				serversCopy = springDocProviders.jsonMapper()
@@ -351,21 +353,22 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 				LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage());
 			}
 
-			openApiLocaleCustomizers.values().forEach(openApiLocaleCustomizer -> openApiLocaleCustomizer.customise(openAPI, finalLocale));
-			openApiCustomisers.ifPresent(apiCustomisers -> apiCustomisers.forEach(openApiCustomiser -> openApiCustomiser.customise(openAPI)));
-			if (!CollectionUtils.isEmpty(openAPI.getServers()) && !openAPI.getServers().equals(serversCopy))
+			openApiLocaleCustomizers.values().forEach(openApiLocaleCustomizer -> openApiLocaleCustomizer.customise(openApi, finalLocale));
+			openApiCustomisers.ifPresent(apiCustomisers -> apiCustomisers.forEach(openApiCustomiser -> openApiCustomiser.customise(openApi)));
+			if (!CollectionUtils.isEmpty(openApi.getServers()) && !openApi.getServers().equals(serversCopy))
 				openAPIService.setServersPresent(true);
 
-			openAPIService.setCachedOpenAPI(openAPI, finalLocale);
+			openAPIService.setCachedOpenAPI(openApi, finalLocale);
+			openAPIService.resetCalculatedOpenAPI();
 
 			LOGGER.info("Init duration for springdoc-openapi is: {} ms",
 					Duration.between(start, Instant.now()).toMillis());
 		}
 		else {
 			LOGGER.debug("Fetching openApi document from cache");
-			openAPI = openAPIService.updateServers(openAPIService.getCachedOpenAPI(finalLocale));
+			openApi = openAPIService.updateServers(openAPIService.getCachedOpenAPI(finalLocale));
 		}
-		return openAPI;
+		return openApi;
 	}
 
 	/**
@@ -373,9 +376,8 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 *
 	 * @param findRestControllers the find rest controllers
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected abstract void getPaths(Map<String, Object> findRestControllers, Locale locale, OpenAPI openAPI);
+	protected abstract void getPaths(Map<String, Object> findRestControllers, Locale locale);
 
 	/**
 	 * Calculate path.
@@ -383,10 +385,8 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 * @param handlerMethod the handler method
 	 * @param routerOperation the router operation
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void calculatePath(HandlerMethod handlerMethod,
-			RouterOperation routerOperation, Locale locale, OpenAPI openAPI) {
+	protected void calculatePath(HandlerMethod handlerMethod, RouterOperation routerOperation, Locale locale) {
 		String operationPath = routerOperation.getPath();
 		Set<RequestMethod> requestMethods = new HashSet<>(Arrays.asList(routerOperation.getMethods()));
 		io.swagger.v3.oas.annotations.Operation apiOperation = routerOperation.getOperation();
@@ -395,6 +395,7 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 		String[] headers = routerOperation.getHeaders();
 		Map<String, String> queryParams = routerOperation.getQueryParams();
 
+		OpenAPI openAPI = openAPIService.getCalculatedOpenAPI();
 		Components components = openAPI.getComponents();
 		Paths paths = openAPI.getPaths();
 
@@ -513,9 +514,8 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 *
 	 * @param routerOperationList the router operation list
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void calculatePath(List<RouterOperation> routerOperationList, Locale locale, OpenAPI openAPI) {
+	protected void calculatePath(List<RouterOperation> routerOperationList, Locale locale) {
 		ApplicationContext applicationContext = openAPIService.getContext();
 		if (!CollectionUtils.isEmpty(routerOperationList)) {
 			Collections.sort(routerOperationList);
@@ -545,14 +545,14 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 							LOGGER.error(e.getMessage());
 						}
 						if (handlerMethod != null && isFilterCondition(handlerMethod, routerOperation.getPath(), routerOperation.getProduces(), routerOperation.getConsumes(), routerOperation.getHeaders()))
-							calculatePath(handlerMethod, routerOperation, locale, openAPI);
+							calculatePath(handlerMethod, routerOperation, locale);
 					}
 				}
 				else if (routerOperation.getOperation() != null && StringUtils.isNotBlank(routerOperation.getOperation().operationId()) && isFilterCondition(routerOperation.getPath(), routerOperation.getProduces(), routerOperation.getConsumes(), routerOperation.getHeaders())) {
-					calculatePath(routerOperation, locale, openAPI);
+					calculatePath(routerOperation, locale);
 				}
 				else if (routerOperation.getOperationModel() != null && StringUtils.isNotBlank(routerOperation.getOperationModel().getOperationId()) && isFilterCondition(routerOperation.getPath(), routerOperation.getProduces(), routerOperation.getConsumes(), routerOperation.getHeaders())) {
-					calculatePath(routerOperation, locale, openAPI);
+					calculatePath(routerOperation, locale);
 				}
 			}
 		}
@@ -564,7 +564,7 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 * @param routerOperation the router operation
 	 * @param locale the locale
 	 */
-	protected void calculatePath(RouterOperation routerOperation, Locale locale, OpenAPI openAPI) {
+	protected void calculatePath(RouterOperation routerOperation, Locale locale) {
 		String operationPath = routerOperation.getPath();
 		io.swagger.v3.oas.annotations.Operation apiOperation = routerOperation.getOperation();
 		String[] methodConsumes = routerOperation.getConsumes();
@@ -572,6 +572,7 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 		String[] headers = routerOperation.getHeaders();
 		Map<String, String> queryParams = routerOperation.getQueryParams();
 
+		OpenAPI openAPI = openAPIService.getCalculatedOpenAPI();
 		Paths paths = openAPI.getPaths();
 		Map<HttpMethod, Operation> operationMap = null;
 		if (paths.containsKey(operationPath)) {
@@ -615,11 +616,10 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 * @param produces the produces
 	 * @param headers the headers
 	 * @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, Locale locale) {
+		this.calculatePath(handlerMethod, new RouterOperation(operationPath, requestMethods.toArray(new RequestMethod[requestMethods.size()]), consumes, produces, headers), locale);
 	}
 
 	/**
@@ -628,15 +628,13 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 	 * @param beanName the bean name
 	 * @param routerFunctionVisitor the router function visitor
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void getRouterFunctionPaths(String beanName, AbstractRouterFunctionVisitor routerFunctionVisitor,
-			Locale locale, OpenAPI openAPI) {
+	protected void getRouterFunctionPaths(String beanName, AbstractRouterFunctionVisitor routerFunctionVisitor, Locale locale) {
 		boolean withRouterOperation = routerFunctionVisitor.getRouterFunctionDatas().stream()
 				.anyMatch(routerFunctionData -> routerFunctionData.getAttributes().containsKey(OPERATION_ATTRIBUTE));
 		if (withRouterOperation) {
 			List<RouterOperation> operationList = routerFunctionVisitor.getRouterFunctionDatas().stream().map(RouterOperation::new).collect(Collectors.toList());
-			calculatePath(operationList, locale, openAPI);
+			calculatePath(operationList, locale);
 		}
 		else {
 			List<org.springdoc.core.annotations.RouterOperation> routerOperationList = new ArrayList<>();
@@ -650,11 +648,11 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
 			else
 				routerOperationList.addAll(Arrays.asList(routerOperations.value()));
 			if (routerOperationList.size() == 1)
-				calculatePath(routerOperationList.stream().map(routerOperation -> new RouterOperation(routerOperation, routerFunctionVisitor.getRouterFunctionDatas().get(0))).collect(Collectors.toList()), locale, openAPI);
+				calculatePath(routerOperationList.stream().map(routerOperation -> new RouterOperation(routerOperation, routerFunctionVisitor.getRouterFunctionDatas().get(0))).collect(Collectors.toList()), locale);
 			else {
 				List<RouterOperation> operationList = routerOperationList.stream().map(RouterOperation::new).collect(Collectors.toList());
 				mergeRouters(routerFunctionVisitor.getRouterFunctionDatas(), operationList);
-				calculatePath(operationList, locale, openAPI);
+				calculatePath(operationList, locale);
 			}
 		}
 	}
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractRequestService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractRequestService.java
index cbf8d35fa..b20db6d85 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractRequestService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/AbstractRequestService.java
@@ -29,7 +29,6 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -99,7 +98,7 @@ public abstract class AbstractRequestService {
 	/**
 	 * The constant PARAM_TYPES_TO_IGNORE.
 	 */
-	private static final List<Class<?>> PARAM_TYPES_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> PARAM_TYPES_TO_IGNORE = new ArrayList<>();
 
 	/**
 	 * The constant ANNOTATIONS_FOR_REQUIRED.
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
index adaecb86b..6e3369e14 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericParameterService.java
@@ -28,7 +28,6 @@ import java.lang.reflect.Type;
 import java.lang.reflect.WildcardType;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -75,7 +74,7 @@ public class GenericParameterService {
 	/**
 	 * The constant FILE_TYPES.
 	 */
-	private static final List<Class<?>> FILE_TYPES = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> FILE_TYPES = new ArrayList<>();
 
 	/**
 	 * The Optional delegating method parameter customizer.
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
index 03ffd9af5..aa9a8f8f5 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GenericResponseService.java
@@ -239,9 +239,7 @@ public class GenericResponseService {
 					apiResponses.forEach(controllerAdviceInfoApiResponseMap::put);
 				}
 			}
-			synchronized (this){
-				controllerAdviceInfos.add(controllerAdviceInfo);
-			}
+			controllerAdviceInfos.add(controllerAdviceInfo);
 		}
 	}
 
@@ -633,7 +631,7 @@ public class GenericResponseService {
 	 * @param beanType the bean type
 	 * @return the generic map response
 	 */
-	private synchronized Map<String, ApiResponse> getGenericMapResponse(Class<?> beanType) {
+	private Map<String, ApiResponse> getGenericMapResponse(Class<?> beanType) {
 		return controllerAdviceInfos.stream()
 				.filter(controllerAdviceInfo ->  new ControllerAdviceBean(controllerAdviceInfo.getControllerAdvice()).isApplicableToBeanType(beanType))
 				.map(ControllerAdviceInfo::getApiResponseMap)
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/GroupedOpenApi.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/GroupedOpenApi.java
index c04adae14..777c623e6 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/GroupedOpenApi.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/GroupedOpenApi.java
@@ -25,6 +25,7 @@ package org.springdoc.core;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
 
@@ -51,12 +52,12 @@ public class GroupedOpenApi {
 	/**
 	 * The Open api customisers.
 	 */
-	private List<OpenApiCustomiser> openApiCustomisers;
+	private final List<OpenApiCustomiser> openApiCustomisers;
 
 	/**
 	 * The Operation customizers.
 	 */
-	private List<OperationCustomizer> operationCustomizers;
+	private final List<OperationCustomizer> operationCustomizers;
 
 	/**
 	 * The Paths to match.
@@ -96,7 +97,7 @@ public class GroupedOpenApi {
 	/**
 	 * The method filters to use.
 	 */
-	private List<OpenApiMethodFilter> openApiMethodFilters;
+	private final List<OpenApiMethodFilter> openApiMethodFilters;
 
 	/**
 	 * The Display name.
@@ -472,10 +473,8 @@ public class GroupedOpenApi {
 	 * @return the grouped open api
 	 */
 	public GroupedOpenApi addAllOpenApiCustomizer(Collection<? extends OpenApiCustomiser> openApiCustomizerCollection) {
-		List<OpenApiCustomiser> result = new ArrayList<>();
-		result.addAll(openApiCustomizerCollection);
-		result.addAll(openApiCustomisers);
-		openApiCustomisers = result;
+		this.openApiCustomisers.addAll(openApiCustomizerCollection);
+		Collections.reverse(openApiCustomisers);
 		return this;
 	}
 
@@ -486,10 +485,8 @@ public class GroupedOpenApi {
 	 * @return the grouped open api
 	 */
 	public GroupedOpenApi addAllOperationCustomizer(Collection<? extends OperationCustomizer> operationCustomizerCollection) {
-		List<OperationCustomizer> result = new ArrayList<>();
-		result.addAll(operationCustomizerCollection);
-		result.addAll(operationCustomizers);
-		operationCustomizers = result;
+		this.operationCustomizers.addAll(operationCustomizerCollection);
+		Collections.reverse(operationCustomizers);
 		return this;
 	}
 
@@ -500,10 +497,8 @@ public class GroupedOpenApi {
 	 * @return the grouped open api
 	 */
 	public GroupedOpenApi addAllOpenApiMethodFilter(Collection<? extends OpenApiMethodFilter> openApiMethodFilterCollection) {
-		List<OpenApiMethodFilter> result = new ArrayList<>();
-		result.addAll(openApiMethodFilterCollection);
-		result.addAll(openApiMethodFilters);
-		openApiMethodFilters = result;
+		this.openApiMethodFilters.addAll(openApiMethodFilterCollection);
+		Collections.reverse(openApiMethodFilters);
 		return this;
 	}
 }
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java
index b8604ac81..c61762e9a 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/OpenAPIService.java
@@ -138,6 +138,11 @@ public class OpenAPIService implements ApplicationContextAware {
 	 */
 	private final Map<String, OpenAPI> cachedOpenAPI = new HashMap<>();
 
+	/**
+	 * The Calculated open api.
+	 */
+	private OpenAPI calculatedOpenAPI;
+
 	/**
 	 * The Is servers present.
 	 */
@@ -236,18 +241,18 @@ public class OpenAPIService implements ApplicationContextAware {
 	 * Build.
 	 * @param locale the locale
 	 */
-	public OpenAPI build(Locale locale) {
+	public void build(Locale locale) {
 		Optional<OpenAPIDefinition> apiDef = getOpenAPIDefinition();
-		OpenAPI calculatedOpenAPI = null;
+
 		if (openAPI == null) {
-			calculatedOpenAPI = new OpenAPI();
-			calculatedOpenAPI.setComponents(new Components());
-			calculatedOpenAPI.setPaths(new Paths());
+			this.calculatedOpenAPI = new OpenAPI();
+			this.calculatedOpenAPI.setComponents(new Components());
+			this.calculatedOpenAPI.setPaths(new Paths());
 		}
 		else {
 			try {
 				ObjectMapper objectMapper = new ObjectMapper();
-				calculatedOpenAPI = objectMapper.readValue(objectMapper.writeValueAsString(openAPI), OpenAPI.class );
+				this.calculatedOpenAPI = objectMapper.readValue(objectMapper.writeValueAsString(openAPI), OpenAPI.class );
 			}
 			catch (JsonProcessingException e) {
 				LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage());
@@ -272,8 +277,6 @@ public class OpenAPIService implements ApplicationContextAware {
 		// add security schemes
 		this.calculateSecuritySchemes(calculatedOpenAPI.getComponents(), locale);
 		openApiBuilderCustomisers.ifPresent(customisers -> customisers.forEach(customiser -> customiser.customise(this)));
-
-		return calculatedOpenAPI;
 	}
 
 	/**
@@ -719,6 +722,22 @@ public class OpenAPIService implements ApplicationContextAware {
 		this.cachedOpenAPI.put(locale.toLanguageTag(), cachedOpenAPI);
 	}
 
+	/**
+	 * Gets calculated open api.
+	 *
+	 * @return the calculated open api
+	 */
+	public OpenAPI getCalculatedOpenAPI() {
+		return calculatedOpenAPI;
+	}
+
+	/**
+	 * Reset calculated open api.
+	 */
+	public void resetCalculatedOpenAPI() {
+		this.calculatedOpenAPI = null;
+	}
+
 	/**
 	 * Gets context.
 	 *
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocAnnotationsUtils.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocAnnotationsUtils.java
index 4d6a193e1..d197ac128 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocAnnotationsUtils.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocAnnotationsUtils.java
@@ -27,7 +27,6 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -74,7 +73,7 @@ public class SpringDocAnnotationsUtils extends AnnotationsUtils {
 	/**
 	 * The constant ANNOTATIOSN_TO_IGNORE.
 	 */
-	private static final List<Class> ANNOTATIONS_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class> ANNOTATIONS_TO_IGNORE = new ArrayList<>();
 
 	static {
 		ANNOTATIONS_TO_IGNORE.add(Hidden.class);
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java
index 92bc36a9b..6a415637b 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java
@@ -52,9 +52,8 @@ import org.springdoc.core.customizers.ActuatorOperationCustomizer;
 import org.springdoc.core.customizers.DataRestDelegatingMethodParameterCustomizer;
 import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer;
 import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
+import org.springdoc.core.customizers.GlobalOperationCustomizer;
 import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
-import org.springdoc.core.customizers.OpenApiCustomiser;
-import org.springdoc.core.customizers.OperationCustomizer;
 import org.springdoc.core.customizers.PropertyCustomizer;
 import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
 import org.springdoc.core.providers.ActuatorProvider;
@@ -462,7 +461,7 @@ public class SpringDocConfiguration {
 		@Bean
 		@Lazy(false)
 		@ConditionalOnManagementPort(ManagementPortType.SAME)
-		OperationCustomizer actuatorCustomizer() {
+		GlobalOperationCustomizer actuatorCustomizer() {
 			return new ActuatorOperationCustomizer();
 		}
 
@@ -475,7 +474,7 @@ public class SpringDocConfiguration {
 		@Bean
 		@Lazy(false)
 		@ConditionalOnManagementPort(ManagementPortType.SAME)
-		OpenApiCustomiser actuatorOpenApiCustomiser(WebEndpointProperties webEndpointProperties) {
+		GlobalOpenApiCustomizer actuatorOpenApiCustomiser(WebEndpointProperties webEndpointProperties) {
 			return new ActuatorOpenApiCustomizer(webEndpointProperties);
 		}
 
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocActuatorBeanFactoryConfigurer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocActuatorBeanFactoryConfigurer.java
index 5484415c3..6266898d9 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocActuatorBeanFactoryConfigurer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocActuatorBeanFactoryConfigurer.java
@@ -77,8 +77,6 @@ public class SpringdocActuatorBeanFactoryConfigurer extends SpringdocBeanFactory
 			GroupedOpenApi actuatorGroup = GroupedOpenApi.builder().group(ACTUATOR_DEFAULT_GROUP)
 					.pathsToMatch(webEndpointProperties.getBasePath() + ALL_PATTERN)
 					.pathsToExclude(webEndpointProperties.getBasePath() + HEALTH_PATTERN)
-					.addOperationCustomizer(actuatorCustomizer)
-					.addOpenApiCustomiser(actuatorOpenApiCustomiser)
 					.build();
 			// Add the actuator group
 			newGroups.add(actuatorGroup);
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/ConverterUtils.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/ConverterUtils.java
index 4d77749e9..69aad6480 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/ConverterUtils.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/ConverterUtils.java
@@ -24,7 +24,6 @@ package org.springdoc.core.converters;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletionStage;
@@ -41,17 +40,17 @@ public class ConverterUtils {
 	/**
 	 * The constant RESULT_WRAPPERS_TO_IGNORE.
 	 */
-	private static final List<Class<?>> RESULT_WRAPPERS_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> RESULT_WRAPPERS_TO_IGNORE = new ArrayList<>();
 
 	/**
 	 * The constant RESPONSE_TYPES_TO_IGNORE.
 	 */
-	private static final List<Class<?>> RESPONSE_TYPES_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> RESPONSE_TYPES_TO_IGNORE = new ArrayList<>();
 
 	/**
 	 * The constant FLUX_WRAPPERS_TO_IGNORE.
 	 */
-	private static final List<Class<?>> FLUX_WRAPPERS_TO_IGNORE = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<?>> FLUX_WRAPPERS_TO_IGNORE = new ArrayList<>();
 
 	static {
 		RESULT_WRAPPERS_TO_IGNORE.add(Callable.class);
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/SchemaPropertyDeprecatingConverter.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/SchemaPropertyDeprecatingConverter.java
index d9e10b421..c211ec88f 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/SchemaPropertyDeprecatingConverter.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/converters/SchemaPropertyDeprecatingConverter.java
@@ -25,7 +25,6 @@ package org.springdoc.core.converters;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.stream.Stream;
@@ -46,7 +45,7 @@ public class SchemaPropertyDeprecatingConverter implements ModelConverter {
 	/**
 	 * The constant DEPRECATED_ANNOTATIONS.
 	 */
-	private static final List<Class<? extends Annotation>> DEPRECATED_ANNOTATIONS = Collections.synchronizedList(new ArrayList<>());
+	private static final List<Class<? extends Annotation>> DEPRECATED_ANNOTATIONS = new ArrayList<>();
 
 	static {
 		DEPRECATED_ANNOTATIONS.add(Deprecated.class);
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOpenApiCustomizer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOpenApiCustomizer.java
index ea2e8b3e0..385a99748 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOpenApiCustomizer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOpenApiCustomizer.java
@@ -22,13 +22,19 @@
 
 package org.springdoc.core.customizers;
 
+import java.util.Comparator;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map.Entry;
 import java.util.Optional;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.Paths;
 import io.swagger.v3.oas.models.media.StringSchema;
 import io.swagger.v3.oas.models.parameters.Parameter;
 import io.swagger.v3.oas.models.parameters.PathParameter;
@@ -42,7 +48,7 @@ import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR;
  * The type Actuator open api customiser.
  * @author bnasslahsen
  */
-public class ActuatorOpenApiCustomizer implements OpenApiCustomiser {
+public class ActuatorOpenApiCustomizer implements GlobalOpenApiCustomizer {
 
 	/**
 	 * The Path pathern.
@@ -63,26 +69,54 @@ public class ActuatorOpenApiCustomizer implements OpenApiCustomiser {
 		this.webEndpointProperties = webEndpointProperties;
 	}
 
+	private Stream<Entry<String, PathItem>> actuatorPathEntryStream(OpenAPI openApi, String relativeSubPath) {
+		String pathPrefix = webEndpointProperties.getBasePath() + Optional.ofNullable(relativeSubPath).orElse("");
+		return Optional.ofNullable(openApi.getPaths())
+				.map(Paths::entrySet)
+				.map(Set::stream)
+				.map(s -> s.filter(entry -> entry.getKey().startsWith(pathPrefix)))
+				.orElse(Stream.empty());
+	}
+
+	private void handleActuatorPathParam(OpenAPI openApi) {
+		actuatorPathEntryStream(openApi, DEFAULT_PATH_SEPARATOR).forEach(stringPathItemEntry -> {
+			String path = stringPathItemEntry.getKey();
+			Matcher matcher = pathPathern.matcher(path);
+			while (matcher.find()) {
+				String pathParam = matcher.group(1);
+				PathItem pathItem = stringPathItemEntry.getValue();
+				pathItem.readOperations().forEach(operation -> {
+					List<Parameter> existingParameters = operation.getParameters();
+					Optional<Parameter> existingParam = Optional.empty();
+					if (!CollectionUtils.isEmpty(existingParameters))
+						existingParam = existingParameters.stream().filter(p -> pathParam.equals(p.getName())).findAny();
+					if (!existingParam.isPresent())
+						operation.addParametersItem(new PathParameter().name(pathParam).schema(new StringSchema()));
+				});
+			}
+		});
+	}
+
+	private void handleActuatorOperationIdUniqueness(OpenAPI openApi) {
+		Set<String> usedOperationIds = new HashSet<>();
+		actuatorPathEntryStream(openApi, null)
+			.sorted(Comparator.comparing(Entry::getKey))
+			.forEachOrdered(stringPathItemEntry -> {
+			stringPathItemEntry.getValue().readOperations().forEach(operation -> {
+				String initialOperationId = operation.getOperationId();
+				String uniqueOperationId = operation.getOperationId();
+				int counter = 1;
+				while (!usedOperationIds.add(uniqueOperationId)) {
+					uniqueOperationId = initialOperationId + "_" + ++counter;
+				}
+				operation.setOperationId(uniqueOperationId);
+			});
+		});
+	}
+
 	@Override
 	public void customise(OpenAPI openApi) {
-		if (!CollectionUtils.isEmpty(openApi.getPaths()))
-			openApi.getPaths().entrySet().stream()
-					.filter(stringPathItemEntry -> stringPathItemEntry.getKey().startsWith(webEndpointProperties.getBasePath() + DEFAULT_PATH_SEPARATOR))
-					.forEach(stringPathItemEntry -> {
-						String path = stringPathItemEntry.getKey();
-						Matcher matcher = pathPathern.matcher(path);
-						while (matcher.find()) {
-							String pathParam = matcher.group(1);
-							PathItem pathItem = stringPathItemEntry.getValue();
-							pathItem.readOperations().forEach(operation -> {
-								List<Parameter> existingParameters = operation.getParameters();
-								Optional<Parameter> existingParam = Optional.empty();
-								if (!CollectionUtils.isEmpty(existingParameters))
-									existingParam = existingParameters.stream().filter(p -> pathParam.equals(p.getName())).findAny();
-								if (!existingParam.isPresent())
-									operation.addParametersItem(new PathParameter().name(pathParam).schema(new StringSchema()));
-							});
-						}
-					});
+		handleActuatorPathParam(openApi);
+		handleActuatorOperationIdUniqueness(openApi);
 	}
 }
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOperationCustomizer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOperationCustomizer.java
index bcf387fa2..4d3a3d8be 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOperationCustomizer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/ActuatorOperationCustomizer.java
@@ -24,7 +24,6 @@ package org.springdoc.core.customizers;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Parameter;
-import java.util.HashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -45,19 +44,13 @@ import org.springframework.boot.actuate.endpoint.invoke.OperationParameter;
 import org.springframework.boot.actuate.endpoint.invoke.reflect.OperationMethod;
 import org.springframework.web.method.HandlerMethod;
 
-import static org.apache.commons.lang3.math.NumberUtils.INTEGER_ONE;
 import static org.springdoc.core.providers.ActuatorProvider.getTag;
 
 /**
  * The type Actuator operation customizer.
  * @author bnasslahsen
  */
-public class ActuatorOperationCustomizer implements OperationCustomizer {
-
-	/**
-	 * The Method count.
-	 */
-	private final HashMap<String, Integer> methodCountMap = new HashMap<>();
+public class ActuatorOperationCustomizer implements GlobalOperationCustomizer {
 
 	/**
 	 * The constant OPERATION.
@@ -113,14 +106,6 @@ public class ActuatorOperationCustomizer implements OperationCustomizer {
 			while (matcher.find()) {
 				operationId = matcher.group(1);
 			}
-			if (methodCountMap.containsKey(operationId)) {
-				Integer methodCount = methodCountMap.get(operationId) + 1;
-				methodCountMap.put(operationId, methodCount);
-				operationId = operationId + "_" + methodCount;
-			}
-			else
-				methodCountMap.put(operationId, INTEGER_ONE);
-
 			if (!summary.contains("$"))
 				operation.setSummary(summary);
 			operation.setOperationId(operationId);
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java
index d5dbef18c..762cd8e85 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java
@@ -28,7 +28,7 @@ package org.springdoc.core.customizers;
  * description and groups
  *
  * @author christophejan
- * @see  OperationCustomizer customize operations on default OpenAPI      description but not groups
+ * @see  OperationCustomizerto customize operations on default OpenAPI      description but not groups
  */
 public interface GlobalOperationCustomizer extends OperationCustomizer {
 }
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomiser.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomiser.java
index c10e6e2f3..c7e12d16d 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomiser.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomiser.java
@@ -29,7 +29,7 @@ import io.swagger.v3.oas.models.OpenAPI;
  * Open api on default OpenAPI description but not on groups
  *
  * @author bnasslahsen
- * @see  GlobalOpenApiCustomizer customize default OpenAPI description and      groups
+ * @see  GlobalOpenApiCustomizerto customize default OpenAPI description and      groups
  */
 @FunctionalInterface
 public interface OpenApiCustomiser {
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java
index 5782638b8..e1aecbb3a 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java
@@ -32,7 +32,7 @@ import org.springframework.web.method.HandlerMethod;
  * groups
  *
  * @author bnasslahsen
- * @see  GlobalOperationCustomizer customize operations on default OpenAPI      description and groups
+ * @see  GlobalOperationCustomizerto customize operations on default OpenAPI      description and groups
  */
 @FunctionalInterface
 public interface OperationCustomizer {
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java
index 811f6542b..f2b004e3c 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java
@@ -28,7 +28,7 @@ package org.springdoc.core.filters;
  * and groups.
  *
  * @author michael.clarke
- * @see  OpenApiMethodFilter filter methods in default OpenAPI description but      not groups
+ * @see  OpenApiMethodFilterto filter methods in default OpenAPI description but      not groups
  */
 @FunctionalInterface
 public interface GlobalOpenApiMethodFilter extends OpenApiMethodFilter {
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java b/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java
index c03ecd723..8b5a12a3b 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java
@@ -30,7 +30,7 @@ import java.lang.reflect.Method;
  * but not groups
  *
  * @author michael.clarke
- * @see  GlobalOpenApiMethodFilter filter methods in default OpenAPI      description and groups
+ * @see  GlobalOpenApiMethodFilterto filter methods in default OpenAPI      description and groups
  */
 @FunctionalInterface
 public interface OpenApiMethodFilter {
diff --git a/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerIndexTransformer.java b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerIndexTransformer.java
index bcc2b008e..7097bf570 100644
--- a/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerIndexTransformer.java
+++ b/springdoc-openapi-common/src/main/java/org/springdoc/ui/AbstractSwaggerIndexTransformer.java
@@ -54,7 +54,7 @@ public class AbstractSwaggerIndexTransformer {
 	 */
 	private static final String PRESETS = "presets: [";
 
-	/**
+	/**<
 	 * The Swagger ui o auth properties.
 	 */
 	protected SwaggerUiOAuthProperties swaggerUiOAuthProperties;
diff --git a/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestResponseService.java b/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestResponseService.java
index c6a055d4b..7112e1774 100644
--- a/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestResponseService.java
+++ b/springdoc-openapi-data-rest/src/main/java/org/springdoc/data/rest/core/DataRestResponseService.java
@@ -296,10 +296,7 @@ public class DataRestResponseService {
 			ParameterizedType wildcardTypeUpperBound = (ParameterizedType) wildcardType.getUpperBounds()[0];
 			if (RepresentationModel.class.equals(wildcardTypeUpperBound.getRawType())) {
 				Class<?> type = findType(requestMethod, dataRestRepository);
-				if (MapModel.class.equals(type))
-					return ResolvableType.forClassWithGenerics(ResponseEntity.class, type).getType();
-				else
-					return resolveGenericType(ResponseEntity.class, type, returnedEntityType);
+				return resolveGenericType(ResponseEntity.class, type, returnedEntityType);
 			}
 		}
 		return null;
@@ -319,10 +316,7 @@ public class DataRestResponseService {
 		Class<?> rawType = ResolvableType.forType(parameterizedType1.getRawType()).getRawClass();
 		if (rawType != null && rawType.isAssignableFrom(RepresentationModel.class)) {
 			Class<?> type = findType(requestMethod, dataRestRepository);
-			if (MapModel.class.equals(type))
-				return ResolvableType.forClassWithGenerics(ResponseEntity.class, type).getType();
-			else
-				return resolveGenericType(ResponseEntity.class, type, returnedEntityType);
+			return resolveGenericType(ResponseEntity.class, type, returnedEntityType);
 		}
 		else if (EntityModel.class.equals(parameterizedType1.getRawType())) {
 			return resolveGenericType(ResponseEntity.class, EntityModel.class, returnedEntityType);
diff --git a/springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiResource.java b/springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiResource.java
index 190ae9dda..99401d325 100644
--- a/springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiResource.java
+++ b/springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/OpenApiResource.java
@@ -153,11 +153,10 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 	 *
 	 * @param restControllers the rest controllers
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
 	@Override
 	@SuppressWarnings("unchecked")
-	protected void getPaths(Map<String, Object> restControllers, Locale locale, OpenAPI openAPI) {
+	protected void getPaths(Map<String, Object> restControllers, Locale locale) {
 		Optional<SpringWebProvider> springWebProviderOptional = springDocProviders.getSpringWebProvider();
 		springWebProviderOptional.ifPresent(springWebProvider -> {
 			Map<RequestMappingInfo, HandlerMethod> map = springWebProvider.getHandlerMethods();
@@ -167,8 +166,8 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 				this.openAPIService.addTag(new HashSet<>(actuatorMap.values()), getTag());
 				map.putAll(actuatorMap);
 			}
-			calculatePath(restControllers, map, locale, openAPI);
-			getWebFluxRouterFunctionPaths(locale, openAPI);
+			calculatePath(restControllers, map, locale);
+			getWebFluxRouterFunctionPaths(locale);
 		});
 	}
 
@@ -178,9 +177,8 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 	 * @param restControllers the rest controllers
 	 * @param map the map
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void calculatePath(Map<String, Object> restControllers, Map<RequestMappingInfo, HandlerMethod> map, Locale locale, OpenAPI openAPI) {
+	protected void calculatePath(Map<String, Object> restControllers, Map<RequestMappingInfo, HandlerMethod> map, Locale locale) {
 		TreeMap<RequestMappingInfo, HandlerMethod> methodTreeMap = new TreeMap<>(byReversedRequestMappingInfos());
 		methodTreeMap.putAll(map);
 		Optional<SpringWebProvider> springWebProviderOptional = springDocProviders.getSpringWebProvider();
@@ -201,7 +199,7 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 						// default allowed requestmethods
 						if (requestMethods.isEmpty())
 							requestMethods = this.getDefaultAllowedHttpMethods();
-						calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, locale, openAPI);
+						calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, locale);
 					}
 				}
 			}
@@ -220,15 +218,14 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 	/**
 	 * Gets web flux router function paths.
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void getWebFluxRouterFunctionPaths(Locale locale, OpenAPI openAPI) {
+	protected void getWebFluxRouterFunctionPaths(Locale locale) {
 		Map<String, RouterFunction> routerBeans = Objects.requireNonNull(openAPIService.getContext()).getBeansOfType(RouterFunction.class);
 		for (Map.Entry<String, RouterFunction> entry : routerBeans.entrySet()) {
 			RouterFunction routerFunction = entry.getValue();
 			RouterFunctionVisitor routerFunctionVisitor = new RouterFunctionVisitor();
 			routerFunction.accept(routerFunctionVisitor);
-			getRouterFunctionPaths(entry.getKey(), routerFunctionVisitor, locale, openAPI);
+			getRouterFunctionPaths(entry.getKey(), routerFunctionVisitor, locale);
 		}
 	}
 
diff --git a/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java b/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java
index 218ddd73a..699dc4de2 100644
--- a/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java
+++ b/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java
@@ -154,16 +154,16 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 
 	@Override
 	@SuppressWarnings("unchecked")
-	protected void getPaths(Map<String, Object> restControllers, Locale locale, OpenAPI openAPI) {
+	protected void getPaths(Map<String, Object> restControllers, Locale locale) {
 		Optional<SpringWebProvider> springWebProviderOptional = springDocProviders.getSpringWebProvider();
 		springWebProviderOptional.ifPresent(springWebProvider -> {
 			Map<RequestMappingInfo, HandlerMethod> map = springWebProvider.getHandlerMethods();
 
 			Optional<RepositoryRestResourceProvider> repositoryRestResourceProviderOptional = springDocProviders.getRepositoryRestResourceProvider();
 			repositoryRestResourceProviderOptional.ifPresent(restResourceProvider -> {
-				List<RouterOperation> operationList = restResourceProvider.getRouterOperations(openAPI, locale);
-				calculatePath(operationList, locale, openAPI);
-				restResourceProvider.customize(openAPI);
+				List<RouterOperation> operationList = restResourceProvider.getRouterOperations(openAPIService.getCalculatedOpenAPI(), locale);
+				calculatePath(operationList, locale);
+				restResourceProvider.customize(openAPIService.getCalculatedOpenAPI());
 				Map<RequestMappingInfo, HandlerMethod> mapDataRest = restResourceProvider.getHandlerMethods();
 				Map<String, Object> requestMappingMap = restResourceProvider.getBasePathAwareControllerEndpoints();
 				Class[] additionalRestClasses = requestMappingMap.values().stream().map(AopUtils::getTargetClass).toArray(Class[]::new);
@@ -177,7 +177,7 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 				this.openAPIService.addTag(new HashSet<>(actuatorMap.values()), getTag());
 				map.putAll(actuatorMap);
 			}
-			calculatePath(restControllers, map, locale, openAPI);
+			calculatePath(restControllers, map, locale);
 		});
 
 		Optional<SecurityOAuth2Provider> securityOAuth2ProviderOptional = springDocProviders.getSpringSecurityOAuth2Provider();
@@ -187,11 +187,11 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 			Map<String, Object> requestMappingMapSec = securityOAuth2Provider.getFrameworkEndpoints();
 			Class[] additionalRestClasses = requestMappingMapSec.values().stream().map(AopUtils::getTargetClass).toArray(Class[]::new);
 			AbstractOpenApiResource.addRestControllers(additionalRestClasses);
-			calculatePath(requestMappingMapSec, mapOauth, locale, openAPI);
+			calculatePath(requestMappingMapSec, mapOauth, locale);
 		}
 
 		springDocProviders.getRouterFunctionProvider().ifPresent(routerFunctions -> routerFunctions.getRouterFunctionPaths()
-				.ifPresent(routerBeans -> routerBeans.forEach((beanName, routerFunctionVisitor) -> getRouterFunctionPaths(beanName, routerFunctionVisitor, locale, openAPI))));
+				.ifPresent(routerBeans -> routerBeans.forEach((beanName, routerFunctionVisitor) -> getRouterFunctionPaths(beanName, routerFunctionVisitor, locale))));
 
 	}
 
@@ -201,9 +201,8 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 	 * @param restControllers the rest controllers
 	 * @param map the map
 	 * @param locale the locale
-	 * @param openAPI the open api
 	 */
-	protected void calculatePath(Map<String, Object> restControllers, Map<RequestMappingInfo, HandlerMethod> map, Locale locale, OpenAPI openAPI) {
+	protected void calculatePath(Map<String, Object> restControllers, Map<RequestMappingInfo, HandlerMethod> map, Locale locale) {
 		TreeMap<RequestMappingInfo, HandlerMethod> methodTreeMap = new TreeMap<>(byReversedRequestMappingInfos());
 		methodTreeMap.putAll(map);
 		Optional<SpringWebProvider> springWebProviderOptional = springDocProviders.getSpringWebProvider();
@@ -225,7 +224,7 @@ public abstract class OpenApiResource extends AbstractOpenApiResource {
 							// default allowed requestmethods
 							if (requestMethods.isEmpty())
 								requestMethods = this.getDefaultAllowedHttpMethods();
-							calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces , headers, locale, openAPI);
+							calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces , headers, locale);
 						}
 					}
 				}
diff --git a/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/core/RequestService.java b/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/core/RequestService.java
index 4801a4c9d..c21969aa3 100644
--- a/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/core/RequestService.java
+++ b/springdoc-openapi-webmvc-core/src/main/java/org/springdoc/webmvc/core/RequestService.java
@@ -46,6 +46,7 @@ public class RequestService extends AbstractRequestService {
 				.addRequestWrapperToIgnore(javax.servlet.ServletResponse.class)
 				.addRequestWrapperToIgnore(javax.servlet.http.HttpServletRequest.class)
 				.addRequestWrapperToIgnore(javax.servlet.http.HttpServletResponse.class)
+				.addRequestWrapperToIgnore(javax.servlet.http.HttpSession.class)
 				.addRequestWrapperToIgnore(javax.servlet.http.HttpSession.class);
 	}
 


Test patch:
diff --git a/springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java b/springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java
index f2059ab07..eaaccd0f7 100644
--- a/springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java
+++ b/springdoc-openapi-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java
@@ -1,21 +1,19 @@
 /*
  *
  *  *
+ *  *  * Copyright 2019-2021 the original author or authors.
  *  *  *
- *  *  *  * Copyright 2019-2022 the original author or authors.
- *  *  *  *
- *  *  *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  *  *  * you may not use this file except in compliance with the License.
- *  *  *  * You may obtain a copy of the License at
- *  *  *  *
- *  *  *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *  *  *
- *  *  *  * Unless required by applicable law or agreed to in writing, software
- *  *  *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  *  *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  *  *  * See the License for the specific language governing permissions and
- *  *  *  * limitations under the License.
+ *  *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  *  * you may not use this file except in compliance with the License.
+ *  *  * You may obtain a copy of the License at
  *  *  *
+ *  *  *	  https://www.apache.org/licenses/LICENSE-2.0
+ *  *  *
+ *  *  * Unless required by applicable law or agreed to in writing, software
+ *  *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  *  * See the License for the specific language governing permissions and
+ *  *  * limitations under the License.
  *  *
  *
  */
@@ -118,8 +116,8 @@ class AbstractOpenApiResourceTest {
 		ReflectionTestUtils.setField(openAPIService, "cachedOpenAPI", new HashMap<>());
 		ReflectionTestUtils.setField(openAPIService, "serverBaseUrlCustomizers", Optional.empty());
 
+		when(openAPIService.getCalculatedOpenAPI()).thenReturn(openAPI);
 		when(openAPIService.getContext()).thenReturn(context);
-		when(openAPIService.build(any())).thenReturn(openAPI);
 
 		when(openAPIBuilderObjectFactory.getObject()).thenReturn(openAPIService);
 		when(springDocProviders.jsonMapper()).thenReturn(Json.mapper());
@@ -162,7 +160,7 @@ class AbstractOpenApiResourceTest {
 		routerOperation.setOperationModel(operation);
 		routerOperation.setPath(PATH);
 
-		resource.calculatePath(routerOperation, Locale.getDefault(), this.openAPI);
+		resource.calculatePath(routerOperation, Locale.getDefault());
 
 		final List<Parameter> parameters = resource.getOpenApi(Locale.getDefault()).getPaths().get(PATH).getGet().getParameters();
 		assertThat(parameters.size(), is(3));
@@ -295,7 +293,7 @@ class AbstractOpenApiResourceTest {
 		}
 
 		@Override
-		public void getPaths(Map<String, Object> findRestControllers, Locale locale, OpenAPI openAPI) {
+		public void getPaths(Map<String, Object> findRestControllers, Locale locale) {
 		}
 	}
 }
\ No newline at end of file
diff --git a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java b/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java
deleted file mode 100644
index 9149c7252..000000000
--- a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.Matchers.containsString;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework"
-})
-public class SpringDocBehindProxyTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldServeSwaggerUIAtDefaultPath() throws Exception {
-		mockMvc.perform(get("/swagger-ui/index.html"))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() throws Exception {
-		mockMvc.perform(get("/swagger-ui/swagger-initializer.js")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(content().string(
-						containsString("\"configUrl\" : \"/path/prefix/v3/api-docs/swagger-config\",")
-				));
-	}
-
-	@Test
-	public void shouldCalculateOauthRedirectBehindProxy() throws Exception {
-		mockMvc.perform(get("/v3/api-docs/swagger-config")
-						.header("X-Forwarded-Proto", "https")
-						.header("X-Forwarded-Host", "proxy-host")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("oauth2RedirectUrl",
-						equalTo("https://proxy-host/path/prefix/swagger-ui/oauth2-redirect.html")
-				));
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() throws Exception {
-		mockMvc.perform(get("/v3/api-docs/swagger-config")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("url",
-						equalTo("/path/prefix/v3/api-docs")
-				))
-				.andExpect(jsonPath("configUrl",
-						equalTo("/path/prefix/v3/api-docs/swagger-config")
-				));
-	}
-}
diff --git a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java b/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java
deleted file mode 100644
index 6371e6dfa..000000000
--- a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.Matchers.containsString;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework",
-		"springdoc.swagger-ui.path=/foo/documentation/swagger.html"
-})
-public class SpringDocBehindProxyWithCustomUIPathTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldRedirectSwaggerUIFromCustomPath() throws Exception {
-		mockMvc.perform(get("/foo/documentation/swagger.html")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isFound())
-				.andExpect(header().string("Location", "/path/prefix/foo/documentation/swagger-ui/index.html"));
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() throws Exception {
-		mockMvc.perform(get("/foo/documentation/swagger-ui/swagger-initializer.js")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(content().string(
-						containsString("\"configUrl\" : \"/path/prefix/v3/api-docs/swagger-config\",")
-				));
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() throws Exception {
-		mockMvc.perform(get("/v3/api-docs/swagger-config")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("url",
-						equalTo("/path/prefix/v3/api-docs")
-				))
-				.andExpect(jsonPath("configUrl",
-						equalTo("/path/prefix/v3/api-docs/swagger-config")
-				));
-	}
-
-}
diff --git a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java b/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java
deleted file mode 100644
index bbb11ba75..000000000
--- a/springdoc-openapi-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.Matchers.containsString;
-import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework",
-		"springdoc.swagger-ui.path=/foo/documentation/swagger.html",
-		"springdoc.api-docs.path=/bar/openapi/v3"
-})
-public class SpringDocBehindProxyWithCustomUIPathWithApiDocsTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldServeOpenapiJsonUnderCustomPath() throws Exception {
-		mockMvc.perform(get("/bar/openapi/v3")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk());
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() throws Exception {
-		mockMvc.perform(get("/foo/documentation/swagger-ui/swagger-initializer.js")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(content().string(
-						containsString("\"configUrl\" : \"/path/prefix/bar/openapi/v3/swagger-config\",")
-				));
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() throws Exception {
-		mockMvc.perform(get("/bar/openapi/v3/swagger-config")
-						.header("X-Forwarded-Prefix", X_FORWARD_PREFIX))
-				.andExpect(status().isOk())
-				.andExpect(jsonPath("url",
-						equalTo("/path/prefix/bar/openapi/v3")
-				))
-				.andExpect(jsonPath("configUrl",
-						equalTo("/path/prefix/bar/openapi/v3/swagger-config")
-				));
-	}
-}
diff --git a/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app186/SpringDocApp186Test.java b/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app186/SpringDocApp186Test.java
new file mode 100644
index 000000000..1b6018505
--- /dev/null
+++ b/springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app186/SpringDocApp186Test.java
@@ -0,0 +1,100 @@
+/*
+ *
+ *  *
+ *  *  * Copyright 2019-2020 the original author or authors.
+ *  *  *
+ *  *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  *  * you may not use this file except in compliance with the License.
+ *  *  * You may obtain a copy of the License at
+ *  *  *
+ *  *  *      https://www.apache.org/licenses/LICENSE-2.0
+ *  *  *
+ *  *  * Unless required by applicable law or agreed to in writing, software
+ *  *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  *  * See the License for the specific language governing permissions and
+ *  *  * limitations under the License.
+ *  *
+ *
+ */
+
+package test.org.springdoc.api.app186;
+
+import static org.springdoc.core.Constants.ALL_PATTERN;
+
+import org.junit.jupiter.api.Test;
+import org.springdoc.core.Constants;
+import org.springdoc.core.GroupedOpenApi;
+import org.springdoc.core.customizers.OpenApiCustomiser;
+import org.springdoc.core.customizers.OperationCustomizer;
+import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.TestPropertySource;
+
+import test.org.springdoc.api.AbstractCommonTest;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@TestPropertySource(properties={ "springdoc.show-actuator=true",
+		"springdoc.group-configs[0].group=group-actuator-as-properties",
+		"springdoc.group-configs[0].paths-to-match=${management.endpoints.web.base-path:/actuator}/**",
+		"management.endpoints.enabled-by-default=true",
+		"management.endpoints.web.exposure.include=*",
+		"management.endpoints.web.exposure.exclude=functions, shutdown"})
+public class SpringDocApp186Test extends AbstractCommonTest {
+
+	@SpringBootApplication
+	@ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.app186" })
+	static class SpringDocTestApp {
+
+		@Bean
+		public GroupedOpenApi asCodeCheckBackwardsCompatibility(OpenApiCustomiser actuatorOpenApiCustomiser,
+				OperationCustomizer actuatorCustomizer, WebEndpointProperties endpointProperties) {
+			return GroupedOpenApi.builder()
+					.group("group-actuator-as-code-check-backwards-compatibility")
+					.pathsToMatch(endpointProperties.getBasePath()+ ALL_PATTERN)
+					.addOpenApiCustomiser(actuatorOpenApiCustomiser)
+					.addOperationCustomizer(actuatorCustomizer)
+					.build();
+		}
+
+		@Bean
+		public GroupedOpenApi asCode(WebEndpointProperties endpointProperties) {
+			return GroupedOpenApi.builder()
+					.group("group-actuator-as-code")
+					.pathsToMatch(endpointProperties.getBasePath()+ ALL_PATTERN)
+					.build();
+		}
+	}
+
+	@Test
+	public void testApp() throws Exception {
+		webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL).exchange()
+				.expectStatus().isOk()
+				.expectBody().json(getContent("results/app186.json"), true);
+	}
+
+	@Test
+	public void testGroupActuatorAsCodeCheckBackwardsCompatibility() throws Exception {
+		webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-code-check-backwards-compatibility").exchange()
+				.expectStatus().isOk()
+				.expectBody().json(getContent("results/app186.json"), true);
+	}
+
+	@Test
+	public void testGroupActuatorAsCode() throws Exception {
+		webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-code").exchange()
+				.expectStatus().isOk()
+				.expectBody().json(getContent("results/app186.json"), true);
+	}
+
+	@Test
+	public void testGroupActuatorAsProperties() throws Exception {
+		webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-properties").exchange()
+				.expectStatus().isOk()
+				.expectBody().json(getContent("results/app186.json"), true);
+	}
+
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webflux-core/src/test/resources/results/app146-1.json b/springdoc-openapi-webflux-core/src/test/resources/results/app146-1.json
index e51be718a..92c2f3cb2 100644
--- a/springdoc-openapi-webflux-core/src/test/resources/results/app146-1.json
+++ b/springdoc-openapi-webflux-core/src/test/resources/results/app146-1.json
@@ -26,7 +26,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_6",
+        "operationId": "handle_5",
         "parameters": [
           {
             "name": "name",
@@ -147,7 +147,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_2",
+        "operationId": "handle_1",
         "responses": {
           "200": {
             "description": "OK",
@@ -177,7 +177,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_3",
+        "operationId": "handle_2",
         "parameters": [
           {
             "name": "requiredMetricName",
@@ -217,7 +217,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_4",
+        "operationId": "handle_3",
         "responses": {
           "200": {
             "description": "OK",
@@ -247,7 +247,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_5",
+        "operationId": "handle_4",
         "responses": {
           "200": {
             "description": "OK",
@@ -277,7 +277,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_7",
+        "operationId": "handle_6",
         "responses": {
           "200": {
             "description": "OK",
@@ -307,7 +307,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_8",
+        "operationId": "handle_7",
         "responses": {
           "200": {
             "description": "OK",
@@ -337,7 +337,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_9",
+        "operationId": "handle_8",
         "responses": {
           "200": {
             "description": "OK",
@@ -357,7 +357,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_10",
+        "operationId": "handle_9",
         "responses": {
           "200": {
             "description": "OK",
@@ -387,7 +387,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_11",
+        "operationId": "handle_10",
         "parameters": [
           {
             "name": "toMatch",
@@ -427,7 +427,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_12",
+        "operationId": "handle_11",
         "responses": {
           "200": {
             "description": "OK",
@@ -457,7 +457,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_13",
+        "operationId": "handle_12",
         "parameters": [
           {
             "name": "prefix",
@@ -497,7 +497,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_14",
+        "operationId": "handle_13",
         "responses": {
           "200": {
             "description": "OK",
@@ -527,7 +527,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_15",
+        "operationId": "handle_14",
         "responses": {
           "200": {
             "description": "OK",
@@ -557,7 +557,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_16",
+        "operationId": "handle_15",
         "parameters": [
           {
             "name": "cache",
@@ -595,7 +595,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_20",
+        "operationId": "handle_19",
         "parameters": [
           {
             "name": "cache",
@@ -635,7 +635,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_17",
+        "operationId": "handle_16",
         "responses": {
           "200": {
             "description": "OK",
@@ -663,7 +663,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_19",
+        "operationId": "handle_18",
         "responses": {
           "200": {
             "description": "OK",
@@ -683,7 +683,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_18",
+        "operationId": "handle_17",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webflux-core/src/test/resources/results/app147-1.json b/springdoc-openapi-webflux-core/src/test/resources/results/app147-1.json
index 7bad9dfe5..b049d12c0 100644
--- a/springdoc-openapi-webflux-core/src/test/resources/results/app147-1.json
+++ b/springdoc-openapi-webflux-core/src/test/resources/results/app147-1.json
@@ -26,7 +26,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_6",
+        "operationId": "handle_5",
         "parameters": [
           {
             "name": "name",
@@ -147,7 +147,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_2",
+        "operationId": "handle_1",
         "responses": {
           "200": {
             "description": "OK",
@@ -177,7 +177,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_3",
+        "operationId": "handle_2",
         "parameters": [
           {
             "name": "requiredMetricName",
@@ -217,7 +217,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_4",
+        "operationId": "handle_3",
         "responses": {
           "200": {
             "description": "OK",
@@ -247,7 +247,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_5",
+        "operationId": "handle_4",
         "responses": {
           "200": {
             "description": "OK",
@@ -277,7 +277,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_7",
+        "operationId": "handle_6",
         "responses": {
           "200": {
             "description": "OK",
@@ -307,7 +307,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_8",
+        "operationId": "handle_7",
         "responses": {
           "200": {
             "description": "OK",
@@ -337,7 +337,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_9",
+        "operationId": "handle_8",
         "responses": {
           "200": {
             "description": "OK",
@@ -357,7 +357,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_10",
+        "operationId": "handle_9",
         "responses": {
           "200": {
             "description": "OK",
@@ -387,7 +387,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_11",
+        "operationId": "handle_10",
         "parameters": [
           {
             "name": "toMatch",
@@ -427,7 +427,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_12",
+        "operationId": "handle_11",
         "responses": {
           "200": {
             "description": "OK",
@@ -457,7 +457,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_13",
+        "operationId": "handle_12",
         "parameters": [
           {
             "name": "prefix",
@@ -497,7 +497,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_14",
+        "operationId": "handle_13",
         "responses": {
           "200": {
             "description": "OK",
@@ -527,7 +527,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_15",
+        "operationId": "handle_14",
         "responses": {
           "200": {
             "description": "OK",
@@ -557,7 +557,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_16",
+        "operationId": "handle_15",
         "parameters": [
           {
             "name": "cache",
@@ -595,7 +595,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_20",
+        "operationId": "handle_19",
         "parameters": [
           {
             "name": "cache",
@@ -635,7 +635,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_17",
+        "operationId": "handle_16",
         "responses": {
           "200": {
             "description": "OK",
@@ -663,7 +663,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_19",
+        "operationId": "handle_18",
         "responses": {
           "200": {
             "description": "OK",
@@ -683,7 +683,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_18",
+        "operationId": "handle_17",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webflux-core/src/test/resources/results/app148-2.json b/springdoc-openapi-webflux-core/src/test/resources/results/app148-2.json
index 51fb1fecf..82983a583 100644
--- a/springdoc-openapi-webflux-core/src/test/resources/results/app148-2.json
+++ b/springdoc-openapi-webflux-core/src/test/resources/results/app148-2.json
@@ -26,7 +26,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_6",
+        "operationId": "handle_5",
         "parameters": [
           {
             "name": "name",
@@ -147,7 +147,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_2",
+        "operationId": "handle_1",
         "responses": {
           "200": {
             "description": "OK",
@@ -177,7 +177,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_3",
+        "operationId": "handle_2",
         "parameters": [
           {
             "name": "requiredMetricName",
@@ -217,7 +217,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_4",
+        "operationId": "handle_3",
         "responses": {
           "200": {
             "description": "OK",
@@ -247,7 +247,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_5",
+        "operationId": "handle_4",
         "responses": {
           "200": {
             "description": "OK",
@@ -277,7 +277,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_7",
+        "operationId": "handle_6",
         "responses": {
           "200": {
             "description": "OK",
@@ -307,7 +307,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_8",
+        "operationId": "handle_7",
         "responses": {
           "200": {
             "description": "OK",
@@ -337,7 +337,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_9",
+        "operationId": "handle_8",
         "responses": {
           "200": {
             "description": "OK",
@@ -357,7 +357,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_10",
+        "operationId": "handle_9",
         "responses": {
           "200": {
             "description": "OK",
@@ -387,7 +387,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_11",
+        "operationId": "handle_10",
         "parameters": [
           {
             "name": "toMatch",
@@ -427,7 +427,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_12",
+        "operationId": "handle_11",
         "responses": {
           "200": {
             "description": "OK",
@@ -457,7 +457,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_13",
+        "operationId": "handle_12",
         "parameters": [
           {
             "name": "prefix",
@@ -497,7 +497,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_14",
+        "operationId": "handle_13",
         "responses": {
           "200": {
             "description": "OK",
@@ -527,7 +527,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_15",
+        "operationId": "handle_14",
         "responses": {
           "200": {
             "description": "OK",
@@ -557,7 +557,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_16",
+        "operationId": "handle_15",
         "parameters": [
           {
             "name": "cache",
@@ -595,7 +595,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_20",
+        "operationId": "handle_19",
         "parameters": [
           {
             "name": "cache",
@@ -635,7 +635,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_17",
+        "operationId": "handle_16",
         "responses": {
           "200": {
             "description": "OK",
@@ -663,7 +663,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_19",
+        "operationId": "handle_18",
         "responses": {
           "200": {
             "description": "OK",
@@ -683,7 +683,7 @@
         "tags": [
           "Actuator"
         ],
-        "operationId": "handle_1_18",
+        "operationId": "handle_17",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webflux-core/src/test/resources/results/app186.json b/springdoc-openapi-webflux-core/src/test/resources/results/app186.json
new file mode 100644
index 000000000..2b4d74f14
--- /dev/null
+++ b/springdoc-openapi-webflux-core/src/test/resources/results/app186.json
@@ -0,0 +1,816 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "OpenAPI definition",
+    "version": "v0"
+  },
+  "servers": [
+    {
+      "url": "",
+      "description": "Generated server url"
+    }
+  ],
+  "tags": [
+    {
+      "name": "Actuator",
+      "description": "Monitor and interact",
+      "externalDocs": {
+        "description": "Spring Boot Actuator Web API Documentation",
+        "url": "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/"
+      }
+    }
+  ],
+  "paths": {
+    "/actuator/loggers/{name}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_5",
+        "parameters": [
+          {
+            "name": "name",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "post": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle",
+        "parameters": [
+          {
+            "name": "name",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "string",
+                "enum": [
+                  "TRACE",
+                  "DEBUG",
+                  "INFO",
+                  "WARN",
+                  "ERROR",
+                  "FATAL",
+                  "OFF"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/threaddump": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_1_1",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "text/plain;charset=UTF-8": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/scheduledtasks": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_1",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/metrics/{requiredMetricName}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_2",
+        "parameters": [
+          {
+            "name": "requiredMetricName",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/metrics": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_3",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/mappings": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_4",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/loggers": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_6",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/info": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_7",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/heapdump": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_8",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/octet-stream": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/health/{*path}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_9",
+        "parameters": [
+          {
+            "name": "*path",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/health": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_10",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/env/{toMatch}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_11",
+        "parameters": [
+          {
+            "name": "toMatch",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/env": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_12",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/configprops/{prefix}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_13",
+        "parameters": [
+          {
+            "name": "prefix",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/configprops": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_14",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/conditions": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_15",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/caches/{cache}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_16",
+        "parameters": [
+          {
+            "name": "cache",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "delete": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_20",
+        "parameters": [
+          {
+            "name": "cache",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/caches": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_17",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "delete": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_19",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/beans": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "operationId": "handle_18",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator root web endpoint",
+        "operationId": "links",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+      "Link": {
+        "type": "object",
+        "properties": {
+          "href": {
+            "type": "string"
+          },
+          "templated": {
+            "type": "boolean"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java
deleted file mode 100644
index a00073054..000000000
--- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework"
-})
-@Import(SpringDocConfig.class)
-public class SpringDocBehindProxyTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldServeSwaggerUIAtDefaultPath() {
-		webTestClient.get().uri("/webjars/swagger-ui/index.html").exchange()
-				.expectStatus().isOk();
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() throws Exception {
-		webTestClient
-				.get().uri("/webjars/swagger-ui/swagger-initializer.js")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk()
-				.expectBody(String.class)
-				.consumeWith(response ->
-						assertThat(response.getResponseBody())
-								.contains("\"configUrl\" : \"/path/prefix/v3/api-docs/swagger-config\",")
-				);
-	}
-
-	@Test
-	public void shouldCalculateOauthRedirectBehindProxy() throws Exception {
-		webTestClient
-				.get().uri("/v3/api-docs/swagger-config")
-				.header("X-Forwarded-Proto", "https")
-				.header("X-Forwarded-Host", "proxy-host")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk().expectBody()
-				.jsonPath("$.oauth2RedirectUrl").isEqualTo("https://proxy-host/path/prefix/webjars/swagger-ui/oauth2-redirect.html");
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() throws Exception {
-		webTestClient
-				.get().uri("/v3/api-docs/swagger-config")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk().expectBody()
-				.jsonPath("$.url")
-				.isEqualTo("/path/prefix/v3/api-docs")
-				.jsonPath("$.configUrl")
-				.isEqualTo("/path/prefix/v3/api-docs/swagger-config");
-	}
-}
diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java
deleted file mode 100644
index 2472b0840..000000000
--- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework",
-		"springdoc.swagger-ui.path=/foo/documentation/swagger.html"
-})
-@Import(SpringDocConfig.class)
-public class SpringDocBehindProxyWithCustomUIPathTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldRedirectSwaggerUIFromCustomPath() {
-		webTestClient
-				.get().uri("/foo/documentation/swagger.html")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isFound()
-				.expectHeader().location("/path/prefix/foo/documentation/webjars/swagger-ui/index.html");
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() {
-		webTestClient
-				.get().uri("/foo/documentation/webjars/swagger-ui/swagger-initializer.js")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk()
-				.expectBody(String.class)
-				.consumeWith(response ->
-						assertThat(response.getResponseBody())
-								.contains("\"configUrl\" : \"/path/prefix/v3/api-docs/swagger-config\"")
-				);
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() throws Exception {
-		webTestClient
-				.get().uri("/v3/api-docs/swagger-config")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk()
-				.expectBody()
-				.jsonPath("$.url")
-				.isEqualTo("/path/prefix/v3/api-docs")
-				.jsonPath("$.configUrl")
-				.isEqualTo("/path/prefix/v3/api-docs/swagger-config");
-	}
-}
diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java
deleted file mode 100644
index f911fb994..000000000
--- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocBehindProxyWithCustomUIPathWithApiDocsTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- *  * Copyright 2019-2020 the original author or authors.
- *  *
- *  * Licensed under the Apache License, Version 2.0 (the "License");
- *  * you may not use this file except in compliance with the License.
- *  * You may obtain a copy of the License at
- *  *
- *  *      https://www.apache.org/licenses/LICENSE-2.0
- *  *
- *  * Unless required by applicable law or agreed to in writing, software
- *  * distributed under the License is distributed on an "AS IS" BASIS,
- *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  * See the License for the specific language governing permissions and
- *  * limitations under the License.
- *
- */
-
-package test.org.springdoc.ui.app32;
-
-import org.junit.jupiter.api.Test;
-import test.org.springdoc.ui.AbstractSpringDocTest;
-
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.context.annotation.Import;
-import org.springframework.test.context.TestPropertySource;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@TestPropertySource(properties = {
-		"server.forward-headers-strategy=framework",
-		"springdoc.swagger-ui.path=/foo/documentation/swagger.html",
-		"springdoc.api-docs.path=/bar/openapi/v3"
-})
-@Import(SpringDocConfig.class)
-public class SpringDocBehindProxyWithCustomUIPathWithApiDocsTest extends AbstractSpringDocTest {
-
-	private static final String X_FORWARD_PREFIX = "/path/prefix";
-
-	@SpringBootApplication
-	static class SpringDocTestApp {}
-
-	@Test
-	public void shouldRedirectSwaggerUIFromCustomPath() {
-		webTestClient
-				.get().uri("/foo/documentation/swagger.html")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isFound()
-				.expectHeader().location("/path/prefix/foo/documentation/webjars/swagger-ui/index.html");
-	}
-
-	@Test
-	public void shouldReturnCorrectInitializerJS() {
-		webTestClient
-				.get().uri("/foo/documentation/webjars/swagger-ui/swagger-initializer.js")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk()
-				.expectBody(String.class)
-				.consumeWith(response ->
-						assertThat(response.getResponseBody())
-								.contains("\"configUrl\" : \"/path/prefix/bar/openapi/v3/swagger-config\",")
-				);
-	}
-
-	@Test
-	public void shouldCalculateUrlsBehindProxy() {
-		webTestClient
-				.get().uri("/bar/openapi/v3/swagger-config")
-				.header("X-Forwarded-Prefix", X_FORWARD_PREFIX)
-				.exchange()
-				.expectStatus().isOk()
-				.expectBody()
-				.jsonPath("$.url")
-				.isEqualTo("/path/prefix/bar/openapi/v3")
-				.jsonPath("$.configUrl")
-				.isEqualTo("/path/prefix/bar/openapi/v3/swagger-config");
-	}
-}
diff --git a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocConfig.java b/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocConfig.java
deleted file mode 100644
index e99250b8e..000000000
--- a/springdoc-openapi-webflux-ui/src/test/java/test/org/springdoc/ui/app32/SpringDocConfig.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package test.org.springdoc.ui.app32;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
-
-@Configuration
-public class SpringDocConfig {
-
-	@Bean
-	ForwardedHeaderTransformer forwardedHeaderTransformer() {
-		return new ForwardedHeaderTransformer();
-	}
-}
diff --git a/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java
new file mode 100644
index 000000000..83c1c3e9f
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java
@@ -0,0 +1,108 @@
+/*
+ *
+ *  *
+ *  *  *
+ *  *  *  * Copyright 2019-2022 the original author or authors.
+ *  *  *  *
+ *  *  *  * Licensed under the Apache License, Version 2.0 (the "License");
+ *  *  *  * you may not use this file except in compliance with the License.
+ *  *  *  * You may obtain a copy of the License at
+ *  *  *  *
+ *  *  *  *      https://www.apache.org/licenses/LICENSE-2.0
+ *  *  *  *
+ *  *  *  * Unless required by applicable law or agreed to in writing, software
+ *  *  *  * distributed under the License is distributed on an "AS IS" BASIS,
+ *  *  *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  *  *  * See the License for the specific language governing permissions and
+ *  *  *  * limitations under the License.
+ *  *  *
+ *  *
+ *
+ */
+
+package test.org.springdoc.api.v30.app186;
+
+import static org.hamcrest.Matchers.is;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import org.junit.jupiter.api.Test;
+import org.springdoc.core.Constants;
+import org.springdoc.core.GroupedOpenApi;
+import org.springdoc.core.customizers.OpenApiCustomiser;
+import org.springdoc.core.customizers.OperationCustomizer;
+import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.test.context.TestPropertySource;
+
+import test.org.springdoc.api.v30.AbstractSpringDocV30Test;
+
+import static org.springdoc.core.Constants.ALL_PATTERN;
+
+@TestPropertySource(properties = { "springdoc.show-actuator=true",
+		"springdoc.group-configs[0].group=group-actuator-as-properties",
+		"springdoc.group-configs[0].paths-to-match=${management.endpoints.web.base-path:/actuator}/**",
+		"management.endpoints.enabled-by-default=true",
+		"management.endpoints.web.exposure.include=*",
+		"management.endpoints.web.exposure.exclude=functions, shutdown"})
+public class SpringDocApp186Test extends AbstractSpringDocV30Test {
+
+	@SpringBootApplication
+	static class SpringDocTestApp {
+
+		@Bean
+		public GroupedOpenApi asCodeCheckBackwardsCompatibility(OpenApiCustomiser actuatorOpenApiCustomiser,
+				OperationCustomizer actuatorCustomizer, WebEndpointProperties endpointProperties) {
+			return GroupedOpenApi.builder()
+					.group("group-actuator-as-code-check-backwards-compatibility")
+					.pathsToMatch(endpointProperties.getBasePath()+ ALL_PATTERN)
+					.addOpenApiCustomiser(actuatorOpenApiCustomiser)
+					.addOperationCustomizer(actuatorCustomizer)
+					.build();
+		}
+
+		@Bean
+		public GroupedOpenApi asCode(WebEndpointProperties endpointProperties) {
+			return GroupedOpenApi.builder()
+					.group("group-actuator-as-code")
+					.pathsToMatch(endpointProperties.getBasePath()+ ALL_PATTERN)
+					.build();
+		}
+	}
+
+	@Test
+	public void testApp() throws Exception {
+		mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL))
+				.andExpect(jsonPath("$.openapi", is("3.0.1")))
+				.andExpect(status().isOk())
+				.andExpect(content().json(getContent("results/3.0.1/app186.json"), true));
+	}
+
+	@Test
+	public void testGroupActuatorAsCodeCheckBackwardsCompatibility() throws Exception {
+		mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-code-check-backwards-compatibility"))
+				.andExpect(jsonPath("$.openapi", is("3.0.1")))
+				.andExpect(status().isOk())
+				.andExpect(content().json(getContent("results/3.0.1/app186.json"), true));
+	}
+
+	@Test
+	public void testGroupActuatorAsCode() throws Exception {
+		mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-code"))
+				.andExpect(jsonPath("$.openapi", is("3.0.1")))
+				.andExpect(status().isOk())
+				.andExpect(content().json(getContent("results/3.0.1/app186.json"), true));
+	}
+
+	@Test
+	public void testGroupActuatorAsProperties() throws Exception {
+		mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL + "/group-actuator-as-properties"))
+				.andExpect(jsonPath("$.openapi", is("3.0.1")))
+				.andExpect(status().isOk())
+				.andExpect(content().json(getContent("results/3.0.1/app186.json"), true));
+	}
+
+}
\ No newline at end of file
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app146-1.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app146-1.json
index fe0684662..ba4820f8c 100644
--- a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app146-1.json
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app146-1.json
@@ -27,7 +27,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name_2",
+        "operationId": "loggers-name",
         "parameters": [
           {
             "name": "name",
@@ -66,7 +66,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name",
+        "operationId": "loggers-name_2",
         "parameters": [
           {
             "name": "name",
@@ -164,7 +164,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'threaddump'",
-        "operationId": "threaddump_2",
+        "operationId": "threaddump",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app147-1.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app147-1.json
index fd8188a40..e9bf873dc 100644
--- a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app147-1.json
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app147-1.json
@@ -1,4 +1,4 @@
-{
+	{
   "openapi": "3.0.1",
   "info": {
     "title": "OpenAPI definition",
@@ -27,7 +27,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name_2",
+        "operationId": "loggers-name",
         "parameters": [
           {
             "name": "name",
@@ -66,7 +66,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name",
+        "operationId": "loggers-name_2",
         "parameters": [
           {
             "name": "name",
@@ -164,7 +164,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'threaddump'",
-        "operationId": "threaddump_2",
+        "operationId": "threaddump",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app148-2.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app148-2.json
index 59eb5850a..2d632ab24 100644
--- a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app148-2.json
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app148-2.json
@@ -27,7 +27,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name_2",
+        "operationId": "loggers-name",
         "parameters": [
           {
             "name": "name",
@@ -66,7 +66,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'loggers-name'",
-        "operationId": "loggers-name",
+        "operationId": "loggers-name_2",
         "parameters": [
           {
             "name": "name",
@@ -164,7 +164,7 @@
           "Actuator"
         ],
         "summary": "Actuator web endpoint 'threaddump'",
-        "operationId": "threaddump_2",
+        "operationId": "threaddump",
         "responses": {
           "200": {
             "description": "OK",
diff --git a/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app186.json b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app186.json
new file mode 100644
index 000000000..c136df41f
--- /dev/null
+++ b/springdoc-openapi-webmvc-core/src/test/resources/results/3.0.1/app186.json
@@ -0,0 +1,828 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "OpenAPI definition",
+    "version": "v0"
+  },
+  "servers": [
+    {
+      "url": "http://localhost",
+      "description": "Generated server url"
+    }
+  ],
+  "tags": [
+    {
+      "name": "Actuator",
+      "description": "Monitor and interact",
+      "externalDocs": {
+        "description": "Spring Boot Actuator Web API Documentation",
+        "url": "https://docs.spring.io/spring-boot/docs/current/actuator-api/html/"
+      }
+    }
+  ],
+  "paths": {
+    "/actuator/loggers/{name}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'loggers-name'",
+        "operationId": "loggers-name",
+        "parameters": [
+          {
+            "name": "name",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "post": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'loggers-name'",
+        "operationId": "loggers-name_2",
+        "parameters": [
+          {
+            "name": "name",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "string",
+                "enum": [
+                  "TRACE",
+                  "DEBUG",
+                  "INFO",
+                  "WARN",
+                  "ERROR",
+                  "FATAL",
+                  "OFF"
+                ]
+              }
+            }
+          }
+        },
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator root web endpoint",
+        "operationId": "links",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object",
+                  "additionalProperties": {
+                    "type": "object",
+                    "additionalProperties": {
+                      "$ref": "#/components/schemas/Link"
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/threaddump": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'threaddump'",
+        "operationId": "threaddump",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "text/plain;charset=UTF-8": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/scheduledtasks": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'scheduledtasks'",
+        "operationId": "scheduledtasks",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/metrics": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'metrics'",
+        "operationId": "metrics",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/metrics/{requiredMetricName}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'metrics-requiredMetricName'",
+        "operationId": "metrics-requiredMetricName",
+        "parameters": [
+          {
+            "name": "requiredMetricName",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/mappings": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'mappings'",
+        "operationId": "mappings",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/loggers": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'loggers'",
+        "operationId": "loggers",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/info": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'info'",
+        "operationId": "info",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/heapdump": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'heapdump'",
+        "operationId": "heapdump",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/octet-stream": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/health": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'health'",
+        "operationId": "health",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/health/**": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'health-path'",
+        "operationId": "health-path",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/env": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'env'",
+        "operationId": "env",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/env/{toMatch}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'env-toMatch'",
+        "operationId": "env-toMatch",
+        "parameters": [
+          {
+            "name": "toMatch",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/configprops": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'configprops'",
+        "operationId": "configprops",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/configprops/{prefix}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'configprops-prefix'",
+        "operationId": "configprops-prefix",
+        "parameters": [
+          {
+            "name": "prefix",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/conditions": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'conditions'",
+        "operationId": "conditions",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/caches": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'caches'",
+        "operationId": "caches",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "delete": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'caches'",
+        "operationId": "caches_2",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/caches/{cache}": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'caches-cache'",
+        "operationId": "caches-cache",
+        "parameters": [
+          {
+            "name": "cache",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      },
+      "delete": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'caches-cache'",
+        "operationId": "caches-cache_2",
+        "parameters": [
+          {
+            "name": "cache",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/actuator/beans": {
+      "get": {
+        "tags": [
+          "Actuator"
+        ],
+        "summary": "Actuator web endpoint 'beans'",
+        "operationId": "beans",
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/vnd.spring-boot.actuator.v3+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/vnd.spring-boot.actuator.v2+json": {
+                "schema": {
+                  "type": "object"
+                }
+              },
+              "application/json": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+      "Link": {
+        "type": "object",
+        "properties": {
+          "href": {
+            "type": "string"
+          },
+          "templated": {
+            "type": "boolean"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file