|
47 | 47 | import java.util.Set;
|
48 | 48 | import java.util.TreeSet;
|
49 | 49 | import java.util.concurrent.Executors;
|
| 50 | +import java.util.concurrent.locks.Lock; |
| 51 | +import java.util.concurrent.locks.ReentrantLock; |
50 | 52 | import java.util.stream.Collectors;
|
51 | 53 |
|
52 | 54 | import com.fasterxml.jackson.annotation.JsonView;
|
@@ -200,6 +202,10 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
|
200 | 202 | */
|
201 | 203 | protected final SpringDocCustomizers springDocCustomizers;
|
202 | 204 |
|
| 205 | + /** |
| 206 | + * The Reentrant lock. |
| 207 | + */ |
| 208 | + private final Lock reentrantLock = new ReentrantLock(); |
203 | 209 |
|
204 | 210 | /**
|
205 | 211 | * Instantiates a new Abstract open api resource.
|
@@ -319,73 +325,78 @@ private void getOpenApi() {
|
319 | 325 | * @param locale the locale
|
320 | 326 | * @return the open api
|
321 | 327 | */
|
322 |
| - protected synchronized OpenAPI getOpenApi(Locale locale) { |
323 |
| - final OpenAPI openAPI; |
324 |
| - final Locale finalLocale = locale == null ? Locale.getDefault() : locale; |
325 |
| - if (openAPIService.getCachedOpenAPI(finalLocale) == null || springDocConfigProperties.isCacheDisabled()) { |
326 |
| - Instant start = Instant.now(); |
327 |
| - openAPI = openAPIService.build(finalLocale); |
328 |
| - Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream() |
329 |
| - .filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(), |
330 |
| - Hidden.class) == null)) |
331 |
| - .filter(controller -> !isHiddenRestControllers(controller.getValue().getClass())) |
332 |
| - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1)); |
333 |
| - |
334 |
| - Map<String, Object> findControllerAdvice = openAPIService.getControllerAdviceMap(); |
335 |
| - if (OpenApiVersion.OPENAPI_3_1 == springDocConfigProperties.getApiDocs().getVersion()) |
336 |
| - openAPI.openapi(OpenApiVersion.OPENAPI_3_1.getVersion()); |
337 |
| - if (springDocConfigProperties.isDefaultOverrideWithGenericResponse()) { |
338 |
| - if (!CollectionUtils.isEmpty(mappingsMap)) |
339 |
| - findControllerAdvice.putAll(mappingsMap); |
340 |
| - responseBuilder.buildGenericResponse(openAPI.getComponents(), findControllerAdvice, finalLocale); |
341 |
| - } |
342 |
| - getPaths(mappingsMap, finalLocale, openAPI); |
343 |
| - |
344 |
| - Optional<CloudFunctionProvider> cloudFunctionProviderOptional = springDocProviders.getSpringCloudFunctionProvider(); |
345 |
| - cloudFunctionProviderOptional.ifPresent(cloudFunctionProvider -> { |
346 |
| - List<RouterOperation> routerOperationList = cloudFunctionProvider.getRouterOperations(openAPI); |
347 |
| - if (!CollectionUtils.isEmpty(routerOperationList)) |
348 |
| - this.calculatePath(routerOperationList, locale, openAPI); |
349 |
| - } |
350 |
| - ); |
351 |
| - if (!CollectionUtils.isEmpty(openAPI.getServers())) |
352 |
| - openAPIService.setServersPresent(true); |
353 |
| - else |
354 |
| - openAPIService.setServersPresent(false); |
355 |
| - openAPIService.updateServers(openAPI); |
356 |
| - |
357 |
| - if (springDocConfigProperties.isRemoveBrokenReferenceDefinitions()) |
358 |
| - this.removeBrokenReferenceDefinitions(openAPI); |
| 328 | + protected OpenAPI getOpenApi(Locale locale) { |
| 329 | + this.reentrantLock.lock(); |
| 330 | + try { |
| 331 | + final OpenAPI openAPI; |
| 332 | + final Locale finalLocale = locale == null ? Locale.getDefault() : locale; |
| 333 | + if (openAPIService.getCachedOpenAPI(finalLocale) == null || springDocConfigProperties.isCacheDisabled()) { |
| 334 | + Instant start = Instant.now(); |
| 335 | + openAPI = openAPIService.build(finalLocale); |
| 336 | + Map<String, Object> mappingsMap = openAPIService.getMappingsMap().entrySet().stream() |
| 337 | + .filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(), |
| 338 | + Hidden.class) == null)) |
| 339 | + .filter(controller -> !isHiddenRestControllers(controller.getValue().getClass())) |
| 340 | + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1)); |
| 341 | + |
| 342 | + Map<String, Object> findControllerAdvice = openAPIService.getControllerAdviceMap(); |
| 343 | + if (OpenApiVersion.OPENAPI_3_1 == springDocConfigProperties.getApiDocs().getVersion()) |
| 344 | + openAPI.openapi(OpenApiVersion.OPENAPI_3_1.getVersion()); |
| 345 | + if (springDocConfigProperties.isDefaultOverrideWithGenericResponse()) { |
| 346 | + if (!CollectionUtils.isEmpty(mappingsMap)) |
| 347 | + findControllerAdvice.putAll(mappingsMap); |
| 348 | + responseBuilder.buildGenericResponse(openAPI.getComponents(), findControllerAdvice, finalLocale); |
| 349 | + } |
| 350 | + getPaths(mappingsMap, finalLocale, openAPI); |
359 | 351 |
|
360 |
| - // run the optional customisers |
361 |
| - List<Server> servers = openAPI.getServers(); |
362 |
| - List<Server> serversCopy = null; |
363 |
| - try { |
364 |
| - serversCopy = springDocProviders.jsonMapper() |
365 |
| - .readValue(springDocProviders.jsonMapper().writeValueAsString(servers), new TypeReference<List<Server>>() {}); |
366 |
| - } |
367 |
| - catch (JsonProcessingException e) { |
368 |
| - LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); |
369 |
| - } |
| 352 | + Optional<CloudFunctionProvider> cloudFunctionProviderOptional = springDocProviders.getSpringCloudFunctionProvider(); |
| 353 | + cloudFunctionProviderOptional.ifPresent(cloudFunctionProvider -> { |
| 354 | + List<RouterOperation> routerOperationList = cloudFunctionProvider.getRouterOperations(openAPI); |
| 355 | + if (!CollectionUtils.isEmpty(routerOperationList)) |
| 356 | + this.calculatePath(routerOperationList, locale, openAPI); |
| 357 | + } |
| 358 | + ); |
| 359 | + if (!CollectionUtils.isEmpty(openAPI.getServers())) |
| 360 | + openAPIService.setServersPresent(true); |
| 361 | + else |
| 362 | + openAPIService.setServersPresent(false); |
| 363 | + openAPIService.updateServers(openAPI); |
| 364 | + |
| 365 | + if (springDocConfigProperties.isRemoveBrokenReferenceDefinitions()) |
| 366 | + this.removeBrokenReferenceDefinitions(openAPI); |
| 367 | + |
| 368 | + // run the optional customisers |
| 369 | + List<Server> servers = openAPI.getServers(); |
| 370 | + List<Server> serversCopy = null; |
| 371 | + try { |
| 372 | + serversCopy = springDocProviders.jsonMapper() |
| 373 | + .readValue(springDocProviders.jsonMapper().writeValueAsString(servers), new TypeReference<List<Server>>() {}); |
| 374 | + } |
| 375 | + catch (JsonProcessingException e) { |
| 376 | + LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); |
| 377 | + } |
370 | 378 |
|
371 |
| - openAPIService.getContext().getBeansOfType(OpenApiLocaleCustomizer.class).values().forEach(openApiLocaleCustomizer -> openApiLocaleCustomizer.customise(openAPI, finalLocale)); |
372 |
| - springDocCustomizers.getOpenApiCustomizers().ifPresent(apiCustomizers -> apiCustomizers.forEach(openApiCustomizer -> openApiCustomizer.customise(openAPI))); |
373 |
| - if (!CollectionUtils.isEmpty(openAPI.getServers()) && !openAPI.getServers().equals(serversCopy)) |
374 |
| - openAPIService.setServersPresent(true); |
| 379 | + openAPIService.getContext().getBeansOfType(OpenApiLocaleCustomizer.class).values().forEach(openApiLocaleCustomizer -> openApiLocaleCustomizer.customise(openAPI, finalLocale)); |
| 380 | + springDocCustomizers.getOpenApiCustomizers().ifPresent(apiCustomizers -> apiCustomizers.forEach(openApiCustomizer -> openApiCustomizer.customise(openAPI))); |
| 381 | + if (!CollectionUtils.isEmpty(openAPI.getServers()) && !openAPI.getServers().equals(serversCopy)) |
| 382 | + openAPIService.setServersPresent(true); |
375 | 383 |
|
376 | 384 |
|
377 |
| - openAPIService.setCachedOpenAPI(openAPI, finalLocale); |
| 385 | + openAPIService.setCachedOpenAPI(openAPI, finalLocale); |
378 | 386 |
|
379 |
| - LOGGER.info("Init duration for springdoc-openapi is: {} ms", |
380 |
| - Duration.between(start, Instant.now()).toMillis()); |
381 |
| - } |
382 |
| - else { |
383 |
| - LOGGER.debug("Fetching openApi document from cache"); |
384 |
| - openAPI = openAPIService.getCachedOpenAPI(finalLocale); |
| 387 | + LOGGER.info("Init duration for springdoc-openapi is: {} ms", |
| 388 | + Duration.between(start, Instant.now()).toMillis()); |
| 389 | + } |
| 390 | + else { |
| 391 | + LOGGER.debug("Fetching openApi document from cache"); |
| 392 | + openAPI = openAPIService.getCachedOpenAPI(finalLocale); |
| 393 | + openAPIService.updateServers(openAPI); |
| 394 | + } |
385 | 395 | openAPIService.updateServers(openAPI);
|
| 396 | + return openAPI; } |
| 397 | + finally { |
| 398 | + this.reentrantLock.unlock(); |
386 | 399 | }
|
387 |
| - openAPIService.updateServers(openAPI); |
388 |
| - return openAPI; |
389 | 400 | }
|
390 | 401 |
|
391 | 402 | /**
|
|
0 commit comments