Skip to content

Commit 577938e

Browse files
committed
Springdoc OpenApi Annotations @ExtensionProperty Not Evaluating Properties from application.yml. Fixes #2461
1 parent b88a3e4 commit 577938e

File tree

16 files changed

+556
-102
lines changed

16 files changed

+556
-102
lines changed

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@
2424

2525
package org.springdoc.core.customizers;
2626

27-
import io.swagger.v3.oas.models.*;
27+
import java.text.MessageFormat;
28+
import java.util.List;
29+
import java.util.Map;
30+
import java.util.function.Consumer;
31+
32+
import io.swagger.v3.oas.models.Components;
33+
import io.swagger.v3.oas.models.OpenAPI;
34+
import io.swagger.v3.oas.models.Operation;
35+
import io.swagger.v3.oas.models.PathItem;
36+
import io.swagger.v3.oas.models.Paths;
2837
import io.swagger.v3.oas.models.info.Info;
2938
import io.swagger.v3.oas.models.media.Schema;
3039
import org.apache.commons.lang3.StringUtils;
40+
3141
import org.springframework.core.env.PropertyResolver;
3242
import org.springframework.util.CollectionUtils;
3343

34-
import java.text.MessageFormat;
35-
import java.util.List;
36-
import java.util.Map;
37-
import java.util.function.Consumer;
38-
3944
import static org.springdoc.core.utils.Constants.SPRINGDOC_SPEC_PROPERTIES_PREFIX;
4045

4146
/**

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SpringDocConfigProperties.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,11 @@ public static class ApiDocs {
12341234
*/
12351235
private boolean resolveSchemaProperties;
12361236

1237+
/**
1238+
* The Resolve extensions properties.
1239+
*/
1240+
private boolean resolveExtensionsProperties;
1241+
12371242
/**
12381243
* The Groups.
12391244
*/
@@ -1370,6 +1375,24 @@ public String getVersion() {
13701375
return version;
13711376
}
13721377
}
1378+
1379+
/**
1380+
* Is resolve extensions properties boolean.
1381+
*
1382+
* @return the boolean
1383+
*/
1384+
public boolean isResolveExtensionsProperties() {
1385+
return resolveExtensionsProperties;
1386+
}
1387+
1388+
/**
1389+
* Sets resolve extensions properties.
1390+
*
1391+
* @param resolveExtensionsProperties the resolve extensions properties
1392+
*/
1393+
public void setResolveExtensionsProperties(boolean resolveExtensionsProperties) {
1394+
this.resolveExtensionsProperties = resolveExtensionsProperties;
1395+
}
13731396
}
13741397

