Skip to content

Commit 0ea096e

Browse files
committed
Merge branch 'christophejan-feature/global-customizer-and-filters'
2 parents 722b793 + 3f7dde6 commit 0ea096e

File tree

30 files changed

+1510
-28
lines changed

30 files changed

+1510
-28
lines changed

springdoc-openapi-common/src/main/java/org/springdoc/core/GroupedOpenApi.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
import java.util.ArrayList;
2424
import java.util.Arrays;
25+
import java.util.Collection;
26+
import java.util.Collections;
2527
import java.util.List;
2628
import java.util.Objects;
2729

@@ -463,11 +465,38 @@ public GroupedOpenApi build() {
463465
}
464466

465467
/**
466-
* Add open api customiser.
468+
* Add all open api customizer grouped open api.
467469
*
468-
* @param openApiCustomiser the open api customiser
470+
* @param openApiCustomizerCollection the open api customizer collection
471+
* @return the grouped open api
469472
*/
470-
public void addOpenApiCustomizer(OpenApiCustomiser openApiCustomiser) {
471-
this.openApiCustomisers.add(openApiCustomiser);
473+
public GroupedOpenApi addAllOpenApiCustomizer(Collection openApiCustomizerCollection) {
474+
this.openApiCustomisers.addAll(openApiCustomizerCollection);
475+
Collections.reverse(openApiCustomisers);
476+
return this;
477+
}
478+
479+
/**
480+
* Add all operation customizer grouped open api.
481+
*
482+
* @param operationCustomizerCollection the operation customizer collection
483+
* @return the grouped open api
484+
*/
485+
public GroupedOpenApi addAllOperationCustomizer(Collection operationCustomizerCollection) {
486+
this.operationCustomizers.addAll(operationCustomizerCollection);
487+
Collections.reverse(operationCustomizers);
488+
return this;
489+
}
490+
491+
/**
492+
* Add all open api method filter grouped open api.
493+
*
494+
* @param openApiMethodFilterCollection the open api method filter collection
495+
* @return the grouped open api
496+
*/
497+
public GroupedOpenApi addAllOpenApiMethodFilter(Collection openApiMethodFilterCollection) {
498+
this.openApiMethodFilters.addAll(openApiMethodFilterCollection);
499+
Collections.reverse(openApiMethodFilters);
500+
return this;
472501
}
473502
}

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringDocConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.springdoc.core.customizers.ActuatorOperationCustomizer;
5050
import org.springdoc.core.customizers.DataRestDelegatingMethodParameterCustomizer;
5151
import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer;
52+
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
5253
import org.springdoc.core.customizers.OpenApiBuilderCustomizer;
5354
import org.springdoc.core.customizers.OpenApiCustomiser;
5455
import org.springdoc.core.customizers.OperationCustomizer;
@@ -341,7 +342,7 @@ GenericParameterService parameterBuilder(PropertyResolverUtils propertyResolverU
341342
@Bean
342343
@ConditionalOnProperty(SPRINGDOC_SCHEMA_RESOLVE_PROPERTIES)
343344
@Lazy(false)
344-
OpenApiCustomiser propertiesResolverForSchema(PropertyResolverUtils propertyResolverUtils) {
345+
GlobalOpenApiCustomizer propertiesResolverForSchema(PropertyResolverUtils propertyResolverUtils) {
345346
return openApi -> {
346347
Components components = openApi.getComponents();
347348
Map<String, Schema> schemas = components.getSchemas();

springdoc-openapi-common/src/main/java/org/springdoc/core/SpringdocBeanFactoryConfigurer.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.stream.Collectors;
2828

2929
import io.swagger.v3.oas.models.OpenAPI;
30+
import org.apache.commons.lang3.StringUtils;
3031

3132
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
3233
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -70,6 +71,18 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
7071
builder.packagesToScan(elt.getPackagesToScan().toArray(new String[0]));
7172
if (!CollectionUtils.isEmpty(elt.getPathsToMatch()))
7273
builder.pathsToMatch(elt.getPathsToMatch().toArray(new String[0]));
74+
if (!CollectionUtils.isEmpty(elt.getProducesToMatch()))
75+
builder.producesToMatch(elt.getProducesToMatch().toArray(new String[0]));
76+
if (!CollectionUtils.isEmpty(elt.getConsumesToMatch()))
77+
builder.consumesToMatch(elt.getConsumesToMatch().toArray(new String[0]));
78+
if (!CollectionUtils.isEmpty(elt.getHeadersToMatch()))
79+
builder.headersToMatch(elt.getHeadersToMatch().toArray(new String[0]));
80+
if (!CollectionUtils.isEmpty(elt.getPathsToExclude()))
81+
builder.pathsToExclude(elt.getPathsToExclude().toArray(new String[0]));
82+
if (!CollectionUtils.isEmpty(elt.getPackagesToExclude()))
83+
builder.packagesToExclude(elt.getPackagesToExclude().toArray(new String[0]));
84+
if (StringUtils.isNotEmpty(elt.getDisplayName()))
85+
builder.displayName(elt.getDisplayName());
7386
return builder.group(elt.getGroup()).build();
7487
})
7588
.collect(Collectors.toList());
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2022 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package org.springdoc.core.customizers;
22+
23+
/**
24+
* Implement and register a bean of type {@link GlobalOpenApiCustomizer} to
25+
* customize Open api on default OpenAPI description and groups.
26+
*
27+
* @author christophejan
28+
* @see OpenApiCustomiser to customize default OpenAPI description but not
29+
* groups
30+
*/
31+
public interface GlobalOpenApiCustomizer extends OpenApiCustomiser {
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2022 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package org.springdoc.core.customizers;
22+
23+
/**
24+
* Implement and register a bean of type {@link GlobalOperationCustomizer} to
25+
* customize an operation based on the handler method input on default OpenAPI
26+
* description and groups
27+
*
28+
* @author christophejan
29+
* @see OperationCustomizer to customize operations on default OpenAPI
30+
* description but not groups
31+
*/
32+
public interface GlobalOperationCustomizer extends OperationCustomizer {
33+
}

springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomiser.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
*
33
* *
4-
* * * Copyright 2019-2020 the original author or authors.
4+
* * * Copyright 2019-2022 the original author or authors.
55
* * *
66
* * * Licensed under the Apache License, Version 2.0 (the "License");
77
* * * you may not use this file except in compliance with the License.
@@ -23,8 +23,12 @@
2323
import io.swagger.v3.oas.models.OpenAPI;
2424

2525
/**
26-
* The interface Open api customiser.
26+
* Implement and register a bean of type {@link OpenApiCustomiser} to customize
27+
* Open api on default OpenAPI description but not on groups
28+
*
2729
* @author bnasslahsen
30+
* @see GlobalOpenApiCustomizer to customize default OpenAPI description and
31+
* groups
2832
*/
2933
@FunctionalInterface
3034
public interface OpenApiCustomiser {

springdoc-openapi-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
*
33
* *
4-
* * * Copyright 2019-2020 the original author or authors.
4+
* * * Copyright 2019-2022 the original author or authors.
55
* * *
66
* * * Licensed under the Apache License, Version 2.0 (the "License");
77
* * * you may not use this file except in compliance with the License.
@@ -26,8 +26,12 @@
2626

2727
/**
2828
* Implement and register a bean of type {@link OperationCustomizer} to customize an operation
29-
* based on the handler method input
29+
* based on the handler method input on default OpenAPI descriptions but not
30+
* groups
31+
*
3032
* @author bnasslahsen
33+
* @see GlobalOperationCustomizer to customize operations on default OpenAPI
34+
* description and groups
3135
*/
3236
@FunctionalInterface
3337
public interface OperationCustomizer {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
*
3+
* *
4+
* * * Copyright 2019-2022 the original author or authors.
5+
* * *
6+
* * * Licensed under the Apache License, Version 2.0 (the "License");
7+
* * * you may not use this file except in compliance with the License.
8+
* * * You may obtain a copy of the License at
9+
* * *
10+
* * * https://www.apache.org/licenses/LICENSE-2.0
11+
* * *
12+
* * * Unless required by applicable law or agreed to in writing, software
13+
* * * distributed under the License is distributed on an "AS IS" BASIS,
14+
* * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* * * See the License for the specific language governing permissions and
16+
* * * limitations under the License.
17+
* *
18+
*
19+
*/
20+
21+
package org.springdoc.core.filters;
22+
23+
/**
24+
* Implement and register a bean of type {@link GlobalOpenApiMethodFilter} to
25+
* conditionally including any detected methods in default OpenAPI description
26+
* and groups.
27+
*
28+
* @author michael.clarke
29+
* @see OpenApiMethodFilter to filter methods in default OpenAPI description but
30+
* not groups
31+
*/
32+
@FunctionalInterface
33+
public interface GlobalOpenApiMethodFilter extends OpenApiMethodFilter {
34+
}

springdoc-openapi-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
*
33
* *
4-
* * * Copyright 2019-2020 the original author or authors.
4+
* * * Copyright 2019-2022 the original author or authors.
55
* * *
66
* * * Licensed under the Apache License, Version 2.0 (the "License");
77
* * * you may not use this file except in compliance with the License.
@@ -23,8 +23,13 @@
2323
import java.lang.reflect.Method;
2424

2525
/**
26-
* A filter to allow conditionally including any detected methods in an OpenApi definition.
26+
* Implement and register a bean of type {@link OpenApiMethodFilter} to
27+
* conditionally include any detected methods in default OpenAPI descriptions
28+
* but not groups
29+
*
2730
* @author michael.clarke
31+
* @see GlobalOpenApiMethodFilter to filter methods in default OpenAPI
32+
* description and groups
2833
*/
2934
@FunctionalInterface
3035
public interface OpenApiMethodFilter {

springdoc-openapi-webflux-core/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import org.springdoc.core.SpringDocConfigProperties;
3535
import org.springdoc.core.SpringDocConfigProperties.GroupConfig;
3636
import org.springdoc.core.SpringDocProviders;
37-
import org.springdoc.core.customizers.OpenApiCustomiser;
37+
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
38+
import org.springdoc.core.customizers.GlobalOperationCustomizer;
39+
import org.springdoc.core.filters.GlobalOpenApiMethodFilter;
3840

3941
import org.springframework.beans.BeansException;
4042
import org.springframework.beans.factory.InitializingBean;
@@ -123,14 +125,20 @@ protected MultipleOpenApiResource(List<GroupedOpenApi> groupedOpenApis,
123125

124126
@Override
125127
public void afterPropertiesSet() {
126-
if (springDocConfigProperties.getApiDocs().isResolveSchemaProperties()) {
127-
OpenApiCustomiser propertiesResolverForSchemaCustomizer = (OpenApiCustomiser) applicationContext.getBean("propertiesResolverForSchema");
128-
this.groupedOpenApis.forEach(groupedOpenApi -> groupedOpenApi.addOpenApiCustomizer(propertiesResolverForSchemaCustomizer));
129-
}
128+
Map<String, GlobalOpenApiCustomizer> globalOpenApiCustomizerMap = applicationContext.getBeansOfType(GlobalOpenApiCustomizer.class);
129+
Map<String, GlobalOperationCustomizer> globalOperationCustomizerMap = applicationContext.getBeansOfType(GlobalOperationCustomizer.class);
130+
Map<String, GlobalOpenApiMethodFilter> globalOpenApiMethodFilterMap = applicationContext.getBeansOfType(GlobalOpenApiMethodFilter.class);
131+
132+
this.groupedOpenApis.forEach(groupedOpenApi -> groupedOpenApi
133+
.addAllOpenApiCustomizer(globalOpenApiCustomizerMap.values())
134+
.addAllOperationCustomizer(globalOperationCustomizerMap.values())
135+
.addAllOpenApiMethodFilter(globalOpenApiMethodFilterMap.values())
136+
);
137+
130138
this.groupedOpenApiResources = groupedOpenApis.stream()
131139
.collect(Collectors.toMap(GroupedOpenApi::getGroup, item ->
132140
{
133-
GroupConfig groupConfig = new GroupConfig(item.getGroup(), item.getPathsToMatch(), item.getPackagesToScan(), item.getPackagesToExclude(), item.getPathsToExclude(), item.getProducesToMatch(), item.getConsumesToMatch(), item.getHeadersToMatch(),item.getDisplayName());
141+
GroupConfig groupConfig = new GroupConfig(item.getGroup(), item.getPathsToMatch(), item.getPackagesToScan(), item.getPackagesToExclude(), item.getPathsToExclude(), item.getProducesToMatch(), item.getConsumesToMatch(), item.getHeadersToMatch(), item.getDisplayName());
134142
springDocConfigProperties.addGroupConfig(groupConfig);
135143
return buildWebFluxOpenApiResource(item);
136144
}

springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app145/SpringDocApp145Test.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* * Copyright 2019-2020 the original author or authors.
3+
* * Copyright 2019-2022 the original author or authors.
44
* *
55
* * Licensed under the Apache License, Version 2.0 (the "License");
66
* * you may not use this file except in compliance with the License.
@@ -18,13 +18,18 @@
1818

1919
package test.org.springdoc.api.app145;
2020

21+
import static org.junit.jupiter.api.Assertions.assertTrue;
22+
import static org.junit.jupiter.api.Assertions.fail;
23+
2124
import org.junit.jupiter.api.Test;
2225
import org.springdoc.core.Constants;
2326
import test.org.springdoc.api.AbstractSpringDocActuatorTest;
2427

2528
import org.springframework.boot.autoconfigure.SpringBootApplication;
2629
import org.springframework.boot.test.context.SpringBootTest;
2730
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
31+
import org.springframework.http.HttpStatus;
32+
import org.springframework.web.reactive.function.client.WebClientResponseException;
2833

2934

3035
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT,
@@ -47,4 +52,19 @@ public void testApp() {
4752
.expectStatus().isNotFound();
4853
}
4954

55+
@Test
56+
public void testApp3() throws Exception {
57+
try {
58+
webClient.get().uri("/application/openapi"+ "/"+Constants.DEFAULT_GROUP_NAME).retrieve()
59+
.bodyToMono(String.class).block();
60+
fail();
61+
}
62+
catch (WebClientResponseException ex) {
63+
if (ex.getStatusCode() == HttpStatus.NOT_FOUND)
64+
assertTrue(true);
65+
else
66+
fail();
67+
}
68+
}
69+
5070
}

springdoc-openapi-webflux-core/src/test/java/test/org/springdoc/api/app147/SpringDocApp147Test.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,11 @@ public void testApp1() throws Exception {
6868
assertEquals(expected, result, true);
6969
}
7070

71+
@Test
72+
public void testApp2() throws Exception {
73+
webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/"+Constants.DEFAULT_GROUP_NAME)
74+
.exchange()
75+
.expectStatus().isNotFound();
76+
}
77+
7178
}

0 commit comments

Comments
 (0)