6060import io .swagger .v3 .core .filter .SpecFilter ;
6161import io .swagger .v3 .core .util .ReflectionUtils ;
6262import io .swagger .v3 .oas .annotations .Hidden ;
63+ import io .swagger .v3 .oas .annotations .Webhook ;
64+ import io .swagger .v3 .oas .annotations .Webhooks ;
6365import io .swagger .v3 .oas .annotations .callbacks .Callback ;
6466import io .swagger .v3 .oas .annotations .enums .ParameterIn ;
6567import io .swagger .v3 .oas .models .Components ;
@@ -213,14 +215,14 @@ public abstract class AbstractOpenApiResource extends SpecFilter {
213215 /**
214216 * Instantiates a new Abstract open api resource.
215217 *
216- * @param groupName the group name
218+ * @param groupName the group name
217219 * @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
224226 */
225227 protected AbstractOpenApiResource (String groupName , ObjectFactory <OpenAPIService > openAPIBuilderObjectFactory ,
226228 AbstractRequestService requestBuilder ,
@@ -239,7 +241,8 @@ protected AbstractOpenApiResource(String groupName, ObjectFactory<OpenAPIService
239241 if (springDocConfigProperties .isPreLoadingEnabled ()) {
240242 if (CollectionUtils .isEmpty (springDocConfigProperties .getPreLoadingLocales ())) {
241243 Executors .newSingleThreadExecutor ().execute (this ::getOpenApi );
242- } else {
244+ }
245+ else {
243246 for (String locale : springDocConfigProperties .getPreLoadingLocales ()) {
244247 Executors .newSingleThreadExecutor ().execute (() -> this .getOpenApi (Locale .forLanguageTag (locale )));
245248 }
@@ -343,9 +346,10 @@ protected OpenAPI getOpenApi(Locale locale) {
343346 .collect (Collectors .toMap (Map .Entry ::getKey , Map .Entry ::getValue , (a1 , a2 ) -> a1 ));
344347
345348 Map <String , Object > findControllerAdvice = openAPIService .getControllerAdviceMap ();
346- if (OpenApiVersion .OPENAPI_3_1 == springDocConfigProperties .getApiDocs ().getVersion ()){
349+ if (OpenApiVersion .OPENAPI_3_1 == springDocConfigProperties .getApiDocs ().getVersion ()) {
347350 openAPI .openapi (OpenApiVersion .OPENAPI_3_1 .getVersion ());
348351 openAPI .specVersion (SpecVersion .V31 );
352+ calculateWebhooks (openAPI , locale );
349353 }
350354 if (springDocConfigProperties .isDefaultOverrideWithGenericResponse ()) {
351355 if (!CollectionUtils .isEmpty (mappingsMap ))
@@ -373,7 +377,7 @@ protected OpenAPI getOpenApi(Locale locale) {
373377 if (springDocConfigProperties .isRemoveBrokenReferenceDefinitions ())
374378 this .removeBrokenReferenceDefinitions (openAPI );
375379
376- // run the optional customisers
380+ // run the optional customizers
377381 List <Server > servers = openAPI .getServers ();
378382 List <Server > serversCopy = null ;
379383 try {
@@ -401,13 +405,15 @@ protected OpenAPI getOpenApi(Locale locale) {
401405 }
402406 openAPIService .updateServers (openAPI );
403407 return openAPI ;
404- } finally {
408+ }
409+ finally {
405410 this .reentrantLock .unlock ();
406411 }
407412 }
408413
409414 /**
410415 * Indents are removed for properties that are mainly used as “explanations” using Open API.
416+ *
411417 * @param openAPI the open api
412418 */
413419 private void trimIndent (OpenAPI openAPI ) {
@@ -417,6 +423,7 @@ private void trimIndent(OpenAPI openAPI) {
417423
418424 /**
419425 * Trim the indent for descriptions in the 'components' of open api.
426+ *
420427 * @param openAPI the open api
421428 */
422429 private void trimComponents (OpenAPI openAPI ) {
@@ -439,6 +446,7 @@ private void trimComponents(OpenAPI openAPI) {
439446
440447 /**
441448 * Trim the indent for descriptions in the 'paths' of open api.
449+ *
442450 * @param openAPI the open api
443451 */
444452 private void trimPaths (OpenAPI openAPI ) {
@@ -461,6 +469,7 @@ private void trimPaths(OpenAPI openAPI) {
461469
462470 /**
463471 * Trim the indent for 'operation'
472+ *
464473 * @param operation the operation
465474 */
466475 private void trimIndentOperation (Operation operation ) {
@@ -476,18 +485,39 @@ private void trimIndentOperation(Operation operation) {
476485 * Gets paths.
477486 *
478487 * @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
481490 */
482491 protected abstract void getPaths (Map <String , Object > findRestControllers , Locale locale , OpenAPI openAPI );
483492
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+
484514 /**
485515 * Calculate path.
486516 *
487- * @param handlerMethod the handler method
517+ * @param handlerMethod the handler method
488518 * @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
491521 */
492522 protected void calculatePath (HandlerMethod handlerMethod , RouterOperation routerOperation , Locale locale , OpenAPI openAPI ) {
493523 routerOperation = customizeRouterOperation (routerOperation , handlerMethod );
@@ -602,10 +632,10 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router
602632 /**
603633 * Build callbacks.
604634 *
605- * @param openAPI the open api
635+ * @param openAPI the open api
606636 * @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
609639 */
610640 private void buildCallbacks (OpenAPI openAPI , MethodAttributes methodAttributes , Operation operation , Set <Callback > apiCallbacks ) {
611641 if (!CollectionUtils .isEmpty (apiCallbacks ))
@@ -617,8 +647,8 @@ private void buildCallbacks(OpenAPI openAPI, MethodAttributes methodAttributes,
617647 * Calculate path.
618648 *
619649 * @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
622652 */
623653 protected void calculatePath (List <RouterOperation > routerOperationList , Locale locale , OpenAPI openAPI ) {
624654 ApplicationContext applicationContext = openAPIService .getContext ();
@@ -667,7 +697,7 @@ else if (routerOperation.getOperationModel() != null && StringUtils.isNotBlank(r
667697 * Calculate path.
668698 *
669699 * @param routerOperation the router operation
670- * @param locale the locale
700+ * @param locale the locale
671701 */
672702 protected void calculatePath (RouterOperation routerOperation , Locale locale , OpenAPI openAPI ) {
673703 routerOperation = customizeDataRestRouterOperation (routerOperation );
@@ -733,13 +763,13 @@ private RouterOperation customizeDataRestRouterOperation(RouterOperation routerO
733763 /**
734764 * Calculate path.
735765 *
736- * @param handlerMethod the handler method
737- * @param operationPath the operation path
766+ * @param handlerMethod the handler method
767+ * @param operationPath the operation path
738768 * @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
743773 */
744774 protected void calculatePath (HandlerMethod handlerMethod , String operationPath ,
745775 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,
749779 /**
750780 * Gets router function paths.
751781 *
752- * @param beanName the bean name
782+ * @param beanName the bean name
753783 * @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
756786 */
757787 protected void getRouterFunctionPaths (String beanName , AbstractRouterFunctionVisitor routerFunctionVisitor ,
758788 Locale locale , OpenAPI openAPI ) {
@@ -788,9 +818,9 @@ protected void getRouterFunctionPaths(String beanName, AbstractRouterFunctionVis
788818 *
789819 * @param handlerMethod the handler method
790820 * @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
794824 * @return the boolean
795825 */
796826 protected boolean isFilterCondition (HandlerMethod handlerMethod , String operationPath , String [] produces , String [] consumes , String [] headers ) {
@@ -816,7 +846,7 @@ protected boolean isMethodToFilter(HandlerMethod handlerMethod) {
816846 * Is condition to match boolean.
817847 *
818848 * @param existingConditions the existing conditions
819- * @param conditionType the condition type
849+ * @param conditionType the condition type
820850 * @return the boolean
821851 */
822852 protected boolean isConditionToMatch (String [] existingConditions , ConditionType conditionType ) {
@@ -915,8 +945,8 @@ protected boolean isAdditionalRestController(Class<?> rawClass) {
915945 * Is rest controller boolean.
916946 *
917947 * @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
920950 * @return the boolean
921951 */
922952 protected boolean isRestController (Map <String , Object > restControllers , HandlerMethod handlerMethod ,
@@ -941,7 +971,7 @@ protected Set<RequestMethod> getDefaultAllowedHttpMethods() {
941971 /**
942972 * Customise operation.
943973 *
944- * @param operation the operation
974+ * @param operation the operation
945975 * @param handlerMethod the handler method
946976 * @return the operation
947977 */
@@ -959,7 +989,7 @@ protected Operation customizeOperation(Operation operation, HandlerMethod handle
959989 * Customise router operation
960990 *
961991 * @param routerOperation the router operation
962- * @param handlerMethod the handler method
992+ * @param handlerMethod the handler method
963993 * @return the router operation
964994 */
965995 protected RouterOperation customizeRouterOperation (RouterOperation routerOperation , HandlerMethod handlerMethod ) {
@@ -1064,9 +1094,9 @@ && isEqualArrays(routerFunctionData1.getConsumes(), routerOperation.getConsumes(
10641094 /**
10651095 * Calculate json view.
10661096 *
1067- * @param apiOperation the api operation
1097+ * @param apiOperation the api operation
10681098 * @param methodAttributes the method attributes
1069- * @param method the method
1099+ * @param method the method
10701100 */
10711101 private void calculateJsonView (io .swagger .v3 .oas .annotations .Operation apiOperation ,
10721102 MethodAttributes methodAttributes , Method method ) {
@@ -1123,8 +1153,8 @@ private boolean isEqualMethods(RequestMethod[] requestMethods1, RequestMethod[]
11231153 /**
11241154 * Fill parameters list.
11251155 *
1126- * @param operation the operation
1127- * @param queryParams the query params
1156+ * @param operation the operation
1157+ * @param queryParams the query params
11281158 * @param methodAttributes the method attributes
11291159 */
11301160 private void fillParametersList (Operation operation , Map <String , String > queryParams , MethodAttributes methodAttributes ) {
@@ -1157,7 +1187,7 @@ private void fillParametersList(Operation operation, Map<String, String> queryPa
11571187 * Fill router operation.
11581188 *
11591189 * @param routerFunctionData the router function data
1160- * @param routerOperation the router operation
1190+ * @param routerOperation the router operation
11611191 */
11621192 private void fillRouterOperation (RouterFunctionData routerFunctionData , RouterOperation routerOperation ) {
11631193 if (ArrayUtils .isEmpty (routerOperation .getConsumes ()))
@@ -1176,9 +1206,9 @@ private void fillRouterOperation(RouterFunctionData routerFunctionData, RouterOp
11761206 * Build path item.
11771207 *
11781208 * @param requestMethod the request method
1179- * @param operation the operation
1209+ * @param operation the operation
11801210 * @param operationPath the operation path
1181- * @param paths the paths
1211+ * @param paths the paths
11821212 * @return the path item
11831213 */
11841214 private PathItem buildPathItem (RequestMethod requestMethod , Operation operation , String operationPath ,
@@ -1191,7 +1221,7 @@ private PathItem buildPathItem(RequestMethod requestMethod, Operation operation,
11911221 if (ParameterIn .PATH .toString ().equals (parameter .getIn ())) {
11921222 // check it's present in the path
11931223 String name = parameter .getName ();
1194- if (!StringUtils .containsAny (operationPath , "{" + name + "}" , "{*" + name + "}" ))
1224+ if (!StringUtils .containsAny (operationPath , "{" + name + "}" , "{*" + name + "}" ))
11951225 paramIt .remove ();
11961226 }
11971227 }
@@ -1236,7 +1266,7 @@ private PathItem buildPathItem(RequestMethod requestMethod, Operation operation,
12361266 /**
12371267 * Gets existing operation.
12381268 *
1239- * @param operationMap the operation map
1269+ * @param operationMap the operation map
12401270 * @param requestMethod the request method
12411271 * @return the existing operation
12421272 */
@@ -1277,7 +1307,7 @@ private Operation getExistingOperation(Map<HttpMethod, Operation> operationMap,
12771307 /**
12781308 * Gets operation.
12791309 *
1280- * @param routerOperation the router operation
1310+ * @param routerOperation the router operation
12811311 * @param existingOperation the existing operation
12821312 * @return the operation
12831313 */
@@ -1336,7 +1366,7 @@ protected byte[] writeYamlValue(OpenAPI openAPI) throws JsonProcessingException
13361366 * Gets actuator uri.
13371367 *
13381368 * @param scheme the scheme
1339- * @param host the host
1369+ * @param host the host
13401370 * @return the actuator uri
13411371 */
13421372 protected URI getActuatorURI (String scheme , String host ) {
@@ -1405,7 +1435,7 @@ protected byte[] writeJsonValue(OpenAPI openAPI) throws JsonProcessingException
14051435 * Gets conditions to match.
14061436 *
14071437 * @param conditionType the condition type
1408- * @param groupConfigs the group configs
1438+ * @param groupConfigs the group configs
14091439 * @return the conditions to match
14101440 */
14111441 private List <String > getConditionsToMatch (ConditionType conditionType , GroupConfig ... groupConfigs ) {
@@ -1433,9 +1463,9 @@ private List<String> getConditionsToMatch(ConditionType conditionType, GroupConf
14331463 * Is filter condition boolean.
14341464 *
14351465 * @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
14391469 * @return the boolean
14401470 */
14411471 private boolean isFilterCondition (String operationPath , String [] produces , String [] consumes , String [] headers ) {
0 commit comments