13751398
/**
@@ -1722,4 +1745,6 @@ public boolean isOpenapi31() {
17221745
return true;
17231746
return false;
17241747
}
1748+
1749+
17251750
}

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ public Parameter buildParameterFromDoc(io.swagger.v3.oas.annotations.Parameter p
300300
setSchema(parameterDoc, components, jsonView, parameter);
301301

302302
setExamples(parameterDoc, parameter);
303-
setExtensions(parameterDoc, parameter);
303+
setExtensions(parameterDoc, parameter, locale);
304304
setParameterStyle(parameter, parameterDoc);
305305
setParameterExplode(parameter, parameterDoc);
306306

@@ -460,12 +460,19 @@ private void setExamples(io.swagger.v3.oas.annotations.Parameter parameterDoc, P
460460
* Sets extensions.
461461
*
462462
* @param parameterDoc the parameter doc
463-
* @param parameter the parameter
463+
* @param parameter the parameter
464+
* @param locale the locale
464465
*/
465-
private void setExtensions(io.swagger.v3.oas.annotations.Parameter parameterDoc, Parameter parameter) {
466+
private void setExtensions(io.swagger.v3.oas.annotations.Parameter parameterDoc, Parameter parameter, Locale locale) {
466467
if (parameterDoc.extensions().length > 0) {
467468
Map<String, Object> extensionMap = AnnotationsUtils.getExtensions(propertyResolverUtils.isOpenapi31(), parameterDoc.extensions());
468-
extensionMap.forEach(parameter::addExtension);
469+
if (propertyResolverUtils.isResolveExtensionsProperties()) {
470+
Map<String, Object> extensionsResolved = propertyResolverUtils.resolveExtensions(locale, extensionMap);
471+
extensionsResolved.forEach(parameter::addExtension);
472+
}
473+
else {
474+
extensionMap.forEach(parameter::addExtension);
475+
}
469476
}
470477
}
471478

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
import org.springdoc.core.parsers.ReturnTypeParser;
6666
import org.springdoc.core.properties.SpringDocConfigProperties;
6767
import org.springdoc.core.providers.JavadocProvider;
68-
import org.springdoc.core.providers.ObjectMapperProvider;
6968
import org.springdoc.core.utils.PropertyResolverUtils;
7069
import org.springdoc.core.utils.SpringDocAnnotationsUtils;
7170

@@ -254,7 +253,7 @@ public ApiResponses build(Components components, HandlerMethod handlerMethod, Op
254253
apiResponsesFromDoc.forEach(apiResponses::addApiResponse);
255254
// for each one build ApiResponse and add it to existing responses
256255
// Fill api Responses
257-
computeResponseFromDoc(components, handlerMethod.getReturnType(), apiResponses, methodAttributes, springDocConfigProperties.isOpenapi31());
256+
computeResponseFromDoc(components, handlerMethod.getReturnType(), apiResponses, methodAttributes, springDocConfigProperties.isOpenapi31(),methodAttributes.getLocale() );
258257
buildApiResponses(components, handlerMethod.getReturnType(), apiResponses, methodAttributes);
259258
return apiResponses;
260259
}
@@ -329,7 +328,7 @@ public void buildGenericResponse(Components components, Map<String, Object> find
329328
JavadocProvider javadocProvider = operationService.getJavadocProvider();
330329
methodAttributes.setJavadocReturn(javadocProvider.getMethodJavadocReturn(methodParameter.getMethod()));
331330
}
332-
Map<String, ApiResponse> apiResponses = computeResponseFromDoc(components, methodParameter, apiResponsesOp, methodAttributes, springDocConfigProperties.isOpenapi31());
331+
Map<String, ApiResponse> apiResponses = computeResponseFromDoc(components, methodParameter, apiResponsesOp, methodAttributes, springDocConfigProperties.isOpenapi31(), locale);
333332
buildGenericApiResponses(components, methodParameter, apiResponsesOp, methodAttributes);
334333
apiResponses.forEach(controllerAdviceInfoApiResponseMap::put);
335334
}
@@ -363,10 +362,11 @@ private boolean isResponseEntityExceptionHandlerMethod(Method m) {
363362
* @param apiResponsesOp the api responses op
364363
* @param methodAttributes the method attributes
365364
* @param openapi31 the openapi 31
365+
* @param locale the locale
366366
* @return the map
367367
*/
368368
private Map<String, ApiResponse> computeResponseFromDoc(Components components, MethodParameter methodParameter, ApiResponses apiResponsesOp,
369-
MethodAttributes methodAttributes, boolean openapi31) {
369+
MethodAttributes methodAttributes, boolean openapi31, Locale locale) {
370370
// Parsing documentation, if present
371371
Set<io.swagger.v3.oas.annotations.responses.ApiResponse> responsesArray = getApiResponses(Objects.requireNonNull(methodParameter.getMethod()));
372372
if (!responsesArray.isEmpty()) {
@@ -382,8 +382,15 @@ private Map<String, ApiResponse> computeResponseFromDoc(Components components, M
382382
apiResponse.setDescription(propertyResolverUtils.resolve(apiResponseAnnotations.description(), methodAttributes.getLocale()));
383383
buildContentFromDoc(components, apiResponsesOp, methodAttributes, apiResponseAnnotations, apiResponse, openapi31);
384384
Map<String, Object> extensions = AnnotationsUtils.getExtensions(propertyResolverUtils.isOpenapi31(), apiResponseAnnotations.extensions());
385-
if (!CollectionUtils.isEmpty(extensions))
386-
apiResponse.extensions(extensions);
385+
if (!CollectionUtils.isEmpty(extensions)){
386+
if (propertyResolverUtils.isResolveExtensionsProperties()) {
387+
Map<String, Object> extensionsResolved = propertyResolverUtils.resolveExtensions(locale, extensions);
388+
extensionsResolved.forEach(apiResponse::addExtension);
389+
}
390+
else {
391+
apiResponse.extensions(extensions);
392+
}
393+
}
387394
AnnotationsUtils.getHeaders(apiResponseAnnotations.headers(), methodAttributes.getJsonViewAnnotation(), openapi31)
388395
.ifPresent(apiResponse::headers);
389396
apiResponsesOp.addApiResponse(httpCode, apiResponse);

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import java.util.stream.Collectors;
4343
import java.util.stream.Stream;
4444

45-
import com.fasterxml.jackson.annotation.JsonInclude.Include;
4645
import com.fasterxml.jackson.core.JsonProcessingException;
4746
import com.fasterxml.jackson.databind.ObjectMapper;
4847
import io.swagger.v3.core.jackson.TypeNameResolver;
@@ -71,7 +70,6 @@
7170
import org.springdoc.core.customizers.ServerBaseUrlCustomizer;
7271
import org.springdoc.core.properties.SpringDocConfigProperties;
7372
import org.springdoc.core.providers.JavadocProvider;
74-
import org.springdoc.core.providers.ObjectMapperProvider;
7573
import org.springdoc.core.utils.PropertyResolverUtils;
7674

7775
import org.springframework.beans.BeansException;
@@ -97,6 +95,7 @@
9795

9896
/**
9997
* The type Open api builder.
98+
*
10099
* @author bnasslahsen
101100
*/
102101
public class OpenAPIService implements ApplicationContextAware {
@@ -179,13 +178,13 @@ public class OpenAPIService implements ApplicationContextAware {
179178
/**
180179
* Instantiates a new Open api builder.
181180
*
182-
* @param openAPI the open api
183-
* @param securityParser the security parser
181+
* @param openAPI the open api
182+
* @param securityParser the security parser
184183
* @param springDocConfigProperties the spring doc config properties
185-
* @param propertyResolverUtils the property resolver utils
184+
* @param propertyResolverUtils the property resolver utils
186185
* @param openApiBuilderCustomizers the open api builder customisers
187-
* @param serverBaseUrlCustomizers the server base url customizers
188-
* @param javadocProvider the javadoc provider
186+
* @param serverBaseUrlCustomizers the server base url customizers
187+
* @param javadocProvider the javadoc provider
189188
*/
190189
public OpenAPIService(Optional<OpenAPI> openAPI, SecurityService securityParser,
191190
SpringDocConfigProperties springDocConfigProperties, PropertyResolverUtils propertyResolverUtils,
@@ -230,6 +229,7 @@ public static String splitCamelCase(String str) {
230229

231230
/**
232231
* Build.
232+
*
233233
* @param locale the locale
234234
* @return the open api
235235
*/
@@ -317,9 +317,9 @@ public void setServersPresent(boolean serversPresent) {
317317
* Build tags operation.
318318
*
319319
* @param handlerMethod the handler method
320-
* @param operation the operation
321-
* @param openAPI the open api
322-
* @param locale the locale
320+
* @param operation the operation
321+
* @param openAPI the open api
322+
* @param locale the locale
323323
* @return the operation
324324
*/
325325
public Operation buildTags(HandlerMethod handlerMethod, Operation operation, OpenAPI openAPI, Locale locale) {
@@ -394,10 +394,10 @@ public Operation buildTags(HandlerMethod handlerMethod, Operation operation, Ope
394394
/**
395395
* Build tags from method.
396396
*
397-
* @param method the method
398-
* @param tags the tags
397+
* @param method the method
398+
* @param tags the tags
399399
* @param tagsStr the tags str
400-
* @param locale the locale
400+
* @param locale the locale
401401
*/
402402
private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
403403
// method tags
@@ -417,8 +417,8 @@ private void buildTagsFromMethod(Method method, Set<io.swagger.v3.oas.models.tag
417417
* Add tags.
418418
*
419419
* @param sourceTags the source tags
420-
* @param tags the tags
421-
* @param locale the locale
420+
* @param tags the tags
421+
* @param locale the locale
422422
*/
423423
private void addTags(List<Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag> tags, Locale locale) {
424424
Optional<Set<io.swagger.v3.oas.models.tags.Tag>> optionalTagSet = AnnotationsUtils
@@ -437,9 +437,9 @@ private void addTags(List<Tag> sourceTags, Set<io.swagger.v3.oas.models.tags.Tag
437437
* Build tags from class.
438438
*
439439
* @param beanType the bean type
440-
* @param tags the tags
441-
* @param tagsStr the tags str
442-
* @param locale the locale
440+
* @param tags the tags
441+
* @param tagsStr the tags str
442+
* @param locale the locale
443443
*/
444444
public void buildTagsFromClass(Class<?> beanType, Set<io.swagger.v3.oas.models.tags.Tag> tags, Set<String> tagsStr, Locale locale) {
445445
List<Tag> allTags = new ArrayList<>();
@@ -473,7 +473,7 @@ public Schema resolveProperties(Schema schema, Locale locale) {
473473
if (!CollectionUtils.isEmpty(properties)) {
474474
LinkedHashMap<String, Schema> resolvedSchemas = properties.entrySet().stream().map(es -> {
475475
es.setValue(resolveProperties(es.getValue(), locale));
476-
if(es.getValue() instanceof ArraySchema arraySchema){
476+
if (es.getValue() instanceof ArraySchema arraySchema) {
477477
resolveProperties(arraySchema.getItems(), locale);
478478
}
479479
return es;
@@ -539,8 +539,8 @@ private Optional<OpenAPIDefinition> getOpenAPIDefinition() {
539539
* Build open api with open api definition.
540540
*
541541
* @param openAPI the open api
542-
* @param apiDef the api def
543-
* @param locale the locale
542+
* @param apiDef the api def
543+
* @param locale the locale
544544
*/
545545
private void buildOpenAPIWithOpenAPIDefinition(OpenAPI openAPI, OpenAPIDefinition apiDef, Locale locale) {
546546
// info
@@ -568,7 +568,7 @@ private void buildOpenAPIWithOpenAPIDefinition(OpenAPI openAPI, OpenAPIDefinitio
568568
* Resolve properties info.
569569
*
570570
* @param servers the servers
571-
* @param locale the locale
571+
* @param locale the locale
572572
* @return the servers
573573
*/
574574
private List<Server> resolveProperties(List<Server> servers, Locale locale) {
@@ -584,7 +584,7 @@ private List<Server> resolveProperties(List<Server> servers, Locale locale) {
584584
/**
585585
* Resolve properties info.
586586
*
587-
* @param info the info
587+
* @param info the info
588588
* @param locale the locale
589589
* @return the info
590590
*/
@@ -606,16 +606,24 @@ private Info resolveProperties(Info info, Locale locale) {
606606
resolveProperty(contact::getEmail, contact::email, propertyResolverUtils, locale);
607607
resolveProperty(contact::getUrl, contact::url, propertyResolverUtils, locale);
608608
}
609+
610+
if(propertyResolverUtils.isResolveExtensionsProperties()){
611+
Map<String, Object> extensionsResolved = propertyResolverUtils.resolveExtensions(locale, info.getExtensions());
612+
info.setExtensions(extensionsResolved);
613+
}
614+
609615
return info;
610616
}
611617

618+
619+
612620
/**
613621
* Resolve property.
614622
*
615-
* @param getProperty the get property
616-
* @param setProperty the set property
623+
* @param getProperty the get property
624+
* @param setProperty the set property
617625
* @param propertyResolverUtils the property resolver utils
618-
* @param locale the locale
626+
* @param locale the locale
619627
*/
620628
private void resolveProperty(Supplier<String> getProperty, Consumer<String> setProperty,
621629
PropertyResolverUtils propertyResolverUtils, Locale locale) {
@@ -629,7 +637,7 @@ private void resolveProperty(Supplier<String> getProperty, Consumer<String> setP
629637
* Calculate security schemes.
630638
*
631639
* @param components the components
632-
* @param locale the locale
640+
* @param locale the locale
633641
*/
634642
private void calculateSecuritySchemes(Components components, Locale locale) {
635643
// Look for SecurityScheme in a spring managed bean
@@ -664,8 +672,8 @@ private void calculateSecuritySchemes(Components components, Locale locale) {
664672
* Add security scheme.
665673
*
666674
* @param apiSecurityScheme the api security scheme
667-
* @param components the components
668-
* @param locale the locale
675+
* @param components the components
676+
* @param locale the locale
669677
*/
670678
private void addSecurityScheme(Set<io.swagger.v3.oas.annotations.security.SecurityScheme> apiSecurityScheme,
671679
Components components, Locale locale) {
@@ -689,7 +697,7 @@ private void addSecurityScheme(Set<io.swagger.v3.oas.annotations.security.Securi
689697
/**
690698
* Gets api def class.
691699
*
692-
* @param scanner the scanner
700+
* @param scanner the scanner
693701
* @param packagesToScan the packages to scan
694702
* @return the api def class
695703
*/
@@ -723,7 +731,7 @@ public boolean isAutoTagClasses(Operation operation) {
723731
/**
724732
* Gets security schemes classes.
725733
*
726-
* @param scanner the scanner
734+
* @param scanner the scanner
727735
* @param packagesToScan the packages to scan
728736
* @return the security schemes classes
729737
*/
@@ -752,7 +760,7 @@ private Set<io.swagger.v3.oas.annotations.security.SecurityScheme> getSecuritySc
752760
* Add tag.
753761
*
754762
* @param handlerMethods the handler methods
755-
* @param tag the tag
763+
* @param tag the tag
756764
*/
757765
public void addTag(Set<HandlerMethod> handlerMethods, io.swagger.v3.oas.models.tags.Tag tag) {
758766
handlerMethods.forEach(handlerMethod -> springdocTags.put(handlerMethod, tag));
@@ -802,7 +810,7 @@ public OpenAPI getCachedOpenAPI(Locale locale) {
802810
* Sets cached open api.
803811
*
804812
* @param cachedOpenAPI the cached open api
805-
* @param locale associated the the cache entry
813+
* @param locale associated the the cache entry
806814
*/
807815
public void setCachedOpenAPI(OpenAPI cachedOpenAPI, Locale locale) {
808816
this.cachedOpenAPI.put(locale.toLanguageTag(), cachedOpenAPI);

0 commit comments

Comments
 (0)