60
60
import io .swagger .v3 .core .filter .SpecFilter ;
61
61
import io .swagger .v3 .core .util .ReflectionUtils ;
62
62
import io .swagger .v3 .oas .annotations .Hidden ;
63
+ import io .swagger .v3 .oas .annotations .Webhook ;
64
+ import io .swagger .v3 .oas .annotations .Webhooks ;
63
65
import io .swagger .v3 .oas .annotations .callbacks .Callback ;
64
66
import io .swagger .v3 .oas .annotations .enums .ParameterIn ;
65
67
import io .swagger .v3 .oas .models .Components ;
@@ -213,14 +215,14 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
213
215
/**
214
216
* Instantiates a new Abstract open api resource.
215
217
*
216
- * @param groupName the group name
218
+ * @param groupName the group name
217
219
* @param openAPIBuilderObjectFactory the open api builder object factory
218
- * @param requestBuilder the request builder
219
- * @param responseBuilder the response builder
220
- * @param operationParser the operation parser
221
- * @param springDocConfigProperties the spring doc config properties
222
- * @param springDocProviders the spring doc providers
223
- * @param springDocCustomizers the spring doc customizers
220
+ * @param requestBuilder the request builder
221
+ * @param responseBuilder the response builder
222
+ * @param operationParser the operation parser
223
+ * @param springDocConfigProperties the spring doc config properties
224
+ * @param springDocProviders the spring doc providers
225
+ * @param springDocCustomizers the spring doc customizers
224
226
*/
225
227
protected AbstractOpenApiResource (String groupName , ObjectFactory <OpenAPIService > openAPIBuilderObjectFactory ,
226
228
AbstractRequestService requestBuilder ,
@@ -239,7 +241,8 @@ protected AbstractOpenApiResource(String groupName, ObjectFactory<OpenAPIService
239
241
if (springDocConfigProperties .isPreLoadingEnabled ()) {
240
242
if (CollectionUtils .isEmpty (springDocConfigProperties .getPreLoadingLocales ())) {
241
243
Executors .newSingleThreadExecutor ().execute (this ::getOpenApi );
242
- } else {
244
+ }
245
+ else {
243
246
for (String locale : springDocConfigProperties .getPreLoadingLocales ()) {
244
247
Executors .newSingleThreadExecutor ().execute (() -> this .getOpenApi (Locale .forLanguageTag (locale )));
245
248
}
@@ -343,9 +346,10 @@ protected OpenAPI getOpenApi(Locale locale) {
343
346
.collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue , (a1 , a2 ) -> a1 ));
344
347
345
348
Map <String , Object > findControllerAdvice = openAPIService .getControllerAdviceMap ();
346
- if (OpenApiVersion .OPENAPI_3_1 == springDocConfigProperties .getApiDocs ().getVersion ()){
349
+ if (OpenApiVersion .OPENAPI_3_1 == springDocConfigProperties .getApiDocs ().getVersion ()) {
347
350
openAPI .openapi (OpenApiVersion .OPENAPI_3_1 .getVersion ());
348
351
openAPI .specVersion (SpecVersion .V31 );
352
+ calculateWebhooks (openAPI , locale );
349
353
}
350
354
if (springDocConfigProperties .isDefaultOverrideWithGenericResponse ()) {
351
355
if (!CollectionUtils .isEmpty (mappingsMap ))
@@ -373,7 +377,7 @@ protected OpenAPI getOpenApi(Locale locale) {
373
377
if (springDocConfigProperties .isRemoveBrokenReferenceDefinitions ())
374
378
this .removeBrokenReferenceDefinitions (openAPI );
375
379
376
- // run the optional customisers
380
+ // run the optional customizers
377
381
List <Server > servers = openAPI .getServers ();
378
382
List <Server > serversCopy = null ;
379
383
try {
@@ -401,13 +405,15 @@ protected OpenAPI getOpenApi(Locale locale) {
401
405
}
402
406
openAPIService .updateServers (openAPI );
403
407
return openAPI ;
404
- } finally {
408
+ }
409
+ finally {
405
410
this .reentrantLock .unlock ();
406
411
}
407
412
}
408
413
409
414
/**
410
415
* Indents are removed for properties that are mainly used as “explanations” using Open API.
416
+ *
411
417
* @param openAPI the open api
412
418
*/
413
419
private void trimIndent (OpenAPI openAPI ) {
@@ -417,6 +423,7 @@ private void trimIndent(OpenAPI openAPI) {
417
423
418
424
/**
419
425
* Trim the indent for descriptions in the 'components' of open api.
426
+ *
420
427
* @param openAPI the open api
421
428
*/
422
429
private void trimComponents (OpenAPI openAPI ) {
@@ -439,6 +446,7 @@ private void trimComponents(OpenAPI openAPI) {
439
446
440
447
/**
441
448
* Trim the indent for descriptions in the 'paths' of open api.
449
+ *
442
450
* @param openAPI the open api
443
451
*/
444
452
private void trimPaths (OpenAPI openAPI ) {
@@ -461,6 +469,7 @@ private void trimPaths(OpenAPI openAPI) {
461
469
462
470
/**
463
471
* Trim the indent for 'operation'
472
+ *
464
473
* @param operation the operation
465
474
*/
466
475
private void trimIndentOperation (Operation operation ) {
@@ -476,18 +485,39 @@ private void trimIndentOperation(Operation operation) {
476
485
* Gets paths.
477
486
*
478
487
* @param findRestControllers the find rest controllers
479
- * @param locale the locale
480
- * @param openAPI the open api
488
+ * @param locale the locale
489
+ * @param openAPI the open api
481
490
*/
482
491
protected abstract void getPaths (Map <String , Object > findRestControllers , Locale locale , OpenAPI openAPI );
483
492
493
+
494
+ /**
495
+ * Calculate webhooks.
496
+ *
497
+ * @param calculatedOpenAPI the calculated open api
498
+ * @param locale the locale
499
+ */
500
+ protected void calculateWebhooks (OpenAPI calculatedOpenAPI , Locale locale ) {
501
+ Webhooks [] webhooksAttr = openAPIService .getWebhooks ();
502
+ var webhooks = Arrays .stream (webhooksAttr ).map (Webhooks ::value ).flatMap (Arrays ::stream ).toArray (Webhook []::new );
503
+ Arrays .stream (webhooks ).forEach (webhook -> {
504
+ io .swagger .v3 .oas .annotations .Operation apiOperation = webhook .operation ();
505
+ Operation operation = new Operation ();
506
+ MethodAttributes methodAttributes = new MethodAttributes (springDocConfigProperties .getDefaultConsumesMediaType (),
507
+ springDocConfigProperties .getDefaultProducesMediaType (), locale );
508
+ operationParser .parse (apiOperation , operation , calculatedOpenAPI , methodAttributes );
509
+ PathItem pathItem = new PathItem ().post (operation );
510
+ calculatedOpenAPI .addWebhooks (webhook .name (), pathItem );
511
+ });
512
+ }
513
+
484
514
/**
485
515
* Calculate path.
486
516
*
487
- * @param handlerMethod the handler method
517
+ * @param handlerMethod the handler method
488
518
* @param routerOperation the router operation
489
- * @param locale the locale
490
- * @param openAPI the open api
519
+ * @param locale the locale
520
+ * @param openAPI the open api
491
521
*/
492
522
protected void calculatePath (HandlerMethod handlerMethod , RouterOperation routerOperation , Locale locale , OpenAPI openAPI ) {
493
523
routerOperation = customizeRouterOperation (routerOperation , handlerMethod );
@@ -602,10 +632,10 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router
602
632
/**
603
633
* Build callbacks.
604
634
*
605
- * @param openAPI the open api
635
+ * @param openAPI the open api
606
636
* @param methodAttributes the method attributes
607
- * @param operation the operation
608
- * @param apiCallbacks the api callbacks
637
+ * @param operation the operation
638
+ * @param apiCallbacks the api callbacks
609
639
*/
610
640
private void buildCallbacks (OpenAPI openAPI , MethodAttributes methodAttributes , Operation operation , Set <Callback > apiCallbacks ) {
611
641
if (!CollectionUtils .isEmpty (apiCallbacks ))
@@ -617,8 +647,8 @@ private void buildCallbacks(OpenAPI openAPI, MethodAttributes methodAttributes,
617
647
* Calculate path.
618
648
*
619
649
* @param routerOperationList the router operation list
620
- * @param locale the locale
621
- * @param openAPI the open api
650
+ * @param locale the locale
651
+ * @param openAPI the open api
622
652
*/
623
653
protected void calculatePath (List <RouterOperation > routerOperationList , Locale locale , OpenAPI openAPI ) {
624
654
ApplicationContext applicationContext = openAPIService .getContext ();
@@ -667,7 +697,7 @@ else if (routerOperation.getOperationModel() != null && StringUtils.isNotBlank(r
667
697
* Calculate path.
668
698
*
669
699
* @param routerOperation the router operation
670
- * @param locale the locale
700
+ * @param locale the locale
671
701
*/
672
702
protected void calculatePath (RouterOperation routerOperation , Locale locale , OpenAPI openAPI ) {
673
703
routerOperation = customizeDataRestRouterOperation (routerOperation );
@@ -733,13 +763,13 @@ private RouterOperation customizeDataRestRouterOperation(RouterOperation routerO
733
763
/**
734
764
* Calculate path.
735
765
*
736
- * @param handlerMethod the handler method
737
- * @param operationPath the operation path
766
+ * @param handlerMethod the handler method
767
+ * @param operationPath the operation path
738
768
* @param requestMethods the request methods
739
- * @param consumes the consumes
740
- * @param produces the produces
741
- * @param headers the headers
742
- * @param locale the locale
769
+ * @param consumes the consumes
770
+ * @param produces the produces
771
+ * @param headers the headers
772
+ * @param locale the locale
743
773
*/
744
774
protected void calculatePath (HandlerMethod handlerMethod , String operationPath ,
745
775
Set <RequestMethod > requestMethods , String [] consumes , String [] produces , String [] headers , String [] params , Locale locale , OpenAPI openAPI ) {
@@ -749,10 +779,10 @@ protected void calculatePath(HandlerMethod handlerMethod, String operationPath,
749
779
/**
750
780
* Gets router function paths.
751
781
*
752
- * @param beanName the bean name
782
+ * @param beanName the bean name
753
783
* @param routerFunctionVisitor the router function visitor
754
- * @param locale the locale
755
- * @param openAPI the open api
784
+ * @param locale the locale
785
+ * @param openAPI the open api
756
786
*/
757
787
protected void getRouterFunctionPaths (String beanName , AbstractRouterFunctionVisitor routerFunctionVisitor ,
758
788
Locale locale , OpenAPI openAPI ) {
@@ -788,9 +818,9 @@ protected void getRouterFunctionPaths(String beanName, AbstractRouterFunctionVis
788
818
*
789
819
* @param handlerMethod the handler method
790
820
* @param operationPath the operation path
791
- * @param produces the produces
792
- * @param consumes the consumes
793
- * @param headers the headers
821
+ * @param produces the produces
822
+ * @param consumes the consumes
823
+ * @param headers the headers
794
824
* @return the boolean
795
825
*/
796
826
protected boolean isFilterCondition (HandlerMethod handlerMethod , String operationPath , String [] produces , String [] consumes , String [] headers ) {
@@ -816,7 +846,7 @@ protected boolean isMethodToFilter(HandlerMethod handlerMethod) {
816
846
* Is condition to match boolean.
817
847
*
818
848
* @param existingConditions the existing conditions
819
- * @param conditionType the condition type
849
+ * @param conditionType the condition type
820
850
* @return the boolean
821
851
*/
822
852
protected boolean isConditionToMatch (String [] existingConditions , ConditionType conditionType ) {
@@ -915,8 +945,8 @@ protected boolean isAdditionalRestController(Class<?> rawClass) {
915
945
* Is rest controller boolean.
916
946
*
917
947
* @param restControllers the rest controllers
918
- * @param handlerMethod the handler method
919
- * @param operationPath the operation path
948
+ * @param handlerMethod the handler method
949
+ * @param operationPath the operation path
920
950
* @return the boolean
921
951
*/
922
952
protected boolean isRestController (Map <String , Object > restControllers , HandlerMethod handlerMethod ,
@@ -941,7 +971,7 @@ protected Set<RequestMethod> getDefaultAllowedHttpMethods() {
941
971
/**
942
972
* Customise operation.
943
973
*
944
- * @param operation the operation
974
+ * @param operation the operation
945
975
* @param handlerMethod the handler method
946
976
* @return the operation
947
977
*/
@@ -959,7 +989,7 @@ protected Operation customizeOperation(Operation operation, HandlerMethod handle
959
989
* Customise router operation
960
990
*
961
991
* @param routerOperation the router operation
962
- * @param handlerMethod the handler method
992
+ * @param handlerMethod the handler method
963
993
* @return the router operation
964
994
*/
965
995
protected RouterOperation customizeRouterOperation (RouterOperation routerOperation , HandlerMethod handlerMethod ) {
@@ -1064,9 +1094,9 @@ && isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes(
1064
1094
/**
1065
1095
* Calculate json view.
1066
1096
*
1067
- * @param apiOperation the api operation
1097
+ * @param apiOperation the api operation
1068
1098
* @param methodAttributes the method attributes
1069
- * @param method the method
1099
+ * @param method the method
1070
1100
*/
1071
1101
private void calculateJsonView (io .swagger .v3 .oas .annotations .Operation apiOperation ,
1072
1102
MethodAttributes methodAttributes , Method method ) {
@@ -1123,8 +1153,8 @@ private boolean isEqualMethods(RequestMethod[] requestMethods1, RequestMethod[]
1123
1153
/**
1124
1154
* Fill parameters list.
1125
1155
*
1126
- * @param operation the operation
1127
- * @param queryParams the query params
1156
+ * @param operation the operation
1157
+ * @param queryParams the query params
1128
1158
* @param methodAttributes the method attributes
1129
1159
*/
1130
1160
private void fillParametersList (Operation operation , Map <String , String > queryParams , MethodAttributes methodAttributes ) {
@@ -1157,7 +1187,7 @@ private void fillParametersList(Operation operation, Map<String, String> queryPa
1157
1187
* Fill router operation.
1158
1188
*
1159
1189
* @param routerFunctionData the router function data
1160
- * @param routerOperation the router operation
1190
+ * @param routerOperation the router operation
1161
1191
*/
1162
1192
private void fillRouterOperation (RouterFunctionData routerFunctionData , RouterOperation routerOperation ) {
1163
1193
if (ArrayUtils .isEmpty (routerOperation .getConsumes ()))
@@ -1176,9 +1206,9 @@ private void fillRouterOperation(RouterFunctionData routerFunctionData, RouterOp
1176
1206
* Build path item.
1177
1207
*
1178
1208
* @param requestMethod the request method
1179
- * @param operation the operation
1209
+ * @param operation the operation
1180
1210
* @param operationPath the operation path
1181
- * @param paths the paths
1211
+ * @param paths the paths
1182
1212
* @return the path item
1183
1213
*/
1184
1214
private PathItem buildPathItem (RequestMethod requestMethod , Operation operation , String operationPath ,
@@ -1191,7 +1221,7 @@ private PathItem buildPathItem(RequestMethod requestMethod, Operation operation,
1191
1221
if (ParameterIn .PATH .toString ().equals (parameter .getIn ())) {
1192
1222
// check it's present in the path
1193
1223
String name = parameter .getName ();
1194
- if (!StringUtils .containsAny (operationPath , "{" + name + "}" , "{*" + name + "}" ))
1224
+ if (!StringUtils .containsAny (operationPath , "{" + name + "}" , "{*" + name + "}" ))
1195
1225
paramIt .remove ();
1196
1226
}
1197
1227
}
@@ -1236,7 +1266,7 @@ private PathItem buildPathItem(RequestMethod requestMethod, Operation operation,
1236
1266
/**
1237
1267
* Gets existing operation.
1238
1268
*
1239
- * @param operationMap the operation map
1269
+ * @param operationMap the operation map
1240
1270
* @param requestMethod the request method
1241
1271
* @return the existing operation
1242
1272
*/
@@ -1277,7 +1307,7 @@ private Operation getExistingOperation(Map<HttpMethod, Operation> operationMap,
1277
1307
/**
1278
1308
* Gets operation.
1279
1309
*
1280
- * @param routerOperation the router operation
1310
+ * @param routerOperation the router operation
1281
1311
* @param existingOperation the existing operation
1282
1312
* @return the operation
1283
1313
*/
@@ -1336,7 +1366,7 @@ protected byte[] writeYamlValue(OpenAPI openAPI) throws JsonProcessingException
1336
1366
* Gets actuator uri.
1337
1367
*
1338
1368
* @param scheme the scheme
1339
- * @param host the host
1369
+ * @param host the host
1340
1370
* @return the actuator uri
1341
1371
*/
1342
1372
protected URI getActuatorURI (String scheme , String host ) {
@@ -1405,7 +1435,7 @@ protected byte[] writeJsonValue(OpenAPI openAPI) throws JsonProcessingException
1405
1435
* Gets conditions to match.
1406
1436
*
1407
1437
* @param conditionType the condition type
1408
- * @param groupConfigs the group configs
1438
+ * @param groupConfigs the group configs
1409
1439
* @return the conditions to match
1410
1440
*/
1411
1441
private List <String > getConditionsToMatch (ConditionType conditionType , GroupConfig ... groupConfigs ) {
@@ -1433,9 +1463,9 @@ private List<String> getConditionsToMatch(ConditionType conditionType, GroupConf
1433
1463
* Is filter condition boolean.
1434
1464
*
1435
1465
* @param operationPath the operation path
1436
- * @param produces the produces
1437
- * @param consumes the consumes
1438
- * @param headers the headers
1466
+ * @param produces the produces
1467
+ * @param consumes the consumes
1468
+ * @param headers the headers
1439
1469
* @return the boolean
1440
1470
*/
1441
1471
private boolean isFilterCondition (String operationPath , String [] produces , String [] consumes , String [] headers ) {
0 commit comments