From 671a4402b8138847a4a4f5fe919cad8a057c5dc6 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 03:17:39 +0200 Subject: [PATCH 01/45] Add Spring Boot 4.0.0-M1 support #3062 --- pom.xml | 34 +---- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 36 +++-- .../configuration/SpringDocConfiguration.java | 2 +- .../SpringDocDataRestConfiguration.java | 2 +- .../SpringDocHateoasConfiguration.java | 2 +- .../SpringDocSecurityConfiguration.java | 23 +--- .../SpringDocSecurityOAuth2Customizer.java | 23 ++-- .../QuerydslPredicateOperationCustomizer.java | 25 ++-- .../core/data/DataRestRequestService.java | 3 +- .../core/providers/ActuatorProvider.java | 6 +- .../core/providers/DataRestHalProvider.java | 10 +- .../core/providers/HateoasHalProvider.java | 31 +++-- .../SpringDataWebPropertiesProvider.java | 3 +- .../core/service/AbstractRequestService.java | 12 +- .../springdoc/core/utils/SpringDocUtils.java | 2 +- .../core/utils/SpringSecurityUtils.java | 47 +++++++ .../SpringDocHateoasConfigurationTest.java | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 21 ++- .../MultipleOpenApiSupportConfiguration.java | 2 +- .../SpringDocWebFluxConfiguration.java | 4 +- .../providers/ActuatorWebFluxProvider.java | 6 +- .../core/visitor/RouterFunctionVisitor.java | 5 + .../app153/DefaultWebFluxRegistrations.java | 2 +- .../springdoc/api/v30/app69/UserHandler.java | 8 +- .../v30/app72/controller/PersonRouter.java | 2 +- .../v30/app72/controller/PositionRouter.java | 2 +- .../springdoc/api/v30/app73/QuoteHandler.java | 4 +- .../springdoc/api/v30/app73/QuoteRouter.java | 8 +- .../springdoc/api/v30/app82/UserHandler.java | 9 +- .../v30/app85/controller/PersonRouter.java | 2 +- .../v30/app85/controller/PositionRouter.java | 2 +- .../springdoc/api/v30/app86/QuoteHandler.java | 4 +- .../springdoc/api/v30/app86/QuoteRouter.java | 4 +- .../v30/app90/position/PositionRouter.java | 2 +- .../api/v30/app90/quotes/QuotesRouter.java | 4 +- .../app153/DefaultWebFluxRegistrations.java | 2 +- .../springdoc/api/v31/app69/UserHandler.java | 9 +- .../v31/app72/controller/PersonRouter.java | 2 +- .../v31/app72/controller/PositionRouter.java | 2 +- .../springdoc/api/v31/app73/QuoteHandler.java | 4 +- .../springdoc/api/v31/app73/QuoteRouter.java | 8 +- .../springdoc/api/v31/app82/UserHandler.java | 8 +- .../v31/app85/controller/PersonRouter.java | 2 +- .../v31/app85/controller/PositionRouter.java | 2 +- .../springdoc/api/v31/app86/QuoteHandler.java | 4 +- .../springdoc/api/v31/app86/QuoteRouter.java | 4 +- .../v31/app90/position/PositionRouter.java | 2 +- .../api/v31/app90/quotes/QuotesRouter.java | 4 +- .../test/resources/results/3.0.1/app72.json | 4 +- .../test/resources/results/3.0.1/app73.json | 2 +- .../test/resources/results/3.0.1/app85.json | 4 +- .../test/resources/results/3.0.1/app86.json | 2 +- .../test/resources/results/3.0.1/app90.json | 4 +- .../test/resources/results/3.1.0/app72.json | 4 +- .../test/resources/results/3.1.0/app73.json | 2 +- .../test/resources/results/3.1.0/app85.json | 4 +- .../test/resources/results/3.1.0/app86.json | 2 +- .../test/resources/results/3.1.0/app90.json | 4 +- springdoc-openapi-starter-webflux-ui/pom.xml | 13 +- .../springdoc/webflux/ui/SwaggerConfig.java | 4 +- .../springdoc/webflux/ui/SwaggerUiHome.java | 2 +- .../ui/AbstractSpringDocActuatorTest.java | 3 +- .../ui/app18/SpringDocApp18Test.java | 2 +- .../ui/app19/SpringDocApp19Test.java | 2 +- .../ui/app20/SpringDocApp20Test.java | 2 +- .../ui/app23/SpringDocApp23Test.java | 2 +- .../SpringDocBehindProxyBasePathTest.java | 2 +- .../springdoc/ui/app33/SpringDocConfig.java | 2 +- .../SpringDocOauthPathsWithPropertyTest.java | 4 +- springdoc-openapi-starter-webmvc-api/pom.xml | 17 ++- .../MultipleOpenApiSupportConfiguration.java | 2 +- .../SpringDocWebMvcConfiguration.java | 4 +- .../providers/ActuatorWebMvcProvider.java | 6 +- .../RouterFunctionWebMvcProvider.java | 5 + .../v30/app105/api/ExceptionTranslator.java | 2 +- .../app169/DefaultWebMvcRegistrations.java | 2 +- .../api/v30/app2/api/ExceptionTranslator.java | 2 +- .../app231/ApplicationsRestController.java | 52 ++++++- .../api/v30/app77/HelloController.java | 2 +- .../v31/app105/api/ExceptionTranslator.java | 2 +- .../app169/DefaultWebMvcRegistrations.java | 2 +- .../api/v31/app2/api/ExceptionTranslator.java | 2 +- .../app231/ApplicationsRestController.java | 54 +++++++- .../api/v31/app241/OpenApiConfig.java | 1 - .../api/v31/app77/HelloController.java | 2 +- .../test/resources/results/3.0.1/app143.json | 31 ----- .../test/resources/results/3.0.1/app196.json | 31 ----- .../test/resources/results/3.0.1/app77.json | 10 +- .../test/resources/results/3.1.0/app143.json | 31 ----- .../test/resources/results/3.1.0/app196.json | 31 ----- .../test/resources/results/3.1.0/app77.json | 14 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 24 ++-- .../springdoc/webmvc/ui/SwaggerConfig.java | 2 +- .../ui/AbstractSpringDocActuatorTest.java | 4 +- .../springdoc/ui/app11/ExampleController.java | 20 --- .../springdoc/ui/app11/SpringDocCSRFTest.java | 51 ------- .../springdoc/ui/app11/WebSecurityConf.java | 23 ---- springdoc-openapi-tests/pom.xml | 2 +- .../pom.xml | 13 +- .../v30/AbstractSpringDocActuatorTest.java | 2 +- .../api/v30/app76/SpringDocApp76Test.java | 2 +- .../api/v30/app76/SpringDocTestApp.java | 6 +- .../v31/AbstractSpringDocActuatorTest.java | 2 +- .../api/v31/app76/SpringDocApp76Test.java | 2 +- .../api/v31/app76/SpringDocTestApp.java | 6 +- .../resources/results/3.0.1/app146-1.json | 126 ----------------- .../resources/results/3.0.1/app147-1.json | 126 ----------------- .../resources/results/3.0.1/app147-2.json | 126 ----------------- .../resources/results/3.0.1/app148-2.json | 126 ----------------- .../test/resources/results/3.0.1/app186.json | 128 +---------------- .../resources/results/3.1.0/app146-1.json | 126 ----------------- .../resources/results/3.1.0/app147-1.json | 126 ----------------- .../resources/results/3.1.0/app147-2.json | 126 ----------------- .../resources/results/3.1.0/app148-2.json | 126 ----------------- .../test/resources/results/3.1.0/app186.json | 128 +---------------- .../pom.xml | 11 +- .../v30/AbstractSpringDocActuatorTest.java | 4 +- .../api/v30/app128/SpringDocApp128Test.java | 2 +- .../v30/app68/api/ExceptionTranslator.java | 2 +- .../v31/AbstractSpringDocActuatorTest.java | 4 +- .../api/v31/app128/SpringDocApp128Test.java | 2 +- .../v31/app68/api/ExceptionTranslator.java | 2 +- .../resources/results/3.0.1/app147-1.json | 126 ----------------- .../resources/results/3.0.1/app148-2.json | 126 ----------------- .../test/resources/results/3.0.1/app186.json | 126 ----------------- .../test/resources/results/3.0.1/app187.json | 126 ----------------- .../resources/results/3.1.0/app147-1.json | 126 ----------------- .../resources/results/3.1.0/app148-2.json | 126 ----------------- .../test/resources/results/3.1.0/app186.json | 126 ----------------- .../springdoc-openapi-data-rest-tests/pom.xml | 24 ++-- .../api/v30/app14/SpringDocApp14Test.java | 2 +- .../api/v30/app17/ChildProperty.java | 4 +- .../org/springdoc/api/v30/app17/Property.java | 4 +- .../springdoc/api/v30/app19/Application.java | 74 +++++++++- .../org/springdoc/api/v30/app23/Clinic.java | 34 +++-- .../org/springdoc/api/v30/app23/Doctor.java | 35 +++-- .../api/v30/app24/TesteResource.java | 2 - .../org/springdoc/api/v30/app24/User.java | 36 ++++- .../api/v30/app25/model/Address.java | 67 +++++++-- .../api/v30/app25/model/BaseEntity.java | 17 ++- .../springdoc/api/v30/app25/model/Cat.java | 26 ++-- .../springdoc/api/v30/app25/model/Clinic.java | 40 ++++-- .../springdoc/api/v30/app25/model/Doctor.java | 54 ++++++-- .../springdoc/api/v30/app25/model/Dog.java | 30 ++-- .../springdoc/api/v30/app25/model/Owner.java | 59 ++++++-- .../springdoc/api/v30/app25/model/Pet.java | 39 ++++-- .../org/springdoc/api/v30/app30/User.java | 36 ++++- .../api/v30/app32/SpringDocApp32Test.java | 2 +- .../api/v30/app35/ChildProperty.java | 6 +- .../org/springdoc/api/v30/app35/Property.java | 5 +- .../springdoc/api/v30/app37/BaseEntity.java | 25 ++-- .../api/v30/app37/ProductEntity.java | 36 +++-- .../org/springdoc/api/v30/app4/Employee.java | 64 ++++++--- .../org/springdoc/api/v30/app6/Employee.java | 63 ++++++--- .../app9/component/dto/DemoComponentDto.java | 60 ++++++-- .../app9/component/model/DemoComponent.java | 56 ++++++-- .../component/service/ComponentsService.java | 5 +- .../api/v30/app9/core/model/ExceptionDto.java | 27 +++- .../api/v31/app14/SpringDocApp14Test.java | 2 +- .../api/v31/app17/ChildProperty.java | 4 +- .../org/springdoc/api/v31/app17/Property.java | 4 +- .../springdoc/api/v31/app19/Application.java | 74 +++++++++- .../org/springdoc/api/v31/app23/Clinic.java | 34 +++-- .../org/springdoc/api/v31/app23/Doctor.java | 32 +++-- .../api/v31/app24/TesteResource.java | 2 - .../org/springdoc/api/v31/app24/User.java | 37 ++++- .../api/v31/app25/model/Address.java | 55 ++++++-- .../api/v31/app25/model/BaseEntity.java | 18 ++- .../springdoc/api/v31/app25/model/Cat.java | 28 ++-- .../springdoc/api/v31/app25/model/Clinic.java | 42 ++++-- .../springdoc/api/v31/app25/model/Doctor.java | 55 ++++++-- .../springdoc/api/v31/app25/model/Dog.java | 22 ++- .../springdoc/api/v31/app25/model/Owner.java | 52 +++++-- .../springdoc/api/v31/app25/model/Pet.java | 39 ++++-- .../org/springdoc/api/v31/app30/User.java | 36 ++++- .../api/v31/app32/SpringDocApp32Test.java | 2 +- .../api/v31/app35/ChildProperty.java | 4 +- .../org/springdoc/api/v31/app35/Property.java | 7 +- .../springdoc/api/v31/app37/BaseEntity.java | 26 ++-- .../api/v31/app37/ProductEntity.java | 36 +++-- .../org/springdoc/api/v31/app4/Employee.java | 63 ++++++--- .../org/springdoc/api/v31/app6/Employee.java | 63 ++++++--- .../app9/component/dto/DemoComponentDto.java | 63 +++++++-- .../app9/component/model/DemoComponent.java | 62 +++++++-- .../api/v31/app9/core/model/ExceptionDto.java | 28 +++- .../test/resources/results/3.0.1/app10.json | 30 ++-- .../test/resources/results/3.0.1/app11.json | 6 +- .../test/resources/results/3.0.1/app12.json | 24 ++-- .../test/resources/results/3.0.1/app13.json | 8 +- .../test/resources/results/3.0.1/app16.json | 40 +++--- .../test/resources/results/3.0.1/app17.json | 6 +- .../test/resources/results/3.0.1/app19.json | 2 +- .../test/resources/results/3.0.1/app20.json | 18 +-- .../test/resources/results/3.0.1/app21.json | 16 +-- .../test/resources/results/3.0.1/app22.json | 8 +- .../test/resources/results/3.0.1/app23.json | 36 ++--- .../test/resources/results/3.0.1/app24.json | 2 +- .../test/resources/results/3.0.1/app25.json | 82 +++++------ .../test/resources/results/3.0.1/app26.json | 18 +-- .../test/resources/results/3.0.1/app29.json | 6 +- .../test/resources/results/3.0.1/app30.json | 2 +- .../test/resources/results/3.0.1/app31.json | 8 +- .../test/resources/results/3.0.1/app34.json | 50 +++---- .../test/resources/results/3.0.1/app36.json | 4 +- .../test/resources/results/3.0.1/app37.json | 28 ++-- .../test/resources/results/3.0.1/app38.json | 2 +- .../test/resources/results/3.0.1/app4.json | 130 +++++++++--------- .../test/resources/results/3.0.1/app5.json | 2 +- .../test/resources/results/3.0.1/app6.json | 2 +- .../test/resources/results/3.0.1/app8.json | 2 +- .../test/resources/results/3.1.0/app10.json | 30 ++-- .../test/resources/results/3.1.0/app11.json | 26 ++-- .../test/resources/results/3.1.0/app12.json | 24 ++-- .../test/resources/results/3.1.0/app13.json | 8 +- .../test/resources/results/3.1.0/app16.json | 40 +++--- .../test/resources/results/3.1.0/app17.json | 6 +- .../test/resources/results/3.1.0/app19.json | 2 +- .../test/resources/results/3.1.0/app20.json | 18 +-- .../test/resources/results/3.1.0/app21.json | 16 +-- .../test/resources/results/3.1.0/app22.json | 8 +- .../test/resources/results/3.1.0/app23.json | 36 ++--- .../test/resources/results/3.1.0/app24.json | 2 +- .../test/resources/results/3.1.0/app25.json | 82 +++++------ .../test/resources/results/3.1.0/app26.json | 6 +- .../test/resources/results/3.1.0/app29.json | 6 +- .../test/resources/results/3.1.0/app30.json | 2 +- .../test/resources/results/3.1.0/app31.json | 8 +- .../test/resources/results/3.1.0/app34.json | 50 +++---- .../test/resources/results/3.1.0/app36.json | 4 +- .../test/resources/results/3.1.0/app37.json | 28 ++-- .../test/resources/results/3.1.0/app38.json | 2 +- .../test/resources/results/3.1.0/app4.json | 6 +- .../test/resources/results/3.1.0/app5.json | 2 +- .../test/resources/results/3.1.0/app6.json | 14 +- .../test/resources/results/3.1.0/app8.json | 14 +- .../pom.xml | 8 +- .../pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 17 +-- .../org/springdoc/api/v30/app1/Employee.java | 63 ++++++--- .../org/springdoc/api/v30/app10/Dummy.java | 15 +- .../api/v30/app2/config/DatabaseConfig.java | 6 +- .../v30/app2/controller/PostController.java | 6 +- .../springdoc/api/v30/app2/entities/Post.java | 48 ++++++- .../api/v30/app2/service/PostService.java | 7 +- .../org/springdoc/api/v30/app3/Employee.java | 63 ++++++--- .../app5/controller/CompanyController.java | 2 - .../api/v30/app5/entities/Company.java | 42 ++++-- .../api/v30/app5/entities/CompanyDto.java | 77 +++++++++-- .../api/v30/app7/application/Foo.java | 17 ++- .../org/springdoc/api/v30/app8/Employee.java | 63 ++++++--- .../v30/app9/application/FooController.java | 7 +- .../app9/application/dto/FeedResponse.java | 17 ++- .../app9/application/dto/ResponseData.java | 2 - .../org/springdoc/api/v31/app1/Employee.java | 63 ++++++--- .../org/springdoc/api/v31/app10/Dummy.java | 15 +- .../api/v31/app2/config/DatabaseConfig.java | 6 +- .../v31/app2/controller/PostController.java | 6 +- .../springdoc/api/v31/app2/entities/Post.java | 48 ++++++- .../api/v31/app2/service/PostService.java | 8 +- .../org/springdoc/api/v31/app3/Employee.java | 63 ++++++--- .../app5/controller/CompanyController.java | 3 - .../api/v31/app5/entities/Company.java | 43 ++++-- .../api/v31/app5/entities/CompanyDto.java | 77 +++++++++-- .../api/v31/app7/application/Foo.java | 16 ++- .../org/springdoc/api/v31/app8/Employee.java | 63 ++++++--- .../v31/app9/application/FooController.java | 7 +- .../app9/application/dto/FeedResponse.java | 18 +-- .../app9/application/dto/ResponseData.java | 2 - .../springdoc-openapi-javadoc-tests/pom.xml | 18 +-- .../v30/app105/api/ExceptionTranslator.java | 2 +- .../api/v30/app2/api/ExceptionTranslator.java | 2 +- .../api/v30/app77/HelloController.java | 2 +- .../v31/app105/api/ExceptionTranslator.java | 2 +- .../api/v31/app2/api/ExceptionTranslator.java | 2 +- .../api/v31/app77/HelloController.java | 2 +- .../test/resources/results/3.0.1/app77.json | 4 +- .../test/resources/results/3.1.0/app77.json | 8 +- .../pom.xml | 19 ++- .../pom.xml | 16 +-- .../springdoc-openapi-security-tests/pom.xml | 25 ++-- .../api/v30/AbstractSpringDocTest.java | 2 +- .../v30/app10/AuthorizationServerConfig.java | 9 +- .../v30/app11/AuthorizationServerConfig.java | 17 ++- .../v30/app12/AuthorizationServerConfig.java | 10 +- .../api/v30/app6/security/WebSecurity.java | 35 +++-- .../api/v30/app8/security/WebConfig.java | 5 +- .../org/springdoc/api/v30/app9/WebConfig.java | 5 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../v31/app10/AuthorizationServerConfig.java | 9 +- .../v31/app11/AuthorizationServerConfig.java | 16 ++- .../v31/app12/AuthorizationServerConfig.java | 11 +- .../api/v31/app6/security/WebSecurity.java | 32 ++--- .../api/v31/app8/security/WebConfig.java | 5 +- .../org/springdoc/api/v31/app9/WebConfig.java | 5 +- .../configuration/SecurityConfiguration.java | 1 + 297 files changed, 3140 insertions(+), 3938 deletions(-) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java delete mode 100644 springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/ExampleController.java delete mode 100644 springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/SpringDocCSRFTest.java delete mode 100644 springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/WebSecurityConf.java diff --git a/pom.xml b/pom.xml index d70938f4b..cd8ea9260 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT pom Spring openapi documentation Spring openapi documentation @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 3.5.4 + 4.0.0-M1 @@ -58,8 +58,8 @@ 1.13.1 0.9.1 0.15.0 - 4.2.2 - 1.4.3 + 5.0.0-M1 + 2.0.0-M1 @@ -223,30 +223,4 @@ - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - true - - - false - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - true - - - false - - - diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 5e2f673d1..d36d6f357 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 692b71dcb..6da51f649 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-common ${project.artifactId} @@ -14,21 +14,21 @@ org.springframework.boot - spring-boot-starter-validation + spring-boot-validation + + + io.swagger.core.v3 + swagger-core-jakarta org.springframework.boot spring-boot-configuration-processor true - - io.swagger.core.v3 - swagger-core-jakarta - org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator-autoconfigure true @@ -61,6 +61,16 @@ spring-security-oauth2-client true + + jakarta.servlet + jakarta.servlet-api + provided + + + org.springframework.boot + spring-boot-web-server + true + com.fasterxml.jackson.module @@ -85,7 +95,12 @@ org.springframework.boot - spring-boot-starter-data-rest + spring-boot-data-rest + true + + + org.springframework.boot + spring-boot-hateoas true @@ -93,6 +108,11 @@ querydsl-core true + + commons-logging + commons-logging + test + diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index 170e19de0..6178d7a3b 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -110,8 +110,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties; import org.springframework.boot.autoconfigure.web.format.WebConversionService; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java index 4cd29a720..6407c6a6a 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java @@ -54,7 +54,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.hateoas.HateoasProperties; +import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportRuntimeHints; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java index 3f93c82b6..abccc4996 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java @@ -44,7 +44,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.hateoas.HateoasProperties; +import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityConfiguration.java index 728c4dfa4..ae5e2f9a2 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityConfiguration.java @@ -67,13 +67,12 @@ import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; -import org.springframework.web.util.pattern.PathPattern; import static org.springdoc.core.utils.Constants.SPRINGDOC_SHOW_LOGIN_ENDPOINT; import static org.springdoc.core.utils.Constants.SPRINGDOC_SHOW_OAUTH2_ENDPOINTS; import static org.springdoc.core.utils.SpringDocUtils.getConfig; +import static org.springdoc.core.utils.SpringSecurityUtils.getPath; /** * The type Spring doc security configuration. @@ -164,24 +163,12 @@ OpenApiCustomizer springSecurityLoginEndpointCustomizer(ApplicationContext appli true ); - String loginPath = null; - - if (requestMatcher instanceof AntPathRequestMatcher) { - loginPath = ((AntPathRequestMatcher) requestMatcher).getPattern(); - } - else if (requestMatcher instanceof PathPatternRequestMatcher) { - PathPattern pathPattern = (PathPattern) FieldUtils.readField( - requestMatcher, - "pattern", - true - ); - loginPath = pathPattern.getPatternString(); + if (requestMatcher instanceof PathPatternRequestMatcher pathPatternRequestMatcher) { + String loginPath = getPath(pathPatternRequestMatcher); + openAPI.getPaths().addPathItem(loginPath, pathItem); } - - openAPI.getPaths().addPathItem(loginPath, pathItem); } - catch (IllegalAccessException | - ClassCastException ignored) { + catch (IllegalAccessException | ClassCastException ignored) { // Exception escaped LOGGER.trace(ignored.getMessage()); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityOAuth2Customizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityOAuth2Customizer.java index dfdfb4cd4..e410b7635 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityOAuth2Customizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocSecurityOAuth2Customizer.java @@ -79,11 +79,12 @@ import org.springframework.security.web.FilterChainProxy; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; -import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import org.springframework.security.web.util.matcher.OrRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import org.springframework.util.ReflectionUtils; +import static org.springdoc.core.utils.SpringSecurityUtils.getPath; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.TEXT_HTML_VALUE; @@ -496,24 +497,26 @@ private void buildPath(Object oAuth2EndpointFilter, String authorizationEndpoint try { RequestMatcher endpointMatcher = (RequestMatcher) FieldUtils.readDeclaredField(oAuth2EndpointFilter, authorizationEndpointMatcher, true); String path = null; - if (endpointMatcher instanceof AntPathRequestMatcher antPathRequestMatcher) - path = antPathRequestMatcher.getPattern(); + if (endpointMatcher instanceof PathPatternRequestMatcher pathPatternRequestMatcher) { + path = getPath(pathPatternRequestMatcher); + } else if (endpointMatcher instanceof OrRequestMatcher endpointMatchers) { Iterable requestMatchers = (Iterable) FieldUtils.readDeclaredField(endpointMatchers, "requestMatchers", true); for (RequestMatcher requestMatcher : requestMatchers) { if (requestMatcher instanceof OrRequestMatcher orRequestMatcher) { requestMatchers = (Iterable) FieldUtils.readDeclaredField(orRequestMatcher, "requestMatchers", true); for (RequestMatcher matcher : requestMatchers) { - if (matcher instanceof AntPathRequestMatcher antPathRequestMatcher) - path = antPathRequestMatcher.getPattern(); + if (matcher instanceof PathPatternRequestMatcher pathPatternRequestMatcher) { + path = getPath(pathPatternRequestMatcher); + } } } - else if (requestMatcher instanceof AntPathRequestMatcher antPathRequestMatcher) { - path = antPathRequestMatcher.getPattern(); + else if (requestMatcher instanceof PathPatternRequestMatcher pathPatternRequestMatcher) { + path = getPath(pathPatternRequestMatcher); } } } - + PathItem pathItem = new PathItem(); if (HttpMethod.POST.equals(requestMethod)) { pathItem.post(operation); @@ -528,8 +531,10 @@ else if (HttpMethod.GET.equals(requestMethod)) { } } + @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) throws + BeansException { this.applicationContext = applicationContext; } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java index e0c280d96..add34935f 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java @@ -53,12 +53,11 @@ import org.springdoc.core.properties.SpringDocConfigProperties; import org.springframework.core.MethodParameter; +import org.springframework.core.ResolvableType; import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; import org.springframework.data.querydsl.binding.QuerydslBindings; import org.springframework.data.querydsl.binding.QuerydslBindingsFactory; import org.springframework.data.querydsl.binding.QuerydslPredicate; -import org.springframework.data.util.CastUtils; -import org.springframework.data.util.ClassTypeInformation; import org.springframework.data.util.TypeInformation; import org.springframework.util.CollectionUtils; import org.springframework.web.method.HandlerMethod; @@ -174,15 +173,23 @@ private boolean getFieldValueOfBoolean(QuerydslBindings instance, String fieldNa * @return the querydsl bindings */ private QuerydslBindings extractQdslBindings(QuerydslPredicate predicate) { - ClassTypeInformation classTypeInformation = ClassTypeInformation.from(predicate.root()); - TypeInformation domainType = classTypeInformation.getRequiredActualType(); - - Optional>> bindingsAnnotation = Optional.of(predicate) - .map(QuerydslPredicate::bindings) - .map(CastUtils::cast); + // Replacement for ClassTypeInformation.from(...).getRequiredActualType() + TypeInformation domainType = TypeInformation + .of(ResolvableType.forClass(predicate.root())) + .getRequiredActualType(); + // Replacement for CastUtils::cast + Optional>> bindingsAnnotation = + Optional.of(predicate) + .map(QuerydslPredicate::bindings) + .map(clazz -> { + @SuppressWarnings("unchecked") + Class> typed = + (Class>) clazz; + return typed; + }); return bindingsAnnotation - .map(it -> querydslBindingsFactory.createBindingsFor(domainType, it)) + .map(customizer -> querydslBindingsFactory.createBindingsFor(domainType, customizer)) .orElseGet(() -> querydslBindingsFactory.createBindingsFor(domainType)); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java index 620e1bc40..8ecb701cb 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java @@ -60,7 +60,6 @@ import org.springframework.data.rest.webmvc.PersistentEntityResource; import org.springframework.data.rest.webmvc.support.BackendId; import org.springframework.data.rest.webmvc.support.DefaultedPageable; -import org.springframework.http.HttpHeaders; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.method.HandlerMethod; @@ -253,6 +252,6 @@ else if (!RequestMethod.GET.equals(requestMethod)) { */ private boolean isHeaderToIgnore(MethodParameter methodParameter) { RequestHeader requestHeader = methodParameter.getParameterAnnotation(RequestHeader.class); - return requestHeader != null && HttpHeaders.ACCEPT.equals(requestHeader.value()); + return requestHeader != null; } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/ActuatorProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/ActuatorProvider.java index c072d0283..33d8a963f 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/ActuatorProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/ActuatorProvider.java @@ -38,10 +38,10 @@ import org.springframework.beans.BeansException; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.web.context.WebServerApplicationContext; -import org.springframework.boot.web.context.WebServerInitializedEvent; import org.springframework.boot.web.server.WebServer; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.web.server.context.WebServerApplicationContext; +import org.springframework.boot.web.server.context.WebServerInitializedEvent; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java index 48e2ad99c..07ba0ca28 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java @@ -28,9 +28,8 @@ import java.util.Optional; -import jakarta.annotation.PostConstruct; - -import org.springframework.boot.autoconfigure.hateoas.HateoasProperties; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; @@ -39,7 +38,7 @@ * * @author bnasslahsen */ -public class DataRestHalProvider extends HateoasHalProvider { +public class DataRestHalProvider extends HateoasHalProvider implements InitializingBean { /** * The Repository rest configuration optional. @@ -59,9 +58,8 @@ public DataRestHalProvider(Optional repositoryRestC this.repositoryRestConfigurationOptional = repositoryRestConfigurationOptional; } - @PostConstruct @Override - protected void init() { + public void afterPropertiesSet() { if (!isHalEnabled()) return; if (!Jackson2HalModule.isAlreadyRegisteredIn(objectMapperProvider.jsonMapper())) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java index fa2c256f2..33bae4b07 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java @@ -29,9 +29,8 @@ import java.util.List; import java.util.Optional; -import jakarta.annotation.PostConstruct; - -import org.springframework.boot.autoconfigure.hateoas.HateoasProperties; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; import org.springframework.lang.NonNull; import org.springframework.util.ReflectionUtils; @@ -41,7 +40,7 @@ * * @author bnasslahsen */ -public class HateoasHalProvider { +public class HateoasHalProvider implements InitializingBean { /** * The Object mapper provider. @@ -83,16 +82,6 @@ private static boolean isHalEnabled(@NonNull HateoasProperties hateoasProperties throw new IllegalStateException("No suitable method found to determine if HAL is enabled"); } - /** - * Init. - */ - @PostConstruct - protected void init() { - if (!isHalEnabled()) - return; - if (!Jackson2HalModule.isAlreadyRegisteredIn(objectMapperProvider.jsonMapper())) - objectMapperProvider.jsonMapper().registerModule(new Jackson2HalModule()); - } /** * Is hal enabled boolean. @@ -104,4 +93,18 @@ public boolean isHalEnabled() { .map(HateoasHalProvider::isHalEnabled) .orElse(true); } + + /** + * After Properties Set. + */ + @Override + public void afterPropertiesSet() { + if (!isHalEnabled()) { + return; + } + var mapper = objectMapperProvider.jsonMapper(); + if (!Jackson2HalModule.isAlreadyRegisteredIn(mapper)) { + mapper.registerModule(new Jackson2HalModule()); + } + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java index b2fd4757e..527cf940d 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java @@ -27,7 +27,8 @@ import java.util.Optional; -import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties; +import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties; + /** * The type Spring data web properties provider. diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 401be359e..390f6ba77 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -113,6 +113,14 @@ */ public abstract class AbstractRequestService { + /** + * The constant ACTUATOR_PKGS. + */ + private static final List ACTUATOR_PKGS = List.of( + "org.springframework.boot.webmvc.actuate", + "org.springframework.boot.webflux.actuate" + ); + /** * The constant PARAM_TYPES_TO_IGNORE. */ @@ -499,9 +507,11 @@ private boolean isRequiredAnnotation(MethodParameter parameter) { */ private boolean isRequestBodyWithMapType(MethodParameter parameter) { // Exclude parameters from the Actuator package - if (parameter.getContainingClass().getPackageName().startsWith("org.springframework.boot.actuate")) { + String pkg = parameter.getContainingClass().getPackageName(); + if (ACTUATOR_PKGS.stream().anyMatch(pkg::startsWith)) { return false; } + // Check for @RequestBody annotation org.springframework.web.bind.annotation.RequestBody requestBody = parameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestBody.class); if (requestBody == null) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java index 41ee5906e..90d6755a4 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java @@ -36,9 +36,9 @@ import io.swagger.v3.oas.models.media.ComposedSchema; import io.swagger.v3.oas.models.media.Content; import io.swagger.v3.oas.models.media.Schema; +import jakarta.validation.constraints.NotNull; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; -import org.jetbrains.annotations.NotNull; import org.springdoc.api.AbstractOpenApiResource; import org.springdoc.core.converters.AdditionalModelsConverter; import org.springdoc.core.converters.ConverterUtils; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java new file mode 100644 index 000000000..51f5a16af --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java @@ -0,0 +1,47 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.core.utils; + +import org.apache.commons.lang3.reflect.FieldUtils; + +import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; +import org.springframework.web.util.pattern.PathPattern; + +/** + * @author bnasslahsen + */ +public final class SpringSecurityUtils { + + public static String getPath(PathPatternRequestMatcher pathPatternRequestMatcher) throws IllegalAccessException { + PathPattern pathPattern = (PathPattern) FieldUtils.readField( + pathPatternRequestMatcher, + "pattern", + true + ); + return pathPattern.getPatternString(); + } +} diff --git a/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/configuration/SpringDocHateoasConfigurationTest.java b/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/configuration/SpringDocHateoasConfigurationTest.java index 5664d1fe5..347aedac0 100644 --- a/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/configuration/SpringDocHateoasConfigurationTest.java +++ b/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/configuration/SpringDocHateoasConfigurationTest.java @@ -6,8 +6,8 @@ import org.springdoc.core.properties.SpringDocConfigProperties; import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration; import org.springframework.hateoas.config.HateoasConfiguration; import static org.assertj.core.api.Assertions.assertThat; diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 299d4f069..0fafb0a14 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webflux-api ${project.artifactId} @@ -15,24 +15,23 @@ ${project.version} - org.springframework - spring-webflux + org.springframework.boot + spring-boot-webflux - org.springframework.boot - spring-boot-starter-actuator - true + spring-boot-web-server + org.springframework.boot - spring-boot-starter-reactor-netty - test + spring-boot-actuator-autoconfigure + true + - io.netty - netty-resolver-dns-native-macos - osx-aarch_64 + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/MultipleOpenApiSupportConfiguration.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/MultipleOpenApiSupportConfiguration.java index 1f1eea887..8538663de 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/MultipleOpenApiSupportConfiguration.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/MultipleOpenApiSupportConfiguration.java @@ -44,12 +44,12 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java index 42cb7338b..4ba8d73ee 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java @@ -55,14 +55,14 @@ import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/ActuatorWebFluxProvider.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/ActuatorWebFluxProvider.java index b8fbfc26a..d2503d95c 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/ActuatorWebFluxProvider.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/ActuatorWebFluxProvider.java @@ -35,9 +35,9 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.endpoint.web.reactive.ControllerEndpointHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webflux.actuate.endpoint.web.ControllerEndpointHandlerMapping; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; import org.springframework.context.ApplicationContextAware; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.result.method.RequestMappingInfo; diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java index 25ba6e58b..d3cfb4e5f 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java @@ -75,6 +75,11 @@ public void unknown(RouterFunction routerFunction) { // Not yet needed } + @Override + public void version(String version) { + // Not yet needed + } + @Override public void unknown(RequestPredicate predicate) { // Not yet needed diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app153/DefaultWebFluxRegistrations.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app153/DefaultWebFluxRegistrations.java index 35c31293d..fa17603a1 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app153/DefaultWebFluxRegistrations.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app153/DefaultWebFluxRegistrations.java @@ -26,7 +26,7 @@ package test.org.springdoc.api.v30.app153; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxRegistrations; +import org.springframework.boot.webflux.autoconfigure.WebFluxRegistrations; import org.springframework.stereotype.Component; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app69/UserHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app69/UserHandler.java index 772161873..547f87c05 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app69/UserHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app69/UserHandler.java @@ -34,7 +34,7 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromValue; @Component public class UserHandler { @@ -71,7 +71,7 @@ public Mono getUser(ServerRequest request) { // build response return customerMono - .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(customer))) + .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(customer))) .switchIfEmpty(notFound); } @@ -98,7 +98,7 @@ public Mono putUser(ServerRequest request) { // build response return responseMono - .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(cust))); + .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(cust))); } /** @@ -113,7 +113,7 @@ public Mono deleteUser(ServerRequest request) { // build response return responseMono - .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromObject(strMono))); + .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromValue(strMono))); } } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PersonRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PersonRouter.java index 11d1dd65a..e5d6ed50d 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PersonRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PersonRouter.java @@ -54,7 +54,7 @@ public class PersonRouter { public RouterFunction personRoute(PersonHandler handler) { return RouterFunctions .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) - .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PositionRouter.java index b12564e96..31f6d3b63 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app72/controller/PositionRouter.java @@ -66,7 +66,7 @@ public class PositionRouter { public RouterFunction positionRoute(PositionHandler handler) { return RouterFunctions .route(GET("/getAllPositions").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) - .andRoute(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .andRoute(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .andRoute(POST("/createPosition").and(accept(MediaType.APPLICATION_JSON)), handler::save) .andRoute(DELETE("/deletePosition/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteHandler.java index 349e9ddda..90564891b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteHandler.java @@ -49,7 +49,7 @@ public QuoteHandler(QuoteGenerator quoteGenerator) { public Mono hello(ServerRequest request) { return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromObject("Hello Spring!")); + .body(BodyInserters.fromValue("Hello Spring!")); } public Mono echo(ServerRequest request) { @@ -59,7 +59,7 @@ public Mono echo(ServerRequest request) { public Mono streamQuotes(ServerRequest request) { return ServerResponse.ok() - .contentType(MediaType.APPLICATION_STREAM_JSON) + .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(this.quoteStream, Quote.class); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteRouter.java index 286b55880..ed6eef7c9 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app73/QuoteRouter.java @@ -45,8 +45,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; @@ -65,7 +65,7 @@ public class QuoteRouter { responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(type = "string"))))), @RouterOperation(path = "/quotes", produces = APPLICATION_JSON_VALUE, operation = @Operation(operationId = "fetchQuotes", parameters = @Parameter(name = "size", in = ParameterIn.QUERY, schema = @Schema(type = "string")), responses = @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Quote.class)))))), - @RouterOperation(path = "/quotes", produces = APPLICATION_STREAM_JSON_VALUE, operation = @Operation(operationId = "fetchQuotes", + @RouterOperation(path = "/quotes", produces = APPLICATION_OCTET_STREAM_VALUE, operation = @Operation(operationId = "fetchQuotes", responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Quote.class))))) }) @Bean public RouterFunction route(QuoteHandler quoteHandler) { @@ -74,6 +74,6 @@ public RouterFunction route(QuoteHandler quoteHandler) { .andRoute(POST("/echo").and(accept(TEXT_PLAIN).and(contentType(TEXT_PLAIN))), quoteHandler::echo) .andRoute(POST("/echo").and(accept(APPLICATION_JSON).and(contentType(APPLICATION_JSON))), quoteHandler::echo) .andRoute(GET("/quotes").and(accept(APPLICATION_JSON)), quoteHandler::fetchQuotes) - .andRoute(GET("/quotes").and(accept(APPLICATION_STREAM_JSON)), quoteHandler::streamQuotes); + .andRoute(GET("/quotes").and(accept(APPLICATION_OCTET_STREAM)), quoteHandler::streamQuotes); } } \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app82/UserHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app82/UserHandler.java index 6622d3d7b..eb22af37f 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app82/UserHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app82/UserHandler.java @@ -34,7 +34,8 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromValue; + @Component public class UserHandler { @@ -71,7 +72,7 @@ public Mono getUser(ServerRequest request) { // build response return customerMono - .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(customer))) + .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(customer))) .switchIfEmpty(notFound); } @@ -98,7 +99,7 @@ public Mono putUser(ServerRequest request) { // build response return responseMono - .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(cust))); + .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(cust))); } /** @@ -113,7 +114,7 @@ public Mono deleteUser(ServerRequest request) { // build response return responseMono - .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromObject(strMono))); + .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromValue(strMono))); } } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PersonRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PersonRouter.java index 3545582ac..58e85e570 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PersonRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PersonRouter.java @@ -52,7 +52,7 @@ public RouterFunction personRoute(PersonHandler handler) { return route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().beanClass(PersonService.class).beanMethod("getAll")) - .and(route(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .and(route(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().beanClass(PersonService.class).beanMethod("getById"))) .and(route(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PositionRouter.java index dbe10abf1..620f5618b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app85/controller/PositionRouter.java @@ -57,7 +57,7 @@ public RouterFunction positionRoute(PositionHandler handler) { .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("findAll").description("Get all positions").tags(new String[] { "positions" }) .response(responseBuilder().responseCode("200").implementationArray(Position.class))) - .and(route(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .and(route(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("findById").description("Find all").tags(new String[] { "positions" }) .parameter(parameterBuilder().in(ParameterIn.PATH).name("id")) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteHandler.java index 9069a7769..bdabc3a39 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteHandler.java @@ -49,7 +49,7 @@ public QuoteHandler(QuoteGenerator quoteGenerator) { public Mono hello(ServerRequest request) { return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromObject("Hello Spring!")); + .body(BodyInserters.fromValue("Hello Spring!")); } public Mono echo(ServerRequest request) { @@ -59,7 +59,7 @@ public Mono echo(ServerRequest request) { public Mono streamQuotes(ServerRequest request) { return ServerResponse.ok() - .contentType(MediaType.APPLICATION_STREAM_JSON) + .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(this.quoteStream, Quote.class); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteRouter.java index 8ff7cc830..2f9c468ef 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app86/QuoteRouter.java @@ -39,7 +39,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; import static org.springdoc.core.utils.Constants.OPERATION_ATTRIBUTE; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RequestPredicates.POST; @@ -71,7 +71,7 @@ public RouterFunction myroute(QuoteHandler quoteHandler) { .parameter(parameterBuilder().in(ParameterIn.QUERY).name("size").implementation(String.class)) .response(responseBuilder().responseCode("200").implementationArray(Quote.class)))) - .and(route(GET("/quotes").and(accept(APPLICATION_STREAM_JSON)), quoteHandler::streamQuotes) + .and(route(GET("/quotes").and(accept(APPLICATION_OCTET_STREAM)), quoteHandler::streamQuotes) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("fetchQuotes") .response(responseBuilder().responseCode("200").implementation(Quote.class)))); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/position/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/position/PositionRouter.java index b25fcf8b4..91056e6a6 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/position/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/position/PositionRouter.java @@ -51,7 +51,7 @@ public RouterFunction positionRoute() { .operationId("findAll").description("Get all positions").tags(new String[] { "positions" }) .response(responseBuilder().responseCode("200").implementationArray(Position.class))).build() - .and(route().GET("/getPosition/{id}", accept(MediaType.APPLICATION_STREAM_JSON), HANDLER_FUNCTION, ops -> ops + .and(route().GET("/getPosition/{id}", accept(MediaType.APPLICATION_OCTET_STREAM), HANDLER_FUNCTION, ops -> ops .operationId("findById").description("Find all").tags(new String[] { "positions" }) .parameter(parameterBuilder().in(ParameterIn.PATH).name("id")) .response(responseBuilder().responseCode("200").implementation(Position.class))).build()) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/quotes/QuotesRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/quotes/QuotesRouter.java index a633d71ab..08b7ce2fd 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/quotes/QuotesRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app90/quotes/QuotesRouter.java @@ -42,7 +42,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.web.reactive.function.server.RequestPredicates.accept; import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; @@ -71,7 +71,7 @@ RouterFunction myroute() { .parameter(parameterBuilder().in(ParameterIn.QUERY).name("size").implementation(String.class)) .response(responseBuilder().responseCode("200").implementationArray(Quote.class))).build()) - .and(route().GET("/quotes", accept(APPLICATION_STREAM_JSON), HANDLER_FUNCTION, ops -> ops.tag("quotes") + .and(route().GET("/quotes", accept(APPLICATION_OCTET_STREAM), HANDLER_FUNCTION, ops -> ops.tag("quotes") .operationId("fetchQuotes") .response(responseBuilder().responseCode("200").implementation(Quote.class))).build()); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app153/DefaultWebFluxRegistrations.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app153/DefaultWebFluxRegistrations.java index cb2d856f6..b3ec6091b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app153/DefaultWebFluxRegistrations.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app153/DefaultWebFluxRegistrations.java @@ -26,7 +26,7 @@ package test.org.springdoc.api.v31.app153; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxRegistrations; +import org.springframework.boot.webflux.autoconfigure.WebFluxRegistrations; import org.springframework.stereotype.Component; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app69/UserHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app69/UserHandler.java index ca4588339..bd8f44555 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app69/UserHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app69/UserHandler.java @@ -34,7 +34,8 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromValue; + @Component public class UserHandler { @@ -71,7 +72,7 @@ public Mono getUser(ServerRequest request) { // build response return customerMono - .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(customer))) + .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(customer))) .switchIfEmpty(notFound); } @@ -98,7 +99,7 @@ public Mono putUser(ServerRequest request) { // build response return responseMono - .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(cust))); + .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(cust))); } /** @@ -113,7 +114,7 @@ public Mono deleteUser(ServerRequest request) { // build response return responseMono - .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromObject(strMono))); + .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromValue(strMono))); } } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PersonRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PersonRouter.java index 7b8d407e0..4cbe8d3da 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PersonRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PersonRouter.java @@ -54,7 +54,7 @@ public class PersonRouter { public RouterFunction personRoute(PersonHandler handler) { return RouterFunctions .route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) - .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) .andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PositionRouter.java index 939029d8d..b131206e8 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app72/controller/PositionRouter.java @@ -66,7 +66,7 @@ public class PositionRouter { public RouterFunction positionRoute(PositionHandler handler) { return RouterFunctions .route(GET("/getAllPositions").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) - .andRoute(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .andRoute(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .andRoute(POST("/createPosition").and(accept(MediaType.APPLICATION_JSON)), handler::save) .andRoute(DELETE("/deletePosition/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteHandler.java index d410a9cb2..a62a99b12 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteHandler.java @@ -49,7 +49,7 @@ public QuoteHandler(QuoteGenerator quoteGenerator) { public Mono hello(ServerRequest request) { return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromObject("Hello Spring!")); + .body(BodyInserters.fromValue("Hello Spring!")); } public Mono echo(ServerRequest request) { @@ -59,7 +59,7 @@ public Mono echo(ServerRequest request) { public Mono streamQuotes(ServerRequest request) { return ServerResponse.ok() - .contentType(MediaType.APPLICATION_STREAM_JSON) + .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(this.quoteStream, Quote.class); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteRouter.java index de9beed44..b0f88cd33 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app73/QuoteRouter.java @@ -45,8 +45,8 @@ import static org.springframework.http.MediaType.APPLICATION_JSON; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.http.MediaType.TEXT_PLAIN_VALUE; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; @@ -65,7 +65,7 @@ public class QuoteRouter { responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(type = "string"))))), @RouterOperation(path = "/quotes", produces = APPLICATION_JSON_VALUE, operation = @Operation(operationId = "fetchQuotes", parameters = @Parameter(name = "size", in = ParameterIn.QUERY, schema = @Schema(type = "string")), responses = @ApiResponse(responseCode = "200", content = @Content(array = @ArraySchema(schema = @Schema(implementation = Quote.class)))))), - @RouterOperation(path = "/quotes", produces = APPLICATION_STREAM_JSON_VALUE, operation = @Operation(operationId = "fetchQuotes", + @RouterOperation(path = "/quotes", produces = APPLICATION_OCTET_STREAM_VALUE, operation = @Operation(operationId = "fetchQuotes", responses = @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Quote.class))))) }) @Bean public RouterFunction route(QuoteHandler quoteHandler) { @@ -74,6 +74,6 @@ public RouterFunction route(QuoteHandler quoteHandler) { .andRoute(POST("/echo").and(accept(TEXT_PLAIN).and(contentType(TEXT_PLAIN))), quoteHandler::echo) .andRoute(POST("/echo").and(accept(APPLICATION_JSON).and(contentType(APPLICATION_JSON))), quoteHandler::echo) .andRoute(GET("/quotes").and(accept(APPLICATION_JSON)), quoteHandler::fetchQuotes) - .andRoute(GET("/quotes").and(accept(APPLICATION_STREAM_JSON)), quoteHandler::streamQuotes); + .andRoute(GET("/quotes").and(accept(APPLICATION_OCTET_STREAM)), quoteHandler::streamQuotes); } } \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app82/UserHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app82/UserHandler.java index 96bf5b6e4..14bfee17b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app82/UserHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app82/UserHandler.java @@ -34,7 +34,7 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; -import static org.springframework.web.reactive.function.BodyInserters.fromObject; +import static org.springframework.web.reactive.function.BodyInserters.fromValue; @Component public class UserHandler { @@ -71,7 +71,7 @@ public Mono getUser(ServerRequest request) { // build response return customerMono - .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(customer))) + .flatMap(customer -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(customer))) .switchIfEmpty(notFound); } @@ -98,7 +98,7 @@ public Mono putUser(ServerRequest request) { // build response return responseMono - .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(cust))); + .flatMap(cust -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromValue(cust))); } /** @@ -113,7 +113,7 @@ public Mono deleteUser(ServerRequest request) { // build response return responseMono - .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromObject(strMono))); + .flatMap(strMono -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(fromValue(strMono))); } } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PersonRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PersonRouter.java index b5a84e11f..b638b194f 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PersonRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PersonRouter.java @@ -52,7 +52,7 @@ public RouterFunction personRoute(PersonHandler handler) { return route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().beanClass(PersonService.class).beanMethod("getAll")) - .and(route(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .and(route(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().beanClass(PersonService.class).beanMethod("getById"))) .and(route(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PositionRouter.java index e8a89d3c5..798cfc27b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app85/controller/PositionRouter.java @@ -57,7 +57,7 @@ public RouterFunction positionRoute(PositionHandler handler) { .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("findAll").description("Get all positions").tags(new String[] { "positions" }) .response(responseBuilder().responseCode("200").implementationArray(Position.class))) - .and(route(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById) + .and(route(GET("/getPosition/{id}").and(accept(MediaType.APPLICATION_OCTET_STREAM)), handler::findById) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("findById").description("Find all").tags(new String[] { "positions" }) .parameter(parameterBuilder().in(ParameterIn.PATH).name("id")) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteHandler.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteHandler.java index 0a7c2103f..aca4fd27c 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteHandler.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteHandler.java @@ -49,7 +49,7 @@ public QuoteHandler(QuoteGenerator quoteGenerator) { public Mono hello(ServerRequest request) { return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN) - .body(BodyInserters.fromObject("Hello Spring!")); + .body(BodyInserters.fromValue("Hello Spring!")); } public Mono echo(ServerRequest request) { @@ -59,7 +59,7 @@ public Mono echo(ServerRequest request) { public Mono streamQuotes(ServerRequest request) { return ServerResponse.ok() - .contentType(MediaType.APPLICATION_STREAM_JSON) + .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(this.quoteStream, Quote.class); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteRouter.java index 39f9e2da9..fe1b17e42 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app86/QuoteRouter.java @@ -39,7 +39,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; import static org.springdoc.core.utils.Constants.OPERATION_ATTRIBUTE; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RequestPredicates.POST; @@ -71,7 +71,7 @@ public RouterFunction myroute(QuoteHandler quoteHandler) { .parameter(parameterBuilder().in(ParameterIn.QUERY).name("size").implementation(String.class)) .response(responseBuilder().responseCode("200").implementationArray(Quote.class)))) - .and(route(GET("/quotes").and(accept(APPLICATION_STREAM_JSON)), quoteHandler::streamQuotes) + .and(route(GET("/quotes").and(accept(APPLICATION_OCTET_STREAM)), quoteHandler::streamQuotes) .withAttribute(OPERATION_ATTRIBUTE, operationBuilder().operationId("fetchQuotes") .response(responseBuilder().responseCode("200").implementation(Quote.class)))); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/position/PositionRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/position/PositionRouter.java index 07661eabc..aa0f8d271 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/position/PositionRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/position/PositionRouter.java @@ -51,7 +51,7 @@ public RouterFunction positionRoute() { .operationId("findAll").description("Get all positions").tags(new String[] { "positions" }) .response(responseBuilder().responseCode("200").implementationArray(Position.class))).build() - .and(route().GET("/getPosition/{id}", accept(MediaType.APPLICATION_STREAM_JSON), HANDLER_FUNCTION, ops -> ops + .and(route().GET("/getPosition/{id}", accept(MediaType.APPLICATION_OCTET_STREAM), HANDLER_FUNCTION, ops -> ops .operationId("findById").description("Find all").tags(new String[] { "positions" }) .parameter(parameterBuilder().in(ParameterIn.PATH).name("id")) .response(responseBuilder().responseCode("200").implementation(Position.class))).build()) diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/quotes/QuotesRouter.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/quotes/QuotesRouter.java index 63f0b37b1..2200fc262 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/quotes/QuotesRouter.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app90/quotes/QuotesRouter.java @@ -42,7 +42,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuilder; import static org.springdoc.webflux.core.fn.SpringdocRouteBuilder.route; import static org.springframework.http.MediaType.APPLICATION_JSON; -import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM; import static org.springframework.http.MediaType.TEXT_PLAIN; import static org.springframework.web.reactive.function.server.RequestPredicates.accept; import static org.springframework.web.reactive.function.server.RequestPredicates.contentType; @@ -71,7 +71,7 @@ RouterFunction myroute() { .parameter(parameterBuilder().in(ParameterIn.QUERY).name("size").implementation(String.class)) .response(responseBuilder().responseCode("200").implementationArray(Quote.class))).build()) - .and(route().GET("/quotes", accept(APPLICATION_STREAM_JSON), HANDLER_FUNCTION, ops -> ops.tag("quotes") + .and(route().GET("/quotes", accept(APPLICATION_OCTET_STREAM), HANDLER_FUNCTION, ops -> ops.tag("quotes") .operationId("fetchQuotes") .response(responseBuilder().responseCode("200").implementation(Quote.class))).build()); } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app72.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app72.json index b1103c0b3..5483df7b4 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app72.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app72.json @@ -114,7 +114,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Person" } @@ -224,7 +224,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app73.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app73.json index 0e297ed56..215df4a12 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app73.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app73.json @@ -81,7 +81,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app85.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app85.json index b1103c0b3..5483df7b4 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app85.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app85.json @@ -114,7 +114,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Person" } @@ -224,7 +224,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app86.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app86.json index 0e297ed56..215df4a12 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app86.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app86.json @@ -81,7 +81,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app90.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app90.json index ec997c6c6..c9ab9032b 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app90.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app90.json @@ -420,7 +420,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } @@ -509,7 +509,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app72.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app72.json index 72f831696..652a1f1e8 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app72.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app72.json @@ -114,7 +114,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Person" } @@ -224,7 +224,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app73.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app73.json index 0b5640c8c..9bf3d8c30 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app73.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app73.json @@ -81,7 +81,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app85.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app85.json index 72f831696..652a1f1e8 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app85.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app85.json @@ -114,7 +114,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Person" } @@ -224,7 +224,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app86.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app86.json index 0b5640c8c..9bf3d8c30 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app86.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app86.json @@ -81,7 +81,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app90.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app90.json index 7716dca85..35edad18a 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app90.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app90.json @@ -420,7 +420,7 @@ "200": { "description": "OK", "content": { - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Position" } @@ -509,7 +509,7 @@ } } }, - "application/stream+json": { + "application/octet-stream": { "schema": { "$ref": "#/components/schemas/Quote" } diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index 705a48488..1194f54df 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webflux-ui ${project.artifactId} @@ -26,12 +26,17 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator-autoconfigure true - io.projectreactor.netty - reactor-netty-http + org.springframework.boot + spring-boot-reactor-netty + test + + + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java index 9a1618b3d..efeeb99e1 100644 --- a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java @@ -40,14 +40,14 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.web.reactive.WebFluxEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; diff --git a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerUiHome.java b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerUiHome.java index a8da09466..172f8480e 100644 --- a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerUiHome.java +++ b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerUiHome.java @@ -34,7 +34,7 @@ import reactor.core.publisher.Mono; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties; import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Controller; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java index a52f1db7e..f5e12c34d 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java @@ -26,9 +26,10 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.web.reactive.function.client.WebClient; + public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { protected WebClient webClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java index 1a16f01e3..51c000ef8 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java index 52172b241..c8a88bc31 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java index 71c9a4a82..c1d7902e1 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java @@ -33,7 +33,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java index 2f8949afb..bbff5133c 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java @@ -33,7 +33,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java index 9134b91df..ec0045029 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java @@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.boot.web.server.test.LocalServerPort; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocConfig.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocConfig.java index 65fb80b6b..86d7a3750 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocConfig.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocConfig.java @@ -6,7 +6,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties; +import org.springframework.boot.webflux.autoconfigure.WebFluxProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.server.reactive.ServerHttpRequest; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app4/SpringDocOauthPathsWithPropertyTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app4/SpringDocOauthPathsWithPropertyTest.java index e7766ed00..e6fe422fb 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app4/SpringDocOauthPathsWithPropertyTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app4/SpringDocOauthPathsWithPropertyTest.java @@ -24,8 +24,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.test.context.TestPropertySource; -import static org.hamcrest.CoreMatchers.equalTo; - @TestPropertySource(properties = "springdoc.swagger-ui.oauth2-redirect-url=http://localhost:8080/toto/test/swagger-ui/oauth2-redirect.html") public class SpringDocOauthPathsWithPropertyTest extends AbstractSpringDocTest { @@ -33,7 +31,7 @@ public class SpringDocOauthPathsWithPropertyTest extends AbstractSpringDocTest { void oauth2_redirect_url_calculated() throws Exception { webTestClient.get().uri("/v3/api-docs/swagger-config").exchange() .expectStatus().isOk().expectBody() - .jsonPath("oauth2RedirectUrl", equalTo("http://localhost:8080/toto/test/swagger-ui/oauth2-redirect.html")); + .jsonPath("oauth2RedirectUrl").isEqualTo("http://localhost:8080/toto/test/swagger-ui/oauth2-redirect.html"); } @SpringBootApplication diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index ca42e048b..0424f1e8e 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webmvc-api ${project.artifactId} @@ -15,13 +15,17 @@ ${project.version} - org.springframework - spring-webmvc + org.springframework.boot + spring-boot-webmvc + + + org.springframework.boot + spring-boot-web-server org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator-autoconfigure true @@ -29,14 +33,15 @@ jakarta.servlet-api provided + javax.money money-api test - org.hibernate.validator - hibernate-validator + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/MultipleOpenApiSupportConfiguration.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/MultipleOpenApiSupportConfiguration.java index 2401b00b3..848d55c85 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/MultipleOpenApiSupportConfiguration.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/MultipleOpenApiSupportConfiguration.java @@ -43,11 +43,11 @@ import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java index 388f8e160..a699e89ec 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java @@ -56,14 +56,14 @@ import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/ActuatorWebMvcProvider.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/ActuatorWebMvcProvider.java index a3eea69ef..6d3bdb0f4 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/ActuatorWebMvcProvider.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/ActuatorWebMvcProvider.java @@ -36,9 +36,9 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementServerProperties; -import org.springframework.boot.actuate.endpoint.web.servlet.ControllerEndpointHandlerMapping; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; -import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.boot.web.server.autoconfigure.ServerProperties; +import org.springframework.boot.webmvc.actuate.endpoint.web.ControllerEndpointHandlerMapping; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/RouterFunctionWebMvcProvider.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/RouterFunctionWebMvcProvider.java index 3fbf2182a..f660bff2b 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/RouterFunctionWebMvcProvider.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/RouterFunctionWebMvcProvider.java @@ -107,6 +107,11 @@ public void unknown(RouterFunction routerFunction) { // Not yet needed } + @Override + public void version(String version) { + // Not yet needed + } + @Override public void unknown(RequestPredicate predicate) { // Not yet needed diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java index 718b7ecfa..ddde62456 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java @@ -29,7 +29,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app169/DefaultWebMvcRegistrations.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app169/DefaultWebMvcRegistrations.java index bded61efe..1e4aac236 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app169/DefaultWebMvcRegistrations.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app169/DefaultWebMvcRegistrations.java @@ -24,7 +24,7 @@ package test.org.springdoc.api.v30.app169; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java index 5aa85f08a..44bc5c5b1 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java @@ -29,7 +29,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app231/ApplicationsRestController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app231/ApplicationsRestController.java index 36a3d9a3a..d96cbd7f1 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app231/ApplicationsRestController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app231/ApplicationsRestController.java @@ -1,9 +1,11 @@ package test.org.springdoc.api.v30.app231; +import java.util.HashMap; +import java.util.Map; + import io.swagger.v3.oas.annotations.Operation; import org.springdoc.core.annotations.ParameterObject; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Application; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -22,4 +24,52 @@ public Application createWithParameterObject( return new Application(); } + static class Application { + private String name = "unnamed_application"; + private String serviceName; + private String clusterName; + private String shardName; + private Map customTags = new HashMap(); + + public String getServiceName() { + return this.serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getClusterName() { + return this.clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getShardName() { + return this.shardName; + } + + public void setShardName(String shardName) { + this.shardName = shardName; + } + + public Map getCustomTags() { + return this.customTags; + } + + public void setCustomTags(Map customTags) { + this.customTags = customTags; + } + } + } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java index f91ea3d9b..7c2c3e379 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java @@ -31,7 +31,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; -import org.hibernate.validator.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java index 244f3905b..b86a7fb5b 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java @@ -29,7 +29,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app169/DefaultWebMvcRegistrations.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app169/DefaultWebMvcRegistrations.java index 0aee15fcd..8983db20d 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app169/DefaultWebMvcRegistrations.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app169/DefaultWebMvcRegistrations.java @@ -24,7 +24,7 @@ package test.org.springdoc.api.v31.app169; -import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; +import org.springframework.boot.webmvc.autoconfigure.WebMvcRegistrations; import org.springframework.stereotype.Component; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java index cf15f5a93..83b98c4a5 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java @@ -29,7 +29,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app231/ApplicationsRestController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app231/ApplicationsRestController.java index 021e5b2fe..8eae9e065 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app231/ApplicationsRestController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app231/ApplicationsRestController.java @@ -1,9 +1,11 @@ package test.org.springdoc.api.v31.app231; +import java.util.HashMap; +import java.util.Map; + import io.swagger.v3.oas.annotations.Operation; import org.springdoc.core.annotations.ParameterObject; -import org.springframework.boot.actuate.autoconfigure.wavefront.WavefrontProperties.Application; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -21,5 +23,55 @@ public Application createWithParameterObject( ) { return new Application(); } + + public static class Application { + private String name = "unnamed_application"; + private String serviceName; + private String clusterName; + private String shardName; + private Map customTags = new HashMap(); + + public String getServiceName() { + return this.serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public String getClusterName() { + return this.clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getShardName() { + return this.shardName; + } + + public void setShardName(String shardName) { + this.shardName = shardName; + } + + public Map getCustomTags() { + return this.customTags; + } + + public void setCustomTags(Map customTags) { + this.customTags = customTags; + } + } + + } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app241/OpenApiConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app241/OpenApiConfig.java index f60639c2c..aa94ddbed 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app241/OpenApiConfig.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app241/OpenApiConfig.java @@ -50,7 +50,6 @@ ServerBaseUrlCustomizer serverBaseUrlCustomizer() { @Override public String customize(final String serverBaseUrl, final HttpRequest request) { - // TODO Auto-generated method stub return null; } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java index 299b58067..b957625ee 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java @@ -31,7 +31,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; -import org.hibernate.validator.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json index 904951914..e38b026a6 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json @@ -69,37 +69,6 @@ } } } - }, - "/actuator/health": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'health'", - "operationId": "health", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json index 0b39821f1..d0d508dbe 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json @@ -89,37 +89,6 @@ } } } - }, - "/actuator/health": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'health'", - "operationId": "health", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app77.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app77.json index 93abd7f12..d2f2f207d 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app77.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app77.json @@ -11,18 +11,19 @@ } ], "paths": { - "/persons2": { + "/persons": { "get": { "tags": [ "hello-controller" ], - "operationId": "persons2", + "operationId": "persons", "parameters": [ { "name": "name", "in": "query", "required": true, "schema": { + "minLength": 1, "type": "string" } } @@ -42,18 +43,19 @@ } } }, - "/persons": { + "/persons2": { "get": { "tags": [ "hello-controller" ], - "operationId": "persons", + "operationId": "persons2", "parameters": [ { "name": "name", "in": "query", "required": true, "schema": { + "minLength": 1, "type": "string" } } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json index 394ce3f0d..3fafb1fc6 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json @@ -69,37 +69,6 @@ } } } - }, - "/actuator/health": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'health'", - "operationId": "health", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json index a5ca0bd5a..02623c8cd 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json @@ -89,37 +89,6 @@ } } } - }, - "/actuator/health": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'health'", - "operationId": "health", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app77.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app77.json index ba0083f4b..826bcaebf 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app77.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app77.json @@ -11,19 +11,20 @@ } ], "paths": { - "/persons2": { + "/persons": { "get": { "tags": [ "hello-controller" ], - "operationId": "persons2", + "operationId": "persons", "parameters": [ { "name": "name", "in": "query", "required": true, "schema": { - "type": "string" + "type": "string", + "minLength": 1 } } ], @@ -42,19 +43,20 @@ } } }, - "/persons": { + "/persons2": { "get": { "tags": [ "hello-controller" ], - "operationId": "persons", + "operationId": "persons2", "parameters": [ { "name": "name", "in": "query", "required": true, "schema": { - "type": "string" + "type": "string", + "minLength": 1 } } ], diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 55dd265d1..9d4aca623 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webmvc-ui ${project.artifactId} @@ -14,11 +14,6 @@ springdoc-openapi-starter-webmvc-api ${project.version} - - jakarta.servlet - jakarta.servlet-api - provided - org.webjars @@ -29,19 +24,24 @@ webjars-locator-lite - org.springframework.boot - spring-boot-starter-security - test + jakarta.servlet + jakarta.servlet-api + provided org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator-autoconfigure true - org.apache.tomcat.embed - tomcat-embed-core + org.springframework.boot + spring-boot-restclient + test + + + org.springframework.boot + spring-boot-tomcat test diff --git a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java index 4593187a0..b4203efa8 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java @@ -40,13 +40,13 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; -import org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java index 96a8a9545..3ca221909 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java @@ -28,8 +28,8 @@ import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.web.client.RestTemplate; public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/ExampleController.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/ExampleController.java deleted file mode 100644 index 654e8741d..000000000 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/ExampleController.java +++ /dev/null @@ -1,20 +0,0 @@ -package test.org.springdoc.ui.app11; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class ExampleController { - - @PostMapping("/post") - public ResponseEntity postExample() { - return ResponseEntity.ok("Successful post"); - } - - @GetMapping("/get") - public ResponseEntity getExample() { - return ResponseEntity.ok("Successful get"); - } -} diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/SpringDocCSRFTest.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/SpringDocCSRFTest.java deleted file mode 100644 index 7f039c044..000000000 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/SpringDocCSRFTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * - * * Copyright 2019-2020 the original author or authors. - * * - * * Licensed under the Apache License, Version 2.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * * - * * https://www.apache.org/licenses/LICENSE-2.0 - * * - * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package test.org.springdoc.ui.app11; - -import jakarta.servlet.http.Cookie; -import test.org.springdoc.ui.AbstractSpringDocTest; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MvcResult; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@TestPropertySource(properties = { - "springdoc.swagger-ui.csrf.enabled=true", - "springdoc.swagger-ui.csrf.cookie-name=XSRF-TOKEN", - "springdoc.swagger-ui.csrf.header-name=X-XSRF-TOKEN" -}) -public class SpringDocCSRFTest extends AbstractSpringDocTest { - - //@Test - public void testApp() throws Exception { - MvcResult mvcResult = mockMvc.perform(get("/swagger-ui.html")) - .andExpect(status().isFound()).andReturn(); - Cookie cookie = mvcResult.getResponse().getCookie("XSRF-TOKEN"); - mockMvc.perform(post("/post").header("X-XSRF-TOKEN", cookie.getValue()).cookie(cookie)) - .andExpect(status().isOk()); - } - - @SpringBootApplication - static class SpringDocTestApp {} - -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/WebSecurityConf.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/WebSecurityConf.java deleted file mode 100644 index bbde2db7d..000000000 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app11/WebSecurityConf.java +++ /dev/null @@ -1,23 +0,0 @@ -package test.org.springdoc.ui.app11; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.csrf.CookieCsrfTokenRepository; - -@EnableWebSecurity -@Configuration -public class WebSecurityConf { - - @Bean - public SecurityFilterChain filterChain1(HttpSecurity http) throws Exception { - http - .csrf(csrf -> csrf - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) - ); - return http.build(); - } - -} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 220d29ec5..8d0e2f1e3 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index dfd47900a..5e414319a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 @@ -19,18 +19,17 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-reactor-netty test - io.projectreactor.netty - reactor-netty-http + org.springframework.boot + spring-boot-starter-actuator test - io.netty - netty-resolver-dns-native-macos - osx-aarch_64 + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java index 2684acc75..28a5f6c36 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java @@ -28,7 +28,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocApp76Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocApp76Test.java index c7206c094..52b55d8ce 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocApp76Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocApp76Test.java @@ -39,7 +39,7 @@ public class SpringDocApp76Test extends AbstractSpringDocTest { protected void testApp() { webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/actuator").exchange().expectStatus().isOk().expectBody() .jsonPath("$.openapi").isEqualTo("3.0.1") - .jsonPath("$.paths./actuator/health.get.operationId").exists(); + .jsonPath("$.paths./actuator.get.operationId").exists(); } } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java index ce3b20223..9f96d7936 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java @@ -32,11 +32,11 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server.NettyReactiveManagementContextAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; @@ -47,7 +47,7 @@ InfoEndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class, WebFluxEndpointManagementContextConfiguration.class, - ReactiveManagementContextAutoConfiguration.class }) + NettyReactiveManagementContextAutoConfiguration.class }) @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v30.app76" }) public class SpringDocTestApp { diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java index bca2f653a..10d8ad439 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java @@ -28,7 +28,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocApp76Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocApp76Test.java index ee3ed0054..5c22e4678 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocApp76Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocApp76Test.java @@ -39,7 +39,7 @@ public class SpringDocApp76Test extends AbstractSpringDocTest { protected void testApp() { webTestClient.get().uri(Constants.DEFAULT_API_DOCS_URL + "/actuator").exchange().expectStatus().isOk().expectBody() .jsonPath("$.openapi").isEqualTo("3.1.0") - .jsonPath("$.paths./actuator/health.get.operationId").exists(); + .jsonPath("$.paths./actuator.get.operationId").exists(); } } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java index e3c869246..9dda7255c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java @@ -32,11 +32,11 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.endpoint.web.reactive.WebFluxEndpointManagementContextConfiguration; import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.web.reactive.ReactiveManagementContextAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server.NettyReactiveManagementContextAutoConfiguration; +import org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Import; @@ -47,7 +47,7 @@ InfoEndpointAutoConfiguration.class, HealthEndpointAutoConfiguration.class, WebFluxEndpointManagementContextConfiguration.class, - ReactiveManagementContextAutoConfiguration.class }) + NettyReactiveManagementContextAutoConfiguration.class }) @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app76" }) public class SpringDocTestApp { diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-1.json index 7b041b75a..9f7d3400d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-1.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-1.json index 63f747bca..defa8dc0f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-1.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-2.json index 63f747bca..defa8dc0f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app147-2.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app148-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app148-2.json index bc0a211d0..8decb67c4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app148-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app148-2.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json index 962339da3..5e00105ad 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json @@ -713,132 +713,6 @@ } } }, - "/actuator/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/actuator/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/actuator/beans": { "get": { "tags": [ @@ -935,4 +809,4 @@ } } } -} \ No newline at end of file +} diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-1.json index c8d3ea0cc..ae7243557 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-1.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-1.json index 9a9d79015..3d5e6fea3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-1.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-2.json index 9a9d79015..3d5e6fea3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app147-2.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app148-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app148-2.json index 84c6cc722..9d8005232 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app148-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app148-2.json @@ -666,132 +666,6 @@ } } }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json index d1e373988..5293fc60a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json @@ -713,132 +713,6 @@ } } }, - "/actuator/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, - "/actuator/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, "/actuator/beans": { "get": { "tags": [ @@ -935,4 +809,4 @@ } } } -} \ No newline at end of file +} diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 7f37df7e3..80067c67e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 @@ -23,8 +23,13 @@ test - org.apache.tomcat.embed - tomcat-embed-core + org.springframework.boot + spring-boot-restclient + test + + + org.springframework.boot + spring-boot-tomcat test diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java index f2303a4b1..1d2774164 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java @@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestTemplate; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app128/SpringDocApp128Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app128/SpringDocApp128Test.java index bddef855f..a95d3b9e4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app128/SpringDocApp128Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app128/SpringDocApp128Test.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v30.AbstractSpringDocTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.webmvc.autoconfigure.error.BasicErrorController; import org.springframework.test.context.TestPropertySource; import static org.hamcrest.Matchers.containsString; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app68/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app68/api/ExceptionTranslator.java index 13beef4db..b8e899f84 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app68/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app68/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java index cfbce68e3..84944977d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java @@ -31,8 +31,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.web.server.LocalManagementPort; -import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.restclient.RestTemplateBuilder; +import org.springframework.boot.web.server.test.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestTemplate; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app128/SpringDocApp128Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app128/SpringDocApp128Test.java index 2f557333c..b50f2893b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app128/SpringDocApp128Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app128/SpringDocApp128Test.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v31.AbstractSpringDocTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController; +import org.springframework.boot.webmvc.autoconfigure.error.BasicErrorController; import org.springframework.test.context.TestPropertySource; import static org.hamcrest.Matchers.containsString; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app68/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app68/api/ExceptionTranslator.java index dc4b5c297..d6a728da3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app68/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app68/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app147-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app147-1.json index a5bd4f9dd..a07783d02 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app147-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app147-1.json @@ -715,132 +715,6 @@ } } }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app148-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app148-2.json index a239113a6..8bcdfd27d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app148-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app148-2.json @@ -715,132 +715,6 @@ } } }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app186.json index f585b1519..b9ba332ef 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app186.json @@ -715,132 +715,6 @@ } } }, - "/actuator/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/actuator/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/actuator/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app187.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app187.json index 570e9ddce..ea02605e5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app187.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.0.1/app187.json @@ -706,132 +706,6 @@ } } }, - "/actuator/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/actuator/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/actuator/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app147-1.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app147-1.json index 7ecc6396b..ff32a5898 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app147-1.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app147-1.json @@ -715,132 +715,6 @@ } } }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app148-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app148-2.json index 8681210a7..1fce7401e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app148-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app148-2.json @@ -715,132 +715,6 @@ } } }, - "/application/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/application/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/application/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app186.json index 18314bb45..42bb8f4e1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/resources/results/3.1.0/app186.json @@ -715,132 +715,6 @@ } } }, - "/actuator/caches": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "caches", - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches'", - "operationId": "clearCaches", - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/actuator/caches/{cache}": { - "get": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "cache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "OK", - "content": { - "application/vnd.spring-boot.actuator.v3+json": { - "schema": { - "type": "object" - } - }, - "application/vnd.spring-boot.actuator.v2+json": { - "schema": { - "type": "object" - } - }, - "application/json": { - "schema": { - "type": "object" - } - } - } - }, - "404": { - "description": "Not Found" - } - } - }, - "delete": { - "tags": [ - "Actuator" - ], - "summary": "Actuator web endpoint 'caches-cache'", - "operationId": "clearCache", - "parameters": [ - { - "name": "cache", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "cacheManager", - "in": "query", - "schema": { - "type": "string" - } - } - ], - "responses": { - "204": { - "description": "No Content" - }, - "404": { - "description": "Not Found" - } - } - } - }, "/actuator/beans": { "get": { "tags": [ diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index ed2690d7e..6bea4a004 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,32 +2,37 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-data-rest-tests ${project.artifactId} + + org.springdoc + springdoc-openapi-starter-webmvc-api + ${project.version} + test + org.springframework.boot spring-boot-starter-data-rest test - com.querydsl - querydsl-core + org.springframework.boot + spring-boot-starter-hateoas test - org.springdoc - springdoc-openapi-starter-webmvc-api - ${project.version} + com.querydsl + querydsl-core test org.springframework.boot - spring-boot-starter-data-jpa + spring-boot-data-jpa test @@ -35,11 +40,6 @@ h2 test - - org.projectlombok - lombok - test - diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java index 44c5b47e3..7b1910299 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java @@ -37,7 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/ChildProperty.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/ChildProperty.java index 94b76dfb0..4c152e047 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/ChildProperty.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/ChildProperty.java @@ -30,11 +30,9 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Data; @Entity -public @Data -class ChildProperty { +public class ChildProperty { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/Property.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/Property.java index ebf39429f..e811710d4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/Property.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app17/Property.java @@ -32,11 +32,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import lombok.Data; @Entity -public @Data -class Property { +public class Property { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app19/Application.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app19/Application.java index 1be0fddf6..a861850e9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app19/Application.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app19/Application.java @@ -38,12 +38,10 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; -import lombok.Data; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -@Data @Entity @Table(schema = "application", name = "application") @Schema(description = "app") @@ -103,4 +101,76 @@ public enum AppType { INNER, EXTERNAL } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public AppType getType() { + return type; + } + + public void setType(AppType type) { + this.type = type; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public AuditStatus getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(AuditStatus auditStatus) { + this.auditStatus = auditStatus; + } + + public LocalDateTime getAuditTime() { + return auditTime; + } + + public void setAuditTime(LocalDateTime auditTime) { + this.auditTime = auditTime; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Clinic.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Clinic.java index 016869bc1..c6531be7d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Clinic.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Clinic.java @@ -32,18 +32,8 @@ import jakarta.persistence.Id; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = false) -@Builder public class Clinic { @Id @@ -54,4 +44,28 @@ public class Clinic { @NotBlank private String name; + public Clinic(Long id, String name) { + this.id = id; + this.name = name; + } + + public Clinic() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Doctor.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Doctor.java index 028a67ab9..41d1d2796 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Doctor.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app23/Doctor.java @@ -37,18 +37,8 @@ import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = false) -@Builder public class Doctor { @Id @@ -63,4 +53,29 @@ public class Doctor { accessMode = AccessMode.WRITE_ONLY )) private Set clinics; + + public Doctor(Long id, Set clinics) { + this.id = id; + this.clinics = clinics; + } + + public Doctor() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getClinics() { + return clinics; + } + + public void setClinics(Set clinics) { + this.clinics = clinics; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/TesteResource.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/TesteResource.java index e1754726f..585291213 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/TesteResource.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/TesteResource.java @@ -27,7 +27,6 @@ package test.org.springdoc.api.v30.app24; import com.querydsl.core.types.Predicate; -import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -37,7 +36,6 @@ @RestController -@AllArgsConstructor public class TesteResource { @GetMapping("/") diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/User.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/User.java index 549d2e385..194b87dfb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/User.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app24/User.java @@ -30,12 +30,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Getter; -import lombok.Setter; @Entity -@Getter -@Setter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -46,5 +42,37 @@ public class User { private String lastName; private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Address.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Address.java index f6b945f40..5eebc7dac 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Address.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Address.java @@ -27,16 +27,8 @@ package test.org.springdoc.api.v30.app25.model; import jakarta.persistence.Embeddable; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; @Embeddable -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Address { private String name; @@ -51,4 +43,63 @@ public class Address { private String country; + public Address(String name, String street, String number, String zipcode, String city, String country) { + this.name = name; + this.street = street; + this.number = number; + this.zipcode = zipcode; + this.city = city; + this.country = country; + } + + public Address() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getZipcode() { + return zipcode; + } + + public void setZipcode(String zipcode) { + this.zipcode = zipcode; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/BaseEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/BaseEntity.java index d948ad680..0f924aa77 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/BaseEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/BaseEntity.java @@ -31,15 +31,9 @@ import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.PrePersist; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; -@Getter -@Setter -@NoArgsConstructor @MappedSuperclass public abstract class BaseEntity { @@ -53,4 +47,15 @@ private void generateId() { id = UUID.randomUUID(); } + public BaseEntity(UUID id) { + this.id = id; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Cat.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Cat.java index ba227f7a9..8839d874d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Cat.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Cat.java @@ -29,26 +29,26 @@ import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Cat extends Pet { @Enumerated(EnumType.STRING) private CoatType coat; - @Builder - public Cat(String name, Owner owner, CoatType coat) { - super(name, owner); + public Cat(CoatType coat) { + this.coat = coat; + } + + public Cat() { + super(); + } + + public CoatType getCoat() { + return coat; + } + + public void setCoat(CoatType coat) { this.coat = coat; } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Clinic.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Clinic.java index eae015c35..3312211dc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Clinic.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Clinic.java @@ -27,23 +27,14 @@ package test.org.springdoc.api.v30.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Clinic extends BaseEntity { @NotNull @@ -53,4 +44,33 @@ public class Clinic extends BaseEntity { @ElementCollection private Set
addresses; + public Clinic(UUID id) { + super(id); + } + + public Clinic(UUID id, String name, Set
addresses) { + super(id); + this.name = name; + this.addresses = addresses; + } + + public Clinic() { + super(UUID.randomUUID()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set
getAddresses() { + return addresses; + } + + public void setAddresses(Set
addresses) { + this.addresses = addresses; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Doctor.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Doctor.java index 0c8f7e8ac..0d4a6833c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Doctor.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Doctor.java @@ -27,6 +27,7 @@ package test.org.springdoc.api.v30.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -34,18 +35,8 @@ import jakarta.persistence.ManyToMany; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Doctor extends BaseEntity { @NotNull @@ -61,4 +52,47 @@ public class Doctor extends BaseEntity { @ManyToMany private Set clinics; + public Doctor(String firstname, String lastname, Specialty specialty, Set clinics) { + super(UUID.randomUUID()); + this.firstname = firstname; + this.lastname = lastname; + this.specialty = specialty; + this.clinics = clinics; + } + + public Doctor() { + super(UUID.randomUUID()); + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public Specialty getSpecialty() { + return specialty; + } + + public void setSpecialty(Specialty specialty) { + this.specialty = specialty; + } + + public Set getClinics() { + return clinics; + } + + public void setClinics(Set clinics) { + this.clinics = clinics; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Dog.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Dog.java index c80eeb000..b0447ce01 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Dog.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Dog.java @@ -26,33 +26,39 @@ package test.org.springdoc.api.v30.app25.model; +import java.util.UUID; + import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@AllArgsConstructor -@NoArgsConstructor public class Dog extends Pet { @Enumerated(EnumType.STRING) private CoatType coat; - @Builder - public Dog(String name, Owner owner, CoatType coat) { - super(name, owner); + public Dog(UUID id, CoatType coat) { + super(id); this.coat = coat; } + public Dog(CoatType coat) { + this.coat = coat; + } + + public Dog() { + } + public static enum CoatType { SMOOTH, SHORT, COMBINATION, DOUBLE, HEAVY, SILKY, LONG, CURLY, WIRE, HAIRLESS } + public CoatType getCoat() { + return coat; + } + + public void setCoat(CoatType coat) { + this.coat = coat; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Owner.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Owner.java index 6b1089837..32b2592b2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Owner.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Owner.java @@ -27,24 +27,15 @@ package test.org.springdoc.api.v30.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.CascadeType; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.OneToMany; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Owner extends BaseEntity { private String firstname; @@ -56,8 +47,54 @@ public class Owner extends BaseEntity { @Embedded private Address addresses; - @EqualsAndHashCode.Exclude @OneToMany(mappedBy = "owner", cascade = { CascadeType.ALL }) private Set pets; + public Owner(UUID id) { + super(id); + } + + public Owner(UUID id, String firstname, String lastname, Address addresses, Set pets) { + super(id); + this.firstname = firstname; + this.lastname = lastname; + this.addresses = addresses; + this.pets = pets; + } + + public Owner() { + super(UUID.randomUUID()); + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public Address getAddresses() { + return addresses; + } + + public void setAddresses(Address addresses) { + this.addresses = addresses; + } + + public Set getPets() { + return pets; + } + + public void setPets(Set pets) { + this.pets = pets; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Pet.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Pet.java index df7035602..4fab042f2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Pet.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app25/model/Pet.java @@ -26,6 +26,8 @@ package test.org.springdoc.api.v30.app25.model; +import java.util.UUID; + import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -34,21 +36,9 @@ import jakarta.persistence.InheritanceType; import jakarta.persistence.ManyToOne; import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; @Entity - -@EqualsAndHashCode(callSuper = false) @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) - -@Data -@NoArgsConstructor -@RequiredArgsConstructor - @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, @@ -59,12 +49,33 @@ }) public class Pet extends BaseEntity { - @NonNull @NotNull private String name; - @NonNull @ManyToOne private Owner owner; + public Pet(UUID id) { + super(id); + } + + public Pet() { + super(UUID.randomUUID()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Owner getOwner() { + return owner; + } + + public void setOwner(Owner owner) { + this.owner = owner; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app30/User.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app30/User.java index 02e35cf5f..956977b67 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app30/User.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app30/User.java @@ -31,12 +31,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Getter; -import lombok.Setter; @Entity -@Getter -@Setter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -47,4 +43,36 @@ public class User { private String lastName; private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java index 322bf51c2..3367c8c72 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java @@ -37,7 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/ChildProperty.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/ChildProperty.java index 7e5af8686..ff065fd13 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/ChildProperty.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/ChildProperty.java @@ -31,11 +31,9 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Data; @Entity -public @Data -class ChildProperty { +public class ChildProperty { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -58,4 +56,6 @@ public String getName() { public void setName(String name) { this.name = name; } + + } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/Property.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/Property.java index 55243b180..15ac04bc9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/Property.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app35/Property.java @@ -33,11 +33,10 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import lombok.Data; + @Entity -public @Data -class Property { +public class Property { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/BaseEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/BaseEntity.java index d9a105654..d87c2e14f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/BaseEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/BaseEntity.java @@ -33,9 +33,6 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; @@ -43,12 +40,9 @@ * @author bnasslahsen */ -@Data @MappedSuperclass -@DynamicInsert(true) -@DynamicUpdate(true) -@SuperBuilder(toBuilder = true) -@NoArgsConstructor +@DynamicInsert +@DynamicUpdate public abstract class BaseEntity implements Serializable { /** @@ -71,4 +65,19 @@ public abstract class BaseEntity implements Serializable { * @return 是否合法 */ public abstract boolean isValid(); + + public BaseEntity(Long id) { + this.id = id; + } + + public BaseEntity() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/ProductEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/ProductEntity.java index 22d21545a..028cd95e9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/ProductEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app37/ProductEntity.java @@ -33,25 +33,13 @@ import jakarta.persistence.Entity; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; -import lombok.experimental.SuperBuilder; /** * @author bnasslahsen */ -@Getter -@Setter -@ToString(callSuper = true) -@EqualsAndHashCode(callSuper = false) @Entity @Table(name = "PRODUCT_ENTITY") -@SuperBuilder(toBuilder = true) -@NoArgsConstructor public class ProductEntity extends BaseEntity implements Comparable { /** @@ -85,6 +73,30 @@ public boolean isValid() { return name != null && price != null && date != null; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + /** * 根据日期排序 */ diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app4/Employee.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app4/Employee.java index 1e2289fb1..9b4955301 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app4/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app4/Employee.java @@ -28,27 +28,9 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +43,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +63,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app6/Employee.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app6/Employee.java index 86b9fd876..2d651d334 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app6/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app6/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/dto/DemoComponentDto.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/dto/DemoComponentDto.java index 67fb6183c..b4f8b49d6 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/dto/DemoComponentDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/dto/DemoComponentDto.java @@ -27,17 +27,9 @@ package test.org.springdoc.api.v30.app9.component.dto; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; import org.springframework.hateoas.server.core.Relation; -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor @Relation(collectionRelation = "components") @Schema(description = "A demo component to illustrate Springdoc Issue #401") public final class DemoComponentDto { @@ -48,4 +40,56 @@ public final class DemoComponentDto { @Schema(description = "Some dummy payload", example = "Hello World") private String payload; + public DemoComponentDto(String id, String payload) { + this.id = id; + this.payload = payload; + } + + private DemoComponentDto(Builder builder) { + setId(builder.id); + setPayload(builder.payload); + } + + public static Builder builder() { + return new Builder(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public static final class Builder { + private String id; + + private String payload; + + private Builder() { + } + + public Builder id(String val) { + id = val; + return this; + } + + public Builder payload(String val) { + payload = val; + return this; + } + + public DemoComponentDto build() { + return new DemoComponentDto(this); + } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/model/DemoComponent.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/model/DemoComponent.java index 04c0409ca..7b34937a1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/model/DemoComponent.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/model/DemoComponent.java @@ -26,17 +26,9 @@ package test.org.springdoc.api.v30.app9.component.model; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; import org.springframework.data.annotation.Id; -@Data -@Builder -@AllArgsConstructor -@EqualsAndHashCode public class DemoComponent { @Id @@ -44,4 +36,52 @@ public class DemoComponent { private String payload; + public DemoComponent(String id, String payload) { + this.id = id; + this.payload = payload; + } + + private DemoComponent(Builder builder) { + setId(builder.id); + setPayload(builder.payload); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public static final class Builder { + private String id; + + private String payload; + + public Builder() { + } + + public Builder id(String val) { + id = val; + return this; + } + + public Builder payload(String val) { + payload = val; + return this; + } + + public DemoComponent build() { + return new DemoComponent(this); + } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/service/ComponentsService.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/service/ComponentsService.java index 97f454e41..cf024e8de 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/service/ComponentsService.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/component/service/ComponentsService.java @@ -32,6 +32,7 @@ import java.util.Optional; import test.org.springdoc.api.v30.app9.component.model.DemoComponent; +import test.org.springdoc.api.v30.app9.component.model.DemoComponent.Builder; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -41,7 +42,9 @@ @Service public class ComponentsService { - private static final Map repo = Collections.singletonMap("1", DemoComponent.builder().id("1").payload("Hello World !").build()); + private static final Map repo = Collections.singletonMap("1", + + new Builder().id("1").payload("Hello World !").build()); public Optional findById(String componentId) { return Optional.ofNullable(repo.get(componentId)); diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/core/model/ExceptionDto.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/core/model/ExceptionDto.java index 1d2c09840..ecf907bc8 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/core/model/ExceptionDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app9/core/model/ExceptionDto.java @@ -31,13 +31,9 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.NonNull; -@Data public class ExceptionDto { - @NonNull @NotNull @NotEmpty @Schema(description = "The date and time the problem occured", example = "2020-02-04T13:21:08.098+0000", type = "string", format = "date-time") @@ -49,4 +45,27 @@ public class ExceptionDto { @Schema(description = "The exception message", example = "Trying to update a non existing component !") private String message; + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public String getException() { + return exception; + } + + public void setException(String exception) { + this.exception = exception; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java index 2fb855d3c..c3a0894f1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java @@ -37,7 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/ChildProperty.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/ChildProperty.java index e56bdb619..eef4ed09d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/ChildProperty.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/ChildProperty.java @@ -30,11 +30,9 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Data; @Entity -public @Data -class ChildProperty { +public class ChildProperty { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/Property.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/Property.java index 2f43f19b9..d90b4a399 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/Property.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app17/Property.java @@ -32,11 +32,9 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import lombok.Data; @Entity -public @Data -class Property { +public class Property { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app19/Application.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app19/Application.java index 9c75f4d81..7cfb25293 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app19/Application.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app19/Application.java @@ -38,12 +38,10 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; -import lombok.Data; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -@Data @Entity @Table(schema = "application", name = "application") @Schema(description = "app") @@ -103,4 +101,76 @@ public enum AppType { INNER, EXTERNAL } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public AppType getType() { + return type; + } + + public void setType(AppType type) { + this.type = type; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public String getPublicKey() { + return publicKey; + } + + public void setPublicKey(String publicKey) { + this.publicKey = publicKey; + } + + public AuditStatus getAuditStatus() { + return auditStatus; + } + + public void setAuditStatus(AuditStatus auditStatus) { + this.auditStatus = auditStatus; + } + + public LocalDateTime getAuditTime() { + return auditTime; + } + + public void setAuditTime(LocalDateTime auditTime) { + this.auditTime = auditTime; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Clinic.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Clinic.java index 03fc86df5..b095f3ca7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Clinic.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Clinic.java @@ -32,18 +32,8 @@ import jakarta.persistence.Id; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = false) -@Builder public class Clinic { @Id @@ -54,4 +44,28 @@ public class Clinic { @NotBlank private String name; + public Clinic(Long id, String name) { + this.id = id; + this.name = name; + } + + public Clinic() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Doctor.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Doctor.java index b3ee601ea..4160bc449 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Doctor.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app23/Doctor.java @@ -26,6 +26,7 @@ package test.org.springdoc.api.v31.app23; + import java.util.Set; import io.swagger.v3.oas.annotations.media.ArraySchema; @@ -37,18 +38,8 @@ import jakarta.persistence.Id; import jakarta.persistence.ManyToMany; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor -@EqualsAndHashCode(callSuper = false) -@Builder public class Doctor { @Id @@ -63,4 +54,25 @@ public class Doctor { accessMode = AccessMode.WRITE_ONLY )) private Set clinics; + + + public Doctor() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getClinics() { + return clinics; + } + + public void setClinics(Set clinics) { + this.clinics = clinics; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/TesteResource.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/TesteResource.java index f5a41ba34..0c3b1c80f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/TesteResource.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/TesteResource.java @@ -27,7 +27,6 @@ package test.org.springdoc.api.v31.app24; import com.querydsl.core.types.Predicate; -import lombok.AllArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -37,7 +36,6 @@ @RestController -@AllArgsConstructor public class TesteResource { @GetMapping("/") diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/User.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/User.java index f79cf1c0f..e18ee8d2a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/User.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app24/User.java @@ -30,12 +30,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Getter; -import lombok.Setter; @Entity -@Getter -@Setter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -46,5 +42,36 @@ public class User { private String lastName; private String email; -} + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Address.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Address.java index add6071b6..7587b4864 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Address.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Address.java @@ -27,16 +27,8 @@ package test.org.springdoc.api.v31.app25.model; import jakarta.persistence.Embeddable; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; @Embeddable -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Address { private String name; @@ -51,4 +43,51 @@ public class Address { private String country; + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public String getZipcode() { + return zipcode; + } + + public void setZipcode(String zipcode) { + this.zipcode = zipcode; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/BaseEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/BaseEntity.java index f0b00557a..f5426664b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/BaseEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/BaseEntity.java @@ -26,20 +26,15 @@ package test.org.springdoc.api.v31.app25.model; + import java.util.UUID; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.PrePersist; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; -@Getter -@Setter -@NoArgsConstructor @MappedSuperclass public abstract class BaseEntity { @@ -53,4 +48,15 @@ private void generateId() { id = UUID.randomUUID(); } + public BaseEntity(UUID id) { + this.id = id; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Cat.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Cat.java index 219d47945..703b69034 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Cat.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Cat.java @@ -29,26 +29,26 @@ import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Cat extends Pet { @Enumerated(EnumType.STRING) - private CoatType coat; + private Cat.CoatType coat; - @Builder - public Cat(String name, Owner owner, CoatType coat) { - super(name, owner); + public Cat(Cat.CoatType coat) { + this.coat = coat; + } + + public Cat() { + super(); + } + + public CoatType getCoat() { + return coat; + } + + public void setCoat(CoatType coat) { this.coat = coat; } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Clinic.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Clinic.java index ca0129e97..c2b70f9bc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Clinic.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Clinic.java @@ -27,23 +27,14 @@ package test.org.springdoc.api.v31.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.ElementCollection; import jakarta.persistence.Entity; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Clinic extends BaseEntity { @NotNull @@ -53,4 +44,33 @@ public class Clinic extends BaseEntity { @ElementCollection private Set
addresses; -} + public Clinic(UUID id) { + super(id); + } + + public Clinic(UUID id, String name, Set
addresses) { + super(id); + this.name = name; + this.addresses = addresses; + } + + public Clinic() { + super(UUID.randomUUID()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set
getAddresses() { + return addresses; + } + + public void setAddresses(Set
addresses) { + this.addresses = addresses; + } +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Doctor.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Doctor.java index 85b1c748f..6c36d0d62 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Doctor.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Doctor.java @@ -27,6 +27,7 @@ package test.org.springdoc.api.v31.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -34,18 +35,9 @@ import jakarta.persistence.ManyToMany; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; + @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Doctor extends BaseEntity { @NotNull @@ -61,4 +53,47 @@ public class Doctor extends BaseEntity { @ManyToMany private Set clinics; + public Doctor(String firstname, String lastname, Specialty specialty, Set clinics) { + super(UUID.randomUUID()); + this.firstname = firstname; + this.lastname = lastname; + this.specialty = specialty; + this.clinics = clinics; + } + + public Doctor() { + super(UUID.randomUUID()); + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public Specialty getSpecialty() { + return specialty; + } + + public void setSpecialty(Specialty specialty) { + this.specialty = specialty; + } + + public Set getClinics() { + return clinics; + } + + public void setClinics(Set clinics) { + this.clinics = clinics; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Dog.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Dog.java index aaf6ecc60..9d8c5781c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Dog.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Dog.java @@ -29,28 +29,24 @@ import jakarta.persistence.Entity; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@AllArgsConstructor -@NoArgsConstructor public class Dog extends Pet { @Enumerated(EnumType.STRING) - private CoatType coat; + private Dog.CoatType coat; - @Builder - public Dog(String name, Owner owner, CoatType coat) { - super(name, owner); + public CoatType getCoat() { + return coat; + } + + public void setCoat(CoatType coat) { this.coat = coat; } + public Dog() { + } + public static enum CoatType { SMOOTH, SHORT, COMBINATION, DOUBLE, HEAVY, SILKY, LONG, CURLY, WIRE, HAIRLESS } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Owner.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Owner.java index fe3a81605..c7aa3231a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Owner.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Owner.java @@ -27,24 +27,16 @@ package test.org.springdoc.api.v31.app25.model; import java.util.Set; +import java.util.UUID; import jakarta.persistence.CascadeType; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; import jakarta.persistence.OneToMany; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; + @Entity -@Data -@EqualsAndHashCode(callSuper = false) -@Builder -@AllArgsConstructor -@NoArgsConstructor public class Owner extends BaseEntity { private String firstname; @@ -56,8 +48,46 @@ public class Owner extends BaseEntity { @Embedded private Address addresses; - @EqualsAndHashCode.Exclude @OneToMany(mappedBy = "owner", cascade = { CascadeType.ALL }) private Set pets; + public Owner(UUID id) { + super(id); + } + + public Owner() { + super(UUID.randomUUID()); + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public Address getAddresses() { + return addresses; + } + + public void setAddresses(Address addresses) { + this.addresses = addresses; + } + + public Set getPets() { + return pets; + } + + public void setPets(Set pets) { + this.pets = pets; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Pet.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Pet.java index d3c1ac5c6..5981e6c3e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Pet.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app25/model/Pet.java @@ -26,6 +26,8 @@ package test.org.springdoc.api.v31.app25.model; +import java.util.UUID; + import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonSubTypes.Type; import com.fasterxml.jackson.annotation.JsonTypeInfo; @@ -34,21 +36,9 @@ import jakarta.persistence.InheritanceType; import jakarta.persistence.ManyToOne; import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.RequiredArgsConstructor; @Entity - -@EqualsAndHashCode(callSuper = false) @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) - -@Data -@NoArgsConstructor -@RequiredArgsConstructor - @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, @@ -59,12 +49,33 @@ }) public class Pet extends BaseEntity { - @NonNull @NotNull private String name; - @NonNull @ManyToOne private Owner owner; + public Pet(UUID id) { + super(id); + } + + public Pet() { + super(UUID.randomUUID()); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Owner getOwner() { + return owner; + } + + public void setOwner(Owner owner) { + this.owner = owner; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app30/User.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app30/User.java index 549e2153c..2a97bf0c6 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app30/User.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app30/User.java @@ -31,12 +31,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Getter; -import lombok.Setter; @Entity -@Getter -@Setter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -47,4 +43,36 @@ public class User { private String lastName; private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java index 1d59b71a7..2fa66d651 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java @@ -37,7 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/ChildProperty.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/ChildProperty.java index 04d00788a..e4d61b1e1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/ChildProperty.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/ChildProperty.java @@ -31,11 +31,9 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import lombok.Data; @Entity -public @Data -class ChildProperty { +public class ChildProperty { @Id @GeneratedValue(strategy = GenerationType.AUTO) diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/Property.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/Property.java index 850825f12..75d6b1ed3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/Property.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app35/Property.java @@ -33,11 +33,10 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import lombok.Data; + @Entity -public @Data -class Property { +public class Property { @Id @GeneratedValue(strategy = GenerationType.AUTO) @@ -72,4 +71,4 @@ public ChildProperty getMyChildPropertyName() { public void setMyChildPropertyName(ChildProperty myChildPropertyName) { this.myChildPropertyName = myChildPropertyName; } -} \ No newline at end of file +} diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/BaseEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/BaseEntity.java index a4b1e3868..aa061d9d3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/BaseEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/BaseEntity.java @@ -33,22 +33,15 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.MappedSuperclass; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; /** * @author bnasslahsen */ - -@Data @MappedSuperclass -@DynamicInsert(true) -@DynamicUpdate(true) -@SuperBuilder(toBuilder = true) -@NoArgsConstructor +@DynamicInsert +@DynamicUpdate public abstract class BaseEntity implements Serializable { /** @@ -71,4 +64,19 @@ public abstract class BaseEntity implements Serializable { * @return 是否合法 */ public abstract boolean isValid(); + + public BaseEntity(Long id) { + this.id = id; + } + + public BaseEntity() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/ProductEntity.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/ProductEntity.java index 89e956a50..e9576cfe7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/ProductEntity.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app37/ProductEntity.java @@ -33,25 +33,13 @@ import jakarta.persistence.Entity; import jakarta.persistence.Table; import jakarta.validation.constraints.NotNull; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; -import lombok.experimental.SuperBuilder; /** * @author bnasslahsen */ -@Getter -@Setter -@ToString(callSuper = true) -@EqualsAndHashCode(callSuper = false) @Entity @Table(name = "PRODUCT_ENTITY") -@SuperBuilder(toBuilder = true) -@NoArgsConstructor public class ProductEntity extends BaseEntity implements Comparable { /** @@ -85,6 +73,30 @@ public boolean isValid() { return name != null && price != null && date != null; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate date) { + this.date = date; + } + /** * 根据日期排序 */ diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app4/Employee.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app4/Employee.java index ace109304..02f852315 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app4/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app4/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app6/Employee.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app6/Employee.java index 3a84364e3..2f5a14caf 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app6/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app6/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/dto/DemoComponentDto.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/dto/DemoComponentDto.java index 8dc94c89c..4081f3ae4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/dto/DemoComponentDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/dto/DemoComponentDto.java @@ -27,17 +27,12 @@ package test.org.springdoc.api.v31.app9.component.dto; import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; import org.springframework.hateoas.server.core.Relation; -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor +/** + * The type Demo component dto. + */ @Relation(collectionRelation = "components") @Schema(description = "A demo component to illustrate Springdoc Issue #401") public final class DemoComponentDto { @@ -48,4 +43,56 @@ public final class DemoComponentDto { @Schema(description = "Some dummy payload", example = "Hello World") private String payload; + public DemoComponentDto(String id, String payload) { + this.id = id; + this.payload = payload; + } + + private DemoComponentDto(Builder builder) { + setId(builder.id); + setPayload(builder.payload); + } + + public static Builder builder() { + return new Builder(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public static final class Builder { + private String id; + + private String payload; + + private Builder() { + } + + public Builder id(String val) { + id = val; + return this; + } + + public Builder payload(String val) { + payload = val; + return this; + } + + public DemoComponentDto build() { + return new DemoComponentDto(this); + } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/model/DemoComponent.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/model/DemoComponent.java index 05180bf00..518270243 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/model/DemoComponent.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/component/model/DemoComponent.java @@ -26,17 +26,8 @@ package test.org.springdoc.api.v31.app9.component.model; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; - import org.springframework.data.annotation.Id; -@Data -@Builder -@AllArgsConstructor -@EqualsAndHashCode public class DemoComponent { @Id @@ -44,4 +35,57 @@ public class DemoComponent { private String payload; + public DemoComponent(String id, String payload) { + this.id = id; + this.payload = payload; + } + + private DemoComponent(Builder builder) { + setId(builder.id); + setPayload(builder.payload); + } + + public static Builder builder() { + return new Builder(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + + public static final class Builder { + private String id; + + private String payload; + + private Builder() { + } + + public Builder id(String val) { + id = val; + return this; + } + + public Builder payload(String val) { + payload = val; + return this; + } + + public DemoComponent build() { + return new DemoComponent(this); + } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/core/model/ExceptionDto.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/core/model/ExceptionDto.java index 6c67e13ce..b8e1d3cda 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/core/model/ExceptionDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app9/core/model/ExceptionDto.java @@ -31,13 +31,10 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; -import lombok.Data; -import lombok.NonNull; -@Data + public class ExceptionDto { - @NonNull @NotNull @NotEmpty @Schema(description = "The date and time the problem occured", example = "2020-02-04T13:21:08.098+0000", type = "string", format = "date-time") @@ -49,4 +46,27 @@ public class ExceptionDto { @Schema(description = "The exception message", example = "Trying to update a non existing component !") private String message; + public Instant getTimestamp() { + return timestamp; + } + + public void setTimestamp(Instant timestamp) { + this.timestamp = timestamp; + } + + public String getException() { + return exception; + } + + public void setException(String exception) { + this.exception = exception; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app10.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app10.json index d7ea17c5e..05fbb0e40 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app10.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app10.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -90,7 +90,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -124,7 +124,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -166,7 +166,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -176,7 +176,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -243,7 +243,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -277,7 +277,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -334,7 +334,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -344,7 +344,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -421,7 +421,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -463,7 +463,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -520,7 +520,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -593,7 +593,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -616,7 +616,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app11.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app11.json index f840c5afd..509c91394 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app11.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app11.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -97,7 +97,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelPerson" } @@ -120,7 +120,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app12.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app12.json index 1b96010df..d500f0944 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app12.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app12.json @@ -39,12 +39,6 @@ } } }, - "204": { - "description": "No Content", - "content": { - "application/vnd.something": {} - } - }, "202": { "description": "Accepted", "content": { @@ -54,6 +48,12 @@ } } } + }, + "204": { + "description": "No Content", + "content": { + "application/vnd.something": {} + } } } } @@ -80,12 +80,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "Link": { "type": "object", "properties": { @@ -114,6 +108,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app13.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app13.json index 31f96751f..5a4e115c0 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app13.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app13.json @@ -111,7 +111,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -167,7 +167,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -226,7 +226,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -286,7 +286,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app16.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app16.json index e95e0eaf6..4c61ab22b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app16.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app16.json @@ -28,7 +28,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -73,7 +73,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -108,7 +108,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -148,7 +148,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -196,7 +196,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -206,7 +206,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -285,7 +285,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -325,7 +325,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -388,7 +388,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -398,7 +398,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -487,7 +487,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -535,7 +535,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -604,7 +604,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -644,7 +644,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -708,7 +708,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -748,7 +748,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -791,7 +791,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -801,7 +801,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -844,7 +844,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -868,7 +868,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app17.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app17.json index e1085bae2..327c61fb2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app17.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app17.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelChildProperty" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -205,7 +205,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelProperty" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app19.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app19.json index 1af2fd9ab..697c8ace7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app19.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app19.json @@ -45,7 +45,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "object" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app20.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app20.json index 8a208bfb0..6e580b072 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app20.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app20.json @@ -57,7 +57,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelBank" } @@ -96,7 +96,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -125,7 +125,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "integer", "format": "int64" @@ -158,7 +158,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -192,7 +192,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -234,7 +234,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -244,7 +244,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -311,7 +311,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -334,7 +334,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app21.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app21.json index f61470407..a9e967e54 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app21.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app21.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -99,7 +99,7 @@ "200": { "description": "another successful operation", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -112,7 +112,7 @@ "404": { "description": "another Contact not found", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -145,7 +145,7 @@ "400": { "description": "Invalid ID supplied", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -158,7 +158,7 @@ "200": { "description": "successful operation", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -171,7 +171,7 @@ "404": { "description": "Contact not found", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -184,7 +184,7 @@ "405": { "description": "Validation exception", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -207,7 +207,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app22.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app22.json index 9ad681c13..f37ddff99 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app22.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app22.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -138,12 +138,12 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/Person" } }, - "application/vnd.hal+json": { + "application/hal+json": { "schema": { "$ref": "#/components/schemas/Person" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app23.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app23.json index 4b297655c..fc73f39de 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app23.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app23.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelClinic" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -92,7 +92,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -134,7 +134,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -144,7 +144,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -211,7 +211,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -235,7 +235,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -274,7 +274,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -305,7 +305,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -347,7 +347,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -357,7 +357,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -424,7 +424,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -458,7 +458,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -515,7 +515,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -525,7 +525,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -602,7 +602,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -644,7 +644,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -700,7 +700,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app24.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app24.json index 30ceb9d64..5447028dd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app24.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app24.json @@ -45,7 +45,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PageUser" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app25.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app25.json index bc4d6ea8b..7edb0e383 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app25.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app25.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelClinic" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -92,7 +92,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -134,7 +134,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -144,7 +144,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -211,7 +211,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -235,7 +235,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -274,7 +274,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -303,7 +303,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -337,7 +337,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -379,7 +379,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -389,7 +389,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -456,7 +456,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -490,7 +490,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -547,7 +547,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -557,7 +557,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -634,7 +634,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -676,7 +676,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -769,7 +769,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelOwner" } @@ -808,7 +808,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -839,7 +839,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -881,7 +881,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -891,7 +891,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -958,7 +958,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -992,7 +992,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1049,7 +1049,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1059,7 +1059,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1136,7 +1136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1178,7 +1178,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1271,7 +1271,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPet" } @@ -1320,7 +1320,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1351,7 +1351,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1403,7 +1403,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1413,7 +1413,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1490,7 +1490,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1524,7 +1524,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1581,7 +1581,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1591,7 +1591,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1668,7 +1668,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1710,7 +1710,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1766,7 +1766,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app26.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app26.json index 562819ee2..71231ab18 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app26.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app26.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -97,7 +97,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelPerson" } @@ -136,7 +136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -245,12 +245,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "RepresentationModelObject": { "type": "object", "properties": { @@ -367,6 +361,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app29.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app29.json index 8eb0185ab..72051a659 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app29.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app29.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -138,7 +138,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/Person" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app30.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app30.json index a1c4cc176..3d02c7855 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app30.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app30.json @@ -37,7 +37,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/User" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app31.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app31.json index 57ed8bdba..3bcac4047 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app31.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app31.json @@ -60,7 +60,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -120,7 +120,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -157,7 +157,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -195,7 +195,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app34.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app34.json index 57c436e53..debea76b7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app34.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app34.json @@ -27,7 +27,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -71,7 +71,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -105,7 +105,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -144,7 +144,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -191,7 +191,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -201,7 +201,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -278,7 +278,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -317,7 +317,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -379,7 +379,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -389,7 +389,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -476,7 +476,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -523,7 +523,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -590,7 +590,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -629,7 +629,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -692,7 +692,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -731,7 +731,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -773,7 +773,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -783,7 +783,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -825,7 +825,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -859,7 +859,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -916,7 +916,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -926,7 +926,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -978,7 +978,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -1020,7 +1020,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -1043,7 +1043,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app36.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app36.json index 3aabae473..d566ecbdb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app36.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app36.json @@ -34,7 +34,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder" } @@ -73,7 +73,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app37.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app37.json index 6b95b0716..d1af5d14c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app37.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app37.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelProductEntity" } @@ -97,7 +97,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -136,7 +136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -176,7 +176,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -216,7 +216,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -273,7 +273,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -313,7 +313,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -347,7 +347,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -387,7 +387,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -421,7 +421,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -463,7 +463,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -473,7 +473,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -540,7 +540,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -563,7 +563,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app38.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app38.json index ad054ae09..957b964b2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app38.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app38.json @@ -38,7 +38,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app4.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app4.json index 8c08cc119..51cd5bc0c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app4.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app4.json @@ -11,30 +11,52 @@ } ], "paths": { - "/employees": { + "/employees/{id}": { "get": { "tags": [ "employee-controller" ], - "operationId": "findAll", + "operationId": "findOne", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], "responses": { "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { - "$ref": "#/components/schemas/CollectionModelEntityModelEmployee" + "$ref": "#/components/schemas/EntityModelEmployee" } } } } } }, - "post": { + "put": { "tags": [ "employee-controller" ], - "operationId": "newEmployee", + "operationId": "updateEmployee", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "integer", + "format": "int64" + } + } + ], "requestBody": { "content": { "application/json": { @@ -47,64 +69,35 @@ }, "responses": { "200": { - "description": "OK", - "content": { - "application/hal+json": { - "schema": { - "$ref": "#/components/schemas/EntityModelEmployee" - } - } - } + "description": "OK" } } } }, - "/employees/{id}": { + "/employees": { "get": { "tags": [ "employee-controller" ], - "operationId": "findOne", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], + "operationId": "findAll", "responses": { "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { - "$ref": "#/components/schemas/EntityModelEmployee" + "$ref": "#/components/schemas/CollectionModelEntityModelEmployee" } } } } } }, - "put": { + "post": { "tags": [ "employee-controller" ], - "operationId": "updateEmployee", - "parameters": [ - { - "name": "id", - "in": "path", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - } - ], + "operationId": "newEmployee", "requestBody": { "content": { "application/json": { @@ -117,7 +110,14 @@ }, "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/vnd.hal+json": { + "schema": { + "$ref": "#/components/schemas/EntityModelEmployee" + } + } + } } } } @@ -125,25 +125,6 @@ }, "components": { "schemas": { - "CollectionModelEntityModelEmployee": { - "type": "object", - "properties": { - "_embedded": { - "type": "object", - "properties": { - "employees": { - "type": "array", - "items": { - "$ref": "#/components/schemas/EntityModelEmployee" - } - } - } - }, - "_links": { - "$ref": "#/components/schemas/Links" - } - } - }, "Employee": { "type": "object", "properties": { @@ -183,10 +164,23 @@ } } }, - "Links": { + "CollectionModelEntityModelEmployee": { "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" + "properties": { + "_embedded": { + "type": "object", + "properties": { + "employees": { + "type": "array", + "items": { + "$ref": "#/components/schemas/EntityModelEmployee" + } + } + } + }, + "_links": { + "$ref": "#/components/schemas/Links" + } } }, "Link": { @@ -217,6 +211,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app5.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app5.json index 932647c22..54b42097a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app5.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app5.json @@ -85,7 +85,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "object" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app6.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app6.json index 23665a63d..e45bb9087 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app6.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app6.json @@ -32,7 +32,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelEmployee" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app8.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app8.json index 2de869822..d82d20405 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app8.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.0.1/app8.json @@ -21,7 +21,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelAlbum" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app10.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app10.json index dc24676ae..0d052b49b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app10.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app10.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -90,7 +90,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -124,7 +124,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -166,7 +166,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -176,7 +176,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -243,7 +243,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -277,7 +277,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -334,7 +334,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -344,7 +344,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -421,7 +421,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -463,7 +463,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -520,7 +520,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -593,7 +593,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -616,7 +616,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app11.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app11.json index 3e9d8a418..f05304c72 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app11.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app11.json @@ -25,9 +25,9 @@ "description": "Zero-based page index (0..N)", "required": false, "schema": { - "minimum": 0, "type": "integer", - "default": 0 + "default": 0, + "minimum": 0 } }, { @@ -36,9 +36,9 @@ "description": "The size of the page to be returned", "required": false, "schema": { - "minimum": 1, "type": "integer", - "default": 20 + "default": 20, + "minimum": 1 } }, { @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -97,7 +97,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelPerson" } @@ -120,7 +120,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -229,12 +229,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "RepresentationModelObject": { "type": "object", "properties": { @@ -347,6 +341,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app12.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app12.json index b5d3256c8..eca51cb99 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app12.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app12.json @@ -39,12 +39,6 @@ } } }, - "204": { - "description": "No Content", - "content": { - "application/vnd.something": {} - } - }, "202": { "description": "Accepted", "content": { @@ -54,6 +48,12 @@ } } } + }, + "204": { + "description": "No Content", + "content": { + "application/vnd.something": {} + } } } } @@ -80,12 +80,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "Link": { "type": "object", "properties": { @@ -114,6 +108,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app13.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app13.json index 7d6b13b15..4cd66765c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app13.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app13.json @@ -111,7 +111,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -167,7 +167,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -226,7 +226,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -286,7 +286,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app16.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app16.json index 28d48fc22..fa865150a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app16.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app16.json @@ -28,7 +28,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -73,7 +73,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -108,7 +108,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -148,7 +148,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -196,7 +196,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -206,7 +206,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -285,7 +285,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -325,7 +325,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -388,7 +388,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -398,7 +398,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -487,7 +487,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -535,7 +535,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -604,7 +604,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -644,7 +644,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -708,7 +708,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -748,7 +748,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -791,7 +791,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -801,7 +801,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -844,7 +844,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -868,7 +868,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app17.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app17.json index f62a6e888..327b5a769 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app17.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app17.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelChildProperty" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -205,7 +205,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelProperty" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app19.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app19.json index 0013f04e1..ebed5509f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app19.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app19.json @@ -45,7 +45,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "object" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app20.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app20.json index 21565f6af..7a728caac 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app20.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app20.json @@ -57,7 +57,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelBank" } @@ -96,7 +96,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -125,7 +125,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "integer", "format": "int64" @@ -158,7 +158,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -192,7 +192,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -234,7 +234,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -244,7 +244,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -311,7 +311,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelBank" } @@ -334,7 +334,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app21.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app21.json index adc13ea4a..e83dedfa1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app21.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app21.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -99,7 +99,7 @@ "200": { "description": "another successful operation", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -112,7 +112,7 @@ "404": { "description": "another Contact not found", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -145,7 +145,7 @@ "400": { "description": "Invalid ID supplied", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -158,7 +158,7 @@ "200": { "description": "successful operation", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -171,7 +171,7 @@ "404": { "description": "Contact not found", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -184,7 +184,7 @@ "405": { "description": "Validation exception", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "array", "items": { @@ -207,7 +207,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app22.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app22.json index d0be6037d..a9cf91eab 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app22.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app22.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -138,12 +138,12 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/Person" } }, - "application/vnd.hal+json": { + "application/hal+json": { "schema": { "$ref": "#/components/schemas/Person" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app23.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app23.json index 5a2a3a851..2ed65471c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app23.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app23.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelClinic" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -92,7 +92,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -134,7 +134,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -144,7 +144,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -211,7 +211,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -235,7 +235,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -274,7 +274,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -305,7 +305,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -347,7 +347,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -357,7 +357,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -424,7 +424,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -458,7 +458,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -515,7 +515,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -525,7 +525,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -602,7 +602,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -644,7 +644,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -700,7 +700,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app24.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app24.json index 1a901539e..a6e140662 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app24.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app24.json @@ -45,7 +45,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PageUser" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app25.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app25.json index 9b57b8898..3538111e3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app25.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app25.json @@ -22,7 +22,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelClinic" } @@ -61,7 +61,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -92,7 +92,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -134,7 +134,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -144,7 +144,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -211,7 +211,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelClinic" } @@ -235,7 +235,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -274,7 +274,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -303,7 +303,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelDoctor" } @@ -337,7 +337,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -379,7 +379,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -389,7 +389,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -456,7 +456,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelDoctor" } @@ -490,7 +490,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -547,7 +547,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -557,7 +557,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -634,7 +634,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -676,7 +676,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelClinic" } @@ -769,7 +769,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelOwner" } @@ -808,7 +808,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -839,7 +839,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -881,7 +881,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -891,7 +891,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -958,7 +958,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -992,7 +992,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1049,7 +1049,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1059,7 +1059,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1136,7 +1136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1178,7 +1178,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelPet" } @@ -1271,7 +1271,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPet" } @@ -1320,7 +1320,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1351,7 +1351,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1403,7 +1403,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1413,7 +1413,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1490,7 +1490,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelPet" } @@ -1524,7 +1524,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1581,7 +1581,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1591,7 +1591,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1668,7 +1668,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1710,7 +1710,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelOwner" } @@ -1766,7 +1766,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app26.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app26.json index 06cd6bc64..d290cd133 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app26.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app26.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -97,7 +97,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelPerson" } @@ -136,7 +136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app29.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app29.json index c692e756d..8d9195080 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app29.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app29.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelPerson" } @@ -88,7 +88,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } @@ -138,7 +138,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/Person" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app30.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app30.json index 62757da1a..97de51742 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app30.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app30.json @@ -37,7 +37,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/User" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app31.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app31.json index 80178d3af..364e13d65 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app31.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app31.json @@ -60,7 +60,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -120,7 +120,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -157,7 +157,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } @@ -195,7 +195,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app34.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app34.json index f0ed805be..09af9ab7b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app34.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app34.json @@ -27,7 +27,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -71,7 +71,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -105,7 +105,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelAccount" } @@ -144,7 +144,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -191,7 +191,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -201,7 +201,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -278,7 +278,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelAccount" } @@ -317,7 +317,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -379,7 +379,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -389,7 +389,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -476,7 +476,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -523,7 +523,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -590,7 +590,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelCustomer" } @@ -629,7 +629,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -692,7 +692,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelCustomer" } @@ -731,7 +731,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -773,7 +773,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -783,7 +783,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -825,7 +825,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelCustomer" } @@ -859,7 +859,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -916,7 +916,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -926,7 +926,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -978,7 +978,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -1020,7 +1020,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelAccount" } @@ -1043,7 +1043,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app36.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app36.json index b148f585a..f8edbb931 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app36.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app36.json @@ -34,7 +34,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder" } @@ -73,7 +73,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelEnumFieldHolder" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app37.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app37.json index 7759dead0..dfd936db6 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app37.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app37.json @@ -58,7 +58,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelEntityModelProductEntity" } @@ -97,7 +97,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -136,7 +136,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -176,7 +176,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -216,7 +216,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -273,7 +273,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -313,7 +313,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -347,7 +347,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelProductEntity" } @@ -387,7 +387,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -421,7 +421,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -463,7 +463,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -473,7 +473,7 @@ "201": { "description": "Created", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -540,7 +540,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelProductEntity" } @@ -563,7 +563,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/RepresentationModelObject" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app38.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app38.json index 44e97f0a1..34698218a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app38.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app38.json @@ -38,7 +38,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "string" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app4.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app4.json index 09eb17db0..9f8a5013d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app4.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app4.json @@ -21,7 +21,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/CollectionModelEntityModelEmployee" } @@ -49,7 +49,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelEmployee" } @@ -80,7 +80,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelEmployee" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app5.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app5.json index fe52268d8..793e8b060 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app5.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app5.json @@ -85,7 +85,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "type": "object" } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app6.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app6.json index 0d368ee00..249558a3d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app6.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app6.json @@ -32,7 +32,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/EntityModelEmployee" } @@ -84,12 +84,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "Link": { "type": "object", "properties": { @@ -118,6 +112,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app8.json b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app8.json index 6fbcf3fd7..844bf353c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app8.json +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/resources/results/3.1.0/app8.json @@ -21,7 +21,7 @@ "200": { "description": "OK", "content": { - "application/hal+json": { + "application/vnd.hal+json": { "schema": { "$ref": "#/components/schemas/PagedModelAlbum" } @@ -48,12 +48,6 @@ } } }, - "Links": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/Link" - } - }, "PageMetadata": { "type": "object", "properties": { @@ -125,6 +119,12 @@ "type": "boolean" } } + }, + "Links": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/Link" + } } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 7b5ca2c88..5dccb5189 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 @@ -21,11 +21,5 @@ spring-cloud-starter-function-webflux test - - io.netty - netty-resolver-dns-native-macos - osx-aarch_64 - test - diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index 5dbc6530e..56c4c0700 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index e392c9f92..561fe7f0f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 2086191b3..fe475b263 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-hateoas-tests @@ -17,22 +17,17 @@ org.springframework.boot - spring-boot-starter-data-jpa - test - - - com.h2database - h2 + spring-boot-starter-hateoas test - org.projectlombok - lombok + org.springframework.boot + spring-boot-data-jpa test - org.springframework.boot - spring-boot-starter-hateoas + com.h2database + h2 test diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app1/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app1/Employee.java index 0a933646a..5fe4b89dc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app1/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app1/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app10/Dummy.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app10/Dummy.java index 8748fc422..4bfcab36c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app10/Dummy.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app10/Dummy.java @@ -26,13 +26,20 @@ package test.org.springdoc.api.v30.app10; -import lombok.AllArgsConstructor; -import lombok.Data; -@Data -@AllArgsConstructor public class Dummy { private T value; + public Dummy(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/config/DatabaseConfig.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/config/DatabaseConfig.java index df2174f5d..8869c3e1d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/config/DatabaseConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/config/DatabaseConfig.java @@ -29,7 +29,6 @@ import java.time.LocalDate; import jakarta.annotation.PostConstruct; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v30.app2.entities.Post; import test.org.springdoc.api.v30.app2.repositories.PostRepository; @@ -40,11 +39,14 @@ * 2020 */ @Configuration -@RequiredArgsConstructor public class DatabaseConfig { private final PostRepository postRepository; + public DatabaseConfig(PostRepository postRepository) { + this.postRepository = postRepository; + } + @PostConstruct private void postConstruct() { for (int i = 0; i < 33; i++) { diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/controller/PostController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/controller/PostController.java index d0b92b9e7..9a81f2551 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/controller/PostController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/controller/PostController.java @@ -26,7 +26,6 @@ package test.org.springdoc.api.v30.app2.controller; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v30.app2.entities.Post; import test.org.springdoc.api.v30.app2.service.PostService; @@ -43,11 +42,14 @@ * 2020 */ @RestController -@RequiredArgsConstructor public class PostController { private final PostService postService; + public PostController(PostService postService) { + this.postService = postService; + } + @GetMapping public ResponseEntity>> getAll(Pageable pageable) { return new ResponseEntity<>(postService.getAll(pageable), HttpStatus.OK); diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/entities/Post.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/entities/Post.java index b15390e7a..0c6ae8775 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/entities/Post.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/entities/Post.java @@ -29,18 +29,12 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; /** * @author Davide Pedone * 2020 */ -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor public class Post { @Id @@ -53,4 +47,46 @@ public class Post { private Long createdAt; + public Post(Long id, String author, String content, Long createdAt) { + this.id = id; + this.author = author; + this.content = content; + this.createdAt = createdAt; + } + + public Post() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Long createdAt) { + this.createdAt = createdAt; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/service/PostService.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/service/PostService.java index dbe43fdc1..6d4fab7af 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/service/PostService.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app2/service/PostService.java @@ -27,7 +27,6 @@ package test.org.springdoc.api.v30.app2.service; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v30.app2.entities.Post; import test.org.springdoc.api.v30.app2.hateoas.PostResourceAssembler; import test.org.springdoc.api.v30.app2.repositories.PostRepository; @@ -43,7 +42,6 @@ * @author Davide Pedone * 2020 */ -@RequiredArgsConstructor @Service public class PostService { @@ -58,4 +56,9 @@ public PagedModel> getAll(Pageable pageable) { return pagedResourcesAssembler.toModel(postPage, postResourceAssembler); } + public PostService(PostRepository postRepository, PagedResourcesAssembler pagedResourcesAssembler, PostResourceAssembler postResourceAssembler) { + this.postRepository = postRepository; + this.pagedResourcesAssembler = pagedResourcesAssembler; + this.postResourceAssembler = postResourceAssembler; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app3/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app3/Employee.java index 90093efb6..2b564c8c0 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app3/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app3/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/controller/CompanyController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/controller/CompanyController.java index 3089df594..b33371ba3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/controller/CompanyController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/controller/CompanyController.java @@ -29,7 +29,6 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v30.app5.entities.CompanyDto; import org.springframework.web.bind.annotation.PostMapping; @@ -41,7 +40,6 @@ * 2020 */ @RestController -@RequiredArgsConstructor public class CompanyController { diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/Company.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/Company.java index feceed029..09276b596 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/Company.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/Company.java @@ -30,21 +30,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; +import org.springframework.hateoas.Link; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.Relation; /** * @author bnasslahsen */ -@AllArgsConstructor -@Data -@Builder -@EqualsAndHashCode(callSuper = false) @Relation(collectionRelation = "companies", itemRelation = "company") public class Company extends RepresentationModel { @JsonProperty(access = JsonProperty.Access.READ_ONLY) @@ -52,4 +45,37 @@ public class Company extends RepresentationModel { @NotNull private String name; + + public Company(UUID id, String name) { + this.id = id; + this.name = name; + } + + public Company(Link initialLink, UUID id, String name) { + super(initialLink); + this.id = id; + this.name = name; + } + + public Company(Iterable initialLinks, UUID id, String name) { + super(initialLinks); + this.id = id; + this.name = name; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/CompanyDto.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/CompanyDto.java index 2725e74df..707295a15 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/CompanyDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app5/entities/CompanyDto.java @@ -29,27 +29,86 @@ import java.util.UUID; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty.Access; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; +import org.springframework.hateoas.Link; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.Relation; /** * @author bnasslahsen */ -@AllArgsConstructor -@Data -@Builder -@EqualsAndHashCode(callSuper = false) @Relation(collectionRelation = "companies", itemRelation = "company") public class CompanyDto extends RepresentationModel { - @JsonProperty(access = JsonProperty.Access.READ_ONLY) + @JsonProperty(access = Access.READ_ONLY) private UUID id; @NotNull private String name; + + private CompanyDto(Builder builder) { + setId(builder.id); + setName(builder.name); + } + + public static Builder builder() { + return new Builder(); + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public CompanyDto(UUID id, String name) { + this.id = id; + this.name = name; + } + + public CompanyDto(Link initialLink, UUID id, String name) { + super(initialLink); + this.id = id; + this.name = name; + } + + public CompanyDto(Iterable initialLinks, UUID id, String name) { + super(initialLinks); + this.id = id; + this.name = name; + } + + public static final class Builder { + private UUID id; + + private @NotNull String name; + + private Builder() { + } + + public Builder id(UUID val) { + id = val; + return this; + } + + public Builder name(@NotNull String val) { + name = val; + return this; + } + + public CompanyDto build() { + return new CompanyDto(this); + } + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app7/application/Foo.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app7/application/Foo.java index 628783cd9..90ed4506e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app7/application/Foo.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app7/application/Foo.java @@ -26,11 +26,18 @@ package test.org.springdoc.api.v30.app7.application; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor public class Foo { String foo; + + public Foo(String foo) { + this.foo = foo; + } + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app8/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app8/Employee.java index 332568774..db74cf80a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app8/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app8/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/FooController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/FooController.java index 61b23fe91..ce5854fa1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/FooController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/FooController.java @@ -26,13 +26,12 @@ package test.org.springdoc.api.v30.app9.application; +import java.time.LocalDate; import java.util.List; import java.util.UUID; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import test.org.springdoc.api.v30.app9.application.dto.FeedResponse; import test.org.springdoc.api.v30.app9.application.dto.ResponseData; @@ -47,8 +46,6 @@ @Tag(name = "ResponseDataController") @RestController @RequestMapping(value = "/some-route", produces = MediaType.APPLICATION_JSON_VALUE) -@RequiredArgsConstructor -@Slf4j public class FooController { @@ -56,7 +53,7 @@ public class FooController { @GetMapping(value = "foo/{id}") @ResponseStatus(HttpStatus.OK) public FeedResponse getFoo(@PathVariable("id") UUID id) { - var dataList = List.of(ResponseData.builder().dataId(id).build()); + var dataList = List.of(new ResponseData(id, LocalDate.now())); return FeedResponse.createForResponseData(dataList, UUID.randomUUID()); } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/FeedResponse.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/FeedResponse.java index 85b3f5825..29e0ab7c3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/FeedResponse.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/FeedResponse.java @@ -31,11 +31,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.experimental.Accessors; import test.org.springdoc.api.v30.app9.application.FooController; import org.springframework.hateoas.IanaLinkRelations; @@ -44,15 +39,15 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; -@Getter -@Accessors(fluent = true) -@Builder(access = AccessLevel.PACKAGE) -@EqualsAndHashCode(callSuper = true) public class FeedResponse extends RepresentationModel { @NotNull @JsonProperty("data") private final List data; + public FeedResponse(List data) { + this.data = data; + } + public static FeedResponse createForResponseData(@NotNull List responseData, UUID uuid) { var feedResponse = new FeedResponse(responseData); feedResponse.add(linkTo(methodOn(FooController.class).getFoo(uuid)).withSelfRel()); @@ -62,4 +57,8 @@ public static FeedResponse createForResponseData(@NotNull List res return feedResponse; } + + public List getData() { + return data; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/ResponseData.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/ResponseData.java index 31bf85aac..d92005f53 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/ResponseData.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/app9/application/dto/ResponseData.java @@ -32,9 +32,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; -import lombok.Builder; -@Builder public record ResponseData( @JsonProperty(value = "DATA_ID", required = true) @NotNull diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app1/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app1/Employee.java index 5783d0fc6..6af9d8eda 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app1/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app1/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app10/Dummy.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app10/Dummy.java index 6e64a57ff..83bb1e00b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app10/Dummy.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app10/Dummy.java @@ -26,13 +26,20 @@ package test.org.springdoc.api.v31.app10; -import lombok.AllArgsConstructor; -import lombok.Data; -@Data -@AllArgsConstructor public class Dummy { private T value; + public Dummy(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/config/DatabaseConfig.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/config/DatabaseConfig.java index bdc8b4c64..234885545 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/config/DatabaseConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/config/DatabaseConfig.java @@ -29,7 +29,6 @@ import java.time.LocalDate; import jakarta.annotation.PostConstruct; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v31.app2.entities.Post; import test.org.springdoc.api.v31.app2.repositories.PostRepository; @@ -40,11 +39,14 @@ * 2020 */ @Configuration -@RequiredArgsConstructor public class DatabaseConfig { private final PostRepository postRepository; + public DatabaseConfig(PostRepository postRepository) { + this.postRepository = postRepository; + } + @PostConstruct private void postConstruct() { for (int i = 0; i < 33; i++) { diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/controller/PostController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/controller/PostController.java index 90a3d4cb8..21050ddda 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/controller/PostController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/controller/PostController.java @@ -26,7 +26,6 @@ package test.org.springdoc.api.v31.app2.controller; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v31.app2.entities.Post; import test.org.springdoc.api.v31.app2.service.PostService; @@ -43,11 +42,14 @@ * 2020 */ @RestController -@RequiredArgsConstructor public class PostController { private final PostService postService; + public PostController(PostService postService) { + this.postService = postService; + } + @GetMapping public ResponseEntity>> getAll(Pageable pageable) { return new ResponseEntity<>(postService.getAll(pageable), HttpStatus.OK); diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/entities/Post.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/entities/Post.java index 4fd161dd7..4450b2669 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/entities/Post.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/entities/Post.java @@ -29,18 +29,12 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; /** * @author Davide Pedone * 2020 */ -@Data @Entity -@NoArgsConstructor -@AllArgsConstructor public class Post { @Id @@ -53,4 +47,46 @@ public class Post { private Long createdAt; + public Post(Long id, String author, String content, Long createdAt) { + this.id = id; + this.author = author; + this.content = content; + this.createdAt = createdAt; + } + + public Post() { + + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public Long getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Long createdAt) { + this.createdAt = createdAt; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/service/PostService.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/service/PostService.java index 5d80fd203..7eb12119f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/service/PostService.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app2/service/PostService.java @@ -27,7 +27,6 @@ package test.org.springdoc.api.v31.app2.service; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v31.app2.entities.Post; import test.org.springdoc.api.v31.app2.hateoas.PostResourceAssembler; import test.org.springdoc.api.v31.app2.repositories.PostRepository; @@ -43,7 +42,6 @@ * @author Davide Pedone * 2020 */ -@RequiredArgsConstructor @Service public class PostService { @@ -53,6 +51,12 @@ public class PostService { private final PostResourceAssembler postResourceAssembler; + public PostService(PostRepository postRepository, PagedResourcesAssembler pagedResourcesAssembler, PostResourceAssembler postResourceAssembler) { + this.postRepository = postRepository; + this.pagedResourcesAssembler = pagedResourcesAssembler; + this.postResourceAssembler = postResourceAssembler; + } + public PagedModel> getAll(Pageable pageable) { Page postPage = postRepository.findAll(pageable); return pagedResourcesAssembler.toModel(postPage, postResourceAssembler); diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app3/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app3/Employee.java index ccb99dc86..d747cc210 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app3/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app3/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/controller/CompanyController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/controller/CompanyController.java index d5adbe7a4..6378f5fcd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/controller/CompanyController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/controller/CompanyController.java @@ -29,7 +29,6 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; import test.org.springdoc.api.v31.app5.entities.CompanyDto; import org.springframework.web.bind.annotation.PostMapping; @@ -41,10 +40,8 @@ * 2020 */ @RestController -@RequiredArgsConstructor public class CompanyController { - @PostMapping @io.swagger.v3.oas.annotations.parameters.RequestBody( description = "Details of the Item to be created", diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/Company.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/Company.java index b0c4c364d..4eb0bf929 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/Company.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/Company.java @@ -30,26 +30,53 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; +import org.springframework.hateoas.Link; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.Relation; /** * @author bnasslahsen */ -@AllArgsConstructor -@Data -@Builder -@EqualsAndHashCode(callSuper = false) @Relation(collectionRelation = "companies", itemRelation = "company") public class Company extends RepresentationModel { + @JsonProperty(access = JsonProperty.Access.READ_ONLY) private UUID id; @NotNull private String name; + + public Company(UUID id, String name) { + this.id = id; + this.name = name; + } + + public Company(Link initialLink, UUID id, String name) { + super(initialLink); + this.id = id; + this.name = name; + } + + public Company(Iterable initialLinks, UUID id, String name) { + super(initialLinks); + this.id = id; + this.name = name; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/CompanyDto.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/CompanyDto.java index 5ba9b9608..953e87881 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/CompanyDto.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app5/entities/CompanyDto.java @@ -29,27 +29,86 @@ import java.util.UUID; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonProperty.Access; import jakarta.validation.constraints.NotNull; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; +import org.springframework.hateoas.Link; import org.springframework.hateoas.RepresentationModel; import org.springframework.hateoas.server.core.Relation; /** * @author bnasslahsen */ -@AllArgsConstructor -@Data -@Builder -@EqualsAndHashCode(callSuper = false) @Relation(collectionRelation = "companies", itemRelation = "company") public class CompanyDto extends RepresentationModel { - @JsonProperty(access = JsonProperty.Access.READ_ONLY) + @JsonProperty(access = Access.READ_ONLY) private UUID id; @NotNull private String name; + + public CompanyDto(UUID id, String name) { + this.id = id; + this.name = name; + } + + public CompanyDto(Link initialLink, UUID id, String name) { + super(initialLink); + this.id = id; + this.name = name; + } + + public CompanyDto(Iterable initialLinks, UUID id, String name) { + super(initialLinks); + this.id = id; + this.name = name; + } + + private CompanyDto(Builder builder) { + setId(builder.id); + setName(builder.name); + } + + public static Builder builder() { + return new Builder(); + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static final class Builder { + private UUID id; + + private @NotNull String name; + + private Builder() { + } + + public Builder id(UUID val) { + id = val; + return this; + } + + public Builder name(@NotNull String val) { + name = val; + return this; + } + + public CompanyDto build() { + return new CompanyDto(this); + } + } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app7/application/Foo.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app7/application/Foo.java index e4a4adf27..b072d1757 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app7/application/Foo.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app7/application/Foo.java @@ -26,11 +26,19 @@ package test.org.springdoc.api.v31.app7.application; -import lombok.AllArgsConstructor; -import lombok.Data; -@Data -@AllArgsConstructor public class Foo { String foo; + + public Foo(String foo) { + this.foo = foo; + } + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app8/Employee.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app8/Employee.java index c3c4351c2..883dbc839 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app8/Employee.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app8/Employee.java @@ -28,27 +28,8 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Domain object representing a company employee. Project Lombok keeps actual code at a minimum. {@code @Data} - - * Generates getters, setters, toString, hash, and equals functions {@code @Entity} - JPA annotation to flag this class - * for DB persistence {@code @NoArgsConstructor} - Create a constructor with no args to support JPA - * {@code @AllArgsConstructor} - Create a constructor with all args to support testing - * {@code @JsonIgnoreProperties(ignoreUnknow=true)} When converting JSON to Java, ignore any unrecognized attributes. - * This is critical for REST because it encourages adding new fields in later versions that won't break. It also allows - * things like _links to be ignore as well, meaning HAL documents can be fetched and later posted to the server without - * adjustment. - * - * @author Greg Turnquist - */ -@Data + @Entity -@NoArgsConstructor(access = AccessLevel.PRIVATE) -@AllArgsConstructor class Employee { @Id @@ -61,6 +42,13 @@ class Employee { private String role; + public Employee(Long id, String firstName, String lastName, String role) { + this.id = id; + this.firstName = firstName; + this.lastName = lastName; + this.role = role; + } + /** * Useful constructor when id is not yet known. * @@ -74,4 +62,39 @@ class Employee { this.lastName = lastName; this.role = role; } + + public Employee() { + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/FooController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/FooController.java index d6ba6224f..f1343f498 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/FooController.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/FooController.java @@ -26,13 +26,12 @@ package test.org.springdoc.api.v31.app9.application; +import java.time.LocalDate; import java.util.List; import java.util.UUID; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import test.org.springdoc.api.v31.app9.application.dto.FeedResponse; import test.org.springdoc.api.v31.app9.application.dto.ResponseData; @@ -47,8 +46,6 @@ @Tag(name = "ResponseDataController") @RestController @RequestMapping(value = "/some-route", produces = MediaType.APPLICATION_JSON_VALUE) -@RequiredArgsConstructor -@Slf4j public class FooController { @@ -56,7 +53,7 @@ public class FooController { @GetMapping(value = "foo/{id}") @ResponseStatus(HttpStatus.OK) public FeedResponse getFoo(@PathVariable("id") UUID id) { - var dataList = List.of(ResponseData.builder().dataId(id).build()); + var dataList = List.of(new ResponseData(id, LocalDate.now())); return FeedResponse.createForResponseData(dataList, UUID.randomUUID()); } } \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/FeedResponse.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/FeedResponse.java index 3ac013555..2647e6275 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/FeedResponse.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/FeedResponse.java @@ -31,11 +31,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotNull; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.experimental.Accessors; import test.org.springdoc.api.v31.app9.application.FooController; import org.springframework.hateoas.IanaLinkRelations; @@ -44,15 +39,16 @@ import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; -@Getter -@Accessors(fluent = true) -@Builder(access = AccessLevel.PACKAGE) -@EqualsAndHashCode(callSuper = true) public class FeedResponse extends RepresentationModel { + @NotNull @JsonProperty("data") private final List data; + public FeedResponse(List data) { + this.data = data; + } + public static FeedResponse createForResponseData(@NotNull List responseData, UUID uuid) { var feedResponse = new FeedResponse(responseData); feedResponse.add(linkTo(methodOn(FooController.class).getFoo(uuid)).withSelfRel()); @@ -62,4 +58,8 @@ public static FeedResponse createForResponseData(@NotNull List res return feedResponse; } + + public List getData() { + return data; + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/ResponseData.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/ResponseData.java index f5be2276c..302125dd3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/ResponseData.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app9/application/dto/ResponseData.java @@ -32,9 +32,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; -import lombok.Builder; -@Builder public record ResponseData( @JsonProperty(value = "DATA_ID", required = true) @NotNull diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index c4d05ca17..550cd3f68 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 @@ -10,6 +10,12 @@ ${project.artifactId} + + org.springdoc + springdoc-openapi-starter-webmvc-api + ${project.version} + test + com.github.therapi @@ -17,12 +23,6 @@ ${therapi-runtime-javadoc.version} test - - org.springdoc - springdoc-openapi-starter-webmvc-api - ${project.version} - test - jakarta.servlet jakarta.servlet-api @@ -34,8 +34,8 @@ test - org.hibernate.validator - hibernate-validator + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java index 4ad34f1a5..b7e8b35f9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app105/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java index 9dc75f21b..162d69365 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app2/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java index 51282c25c..bbfcebe35 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app77/HelloController.java @@ -33,7 +33,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; -import org.hibernate.validator.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java index 8982d96d5..4c8ebf009 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app105/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java index c13e63fc2..f8d40153f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app2/api/ExceptionTranslator.java @@ -31,7 +31,7 @@ import jakarta.validation.ConstraintViolationException; import org.springframework.boot.web.error.ErrorAttributeOptions; -import org.springframework.boot.web.servlet.error.ErrorAttributes; +import org.springframework.boot.webmvc.error.ErrorAttributes; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java index a0d8cd12f..c869e2bbf 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app77/HelloController.java @@ -33,7 +33,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import jakarta.validation.Valid; -import org.hibernate.validator.constraints.NotBlank; +import jakarta.validation.constraints.NotBlank; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.0.1/app77.json b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.0.1/app77.json index 5698d54ac..cacab4e30 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.0.1/app77.json +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.0.1/app77.json @@ -32,6 +32,7 @@ "description": "the name", "required": true, "schema": { + "minLength": 1, "type": "string" } } @@ -66,6 +67,7 @@ "description": "the name", "required": true, "schema": { + "minLength": 1, "type": "string" } } @@ -87,4 +89,4 @@ } }, "components": {} -} \ No newline at end of file +} diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app77.json b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app77.json index 0d5e8e402..c2f6288ee 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app77.json +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app77.json @@ -32,7 +32,8 @@ "description": "the name", "required": true, "schema": { - "type": "string" + "type": "string", + "minLength": 1 } } ], @@ -66,7 +67,8 @@ "description": "the name", "required": true, "schema": { - "type": "string" + "type": "string", + "minLength": 1 } } ], @@ -87,4 +89,4 @@ } }, "components": {} -} \ No newline at end of file +} diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 19d03cabe..541e282b4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,13 +2,19 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webflux-tests ${project.artifactId} + + org.springdoc + springdoc-openapi-starter-webflux-api + ${project.version} + test + com.fasterxml.jackson.module jackson-module-kotlin @@ -24,21 +30,14 @@ kotlinx-coroutines-reactor test - - org.springdoc - springdoc-openapi-starter-webflux-api - ${project.version} - test - org.springframework.boot spring-boot-starter-reactor-netty test - io.netty - netty-resolver-dns-native-macos - osx-aarch_64 + org.springframework.boot + spring-boot-jackson test diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 21895779e..64f4c12ef 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,32 +2,32 @@ springdoc-openapi-tests org.springdoc - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webmvc-tests ${project.artifactId} - - com.fasterxml.jackson.module - jackson-module-kotlin - test - org.springdoc springdoc-openapi-starter-webmvc-api ${project.version} test + + com.fasterxml.jackson.module + jackson-module-kotlin + test + org.jetbrains.kotlin kotlin-stdlib-jdk8 test - org.springframework.boot - spring-boot-starter-web + jakarta.servlet + jakarta.servlet-api test diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index fce364bee..cf7fcaf28 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,19 +3,20 @@ org.springdoc springdoc-openapi-tests - 2.8.11-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-security-tests ${project.artifactId} - org.springframework.security - spring-security-web + org.springdoc + springdoc-openapi-starter-webmvc-api + ${project.version} test - org.springframework.security - spring-security-config + org.springframework.boot + spring-boot-security test @@ -24,14 +25,13 @@ test - jakarta.servlet - jakarta.servlet-api + org.springframework.security + spring-security-oauth2-authorization-server test - org.springdoc - springdoc-openapi-starter-webmvc-api - ${project.version} + jakarta.servlet + jakarta.servlet-api test @@ -39,10 +39,5 @@ jjwt test - - org.springframework.security - spring-security-oauth2-authorization-server - test - diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 864da38b3..6c931c2c8 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Configuration; diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app10/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app10/AuthorizationServerConfig.java index 103c585e0..93b80eb86 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app10/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app10/AuthorizationServerConfig.java @@ -35,6 +35,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.jwt.JwtDecoder; @@ -44,6 +45,7 @@ import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.web.SecurityFilterChain; @@ -54,9 +56,14 @@ */ @Configuration public class AuthorizationServerConfig { + @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + var as = OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(as.getEndpointsMatcher()) + .with(as, Customizer.withDefaults()) + .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app11/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app11/AuthorizationServerConfig.java index 56c259d5a..08fcf5f99 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app11/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app11/AuthorizationServerConfig.java @@ -55,11 +55,22 @@ */ @Configuration public class AuthorizationServerConfig { + @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .oidc(Customizer.withDefaults()); + OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = + OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) + .with(authorizationServerConfigurer, (authorizationServer) -> + authorizationServer + .oidc(Customizer.withDefaults()) + ) + .authorizeHttpRequests((authorize) -> + authorize + .anyRequest().authenticated() + ); + return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app12/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app12/AuthorizationServerConfig.java index ca2578d66..b43d3facd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app12/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app12/AuthorizationServerConfig.java @@ -57,9 +57,13 @@ public class AuthorizationServerConfig { @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .oidc(oidc -> oidc.clientRegistrationEndpoint(Customizer.withDefaults())); + var as = OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(as.getEndpointsMatcher()) + .with(as, cfg -> cfg + .oidc(oidc -> oidc.clientRegistrationEndpoint(Customizer.withDefaults())) + ) + .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/WebSecurity.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/WebSecurity.java index 5e9ec33f4..722e96ac9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/WebSecurity.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/WebSecurity.java @@ -27,15 +27,19 @@ package test.org.springdoc.api.v30.app6.security; import org.springdoc.core.properties.SpringDocConfigProperties; +import test.org.springdoc.api.v31.app6.security.JWTAuthenticationFilter; +import test.org.springdoc.api.v31.app6.security.JWTAuthorizationFilter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -81,29 +85,24 @@ public WebSecurity(UserDetailsService userDetailsService) { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { String apiDocsPath = configProperties.getApiDocs().getPath(); - http.cors() - .and() - .csrf() - .disable() - .authorizeRequests() - .requestMatchers(apiDocsPath + ALL_PATTERN) - .permitAll() - .requestMatchers(apiDocsPath.substring(0, apiDocsPath.lastIndexOf("/") + 1) + "api-docs.yaml") - .permitAll() - .anyRequest() - .authenticated() - .and() - .exceptionHandling() - .and() + String apiDocsYaml = apiDocsPath.substring(0, apiDocsPath.lastIndexOf('/') + 1) + "api-docs.yaml"; + + return http + .cors(Customizer.withDefaults()) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(auth -> auth + .requestMatchers(apiDocsPath + ALL_PATTERN).permitAll() + .requestMatchers(apiDocsYaml).permitAll() + .anyRequest().authenticated() + ) .addFilter(new JWTAuthenticationFilter(authenticationManager, lifetime, key)) .addFilter(new JWTAuthorizationFilter(authenticationManager, key)) - // this disables session creation on Spring Security - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - return http.build(); + .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .build(); } + @Autowired public void configure(AuthenticationManagerBuilder auth) throws Exception { diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app8/security/WebConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app8/security/WebConfig.java index 1ca9d2042..8f45b666e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app8/security/WebConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app8/security/WebConfig.java @@ -40,8 +40,9 @@ public class WebConfig { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception { - http.formLogin() - .loginProcessingUrl("/api/login"); + http.formLogin(form -> form + .loginProcessingUrl("/api/login") + ); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app9/WebConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app9/WebConfig.java index a81bf079d..ea661082e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app9/WebConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app9/WebConfig.java @@ -40,8 +40,9 @@ public class WebConfig { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception { - http.formLogin() - .loginProcessingUrl("/api/login"); + http.formLogin(form -> form + .loginProcessingUrl("/api/login") + ); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index fb966e1dc..3a23f2acc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -36,7 +36,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Configuration; diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app10/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app10/AuthorizationServerConfig.java index 00abe57bc..430a12750 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app10/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app10/AuthorizationServerConfig.java @@ -35,6 +35,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.jwt.JwtDecoder; @@ -44,6 +45,7 @@ import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration; +import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer; import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.web.SecurityFilterChain; @@ -54,9 +56,14 @@ */ @Configuration public class AuthorizationServerConfig { + @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); + var as = OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(as.getEndpointsMatcher()) + .with(as, Customizer.withDefaults()) + .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app11/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app11/AuthorizationServerConfig.java index 68325aa54..ef151d06d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app11/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app11/AuthorizationServerConfig.java @@ -57,9 +57,19 @@ public class AuthorizationServerConfig { @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .oidc(Customizer.withDefaults()); + OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = + OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) + .with(authorizationServerConfigurer, (authorizationServer) -> + authorizationServer + .oidc(Customizer.withDefaults()) + ) + .authorizeHttpRequests((authorize) -> + authorize + .anyRequest().authenticated() + ); + return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app12/AuthorizationServerConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app12/AuthorizationServerConfig.java index d11e1cd6c..0f074adbb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app12/AuthorizationServerConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app12/AuthorizationServerConfig.java @@ -55,11 +55,16 @@ */ @Configuration public class AuthorizationServerConfig { + @Bean public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception { - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http); - http.getConfigurer(OAuth2AuthorizationServerConfigurer.class) - .oidc(oidc -> oidc.clientRegistrationEndpoint(Customizer.withDefaults())); + var as = OAuth2AuthorizationServerConfigurer.authorizationServer(); + http + .securityMatcher(as.getEndpointsMatcher()) + .with(as, cfg -> cfg + .oidc(oidc -> oidc.clientRegistrationEndpoint(Customizer.withDefaults())) + ) + .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/WebSecurity.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/WebSecurity.java index edfe0306c..4e1ca9aac 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/WebSecurity.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/WebSecurity.java @@ -33,9 +33,11 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @@ -81,26 +83,20 @@ public WebSecurity(UserDetailsService userDetailsService) { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception { String apiDocsPath = configProperties.getApiDocs().getPath(); - http.cors() - .and() - .csrf() - .disable() - .authorizeRequests() - .requestMatchers(apiDocsPath + ALL_PATTERN) - .permitAll() - .requestMatchers(apiDocsPath.substring(0, apiDocsPath.lastIndexOf("/") + 1) + "api-docs.yaml") - .permitAll() - .anyRequest() - .authenticated() - .and() - .exceptionHandling() - .and() + String apiDocsYaml = apiDocsPath.substring(0, apiDocsPath.lastIndexOf('/') + 1) + "api-docs.yaml"; + + return http + .cors(Customizer.withDefaults()) + .csrf(AbstractHttpConfigurer::disable) + .authorizeHttpRequests(auth -> auth + .requestMatchers(apiDocsPath + ALL_PATTERN).permitAll() + .requestMatchers(apiDocsYaml).permitAll() + .anyRequest().authenticated() + ) .addFilter(new JWTAuthenticationFilter(authenticationManager, lifetime, key)) .addFilter(new JWTAuthorizationFilter(authenticationManager, key)) - // this disables session creation on Spring Security - .sessionManagement() - .sessionCreationPolicy(SessionCreationPolicy.STATELESS); - return http.build(); + .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) + .build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app8/security/WebConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app8/security/WebConfig.java index ff0ff474c..97056aaed 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app8/security/WebConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app8/security/WebConfig.java @@ -40,8 +40,9 @@ public class WebConfig { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception { - http.formLogin() - .loginProcessingUrl("/api/login"); + http.formLogin(form -> form + .loginProcessingUrl("/api/login") + ); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app9/WebConfig.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app9/WebConfig.java index bb5d30d28..8187c6513 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app9/WebConfig.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app9/WebConfig.java @@ -40,8 +40,9 @@ public class WebConfig { @Bean public SecurityFilterChain securityWebFilterChain(HttpSecurity http) throws Exception { - http.formLogin() - .loginProcessingUrl("/api/login"); + http.formLogin(form -> form + .loginProcessingUrl("/api/login") + ); return http.build(); } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/configuration/SecurityConfiguration.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/configuration/SecurityConfiguration.java index c9e98ffa3..533d6328b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/configuration/SecurityConfiguration.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/configuration/SecurityConfiguration.java @@ -46,6 +46,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .authorizeHttpRequests((requests) -> requests.requestMatchers("/**").permitAll()); return http.build(); } + @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration authConfig) throws Exception { From c6b65b2e54b3acc33c57a5ba2cf25fc0f28eb7df Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 10:56:09 +0200 Subject: [PATCH 02/45] Add Spring Boot 4.0.0-M1 support #3062 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 851b03156..3cf5f700c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ ![Octocat](https://springdoc.org/img/banner-logo.svg) -[![Build Status](https://ci-cd.springdoc.org:8443/buildStatus/icon?job=springdoc-openapi-starter-IC)](https://ci-cd.springdoc.org:8443/view/springdoc-openapi/job/springdoc-openapi-starter-IC/) +[![Build Status](https://ci-cd.springdoc.org:8443/buildStatus/icon?job=springdoc-openapi-branch-IC)](https://ci-cd.springdoc.org:8443/view/springdoc-openapi/job/springdoc-openapi-branch-IC/) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=springdoc_springdoc-openapi&metric=alert_status)](https://sonarcloud.io/dashboard?id=springdoc_springdoc-openapi) [![Known Vulnerabilities](https://snyk.io/test/github/springdoc/springdoc-openapi.git/badge.svg)](https://snyk.io/test/github/springdoc/springdoc-openapi.git) [![Stack Exchange questions](https://img.shields.io/stackexchange/stackoverflow/t/springdoc)](https://stackoverflow.com/questions/tagged/springdoc?tab=Votes) From 9545c31ffed60e9f9e5b18e03fe0d2f375f818c6 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 13:27:27 +0200 Subject: [PATCH 03/45] Adding spring-boot 4 pages --- README.md | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3cf5f700c..f6e1a582f 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,6 @@ [![Known Vulnerabilities](https://snyk.io/test/github/springdoc/springdoc-openapi.git/badge.svg)](https://snyk.io/test/github/springdoc/springdoc-openapi.git) [![Stack Exchange questions](https://img.shields.io/stackexchange/stackoverflow/t/springdoc)](https://stackoverflow.com/questions/tagged/springdoc?tab=Votes) -IMPORTANT: ``springdoc-openapi v1.8.0`` is the latest Open Source release supporting -Spring Boot 2.x and 1.x. - -An extended support for [*springdoc-openapi v1*](https://springdoc.org/v1) -project is now available for organizations that need support beyond 2023. - -For more details, feel free to reach -out: [sales@springdoc.org](mailto:sales@springdoc.org) ``springdoc-openapi`` is on [Open Collective](https://opencollective.com/springdoc). If you ❤️ this project consider becoming a [sponsor](https://github.com/sponsors/springdoc). @@ -48,11 +40,11 @@ This project is sponsored by - [Library for springdoc-openapi integration with spring-boot and swagger-ui](#library-for-springdoc-openapi-integration-with-spring-boot-and-swagger-ui) - [Spring-boot with OpenAPI Demo applications.](#spring-boot-with-openapi-demo-applications) - [Source Code for Demo Applications.](#source-code-for-demo-applications) - - [Demo Spring Boot 2 Web MVC with OpenAPI 3.](#demo-spring-boot-2-web-mvc-with-openapi-3) - - [Demo Spring Boot 2 WebFlux with OpenAPI 3.](#demo-spring-boot-2-webflux-with-openapi-3) - - [Demo Spring Boot 2 WebFlux with Functional endpoints OpenAPI 3.](#demo-spring-boot-2-webflux-with-functional-endpoints-openapi-3) - - [Demo Spring Boot 2 and Spring Hateoas with OpenAPI 3.](#demo-spring-boot-2-and-spring-hateoas-with-openapi-3) - - [Integration of the library in a Spring Boot 3.x project without the swagger-ui:](#integration-of-the-library-in-a-spring-boot-3x-project-without-the-swagger-ui) + - [Demo Spring Boot 4 Web MVC with OpenAPI 3.](#demo-spring-boot-4-web-mvc-with-openapi-3) + - [Demo Spring Boot 4 WebFlux with OpenAPI 3.](#demo-spring-boot-4-webflux-with-openapi-3) + - [Demo Spring Boot 4 WebFlux with Functional endpoints OpenAPI 3.](#demo-spring-boot-4-webflux-with-functional-endpoints-openapi-3) + - [Demo Spring Boot 4 and Spring Hateoas with OpenAPI 3.](#demo-spring-boot-4-and-spring-hateoas-with-openapi-3) + - [Integration of the library in a Spring Boot 4.x project without the swagger-ui:](#integration-of-the-library-in-a-spring-boot-3x-project-without-the-swagger-ui) - [Error Handling for REST using @ControllerAdvice](#error-handling-for-rest-using-controlleradvice) - [Adding API Information and Security documentation](#adding-api-information-and-security-documentation) - [spring-webflux support with Annotated Controllers](#spring-webflux-support-with-annotated-controllers) @@ -95,7 +87,7 @@ Pivotal) ## Library for springdoc-openapi integration with spring-boot and swagger-ui -* Automatically deploys swagger-ui to a Spring Boot 3.x application +* Automatically deploys swagger-ui to a Spring Boot 4.x application * Documentation will be available in HTML format, using the official [swagger-ui jars](https://github.com/swagger-api/swagger-ui.git). * The Swagger UI page should then be available at http://server: @@ -135,23 +127,23 @@ springdoc.swagger-ui.path=/swagger-ui.html ## Spring-boot with OpenAPI Demo applications. -### [Source Code for Demo Applications](https://github.com/springdoc/springdoc-openapi-demos/tree/master). +### [Source Code for Demo Applications](https://github.com/springdoc/springdoc-openapi-demos/4.x/master). -## [Demo Spring Boot 3 Web MVC with OpenAPI 3](https://demos.springdoc.org/demo-spring-boot-3-webmvc). +## [Demo Spring Boot 4 Web MVC with OpenAPI 3](https://demos1.springdoc.org/demo-spring-boot-webmvc). -## [Demo Spring Boot 3 WebFlux with OpenAPI 3](https://demos.springdoc.org/demo-spring-boot-3-webflux/swagger-ui.html). +## [Demo Spring Boot 4 WebFlux with OpenAPI 3](https://demos1.springdoc.org/demo-spring-boot-webflux/swagger-ui.html). -## [Demo Spring Boot 3 WebFlux with Functional endpoints OpenAPI 3](https://demos.springdoc.org/demo-spring-boot-3-webflux-functional/swagger-ui.html). +## [Demo Spring Boot 4 WebFlux with Functional endpoints OpenAPI 3](https://demos1.springdoc.org/demo-spring-boot-webflux-functional/swagger-ui.html). -## [Demo Spring Boot 3 and Spring Cloud Function Web MVC](https://demos.springdoc.org/spring-cloud-function-webmvc). +## [Demo Spring Boot 4 and Spring Cloud Function Web MVC](https://demos1.springdoc.org/spring-cloud-function-webmvc). -## [Demo Spring Boot 3 and Spring Cloud Function WebFlux](http://158.101.191.70:8085/swagger-ui.html). +## [Demo Spring Boot 4 and Spring Cloud Function WebFlux](http://158.101.191.70:8085/swagger-ui.html). -## [Demo Spring Boot 3 and Spring Cloud Gateway](https://demos.springdoc.org/demo-microservices/swagger-ui.html). +## [Demo Spring Boot 4 and Spring Cloud Gateway](https://demos1.springdoc.org/demo-microservices/swagger-ui.html). ![Branching](https://springdoc.org/img/pets.png) -## Integration of the library in a Spring Boot 3.x project without the swagger-ui: +## Integration of the library in a Spring Boot 4.x project without the swagger-ui: * Documentation will be available at the following url for json format: http://server: port/context-path/v3/api-docs From 115589097f9439ec067facb99a5e6f223cfc8d73 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 16:30:04 +0200 Subject: [PATCH 04/45] Changes report for #3064 --- .../SpringDocKotlinConfiguration.kt | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt index 5adc7696c..ab3c8a375 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt @@ -69,20 +69,6 @@ class SpringDocKotlinConfiguration() { .addDeprecatedType(Deprecated::class.java) } - @Bean - @ConditionalOnProperty( - name = [Constants.SPRINGDOC_NULLABLE_REQUEST_PARAMETER_ENABLED], - matchIfMissing = true - ) - @Lazy(false) - fun kotlinDefaultsInParamObjects(): DelegatingMethodParameterCustomizer = - DelegatingMethodParameterCustomizer { _, mp -> - val kProp = mp.containingClass.kotlin.primaryConstructor - ?.parameters - ?.firstOrNull { it.name == mp.parameterName } - if (kProp?.isOptional == true) - (mp as DelegatingMethodParameter).isNotRequired = true - } @ConditionalOnClass(name = ["kotlin.reflect.full.KClasses"]) class KotlinReflectDependingConfiguration { @@ -100,6 +86,21 @@ class SpringDocKotlinConfiguration() { fun kotlinModelConverter(objectMapperProvider: ObjectMapperProvider): KotlinInlineClassUnwrappingConverter { return KotlinInlineClassUnwrappingConverter(objectMapperProvider) } + + @Bean + @ConditionalOnProperty( + name = [Constants.SPRINGDOC_NULLABLE_REQUEST_PARAMETER_ENABLED], + matchIfMissing = true + ) + @Lazy(false) + fun kotlinDefaultsInParamObjects(): DelegatingMethodParameterCustomizer = + DelegatingMethodParameterCustomizer { _, mp -> + val kProp = mp.containingClass.kotlin.primaryConstructor + ?.parameters + ?.firstOrNull { it.name == mp.parameterName } + if (kProp?.isOptional == true) + (mp as DelegatingMethodParameter).isNotRequired = true + } } } From 7db34e2ce59ca6f444c62d04a03cc457755cf8ff Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 17:31:57 +0200 Subject: [PATCH 05/45] README.md update for spring-boot-4 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f6e1a582f..e9a90d3fe 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ The generated documentation can be complemented using `swagger-api` annotations. This library supports: * OpenAPI 3 -* Spring-boot v3 (Java 17 & Jakarta EE 9) +* Spring-boot v4 (Java 17 & Jakarta EE 9) * JSR-303, specifically for @NotNull, @Min, @Max, and @Size. * Swagger-ui * OAuth 2 @@ -77,7 +77,7 @@ The following video introduces the Library: * [https://youtu.be/utRxyPfFlDw](https://youtu.be/utRxyPfFlDw) -For *spring-boot v3* support, make sure you +For *Spring-boot v4* support, make sure you use [springdoc-openapi v2](https://springdoc.org/) This is a community-based project, not maintained by the Spring Framework Contributors ( From 31c99b3ae0fed57bb5dbdadca9768d9d05f814d6 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 22 Aug 2025 17:50:21 +0200 Subject: [PATCH 06/45] changes report for #3065 --- .../api/AbstractOpenApiResource.java | 4 ++ .../core/providers/JavadocProvider.java | 5 ++ .../providers/SpringDocJavadocProvider.java | 56 ++++++++++++++++--- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index eb8658110..c275e70b2 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -419,6 +419,10 @@ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { return openAPI; } finally { + JavadocProvider javadocProvider = operationParser.getJavadocProvider(); + if (javadocProvider != null) { + javadocProvider.clean(); + } this.reentrantLock.unlock(); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java index 3615bff3f..3110a56f0 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java @@ -102,4 +102,9 @@ public interface JavadocProvider { * @return the first sentence based on javadoc guidelines */ String getFirstSentence(String text); + + /** + * Clean the temp resources. + */ + default void clean() {} } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java index 33d27636e..b61bc23ff 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java @@ -28,8 +28,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; import com.github.therapi.runtimejavadoc.ClassJavadoc; @@ -56,6 +55,11 @@ public class SpringDocJavadocProvider implements JavadocProvider { */ private final CommentFormatter formatter = new CommentFormatter(); + /** + * The Class javadoc cache. + */ + private final Map, ClassJavadoc> classJavadocCache = new HashMap<>(); + /** * Gets class description. @@ -65,7 +69,7 @@ public class SpringDocJavadocProvider implements JavadocProvider { */ @Override public String getClassJavadoc(Class cl) { - ClassJavadoc classJavadoc = RuntimeJavadoc.getJavadoc(cl); + ClassJavadoc classJavadoc = getJavadoc(cl); return formatter.format(classJavadoc.getComment()); } @@ -77,7 +81,7 @@ public String getClassJavadoc(Class cl) { */ @Override public Map getRecordClassParamJavadoc(Class cl) { - ClassJavadoc classJavadoc = RuntimeJavadoc.getJavadoc(cl); + ClassJavadoc classJavadoc = getJavadoc(cl); return classJavadoc.getRecordComponents().stream() .collect(Collectors.toMap(ParamJavadoc::getName, recordClass -> formatter.format(recordClass.getComment()))); } @@ -90,7 +94,7 @@ public Map getRecordClassParamJavadoc(Class cl) { */ @Override public String getMethodJavadocDescription(Method method) { - MethodJavadoc methodJavadoc = RuntimeJavadoc.getJavadoc(method); + MethodJavadoc methodJavadoc = getJavadoc(method); return formatter.format(methodJavadoc.getComment()); } @@ -102,7 +106,7 @@ public String getMethodJavadocDescription(Method method) { */ @Override public String getMethodJavadocReturn(Method method) { - MethodJavadoc methodJavadoc = RuntimeJavadoc.getJavadoc(method); + MethodJavadoc methodJavadoc = getJavadoc(method); return formatter.format(methodJavadoc.getReturns()); } @@ -113,7 +117,7 @@ public String getMethodJavadocReturn(Method method) { * @return the method throws (name-description map) */ public Map getMethodJavadocThrows(Method method) { - return RuntimeJavadoc.getJavadoc(method) + return getJavadoc(method) .getThrows() .stream() .collect(toMap(ThrowsJavadoc::getName, javadoc -> formatter.format(javadoc.getComment()))); @@ -128,7 +132,7 @@ public Map getMethodJavadocThrows(Method method) { */ @Override public String getParamJavadoc(Method method, String name) { - MethodJavadoc methodJavadoc = RuntimeJavadoc.getJavadoc(method); + MethodJavadoc methodJavadoc = getJavadoc(method); List paramsDoc = methodJavadoc.getParams(); return paramsDoc.stream().filter(paramJavadoc1 -> name.equals(paramJavadoc1.getName())).findAny() .map(paramJavadoc1 -> formatter.format(paramJavadoc1.getComment())).orElse(null); @@ -142,7 +146,7 @@ public String getParamJavadoc(Method method, String name) { */ @Override public String getFieldJavadoc(Field field) { - FieldJavadoc fieldJavadoc = RuntimeJavadoc.getJavadoc(field); + FieldJavadoc fieldJavadoc = getJavadoc(field); return formatter.format(fieldJavadoc.getComment()); } @@ -173,4 +177,38 @@ public String getFirstSentence(String text) { } return text; } + + private ClassJavadoc getJavadoc(Class cl) { + ClassJavadoc classJavadoc = classJavadocCache.get(cl); + if (classJavadoc != null) { + return classJavadoc; + } + classJavadoc = RuntimeJavadoc.getJavadoc(cl); + classJavadocCache.put(cl, classJavadoc); + return classJavadoc; + } + + private MethodJavadoc getJavadoc(Method method) { + ClassJavadoc classJavadoc = getJavadoc(method.getDeclaringClass()); + List paramTypes = Arrays.stream(method.getParameterTypes()) + .map(Class::getCanonicalName) + .toList(); + return classJavadoc.getMethods() + .stream() + .filter(it -> Objects.equals(method.getName(), it.getName()) && Objects.equals(paramTypes, it.getParamTypes())) + .findFirst().orElseGet(() -> MethodJavadoc.createEmpty(method)); + } + + private FieldJavadoc getJavadoc(Field field) { + ClassJavadoc classJavadoc = getJavadoc(field.getDeclaringClass()); + return classJavadoc.getFields() + .stream() + .filter(it -> Objects.equals(field.getName(), it.getName())) + .findFirst().orElseGet(() -> FieldJavadoc.createEmpty(field.getName())); + } + + @Override + public void clean() { + classJavadocCache.clear(); + } } From b403d0fbb4b331e99dc1c815d72f848fd2d13465 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 23 Aug 2025 00:55:16 +0200 Subject: [PATCH 07/45] Add Spring Boot 4.0.0-M2 support #3062 --- pom.xml | 7 ++- .../providers/SpringDocJavadocProvider.java | 6 ++- springdoc-openapi-starter-webflux-api/pom.xml | 6 +-- springdoc-openapi-starter-webflux-ui/pom.xml | 5 -- springdoc-openapi-starter-webmvc-api/pom.xml | 15 ++---- springdoc-openapi-starter-webmvc-ui/pom.xml | 5 -- .../ui/AbstractSpringDocActuatorTest.java | 22 ++++---- .../ui/app13/SpringDocApp13Test.java | 10 +++- .../ui/app14/SpringDocApp14Test.java | 16 ++++-- .../ui/app15/SpringDocApp15Test.java | 14 ++++- .../ui/app16/SpringDocApp16Test.java | 13 ++++- .../pom.xml | 7 +-- .../pom.xml | 5 -- .../v30/AbstractSpringDocActuatorTest.java | 33 +++++++----- .../api/v30/app144/SpringDocApp144Test.java | 9 +++- .../api/v30/app145/SpringDocApp145Test.java | 54 +++++++++---------- .../api/v30/app148/SpringDocApp148Test.java | 22 ++++---- .../v31/AbstractSpringDocActuatorTest.java | 34 +++++++----- .../api/v31/app144/SpringDocApp144Test.java | 12 +++-- .../api/v31/app145/SpringDocApp145Test.java | 53 +++++++++--------- .../api/v31/app148/SpringDocApp148Test.java | 22 ++++---- .../springdoc-openapi-javadoc-tests/pom.xml | 5 -- .../pom.xml | 5 -- 23 files changed, 203 insertions(+), 177 deletions(-) diff --git a/pom.xml b/pom.xml index cd8ea9260..422d7c610 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 4.0.0-M1 + 4.0.0-M2 @@ -104,6 +104,11 @@ spring-boot-starter-test test + + org.springframework.boot + spring-boot-jackson + test + diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java index b61bc23ff..ebffd6999 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java @@ -28,7 +28,11 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; import com.github.therapi.runtimejavadoc.ClassJavadoc; diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 0fafb0a14..38c9117b3 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -29,11 +29,7 @@ true - - org.springframework.boot - spring-boot-jackson - test - + diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index 1194f54df..bbc1d3512 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -34,11 +34,6 @@ spring-boot-reactor-netty test - - org.springframework.boot - spring-boot-jackson - test - diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 0424f1e8e..293756279 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -22,28 +22,23 @@ org.springframework.boot spring-boot-web-server + + jakarta.servlet + jakarta.servlet-api + provided + org.springframework.boot spring-boot-actuator-autoconfigure true - - jakarta.servlet - jakarta.servlet-api - provided - javax.money money-api test - - org.springframework.boot - spring-boot-jackson - test - diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 9d4aca623..93802d2b7 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -34,11 +34,6 @@ spring-boot-actuator-autoconfigure true - - org.springframework.boot - spring-boot-restclient - test - org.springframework.boot spring-boot-tomcat diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java index 3ca221909..ccbe9aa31 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java @@ -25,26 +25,30 @@ package test.org.springdoc.ui; +import java.net.http.HttpClient; + import jakarta.annotation.PostConstruct; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.web.server.test.LocalManagementPort; -import org.springframework.web.client.RestTemplate; +import org.springframework.http.client.JdkClientHttpRequestFactory; +import org.springframework.web.client.RestClient; public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { - protected RestTemplate actuatorRestTemplate; + protected RestClient actuatorClient; @LocalManagementPort private int managementPort; - @Autowired - private RestTemplateBuilder restTemplateBuilder; - @PostConstruct void init() { - actuatorRestTemplate = restTemplateBuilder - .rootUri("http://localhost:" + this.managementPort).build(); + HttpClient jdkClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + this.actuatorClient = RestClient.builder() + .requestFactory(new JdkClientHttpRequestFactory(jdkClient)) + .baseUrl("http://localhost:" + managementPort) + .build(); } + } diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app13/SpringDocApp13Test.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app13/SpringDocApp13Test.java index ca4b91e7d..58bde1229 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app13/SpringDocApp13Test.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app13/SpringDocApp13Test.java @@ -45,13 +45,19 @@ void testIndex() throws Exception { @Test void testIndexActuator() { - String contentAsString = actuatorRestTemplate.getForObject("/application/swagger-ui", String.class); + String contentAsString = actuatorClient.get() + .uri("/application/swagger-ui") + .retrieve() + .body(String.class); assertTrue(contentAsString.contains("Swagger UI")); } @Test void testIndexSwaggerConfig() throws Exception { - String contentAsString = actuatorRestTemplate.getForObject("/application/swagger-ui/swagger-config", String.class); + String contentAsString = actuatorClient.get() + .uri("/application/swagger-ui/swagger-config") + .retrieve() + .body(String.class); String expected = getContent("results/app13-1.json"); assertEquals(expected, contentAsString, true); } diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app14/SpringDocApp14Test.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app14/SpringDocApp14Test.java index 57427c878..5b587e628 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app14/SpringDocApp14Test.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app14/SpringDocApp14Test.java @@ -42,18 +42,26 @@ void testIndex() throws Exception { String contentAsString = mvcResult.getResponse().getContentAsString(); assertTrue(contentAsString.contains("Swagger UI")); } - @Test void testIndexActuator() { - String contentAsString = actuatorRestTemplate.getForObject("/application/swagger-ui", String.class); + String contentAsString = actuatorClient.get() + .uri("/application/swagger-ui") + .retrieve() + .body(String.class); + assertTrue(contentAsString.contains("Swagger UI")); } @Test void testIndexSwaggerConfig() throws Exception { - String contentAsString = actuatorRestTemplate.getForObject("/application/swagger-ui/swagger-config", String.class); + String contentAsString = actuatorClient.get() + .uri("/application/swagger-ui/swagger-config") + .retrieve() + .body(String.class); + String expected = getContent("results/app14-1.json"); - assertEquals(expected, contentAsString, true); + + assertEquals(expected, contentAsString, true); // true = strict comparison } @SpringBootApplication diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app15/SpringDocApp15Test.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app15/SpringDocApp15Test.java index 88675ccba..3d130c2ef 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app15/SpringDocApp15Test.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app15/SpringDocApp15Test.java @@ -46,16 +46,26 @@ void testIndex() throws Exception { assertTrue(contentAsString.contains("Swagger UI")); } + @Test void testIndexActuator() { - String contentAsString = actuatorRestTemplate.getForObject("/test/application/swagger-ui", String.class); + String contentAsString = actuatorClient.get() + .uri("/test/application/swagger-ui") + .retrieve() + .body(String.class); + assertTrue(contentAsString.contains("Swagger UI")); } @Test void testIndexSwaggerConfig() throws Exception { - String contentAsString = actuatorRestTemplate.getForObject("/test/application/swagger-ui/swagger-config", String.class); + String contentAsString = actuatorClient.get() + .uri("/test/application/swagger-ui/swagger-config") + .retrieve() + .body(String.class); + String expected = getContent("results/app15-1.json"); + assertEquals(expected, contentAsString, true); } diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app16/SpringDocApp16Test.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app16/SpringDocApp16Test.java index e7a9d7eea..edcc000cd 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app16/SpringDocApp16Test.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/app16/SpringDocApp16Test.java @@ -48,14 +48,23 @@ void testIndex() throws Exception { @Test void testIndexActuator() { - String contentAsString = actuatorRestTemplate.getForObject("/test/application/swagger-ui", String.class); + String contentAsString = actuatorClient.get() + .uri("/test/application/swagger-ui") + .retrieve() + .body(String.class); + assertTrue(contentAsString.contains("Swagger UI")); } @Test void testIndexSwaggerConfig() throws Exception { - String contentAsString = actuatorRestTemplate.getForObject("/test/application/swagger-ui/swagger-config", String.class); + String contentAsString = actuatorClient.get() + .uri("/test/application/swagger-ui/swagger-config") + .retrieve() + .body(String.class); + String expected = getContent("results/app16-1.json"); + assertEquals(expected, contentAsString, true); } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 5e414319a..35b8f28f9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -17,11 +17,6 @@ test - - org.springframework.boot - spring-boot-reactor-netty - test - org.springframework.boot spring-boot-starter-actuator @@ -29,7 +24,7 @@ org.springframework.boot - spring-boot-jackson + spring-boot-reactor-netty test diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 80067c67e..064ff4a05 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -22,11 +22,6 @@ spring-boot-starter-actuator test - - org.springframework.boot - spring-boot-restclient - test - org.springframework.boot spring-boot-tomcat diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java index 1d2774164..74866402b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java @@ -26,16 +26,18 @@ package test.org.springdoc.api.v30; +import java.net.http.HttpClient; + import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.test.context.TestPropertySource; -import org.springframework.web.client.RestTemplate; +import org.springframework.web.client.RestClient; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; @TestPropertySource(properties = { "management.endpoints.enabled-by-default=true" }) @@ -43,29 +45,34 @@ public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCommonTest.class); - protected RestTemplate actuatorRestTemplate; + protected RestClient actuatorClient; @LocalManagementPort private int managementPort; - @Autowired - private RestTemplateBuilder restTemplateBuilder; - @PostConstruct void init() { - actuatorRestTemplate = restTemplateBuilder - .rootUri("http://localhost:" + this.managementPort).build(); + HttpClient jdkClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + this.actuatorClient = RestClient.builder() + .requestFactory(new JdkClientHttpRequestFactory(jdkClient)) + .baseUrl("http://localhost:" + managementPort) + .build(); } protected void testWithRestTemplate(String testId, String uri) throws Exception { String result = null; try { - result = actuatorRestTemplate.getForObject(uri, String.class); + result = actuatorClient.get() + .uri(uri) + .retrieve() + .body(String.class); + assertNotNull(result, "Response body was null for URI: " + uri); String expected = getContent("results/3.0.1/app" + testId + ".json"); assertEquals(expected, result, true); - } - catch (AssertionError e) { - LOGGER.error(result); + } catch (AssertionError e) { + LOGGER.error("JSON response for [{}]:\n{}", uri, result); throw e; } } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app144/SpringDocApp144Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app144/SpringDocApp144Test.java index 1ea455b4f..41e983761 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app144/SpringDocApp144Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app144/SpringDocApp144Test.java @@ -26,6 +26,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -47,9 +48,13 @@ void testApp() throws Exception { @Test void testApp1() throws Exception { - String result = actuatorRestTemplate.getForObject("/application/openapi", String.class); + String result = actuatorClient.get() + .uri("/application/openapi") + .retrieve() + .body(String.class); + assertNotNull(result, "Response body was null"); String expected = getContent("results/3.0.1/app144.json"); - assertEquals(expected, result, true); + assertEquals(expected, result, true); // strict JSON comparison } @SpringBootApplication diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app145/SpringDocApp145Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app145/SpringDocApp145Test.java index 3ac609f88..6126895f1 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app145/SpringDocApp145Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app145/SpringDocApp145Test.java @@ -19,6 +19,7 @@ package test.org.springdoc.api.v30.app145; import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; import org.springdoc.core.utils.Constants; import test.org.springdoc.api.v30.AbstractSpringDocActuatorTest; @@ -27,11 +28,10 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpStatus; import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestClientResponseException; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -53,38 +53,38 @@ void testApp() throws Exception { } @Test - void testApp1() throws Exception { - try { - actuatorRestTemplate.getForObject("/application/openapi", String.class); - fail(); - } - catch (HttpClientErrorException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - else - fail(); - } + void testApp1() { + // expect 404 on /application/openapi + assertThrows(HttpClientErrorException.NotFound.class, () -> + actuatorClient.get() + .uri("/application/openapi") + .retrieve() + .body(String.class) + ); } @Test void testApp2() throws Exception { - String result = actuatorRestTemplate.getForObject("/application/openapi/users", String.class); + String result = actuatorClient.get() + .uri("/application/openapi/users") + .retrieve() + .body(String.class); + String expected = getContent("results/3.0.1/app145.json"); - assertEquals(expected, result, true); + // strict JSON comparison (structure, values, no extras) + JSONAssert.assertEquals(expected, result, true); } @Test - void testApp3() throws Exception { - try { - actuatorRestTemplate.getForObject("/application/openapi" + "/" + Constants.DEFAULT_GROUP_NAME, String.class); - fail(); - } - catch (HttpStatusCodeException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - } + void testApp3() { + RestClientResponseException ex = assertThrows(RestClientResponseException.class, () -> + actuatorClient.get() + .uri("/application/openapi/{group}", Constants.DEFAULT_GROUP_NAME) + .retrieve() + .body(String.class) + ); + assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); } - @SpringBootApplication static class SpringDocTestApp {} } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app148/SpringDocApp148Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app148/SpringDocApp148Test.java index 18fa2c940..4a12bf3ef 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app148/SpringDocApp148Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/app148/SpringDocApp148Test.java @@ -25,11 +25,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.HttpClientErrorException; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, @@ -56,15 +54,13 @@ void testApp2() throws Exception { } @Test - void testApp3() throws Exception { - try { - actuatorRestTemplate.getForObject("/test/application/openapi" + "/" + Constants.DEFAULT_GROUP_NAME, String.class); - fail(); - } - catch (HttpStatusCodeException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - } + void testApp3() { + assertThrows(HttpClientErrorException.NotFound.class, () -> + actuatorClient.get() + .uri("/test/application/openapi/{group}", Constants.DEFAULT_GROUP_NAME) + .retrieve() + .body(String.class) + ); } @SpringBootApplication diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java index 84944977d..6a0a3cf6d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java @@ -26,16 +26,18 @@ package test.org.springdoc.api.v31; +import java.net.http.HttpClient; + import jakarta.annotation.PostConstruct; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.restclient.RestTemplateBuilder; import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.test.context.TestPropertySource; -import org.springframework.web.client.RestTemplate; +import org.springframework.web.client.RestClient; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; @TestPropertySource(properties = { "management.endpoints.enabled-by-default=true" }) @@ -43,31 +45,37 @@ public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCommonTest.class); - protected RestTemplate actuatorRestTemplate; + protected RestClient actuatorClient; @LocalManagementPort private int managementPort; - @Autowired - private RestTemplateBuilder restTemplateBuilder; - @PostConstruct void init() { - actuatorRestTemplate = restTemplateBuilder - .rootUri("http://localhost:" + this.managementPort).build(); + HttpClient jdkClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + this.actuatorClient = RestClient.builder() + .requestFactory(new JdkClientHttpRequestFactory(jdkClient)) + .baseUrl("http://localhost:" + managementPort) + .build(); } protected void testWithRestTemplate(String testId, String uri) throws Exception { String result = null; try { - result = actuatorRestTemplate.getForObject(uri, String.class); + result = actuatorClient.get() + .uri(uri) + .retrieve() + .body(String.class); + assertNotNull(result, "Response body was null for URI: " + uri); String expected = getContent("results/3.1.0/app" + testId + ".json"); assertEquals(expected, result, true); - } - catch (AssertionError e) { - LOGGER.error(result); + } catch (AssertionError e) { + LOGGER.error("JSON response for [{}]:\n{}", uri, result); throw e; } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app144/SpringDocApp144Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app144/SpringDocApp144Test.java index 19c78b23e..4e601cc61 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app144/SpringDocApp144Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app144/SpringDocApp144Test.java @@ -19,6 +19,7 @@ package test.org.springdoc.api.v31.app144; import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; import org.springdoc.core.utils.Constants; import test.org.springdoc.api.v31.AbstractSpringDocActuatorTest; @@ -26,7 +27,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -45,11 +46,16 @@ void testApp() throws Exception { .andExpect(status().isNotFound()); } + @Test void testApp1() throws Exception { - String result = actuatorRestTemplate.getForObject("/application/openapi", String.class); + String result = actuatorClient.get() + .uri("/application/openapi") + .retrieve() + .body(String.class); + assertNotNull(result, "Response body was null"); String expected = getContent("results/3.1.0/app144.json"); - assertEquals(expected, result, true); + JSONAssert.assertEquals(expected, result, true); // strict JSON comparison } @SpringBootApplication diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app145/SpringDocApp145Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app145/SpringDocApp145Test.java index a2b9b22f1..dc75091b7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app145/SpringDocApp145Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app145/SpringDocApp145Test.java @@ -19,6 +19,7 @@ package test.org.springdoc.api.v31.app145; import org.junit.jupiter.api.Test; +import org.skyscreamer.jsonassert.JSONAssert; import org.springdoc.core.utils.Constants; import test.org.springdoc.api.v31.AbstractSpringDocActuatorTest; @@ -27,11 +28,10 @@ import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpStatus; import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.RestClientResponseException; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -53,36 +53,37 @@ void testApp() throws Exception { } @Test - void testApp1() throws Exception { - try { - actuatorRestTemplate.getForObject("/application/openapi", String.class); - fail(); - } - catch (HttpClientErrorException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - else - fail(); - } + void testApp1() { + // /application/openapi should be 404 + assertThrows(HttpClientErrorException.NotFound.class, () -> + actuatorClient.get() + .uri("/application/openapi") + .retrieve() + .body(String.class) + ); } @Test void testApp2() throws Exception { - String result = actuatorRestTemplate.getForObject("/application/openapi/users", String.class); + String result = actuatorClient.get() + .uri("/application/openapi/users") + .retrieve() + .body(String.class); + String expected = getContent("results/3.1.0/app145.json"); - assertEquals(expected, result, true); + // strict JSON comparison + JSONAssert.assertEquals(expected, result, true); } @Test - void testApp3() throws Exception { - try { - actuatorRestTemplate.getForObject("/application/openapi" + "/" + Constants.DEFAULT_GROUP_NAME, String.class); - fail(); - } - catch (HttpStatusCodeException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - } + void testApp3() { + RestClientResponseException ex = assertThrows(RestClientResponseException.class, () -> + actuatorClient.get() + .uri("/application/openapi/{group}", Constants.DEFAULT_GROUP_NAME) + .retrieve() + .body(String.class) + ); + assertEquals(HttpStatus.NOT_FOUND, ex.getStatusCode()); } @SpringBootApplication diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app148/SpringDocApp148Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app148/SpringDocApp148Test.java index 6232ca977..05bb9c01e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app148/SpringDocApp148Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/app148/SpringDocApp148Test.java @@ -25,11 +25,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.http.HttpStatus; -import org.springframework.web.client.HttpStatusCodeException; +import org.springframework.web.client.HttpClientErrorException; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.assertThrows; @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, @@ -56,15 +54,13 @@ void testApp2() throws Exception { } @Test - void testApp3() throws Exception { - try { - actuatorRestTemplate.getForObject("/test/application/openapi" + "/" + Constants.DEFAULT_GROUP_NAME, String.class); - fail(); - } - catch (HttpStatusCodeException ex) { - if (ex.getStatusCode() == HttpStatus.NOT_FOUND) - assertTrue(true); - } + void testApp3() { + assertThrows(HttpClientErrorException.NotFound.class, () -> + actuatorClient.get() + .uri("/test/application/openapi/{group}", Constants.DEFAULT_GROUP_NAME) + .retrieve() + .body(String.class) + ); } @SpringBootApplication diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 550cd3f68..a662c2bfb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -33,11 +33,6 @@ money-api test - - org.springframework.boot - spring-boot-jackson - test - diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 541e282b4..61e033943 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -35,11 +35,6 @@ spring-boot-starter-reactor-netty test - - org.springframework.boot - spring-boot-jackson - test - From 6e17128fdd986543e3d7d9de4dc889e9ae8ad640 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 23 Aug 2025 01:39:08 +0200 Subject: [PATCH 08/45] perf test --- springdoc-openapi-starter-webmvc-api/pom.xml | 42 ++++++ .../test/groovy/v31/app248/generate.groovy | 124 ++++++++++++++++++ .../api/v31/app248/SpringDocApp248Test.java | 37 ++++++ .../springdoc/api/v31/app248/dto/Address.java | 59 +++++++++ .../api/v31/app248/dto/AddressCity.java | 18 +++ .../api/v31/app248/dto/AddressCountry.java | 18 +++ .../api/v31/app248/dto/AddressLine.java | 19 +++ .../api/v31/app248/dto/AddressState.java | 18 +++ 8 files changed, 335 insertions(+) create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 293756279..76607baa5 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -39,9 +39,51 @@ money-api test + + org.apache.groovy + groovy + test + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-generated-test-sources + generate-test-sources + + add-test-source + + + + target/generated-test-sources + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + ${gmavenplus-plugin.version} + + + generate-dtos + generate-test-sources + + execute + + + + + + + + + org.apache.maven.plugins maven-jar-plugin diff --git a/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy b/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy new file mode 100644 index 000000000..42b0224da --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy @@ -0,0 +1,124 @@ +package v31.app248 + +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +BASE_PACKAGE = 'test.org.springdoc.api.v31.app248' + +def parse(String qualifiedClassName) { + parts = qualifiedClassName.split('\\.') + packages = parts[0..-2] + className = parts[-1] + return [className, packages] +} + +def package_name(List packages) { + return String.join('.', [BASE_PACKAGE] + packages) +} + +def directory(List packages) { + packages = BASE_PACKAGE.split('\\.') + packages + return Paths.get(project.build.directory, "generated-test-sources", *packages) +} + +Path filePath(String className, List packages) { + return directory(packages).resolve(className + ".java") +} + +def generateDTO(String className, properties) { + (className, packages) = parse(className) + def package_ = package_name(packages) + def path = filePath(className, packages) + Files.createDirectories(path.parent) + Files.newBufferedWriter(path).withWriter { w -> + w << "package ${package_};\n\n" + w << "public class ${className} {\n\n" + properties.each { type, name -> + w << "\tprivate $type $name;\n\n" + } + w << "\tpublic $className() {}\n\n" + properties.each { type, name -> + def capitalized = name.capitalize() + w << "\tpublic $type get$capitalized() {\n" + w << "\t\treturn this.$name;\n" + w << "\t}\n\n" + w << "\tpublic void set$capitalized($type $name) {\n" + w << "\t\tthis.$name = $name;\n" + w << "\t}\n\n" + } + w << "}\n\n" + } +} + +def generateController(String className, String requestPath) { + def imports = [ + 'java.util.List', + 'org.springframework.http.ResponseEntity', + 'org.springframework.web.bind.annotation.GetMapping', + 'org.springframework.web.bind.annotation.PostMapping', + 'org.springframework.web.bind.annotation.RequestMapping', + 'org.springframework.web.bind.annotation.RestController', + 'test.org.springdoc.api.v31.app248.dto.PersonDTO' + ] + + (className, packages) = parse(className) + def package_ = package_name(packages) + def path = filePath(className, packages) + Files.createDirectories(path.parent) + Files.newBufferedWriter(path).withWriter { w -> + w << "package ${package_};\n\n" + imports.each { imp -> w << "import $imp;\n\n" } + w << "\n@RestController\n" + w << "@RequestMapping(\"$requestPath\")\n" + w << "public class ${className} {\n\n" + w << "\t@PostMapping\n" + w << "\tpublic ResponseEntity createPerson(PersonDTO createDto) {\n" + w << "\t\treturn null;\n" + w << "\t}\n\n" + w << "\t@GetMapping\n" + w << "\tpublic ResponseEntity> listPerson() {\n" + w << "\t\treturn null;\n" + w << "\t}\n\n" + w << "\t@GetMapping(\"{id}\")\n" + w << "\tpublic ResponseEntity getPerson(Long id) {\n" + w << "\t\treturn null;\n" + w << "\t}\n\n" + w << "}\n" + } +} + +def main() { + generateDTO('dto.PersonDTO', [ + ['Long', 'id'], + ['String', 'name'], + ['Address', 'address'], + ['PersonDetails1', 'details'] + ]) + + def numControllers = 200 + def numDtos = 512 + (1..numDtos).each { i -> + def className = "dto.PersonDetails$i" + def props = [['String', 'value']] + if (2 * i <= numDtos) { + props << ["PersonDetails${2 * i}", 'details1'] + } + if (2 * i + 1 <= numDtos) { + props << ["PersonDetails${2 * i + 1}", 'details2'] + } + generateDTO(className, props) + } + + (1..numControllers).each { i -> + generateController("controller.Hello${i}Controller", "test${i}") + } + + Paths.get(project.build.directory, "generated-test-sources") + .toFile() + .eachFileRecurse {file -> + println(file) + } +} + +main() \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java new file mode 100644 index 000000000..dbd86bfdf --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java @@ -0,0 +1,37 @@ +package test.org.springdoc.api.v31.app248; + + +import java.time.Duration; + +import org.junit.jupiter.api.Test; +import org.springdoc.core.utils.Constants; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import test.org.springdoc.api.AbstractCommonTest; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest(properties = { + "logging.level.io.swagger=DEBUG" +}) +public class SpringDocApp248Test extends AbstractCommonTest { + + public static String className; + + @Test + void performanceTest() { + className = getClass().getSimpleName(); + assertTimeout(Duration.ofSeconds(2), () -> { + mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk()) + .andExpect(jsonPath("$.openapi", is("3.1.0"))).andReturn(); + }); + } + + @SpringBootApplication + static class SpringDocTestApp { + + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java new file mode 100644 index 000000000..a4fabf3cd --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java @@ -0,0 +1,59 @@ +package test.org.springdoc.api.v31.app248.dto; + +/** + * @author bnasslahsen + */ + +public class Address { + private AddressLine line1; + + private AddressLine line2; + + private AddressCity city; + + private AddressState state; + + private AddressCountry country; + + public Address() {} + + public AddressLine getLine1() { + return line1; + } + + public void setLine1(AddressLine line1) { + this.line1 = line1; + } + + public AddressLine getLine2() { + return line2; + } + + public void setLine2(AddressLine line2) { + this.line2 = line2; + } + + public AddressCity getCity() { + return city; + } + + public void setCity(AddressCity city) { + this.city = city; + } + + public AddressState getState() { + return state; + } + + public void setState(AddressState state) { + this.state = state; + } + + public AddressCountry getCountry() { + return country; + } + + public void setCountry(AddressCountry country) { + this.country = country; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java new file mode 100644 index 000000000..e07850ec0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java @@ -0,0 +1,18 @@ +package test.org.springdoc.api.v31.app248.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public class AddressCity { + private final String value; + + @JsonCreator + public AddressCity(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java new file mode 100644 index 000000000..685654a50 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java @@ -0,0 +1,18 @@ +package test.org.springdoc.api.v31.app248.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public class AddressCountry { + private final String value; + + @JsonCreator + public AddressCountry(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java new file mode 100644 index 000000000..872f80ce3 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java @@ -0,0 +1,19 @@ +package test.org.springdoc.api.v31.app248.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + +public class AddressLine { + private final String value; + + @JsonCreator + public AddressLine(@JsonProperty("value") String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java new file mode 100644 index 000000000..90d2a90c0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java @@ -0,0 +1,18 @@ +package test.org.springdoc.api.v31.app248.dto; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public class AddressState { + private final String value; + + @JsonCreator + public AddressState(String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } +} \ No newline at end of file From 1820e97467cae1f9eaa9c9e6dc0457d2d367160c Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 23 Aug 2025 01:41:52 +0200 Subject: [PATCH 09/45] perf test --- springdoc-openapi-starter-webmvc-api/pom.xml | 42 ------ .../test/groovy/v31/app248/generate.groovy | 124 ------------------ .../api/v31/app248/SpringDocApp248Test.java | 37 ------ .../springdoc/api/v31/app248/dto/Address.java | 59 --------- .../api/v31/app248/dto/AddressCity.java | 18 --- .../api/v31/app248/dto/AddressCountry.java | 18 --- .../api/v31/app248/dto/AddressLine.java | 19 --- .../api/v31/app248/dto/AddressState.java | 18 --- 8 files changed, 335 deletions(-) delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java delete mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 76607baa5..293756279 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -39,51 +39,9 @@ money-api test - - org.apache.groovy - groovy - test - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-generated-test-sources - generate-test-sources - - add-test-source - - - - target/generated-test-sources - - - - - - - org.codehaus.gmavenplus - gmavenplus-plugin - ${gmavenplus-plugin.version} - - - generate-dtos - generate-test-sources - - execute - - - - - - - - - org.apache.maven.plugins maven-jar-plugin diff --git a/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy b/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy deleted file mode 100644 index 42b0224da..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/groovy/v31/app248/generate.groovy +++ /dev/null @@ -1,124 +0,0 @@ -package v31.app248 - -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths - -BASE_PACKAGE = 'test.org.springdoc.api.v31.app248' - -def parse(String qualifiedClassName) { - parts = qualifiedClassName.split('\\.') - packages = parts[0..-2] - className = parts[-1] - return [className, packages] -} - -def package_name(List packages) { - return String.join('.', [BASE_PACKAGE] + packages) -} - -def directory(List packages) { - packages = BASE_PACKAGE.split('\\.') + packages - return Paths.get(project.build.directory, "generated-test-sources", *packages) -} - -Path filePath(String className, List packages) { - return directory(packages).resolve(className + ".java") -} - -def generateDTO(String className, properties) { - (className, packages) = parse(className) - def package_ = package_name(packages) - def path = filePath(className, packages) - Files.createDirectories(path.parent) - Files.newBufferedWriter(path).withWriter { w -> - w << "package ${package_};\n\n" - w << "public class ${className} {\n\n" - properties.each { type, name -> - w << "\tprivate $type $name;\n\n" - } - w << "\tpublic $className() {}\n\n" - properties.each { type, name -> - def capitalized = name.capitalize() - w << "\tpublic $type get$capitalized() {\n" - w << "\t\treturn this.$name;\n" - w << "\t}\n\n" - w << "\tpublic void set$capitalized($type $name) {\n" - w << "\t\tthis.$name = $name;\n" - w << "\t}\n\n" - } - w << "}\n\n" - } -} - -def generateController(String className, String requestPath) { - def imports = [ - 'java.util.List', - 'org.springframework.http.ResponseEntity', - 'org.springframework.web.bind.annotation.GetMapping', - 'org.springframework.web.bind.annotation.PostMapping', - 'org.springframework.web.bind.annotation.RequestMapping', - 'org.springframework.web.bind.annotation.RestController', - 'test.org.springdoc.api.v31.app248.dto.PersonDTO' - ] - - (className, packages) = parse(className) - def package_ = package_name(packages) - def path = filePath(className, packages) - Files.createDirectories(path.parent) - Files.newBufferedWriter(path).withWriter { w -> - w << "package ${package_};\n\n" - imports.each { imp -> w << "import $imp;\n\n" } - w << "\n@RestController\n" - w << "@RequestMapping(\"$requestPath\")\n" - w << "public class ${className} {\n\n" - w << "\t@PostMapping\n" - w << "\tpublic ResponseEntity createPerson(PersonDTO createDto) {\n" - w << "\t\treturn null;\n" - w << "\t}\n\n" - w << "\t@GetMapping\n" - w << "\tpublic ResponseEntity> listPerson() {\n" - w << "\t\treturn null;\n" - w << "\t}\n\n" - w << "\t@GetMapping(\"{id}\")\n" - w << "\tpublic ResponseEntity getPerson(Long id) {\n" - w << "\t\treturn null;\n" - w << "\t}\n\n" - w << "}\n" - } -} - -def main() { - generateDTO('dto.PersonDTO', [ - ['Long', 'id'], - ['String', 'name'], - ['Address', 'address'], - ['PersonDetails1', 'details'] - ]) - - def numControllers = 200 - def numDtos = 512 - (1..numDtos).each { i -> - def className = "dto.PersonDetails$i" - def props = [['String', 'value']] - if (2 * i <= numDtos) { - props << ["PersonDetails${2 * i}", 'details1'] - } - if (2 * i + 1 <= numDtos) { - props << ["PersonDetails${2 * i + 1}", 'details2'] - } - generateDTO(className, props) - } - - (1..numControllers).each { i -> - generateController("controller.Hello${i}Controller", "test${i}") - } - - Paths.get(project.build.directory, "generated-test-sources") - .toFile() - .eachFileRecurse {file -> - println(file) - } -} - -main() \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java deleted file mode 100644 index dbd86bfdf..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java +++ /dev/null @@ -1,37 +0,0 @@ -package test.org.springdoc.api.v31.app248; - - -import java.time.Duration; - -import org.junit.jupiter.api.Test; -import org.springdoc.core.utils.Constants; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import test.org.springdoc.api.AbstractCommonTest; -import static org.hamcrest.Matchers.is; -import static org.junit.jupiter.api.Assertions.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -@SpringBootTest(properties = { - "logging.level.io.swagger=DEBUG" -}) -public class SpringDocApp248Test extends AbstractCommonTest { - - public static String className; - - @Test - void performanceTest() { - className = getClass().getSimpleName(); - assertTimeout(Duration.ofSeconds(2), () -> { - mockMvc.perform(get(Constants.DEFAULT_API_DOCS_URL)).andExpect(status().isOk()) - .andExpect(jsonPath("$.openapi", is("3.1.0"))).andReturn(); - }); - } - - @SpringBootApplication - static class SpringDocTestApp { - - } -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java deleted file mode 100644 index a4fabf3cd..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/Address.java +++ /dev/null @@ -1,59 +0,0 @@ -package test.org.springdoc.api.v31.app248.dto; - -/** - * @author bnasslahsen - */ - -public class Address { - private AddressLine line1; - - private AddressLine line2; - - private AddressCity city; - - private AddressState state; - - private AddressCountry country; - - public Address() {} - - public AddressLine getLine1() { - return line1; - } - - public void setLine1(AddressLine line1) { - this.line1 = line1; - } - - public AddressLine getLine2() { - return line2; - } - - public void setLine2(AddressLine line2) { - this.line2 = line2; - } - - public AddressCity getCity() { - return city; - } - - public void setCity(AddressCity city) { - this.city = city; - } - - public AddressState getState() { - return state; - } - - public void setState(AddressState state) { - this.state = state; - } - - public AddressCountry getCountry() { - return country; - } - - public void setCountry(AddressCountry country) { - this.country = country; - } -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java deleted file mode 100644 index e07850ec0..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCity.java +++ /dev/null @@ -1,18 +0,0 @@ -package test.org.springdoc.api.v31.app248.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -public class AddressCity { - private final String value; - - @JsonCreator - public AddressCity(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java deleted file mode 100644 index 685654a50..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressCountry.java +++ /dev/null @@ -1,18 +0,0 @@ -package test.org.springdoc.api.v31.app248.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -public class AddressCountry { - private final String value; - - @JsonCreator - public AddressCountry(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java deleted file mode 100644 index 872f80ce3..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressLine.java +++ /dev/null @@ -1,19 +0,0 @@ -package test.org.springdoc.api.v31.app248.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.annotation.JsonValue; - -public class AddressLine { - private final String value; - - @JsonCreator - public AddressLine(@JsonProperty("value") String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } -} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java deleted file mode 100644 index 90d2a90c0..000000000 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/dto/AddressState.java +++ /dev/null @@ -1,18 +0,0 @@ -package test.org.springdoc.api.v31.app248.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -public class AddressState { - private final String value; - - @JsonCreator - public AddressState(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } -} \ No newline at end of file From 8184f8019c8fd90baab0c02fa0c140a3da5b79f7 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 23 Aug 2025 13:56:54 +0200 Subject: [PATCH 10/45] Performance tunning --- .../api/AbstractOpenApiResource.java | 16 +--- .../converters/AdditionalModelsConverter.java | 19 ++--- .../core/providers/JavadocProvider.java | 2 +- .../providers/SpringDocJavadocProvider.java | 2 +- .../core/service/AbstractRequestService.java | 4 + .../core/service/GenericResponseService.java | 15 +--- .../core/service/OpenAPIService.java | 11 +-- .../core/utils/SpringDocAnnotationsUtils.java | 74 ++++++++++++++++--- .../springdoc/core/utils/SpringDocUtils.java | 52 +++++++++++++ .../security/JWTAuthenticationFilter.java | 7 +- .../security/JWTAuthenticationFilter.java | 7 +- 11 files changed, 142 insertions(+), 67 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index c275e70b2..3c016f624 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -109,6 +109,7 @@ import org.springdoc.core.service.OpenAPIService; import org.springdoc.core.service.OperationService; import org.springdoc.core.utils.PropertyResolverUtils; +import org.springdoc.core.utils.SpringDocAnnotationsUtils; import org.springdoc.core.utils.SpringDocUtils; import org.springframework.aop.support.AopUtils; @@ -131,6 +132,7 @@ import static org.springdoc.core.utils.Constants.DOT; import static org.springdoc.core.utils.Constants.OPERATION_ATTRIBUTE; import static org.springdoc.core.utils.Constants.SPRING_MVC_SERVLET_PATH; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; /** @@ -392,14 +394,7 @@ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { // run the optional customizers List servers = openAPI.getServers(); - List serversCopy = null; - try { - serversCopy = springDocProviders.jsonMapper() - .readValue(springDocProviders.jsonMapper().writeValueAsString(servers), new TypeReference>() {}); - } - catch (JsonProcessingException e) { - LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); - } + List serversCopy = cloneViaJson(servers, new TypeReference>() {}, springDocProviders.jsonMapper()); openAPIService.getContext().getBeansOfType(OpenApiLocaleCustomizer.class).values().forEach(openApiLocaleCustomizer -> openApiLocaleCustomizer.customise(openAPI, finalLocale)); springDocCustomizers.getOpenApiCustomizers().ifPresent(apiCustomizers -> apiCustomizers.forEach(openApiCustomizer -> openApiCustomizer.customise(openAPI))); @@ -419,10 +414,7 @@ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { return openAPI; } finally { - JavadocProvider javadocProvider = operationParser.getJavadocProvider(); - if (javadocProvider != null) { - javadocProvider.clean(); - } + SpringDocAnnotationsUtils.clearCache(operationParser.getJavadocProvider()); this.reentrantLock.unlock(); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java index 4b4965618..c2b47676c 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/AdditionalModelsConverter.java @@ -30,7 +30,6 @@ import java.util.Iterator; import java.util.Map; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import io.swagger.v3.core.converter.AnnotatedType; @@ -41,6 +40,7 @@ import org.slf4j.LoggerFactory; import org.springdoc.core.providers.ObjectMapperProvider; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; import static org.springdoc.core.utils.SpringDocUtils.handleSchemaTypes; /** @@ -164,17 +164,12 @@ public Schema resolve(AnnotatedType type, ModelConverterContext context, Iterato JavaType javaType = springDocObjectMapper.jsonMapper().constructType(type.getType()); if (javaType != null) { Class cls = javaType.getRawClass(); - if (modelToSchemaMap.containsKey(cls)) - try { - Schema schema = modelToSchemaMap.get(cls); - if (springDocObjectMapper.isOpenapi31()) - handleSchemaTypes(schema); - return springDocObjectMapper.jsonMapper() - .readValue(springDocObjectMapper.jsonMapper().writeValueAsString(schema), new TypeReference() {}); - } - catch (JsonProcessingException e) { - LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); - } + if (modelToSchemaMap.containsKey(cls)) { + Schema schema = modelToSchemaMap.get(cls); + if (springDocObjectMapper.isOpenapi31()) + handleSchemaTypes(schema); + return cloneViaJson(schema, new TypeReference() {}, springDocObjectMapper.jsonMapper()); + } if (modelToClassMap.containsKey(cls)) type = new AnnotatedType(modelToClassMap.get(cls)).resolveAsRef(true); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java index 3110a56f0..06f16778d 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/JavadocProvider.java @@ -106,5 +106,5 @@ public interface JavadocProvider { /** * Clean the temp resources. */ - default void clean() {} + default void clearCache() {} } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java index ebffd6999..ca9f75cc8 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDocJavadocProvider.java @@ -212,7 +212,7 @@ private FieldJavadoc getJavadoc(Field field) { } @Override - public void clean() { + public void clearCache() { classJavadocCache.clear(); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 390f6ba77..4242e485d 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -77,6 +77,7 @@ import org.springdoc.core.models.RequestBodyInfo; import org.springdoc.core.properties.SpringDocConfigProperties.ApiDocs.OpenApiVersion; import org.springdoc.core.providers.JavadocProvider; +import org.springdoc.core.providers.ObjectMapperProvider; import org.springdoc.core.utils.SchemaUtils; import org.springdoc.core.utils.SpringDocAnnotationsUtils; @@ -102,6 +103,7 @@ import static org.springdoc.core.converters.SchemaPropertyDeprecatingConverter.containsDeprecatedAnnotation; import static org.springdoc.core.service.GenericParameterService.isFile; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; import static org.springdoc.core.utils.SpringDocUtils.getParameterAnnotations; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; import static org.springframework.http.MediaType.MULTIPART_FORM_DATA_VALUE; @@ -674,6 +676,8 @@ public void applyBeanValidatorAnnotations(final MethodParameter methodParameter, java.lang.reflect.AnnotatedType[] typeArgs = paramType.getAnnotatedActualTypeArguments(); for (java.lang.reflect.AnnotatedType typeArg : typeArgs) { List genericAnnotations = Arrays.stream(typeArg.getAnnotations()).toList(); + Schema schemaItemsClone = cloneViaJson(schema.getItems(), Schema.class, ObjectMapperProvider.createJson(parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties())); + schema.items(schemaItemsClone); SchemaUtils.applyValidationsToSchema(schema.getItems(), genericAnnotations, openapiVersion); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java index 74f1b0ff2..2a0542872 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericResponseService.java @@ -51,8 +51,6 @@ import java.util.stream.Stream; import com.fasterxml.jackson.annotation.JsonView; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.core.util.AnnotationsUtils; import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.Operation; @@ -99,6 +97,7 @@ import static org.springdoc.core.utils.SpringDocAnnotationsUtils.extractSchema; import static org.springdoc.core.utils.SpringDocAnnotationsUtils.getContent; import static org.springdoc.core.utils.SpringDocAnnotationsUtils.mergeSchema; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; import static org.springdoc.core.utils.SpringDocUtils.getParameterAnnotations; /** @@ -753,17 +752,7 @@ private Map getGenericMapResponse(HandlerMethod handlerMeth } } } - - LinkedHashMap genericApiResponsesClone; - try { - ObjectMapper objectMapper = ObjectMapperProvider.createJson(springDocConfigProperties); - genericApiResponsesClone = objectMapper.readValue(objectMapper.writeValueAsString(genericApiResponseMap), ApiResponses.class); - return genericApiResponsesClone; - } - catch (JsonProcessingException e) { - LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); - return genericApiResponseMap; - } + return cloneViaJson(genericApiResponseMap, ApiResponses.class, ObjectMapperProvider.createJson(springDocConfigProperties)); } finally { reentrantLock.unlock(); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java index 00f50b164..3d356693b 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java @@ -47,7 +47,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.core.jackson.TypeNameResolver; import io.swagger.v3.core.util.AnnotationsUtils; @@ -98,6 +97,7 @@ import static org.springdoc.core.utils.Constants.DEFAULT_SERVER_DESCRIPTION; import static org.springdoc.core.utils.Constants.DEFAULT_TITLE; import static org.springdoc.core.utils.Constants.DEFAULT_VERSION; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; import static org.springdoc.core.utils.SpringDocUtils.getConfig; /** @@ -246,14 +246,7 @@ public OpenAPI build(Locale locale) { calculatedOpenAPI.setPaths(new Paths()); } else { - try { - ObjectMapper objectMapper = new ObjectMapper(); - calculatedOpenAPI = objectMapper.readValue(objectMapper.writeValueAsString(openAPI), OpenAPI.class); - } - catch (JsonProcessingException e) { - LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); - calculatedOpenAPI = openAPI; - } + calculatedOpenAPI = cloneViaJson(openAPI, OpenAPI.class, new ObjectMapper()); } if (apiDef.isPresent()) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java index b612c891b..35a001e34 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -44,6 +45,8 @@ import com.fasterxml.jackson.annotation.JsonView; import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.core.converter.AnnotatedType; +import io.swagger.v3.core.converter.ModelConverterContext; +import io.swagger.v3.core.converter.ModelConverterContextImpl; import io.swagger.v3.core.converter.ModelConverters; import io.swagger.v3.core.converter.ResolvedSchema; import io.swagger.v3.core.util.AnnotationsUtils; @@ -65,6 +68,7 @@ import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springdoc.core.providers.JavadocProvider; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; @@ -91,6 +95,11 @@ public class SpringDocAnnotationsUtils extends AnnotationsUtils { */ private static final List ANNOTATIONS_TO_IGNORE = Collections.synchronizedList(new ArrayList<>()); + /** + * The reusable context + */ + private static final ThreadLocal> MODEL_CONVERTER_CONTEXT_MAP = ThreadLocal.withInitial(HashMap::new); + static { ANNOTATIONS_TO_IGNORE.add(Hidden.class); ANNOTATIONS_TO_IGNORE.add(JsonIgnore.class); @@ -131,18 +140,16 @@ public static Schema resolveSchemaFromType(Class schemaImplementation, Compon public static Schema extractSchema(Components components, Type returnType, JsonView jsonView, Annotation[] annotations, SpecVersion specVersion) { if (returnType == null) return null; Schema schemaN = null; - ResolvedSchema resolvedSchema; boolean openapi31 = SpecVersion.V31 == specVersion; - try { - resolvedSchema = ModelConverters.getInstance(openapi31) - .resolveAsResolvedSchema( - new AnnotatedType(returnType) - .resolveAsRef(true).jsonViewAnnotation(jsonView).ctxAnnotations(annotations)); - } - catch (Exception e) { - LOGGER.warn(Constants.GRACEFUL_EXCEPTION_OCCURRED, e); - return null; - } + if (jsonView != null) + annotations = ArrayUtils.addAll(annotations, jsonView); + + AnnotatedType annotatedType = new AnnotatedType(returnType) + .resolveAsRef(true) + .jsonViewAnnotation(jsonView) + .ctxAnnotations(annotations); + ResolvedSchema resolvedSchema = resolveAsResolvedSchema(openapi31, annotatedType); + if (resolvedSchema != null) { Map schemaMap = resolvedSchema.referencedSchemas; if (!CollectionUtils.isEmpty(schemaMap) && components != null) { @@ -496,4 +503,49 @@ public static Optional> getHeaders(io.swagger.v3.oas.annotat } return headerMap; } + + /** + * Clear cache. + * + * @param javadocProvider the javadoc provider + */ + public static void clearCache(JavadocProvider javadocProvider) { + if (javadocProvider != null) + javadocProvider.clearCache(); + MODEL_CONVERTER_CONTEXT_MAP.remove();; + } + + /** + * Resolve as resolved schema resolved schema. + * + * @param openapi31 the openapi 31 + * @param type the type + * @return the resolved schema + */ + private static ResolvedSchema resolveAsResolvedSchema(boolean openapi31, AnnotatedType type) { + try { + ModelConverterContext modelConverterContext = getModelConverterContext(openapi31); + ResolvedSchema resolvedSchema = new ResolvedSchema(); + resolvedSchema.schema = modelConverterContext.resolve(type); + resolvedSchema.referencedSchemas = modelConverterContext.getDefinedModels(); + return resolvedSchema; + } + catch (Exception e) { + LOGGER.warn(Constants.GRACEFUL_EXCEPTION_OCCURRED, e); + return null; + } + } + + /** + * Gets model converter context. + * + * @param openapi31 the openapi 31 + * @return the model converter context + */ + private static ModelConverterContext getModelConverterContext(boolean openapi31) { + Map perThread = MODEL_CONVERTER_CONTEXT_MAP.get(); + return perThread.computeIfAbsent(openapi31, key -> + new ModelConverterContextImpl(ModelConverters.getInstance(openapi31).getConverters())); + } + } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java index 90d6755a4..ad077f1a5 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java @@ -26,11 +26,14 @@ package org.springdoc.core.utils; +import java.io.IOException; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.core.converter.AnnotatedType; import io.swagger.v3.core.util.PrimitiveType; import io.swagger.v3.oas.models.media.ComposedSchema; @@ -39,6 +42,8 @@ import jakarta.validation.constraints.NotNull; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springdoc.api.AbstractOpenApiResource; import org.springdoc.core.converters.AdditionalModelsConverter; import org.springdoc.core.converters.ConverterUtils; @@ -66,6 +71,11 @@ public class SpringDocUtils { */ private static final SpringDocUtils springDocConfig = new SpringDocUtils(); + /** + * The constant LOGGER. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SpringDocUtils.class); + /** * Instantiates a new Spring doc utils. */ @@ -562,6 +572,48 @@ public SpringDocUtils resetExtraSchemas() { return this; } + + /** + * Clone via json t. + * + * @param the type parameter + * @param source the source + * @param targetType the target type + * @return the t + */ + public static T cloneViaJson(Object source, Class targetType, ObjectMapper mapper) { + if (source == null) return null; + try { + return mapper.readValue(mapper.writeValueAsBytes(source), targetType); + } + catch (IOException e) { + LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); + @SuppressWarnings("unchecked") + T fallback = (T) source; + return fallback; + } + } + + /** + * Clone via json t. + * + * @param the type parameter + * @param source the source + * @param typeRef the type ref + * @return the t + */ + public static T cloneViaJson(Object source, TypeReference typeRef, ObjectMapper mapper) { + if (source == null) return null; + try { + return mapper.readValue(mapper.writeValueAsBytes(source), typeRef); + } + catch (IOException e) { + LOGGER.warn("Json Processing Exception occurred: {}", e.getMessage()); + @SuppressWarnings("unchecked") + T fallback = (T) source; + return fallback; + } + } } diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/JWTAuthenticationFilter.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/JWTAuthenticationFilter.java index ddd311ede..3d476e366 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/JWTAuthenticationFilter.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/app6/security/JWTAuthenticationFilter.java @@ -47,6 +47,8 @@ import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; + public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @@ -72,10 +74,7 @@ public JWTAuthenticationFilter(AuthenticationManager authenticationManager, long public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException { try { - - UserCredentials credentials = - new ObjectMapper().readValue(req.getInputStream(), UserCredentials.class); - + UserCredentials credentials =cloneViaJson(req.getInputStream(), UserCredentials.class, new ObjectMapper()); return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), new ArrayList<>())); diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/JWTAuthenticationFilter.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/JWTAuthenticationFilter.java index 4ae0f8a7a..28171de15 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/JWTAuthenticationFilter.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/app6/security/JWTAuthenticationFilter.java @@ -47,6 +47,8 @@ import org.springframework.security.core.userdetails.User; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import static org.springdoc.core.utils.SpringDocUtils.cloneViaJson; + public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter { @@ -72,10 +74,7 @@ public JWTAuthenticationFilter(AuthenticationManager authenticationManager, long public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException { try { - - UserCredentials credentials = - new ObjectMapper().readValue(req.getInputStream(), UserCredentials.class); - + UserCredentials credentials = cloneViaJson(req.getInputStream(), UserCredentials.class,new ObjectMapper()); return authenticationManager.authenticate( new UsernamePasswordAuthenticationToken(credentials.getUsername(), credentials.getPassword(), new ArrayList<>())); From ea167ed98cfff68722c96cba490ff5c8726fc633 Mon Sep 17 00:00:00 2001 From: jenkins Date: Sat, 23 Aug 2025 14:12:20 +0000 Subject: [PATCH 11/45] [maven-release-plugin] prepare release v3.0.0-M1 --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index 422d7c610..b0942d01b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - HEAD + v3.0.0-M1 diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index d36d6f357..81a8dc4a6 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 6da51f649..6ea58ecfd 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 38c9117b3..71243e419 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index bbc1d3512..69df76651 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 293756279..bc99909f6 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 93802d2b7..602b58f1e 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 8d0e2f1e3..f9927305d 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 35b8f28f9..39a6ec28d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 064ff4a05..fbcc49ed3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index 6bea4a004..237148c5e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 5dccb5189..78c313ad0 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index 56c4c0700..fbd148ec5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index 561fe7f0f..2c985f7f3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index fe475b263..984bb9729 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index a662c2bfb..184a0bdde 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 61e033943..8513f1e28 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 64f4c12ef..1c081ec0e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0-M1 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index cf7fcaf28..5f49e3555 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0-M1 springdoc-openapi-security-tests ${project.artifactId} From 633d322af82eecfc58289e324776d008c8a7796f Mon Sep 17 00:00:00 2001 From: jenkins Date: Sat, 23 Aug 2025 14:12:23 +0000 Subject: [PATCH 12/45] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 19 files changed, 20 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index b0942d01b..cae83f5a1 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - v3.0.0-M1 + HEAD diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 81a8dc4a6..7ccb85196 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 6ea58ecfd..fca00c626 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 71243e419..01355244d 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index 69df76651..cb93775fc 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index bc99909f6..c9eff3a32 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 602b58f1e..b8dc2eaca 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index f9927305d..64ce976f1 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 39a6ec28d..0165f2282 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index fbcc49ed3..73517670f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index 237148c5e..ecd2212d5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 78c313ad0..5c08707fe 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index fbd148ec5..d6087473e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index 2c985f7f3..ed80697a4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 984bb9729..0f61eee5c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 184a0bdde..527b11947 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 8513f1e28..76e14c215 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 1c081ec0e..1a8418245 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index 5f49e3555..fbd2fd2c5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M1 + 3.0.0-M2-SNAPSHOT springdoc-openapi-security-tests ${project.artifactId} From 7ceb189f129acd27c086d5ddfe76262769dbb9ab Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sun, 31 Aug 2025 20:54:53 +0200 Subject: [PATCH 13/45] Parameter is now required after upgrading to springdoc-openapi 2.8.10. Fixes #3066 --- .../configuration/SpringDocConfiguration.java | 59 +++- .../SpringDocDataRestConfiguration.java | 9 +- .../SpringDocKotlinConfiguration.kt | 11 +- .../customizers/SpringDocCustomizers.java | 35 ++- .../core/data/DataRestRequestService.java | 27 +- .../extractor/DelegatingMethodParameter.java | 6 +- .../MethodParameterPojoExtractor.java | 20 +- .../core/service/AbstractRequestService.java | 56 ++-- .../core/service/GenericParameterService.java | 19 +- .../org/springdoc/core/utils/SchemaUtils.java | 283 ++++++++++++++++-- .../core/utils/SpringDocKotlinUtils.java | 117 ++++++++ .../api/AbstractOpenApiResourceTest.java | 6 +- .../MethodParameterPojoExtractorTest.java | 9 +- .../webflux/api/MultipleOpenApiResource.java | 4 +- .../SpringDocWebFluxConfiguration.java | 11 +- .../webflux/core/service/RequestService.java | 12 +- .../webmvc/api/MultipleOpenApiResource.java | 4 +- .../SpringDocWebMvcConfiguration.java | 11 +- .../webmvc/core/service/RequestService.java | 12 +- .../api/v31/app21/SpringDocApp21Test.kt | 73 +++++ .../test/resources/results/3.1.0/app21.json | 77 +++++ 21 files changed, 726 insertions(+), 135 deletions(-) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocKotlinUtils.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app21/SpringDocApp21Test.kt create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app21.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index 6178d7a3b..3c5edd005 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -68,6 +68,7 @@ import org.springdoc.core.customizers.OpenApiCustomizer; import org.springdoc.core.customizers.OperationCustomizer; import org.springdoc.core.customizers.OperationIdCustomizer; +import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.ParameterObjectNamingStrategyCustomizer; import org.springdoc.core.customizers.PropertyCustomizer; import org.springdoc.core.customizers.QuerydslPredicateOperationCustomizer; @@ -75,6 +76,7 @@ import org.springdoc.core.customizers.ServerBaseUrlCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.filters.GlobalOpenApiMethodFilter; import org.springdoc.core.filters.OpenApiMethodFilter; import org.springdoc.core.models.GroupedOpenApi; @@ -97,6 +99,8 @@ import org.springdoc.core.service.RequestBodyService; import org.springdoc.core.service.SecurityService; import org.springdoc.core.utils.PropertyResolverUtils; +import org.springdoc.core.utils.SchemaUtils; +import org.springdoc.core.utils.SpringDocKotlinUtils; import reactor.core.publisher.Flux; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; @@ -383,7 +387,6 @@ SecurityService securityParser(PropertyResolverUtils propertyResolverUtils) { * Parameter builder generic parameter builder. * * @param propertyResolverUtils the property resolver utils - * @param optionalDelegatingMethodParameterCustomizers the optional list delegating method parameter customizer * @param optionalWebConversionServiceProvider the optional web conversion service provider * @param objectMapperProvider the object mapper provider * @param javadocProvider the javadoc provider @@ -393,9 +396,8 @@ SecurityService securityParser(PropertyResolverUtils propertyResolverUtils) { @ConditionalOnMissingBean @Lazy(false) GenericParameterService parameterBuilder(PropertyResolverUtils propertyResolverUtils, - Optional> optionalDelegatingMethodParameterCustomizers, Optional optionalWebConversionServiceProvider, ObjectMapperProvider objectMapperProvider, Optional javadocProvider) { - return new GenericParameterService(propertyResolverUtils, optionalDelegatingMethodParameterCustomizers, + return new GenericParameterService(propertyResolverUtils, optionalWebConversionServiceProvider, objectMapperProvider, javadocProvider); } @@ -456,14 +458,16 @@ ObjectMapperProvider springdocObjectMapperProvider(SpringDocConfigProperties spr /** * Spring doc customizers spring doc customizers. * - * @param openApiCustomizers the open api customizers - * @param operationCustomizers the operation customizers - * @param routerOperationCustomizers the router operation customizers - * @param dataRestRouterOperationCustomizers the data rest router operation customizers - * @param methodFilters the method filters - * @param globalOpenApiCustomizers the global open api customizers - * @param globalOperationCustomizers the global operation customizers - * @param globalOpenApiMethodFilters the global open api method filters + * @param openApiCustomizers the open api customizers + * @param operationCustomizers the operation customizers + * @param routerOperationCustomizers the router operation customizers + * @param dataRestRouterOperationCustomizers the data rest router operation customizers + * @param methodFilters the method filters + * @param globalOpenApiCustomizers the global open api customizers + * @param globalOperationCustomizers the global operation customizers + * @param globalOpenApiMethodFilters the global open api method filters + * @param optionalDelegatingMethodParameterCustomizers the optional delegating method parameter customizers + * @param parameterCustomizers the parameter customizers * @return the spring doc customizers */ @Bean @@ -475,12 +479,15 @@ public SpringDocCustomizers springDocCustomizers(Optional Optional> dataRestRouterOperationCustomizers, Optional> methodFilters, Optional> globalOpenApiCustomizers, Optional> globalOperationCustomizers, - Optional> globalOpenApiMethodFilters) { + Optional> globalOpenApiMethodFilters, + Optional> optionalDelegatingMethodParameterCustomizers, + Optional> parameterCustomizers) { return new SpringDocCustomizers(openApiCustomizers, operationCustomizers, routerOperationCustomizers, dataRestRouterOperationCustomizers, - methodFilters, globalOpenApiCustomizers, globalOperationCustomizers, globalOpenApiMethodFilters); + methodFilters, globalOpenApiCustomizers, globalOperationCustomizers, globalOpenApiMethodFilters, + optionalDelegatingMethodParameterCustomizers, parameterCustomizers); } /** @@ -686,4 +693,30 @@ public ResponseEntity handleNoHandlerFound(OpenApiResourceNotFound return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ErrorMessage(e.getMessage())); } } + + /** + * Schema utils schema utils. + * + * @param springDocKotlinUtils the spring doc kotlin utils + * @return the schema utils + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + SchemaUtils schemaUtils(Optional springDocKotlinUtils){ + return new SchemaUtils(springDocKotlinUtils); + } + + /** + * Method parameter pojo extractor method parameter pojo extractor. + * + * @param schemaUtils the schema utils + * @return the method parameter pojo extractor + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + MethodParameterPojoExtractor methodParameterPojoExtractor(SchemaUtils schemaUtils){ + return new MethodParameterPojoExtractor(schemaUtils); + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java index 6407c6a6a..e93abd2aa 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java @@ -173,8 +173,6 @@ DataRestOperationService dataRestOperationBuilder(DataRestRequestService dataRes * Data rest request builder data rest request builder. * * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer - * @param parameterBuilder the parameter builder - * @param requestBodyService the request body builder * @param requestBuilder the request builder * @param springDocDataRestUtils the spring doc data rest utils * @return the data rest request builder @@ -182,10 +180,9 @@ DataRestOperationService dataRestOperationBuilder(DataRestRequestService dataRes @Bean @ConditionalOnMissingBean @Lazy(false) - DataRestRequestService dataRestRequestBuilder(SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, GenericParameterService parameterBuilder, - RequestBodyService requestBodyService, AbstractRequestService requestBuilder, SpringDocDataRestUtils springDocDataRestUtils) { - return new DataRestRequestService(localSpringDocParameterNameDiscoverer, parameterBuilder, - requestBodyService, requestBuilder, springDocDataRestUtils); + DataRestRequestService dataRestRequestBuilder(SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + AbstractRequestService requestBuilder, SpringDocDataRestUtils springDocDataRestUtils) { + return new DataRestRequestService(localSpringDocParameterNameDiscoverer, requestBuilder, springDocDataRestUtils); } /** diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt index ab3c8a375..e5bc8f0c0 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt @@ -32,6 +32,7 @@ import org.springdoc.core.customizers.KotlinDeprecatedPropertyCustomizer import org.springdoc.core.extractor.DelegatingMethodParameter import org.springdoc.core.providers.ObjectMapperProvider import org.springdoc.core.utils.Constants +import org.springdoc.core.utils.SpringDocKotlinUtils import org.springdoc.core.utils.SpringDocUtils import org.springframework.boot.autoconfigure.condition.ConditionalOnBean import org.springframework.boot.autoconfigure.condition.ConditionalOnClass @@ -93,14 +94,8 @@ class SpringDocKotlinConfiguration() { matchIfMissing = true ) @Lazy(false) - fun kotlinDefaultsInParamObjects(): DelegatingMethodParameterCustomizer = - DelegatingMethodParameterCustomizer { _, mp -> - val kProp = mp.containingClass.kotlin.primaryConstructor - ?.parameters - ?.firstOrNull { it.name == mp.parameterName } - if (kProp?.isOptional == true) - (mp as DelegatingMethodParameter).isNotRequired = true - } + fun springDocKotlinUtils(): SpringDocKotlinUtils = + SpringDocKotlinUtils() } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java index 19900e4fd..eb30251a1 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java @@ -25,6 +25,7 @@ */ package org.springdoc.core.customizers; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -94,7 +95,15 @@ public class SpringDocCustomizers implements ApplicationContextAware, Initializi */ private Optional> globalOpenApiMethodFilters; + /** + * The Optional delegating method parameter customizers. + */ + private final Optional> optionalDelegatingMethodParameterCustomizers; + /** + * The Parameter customizers. + */ + private final Optional> parameterCustomizers; /** * Instantiates a new Spring doc customizers. * @@ -113,12 +122,14 @@ public SpringDocCustomizers(Optional> openApiCustomizers, Optional> dataRestRouterOperationCustomizers, Optional> methodFilters, Optional> globalOpenApiCustomizers, Optional> globalOperationCustomizers, - Optional> globalOpenApiMethodFilters) { + Optional> globalOpenApiMethodFilters, Optional> optionalDelegatingMethodParameterCustomizers, Optional> parameterCustomizers) { this.openApiCustomizers = openApiCustomizers; this.operationCustomizers = operationCustomizers; this.globalOpenApiCustomizers = globalOpenApiCustomizers; this.globalOperationCustomizers = globalOperationCustomizers; this.globalOpenApiMethodFilters = globalOpenApiMethodFilters; + this.optionalDelegatingMethodParameterCustomizers = optionalDelegatingMethodParameterCustomizers; + this.parameterCustomizers = parameterCustomizers; operationCustomizers.ifPresent(customizers -> customizers.removeIf(Objects::isNull)); this.routerOperationCustomizers = routerOperationCustomizers; this.dataRestRouterOperationCustomizers = dataRestRouterOperationCustomizers; @@ -134,11 +145,13 @@ public SpringDocCustomizers(Optional> openApiCustomizers, * @param openApiMethodFilters the open api method filters */ public SpringDocCustomizers(Optional> openApiCustomizers, Optional> operationCustomizers, - Optional> routerOperationCustomizers, Optional> openApiMethodFilters) { + Optional> routerOperationCustomizers, Optional> openApiMethodFilters, Optional> optionalDelegatingMethodParameterCustomizers, Optional> parameterCustomizers) { this.openApiCustomizers = openApiCustomizers; this.operationCustomizers = operationCustomizers; this.routerOperationCustomizers = routerOperationCustomizers; this.methodFilters = openApiMethodFilters; + this.optionalDelegatingMethodParameterCustomizers = optionalDelegatingMethodParameterCustomizers; + this.parameterCustomizers = parameterCustomizers; this.dataRestRouterOperationCustomizers = Optional.empty(); } @@ -219,6 +232,24 @@ public Optional> getGlobalOpenApiMethodFilters() return globalOpenApiMethodFilters; } + /** + * Gets optional delegating method parameter customizers. + * + * @return the optional delegating method parameter customizers + */ + public Optional> getOptionalDelegatingMethodParameterCustomizers() { + return optionalDelegatingMethodParameterCustomizers; + } + + /** + * Gets parameter customizers. + * + * @return the parameter customizers + */ + public Optional> getParameterCustomizers() { + return parameterCustomizers; + } + @Override public void afterPropertiesSet() { //add the default customizers diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java index 8ecb701cb..9a439d9bb 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRequestService.java @@ -43,8 +43,10 @@ import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; import org.apache.commons.lang3.ArrayUtils; +import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.DelegatingMethodParameter; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.models.MethodAttributes; import org.springdoc.core.models.ParameterInfo; import org.springdoc.core.models.RequestBodyInfo; @@ -97,23 +99,34 @@ public class DataRestRequestService { * The Spring doc data rest utils. */ private final SpringDocDataRestUtils springDocDataRestUtils; + + /** + * The Optional delegating method parameter customizers. + */ + private final Optional> optionalDelegatingMethodParameterCustomizers; + + /** + * The Method parameter pojo extractor. + */ + private final MethodParameterPojoExtractor methodParameterPojoExtractor; /** * Instantiates a new Data rest request builder. * * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer - * @param parameterBuilder the parameter builder - * @param requestBodyService the request body builder * @param requestBuilder the request builder * @param springDocDataRestUtils the spring doc data rest utils */ - public DataRestRequestService(SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, GenericParameterService parameterBuilder, - RequestBodyService requestBodyService, AbstractRequestService requestBuilder, SpringDocDataRestUtils springDocDataRestUtils) { + public DataRestRequestService(SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + AbstractRequestService requestBuilder, + SpringDocDataRestUtils springDocDataRestUtils) { this.localSpringDocParameterNameDiscoverer = localSpringDocParameterNameDiscoverer; - this.parameterBuilder = parameterBuilder; - this.requestBodyService = requestBodyService; this.requestBuilder = requestBuilder; this.springDocDataRestUtils = springDocDataRestUtils; + this.optionalDelegatingMethodParameterCustomizers = requestBuilder.getOptionalDelegatingMethodParameterCustomizers(); + this.methodParameterPojoExtractor = requestBuilder.getMethodParameterPojoExtractor(); + this.parameterBuilder = requestBuilder.getParameterBuilder(); + this.requestBodyService=requestBuilder.getRequestBodyBuilder(); } /** @@ -155,7 +168,7 @@ public void buildParameters(OpenAPI openAPI, HandlerMethod handlerMethod, Reques */ public void buildCommonParameters(OpenAPI openAPI, RequestMethod requestMethod, MethodAttributes methodAttributes, Operation operation, String[] pNames, MethodParameter[] parameters, DataRestRepository dataRestRepository) { - parameters = DelegatingMethodParameter.customize(pNames, parameters, parameterBuilder.getOptionalDelegatingMethodParameterCustomizers(), requestBuilder.isDefaultFlatParamObject()); + parameters = DelegatingMethodParameter.customize(pNames, parameters, this.optionalDelegatingMethodParameterCustomizers, this.methodParameterPojoExtractor, requestBuilder.isDefaultFlatParamObject()); Class domainType = dataRestRepository.getDomainType(); for (MethodParameter methodParameter : parameters) { final String pName = methodParameter.getParameterName(); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java index b72448bdc..665481047 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java @@ -131,11 +131,11 @@ public class DelegatingMethodParameter extends MethodParameter { * @param pNames the p names * @param parameters the parameters * @param optionalDelegatingMethodParameterCustomizers the optional list delegating method parameter customizer - * @param defaultFlatParamObject the default flat param object + * @param methodParameterPojoExtractor the method parameter pojo extractor * @return the method parameter [ ] */ public static MethodParameter[] customize(String[] pNames, MethodParameter[] parameters, - Optional> optionalDelegatingMethodParameterCustomizers, boolean defaultFlatParamObject) { + Optional> optionalDelegatingMethodParameterCustomizers, MethodParameterPojoExtractor methodParameterPojoExtractor, boolean defaultFlatParamObject) { List explodedParameters = new ArrayList<>(); for (int i = 0; i < parameters.length; ++i) { MethodParameter p = parameters[i]; @@ -147,7 +147,7 @@ public static MethodParameter[] customize(String[] pNames, MethodParameter[] par if (!MethodParameterPojoExtractor.isSimpleType(paramClass) && (hasFlatAnnotation || (defaultFlatParamObject && !hasNotFlatAnnotation && !AbstractRequestService.isRequestTypeToIgnore(paramClass)))) { List flatParams = new CopyOnWriteArrayList<>(); - MethodParameterPojoExtractor.extractFrom(paramClass).forEach(flatParams::add); + methodParameterPojoExtractor.extractFrom(paramClass).forEach(flatParams::add); optionalDelegatingMethodParameterCustomizers.orElseGet(ArrayList::new).forEach(cz -> cz.customizeList(p, flatParams)); explodedParameters.addAll(flatParams); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java index b3d384442..df103ed44 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java @@ -78,6 +78,11 @@ */ public class MethodParameterPojoExtractor { + /** + * The Schema utils. + */ + private final SchemaUtils schemaUtils; + /** * The constant SIMPLE_TYPE_PREDICATES. */ @@ -123,7 +128,8 @@ public class MethodParameterPojoExtractor { /** * Instantiates a new Method parameter pojo extractor. */ - private MethodParameterPojoExtractor() { + public MethodParameterPojoExtractor(SchemaUtils schemaUtils) { + this.schemaUtils = schemaUtils; } /** @@ -132,7 +138,7 @@ private MethodParameterPojoExtractor() { * @param clazz the clazz * @return the stream */ - static Stream extractFrom(Class clazz) { + Stream extractFrom(Class clazz) { return extractFrom(clazz, "", true); } @@ -144,7 +150,7 @@ static Stream extractFrom(Class clazz) { * @param parentRequired whether the field that hold the class currently being inspected was required or optional * @return the stream */ - private static Stream extractFrom(Class clazz, String fieldNamePrefix, boolean parentRequired) { + private Stream extractFrom(Class clazz, String fieldNamePrefix, boolean parentRequired) { return allFieldsOf(clazz).stream() .filter(field -> !field.getType().equals(clazz)) .flatMap(f -> fromGetterOfField(clazz, f, fieldNamePrefix, parentRequired)) @@ -160,7 +166,7 @@ private static Stream extractFrom(Class clazz, String fieldN * @param parentRequired whether the field that holds the class currently being examined was required or optional * @return the stream */ - private static Stream fromGetterOfField(Class paramClass, Field field, String fieldNamePrefix, boolean parentRequired) { + private Stream fromGetterOfField(Class paramClass, Field field, String fieldNamePrefix, boolean parentRequired) { Class type = extractType(paramClass, field); if (Objects.isNull(type)) @@ -176,7 +182,7 @@ private static Stream fromGetterOfField(Class paramClass, Fi return Stream.empty(); } String prefix = fieldNamePrefix + resolveName(parameter, schema).orElse(field.getName()) + DOT; - boolean fieldRequired = SchemaUtils.fieldRequired(field, schema, parameter); + boolean fieldRequired = this.schemaUtils.fieldRequired(field, schema, parameter); return extractFrom(type, prefix, parentRequired && fieldRequired); } } @@ -234,12 +240,12 @@ private static Class extractType(Class paramClass, Field field) { * @param fieldNamePrefix the field name prefix * @return the stream */ - private static Stream fromSimpleClass(Class paramClass, Field field, String fieldNamePrefix, boolean parentRequired) { + private Stream fromSimpleClass(Class paramClass, Field field, String fieldNamePrefix, boolean parentRequired) { Annotation[] fieldAnnotations = field.getDeclaredAnnotations(); try { Parameter parameter = field.getAnnotation(Parameter.class); Schema schema = field.getAnnotation(Schema.class); - boolean fieldRequired = SchemaUtils.fieldRequired(field, schema, parameter); + boolean fieldRequired = this.schemaUtils.fieldRequired(field, schema, parameter); boolean paramRequired = parentRequired && fieldRequired; if (paramClass.getSuperclass() != null && paramClass.isRecord()) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 4242e485d..7177b23be 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -68,9 +68,12 @@ import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; import org.apache.commons.lang3.StringUtils; +import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; import org.springdoc.core.customizers.ParameterCustomizer; +import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.DelegatingMethodParameter; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.models.MethodAttributes; import org.springdoc.core.models.ParameterId; import org.springdoc.core.models.ParameterInfo; @@ -180,28 +183,41 @@ public abstract class AbstractRequestService { */ private boolean defaultSupportFormData; + /** + * The Optional delegating method parameter customizers. + */ + private final Optional> optionalDelegatingMethodParameterCustomizers; + + /** + * The Method parameter pojo extractor. + */ + private final MethodParameterPojoExtractor methodParameterPojoExtractor; /** * Instantiates a new Abstract request builder. * * @param parameterBuilder the parameter builder * @param requestBodyService the request body builder - * @param parameterCustomizers the parameter customizers + * @param springDocCustomizers the spring doc customizers * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer + * @param methodParameterPojoExtractor the method parameter pojo extractor */ protected AbstractRequestService(GenericParameterService parameterBuilder, RequestBodyService requestBodyService, - Optional> parameterCustomizers, - SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) { + SpringDocCustomizers springDocCustomizers, + SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + MethodParameterPojoExtractor methodParameterPojoExtractor) { super(); this.parameterBuilder = parameterBuilder; this.requestBodyService = requestBodyService; + this.optionalDelegatingMethodParameterCustomizers = springDocCustomizers.getOptionalDelegatingMethodParameterCustomizers(); + this.methodParameterPojoExtractor = methodParameterPojoExtractor; + this.parameterCustomizers = springDocCustomizers.getParameterCustomizers(); parameterCustomizers.ifPresent(customizers -> customizers.removeIf(Objects::isNull)); - this.parameterCustomizers = parameterCustomizers; this.localSpringDocParameterNameDiscoverer = localSpringDocParameterNameDiscoverer; this.defaultFlatParamObject = parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties().isDefaultFlatParamObject(); this.defaultSupportFormData = parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties().isDefaultSupportFormData(); } - + /** * Add request wrapper to ignore. * @@ -261,17 +277,6 @@ public static Collection getHeaders(MethodAttributes methodAttributes return map.values(); } - /** - * deprecated use {@link SchemaUtils#hasNotNullAnnotation(Collection)} - * - * @param annotationSimpleNames the annotation simple names - * @return boolean - */ - @Deprecated(forRemoval = true) - public static boolean hasNotNullAnnotation(Collection annotationSimpleNames) { - return SchemaUtils.hasNotNullAnnotation(annotationSimpleNames); - } - /** * Build operation. * @@ -297,7 +302,7 @@ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod, if (pNames == null || Arrays.stream(pNames).anyMatch(Objects::isNull)) pNames = reflectionParametersNames; // Process: DelegatingMethodParameterCustomizer - parameters = DelegatingMethodParameter.customize(pNames, parameters, parameterBuilder.getOptionalDelegatingMethodParameterCustomizers(), this.defaultFlatParamObject); + parameters = DelegatingMethodParameter.customize(pNames, parameters, optionalDelegatingMethodParameterCustomizers, methodParameterPojoExtractor, this.defaultFlatParamObject); RequestBodyInfo requestBodyInfo = new RequestBodyInfo(); List operationParameters = (operation.getParameters() != null) ? operation.getParameters() : new ArrayList<>(); Map parametersDocMap = getApiParameters(handlerMethod.getMethod()); @@ -843,4 +848,21 @@ else if (requestBody.content().length > 0) return false; } + /** + * Gets optional delegating method parameter customizers. + * + * @return the optional delegating method parameter customizers + */ + public Optional> getOptionalDelegatingMethodParameterCustomizers() { + return optionalDelegatingMethodParameterCustomizers; + } + + /** + * Gets method parameter pojo extractor. + * + * @return the method parameter pojo extractor + */ + public MethodParameterPojoExtractor getMethodParameterPojoExtractor() { + return methodParameterPojoExtractor; + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java index ae38abc94..60140a40e 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java @@ -62,7 +62,6 @@ import org.apache.commons.lang3.reflect.FieldUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; import org.springdoc.core.extractor.DelegatingMethodParameter; import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.models.ParameterInfo; @@ -115,11 +114,6 @@ public class GenericParameterService { FILE_TYPES.add(MultipartRequest.class); } - /** - * The Optional delegating method parameter customizer. - */ - private final Optional> optionalDelegatingMethodParameterCustomizers; - /** * The Web conversion service. */ @@ -154,15 +148,13 @@ public class GenericParameterService { * Instantiates a new Generic parameter builder. * * @param propertyResolverUtils the property resolver utils - * @param optionalDelegatingMethodParameterCustomizers the optional list delegating method parameter customizer * @param optionalWebConversionServiceProvider the optional web conversion service provider * @param objectMapperProvider the object mapper provider * @param javadocProviderOptional the javadoc provider */ - public GenericParameterService(PropertyResolverUtils propertyResolverUtils, Optional> optionalDelegatingMethodParameterCustomizers, + public GenericParameterService(PropertyResolverUtils propertyResolverUtils, Optional optionalWebConversionServiceProvider, ObjectMapperProvider objectMapperProvider, Optional javadocProviderOptional) { this.propertyResolverUtils = propertyResolverUtils; - this.optionalDelegatingMethodParameterCustomizers = optionalDelegatingMethodParameterCustomizers; this.optionalWebConversionServiceProvider = optionalWebConversionServiceProvider; this.configurableBeanFactory = propertyResolverUtils.getFactory(); this.expressionContext = (configurableBeanFactory != null ? new BeanExpressionContext(configurableBeanFactory, new RequestScope()) : null); @@ -552,15 +544,6 @@ public boolean isFile(MethodParameter methodParameter) { } } - /** - * Gets optional delegating method parameter customizers. - * - * @return the optional delegating method parameter customizers - */ - public Optional> getOptionalDelegatingMethodParameterCustomizers() { - return optionalDelegatingMethodParameterCustomizers; - } - /** * Is file boolean. * diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java index e0e66f6d1..70f641e32 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java @@ -1,7 +1,10 @@ package org.springdoc.core.utils; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.math.BigDecimal; import java.util.Arrays; import java.util.Collection; @@ -14,6 +17,7 @@ import java.util.Set; import java.util.stream.Collectors; +import com.fasterxml.jackson.annotation.JsonProperty; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; import io.swagger.v3.oas.models.media.Schema; @@ -27,15 +31,15 @@ import jakarta.validation.constraints.Positive; import jakarta.validation.constraints.PositiveOrZero; import jakarta.validation.constraints.Size; -import kotlin.reflect.KProperty; -import kotlin.reflect.jvm.ReflectJvmMapping; import org.springdoc.core.properties.SpringDocConfigProperties.ApiDocs.OpenApiVersion; -import org.springframework.core.KotlinDetector; import org.springframework.lang.Nullable; import static org.springdoc.core.utils.Constants.OPENAPI_ARRAY_TYPE; import static org.springdoc.core.utils.Constants.OPENAPI_STRING_TYPE; +import static org.springdoc.core.utils.SpringDocKotlinUtils.isKotlinDeclaringClass; +import static org.springdoc.core.utils.SpringDocKotlinUtils.kotlinConstructorParamIsOptional; +import static org.springdoc.core.utils.SpringDocKotlinUtils.kotlinNullability; /** * The type Validation utils. @@ -56,6 +60,11 @@ public class SchemaUtils { public static final List ANNOTATIONS_FOR_REQUIRED = Arrays.asList("NotNull", "NonNull", "NotBlank", "NotEmpty"); + /** + * The constant ANNOTATIONS_FOR_NULLABLE. + */ + public static final List ANNOTATIONS_FOR_NULLABLE = + Arrays.asList("Nullable"); /** * The constant OPTIONAL_TYPES. */ @@ -68,10 +77,18 @@ public class SchemaUtils { OPTIONAL_TYPES.add(OptionalDouble.class); } + /** + * The Kotlin utils optional. + */ + private final Optional kotlinUtilsOptional; + /** * The constructor. + * + * @param kotlinUtilsOptional the kotlin utils optional */ - private SchemaUtils() { + public SchemaUtils(Optional kotlinUtilsOptional) { + this.kotlinUtilsOptional = kotlinUtilsOptional; } /** @@ -121,16 +138,6 @@ public static Boolean swaggerRequired(@Nullable io.swagger.v3.oas.annotations.me return null; } - /** - * Check if the parameter has any of the annotations that make it non-optional - * - * @param annotationSimpleNames the annotation simple class named, e.g. NotNull - * @return whether any of the known NotNull annotations are present - */ - public static boolean hasNotNullAnnotation(Collection annotationSimpleNames) { - return ANNOTATIONS_FOR_REQUIRED.stream().anyMatch(annotationSimpleNames::contains); - } - /** * Is annotated notnull. * @@ -151,17 +158,25 @@ public static boolean annotatedNotNull(List annotations) { * @param field the field * @return the boolean */ - public static boolean fieldNullable(Field field) { + public boolean fieldNullable(Field field) { + // primitives cannot be null + if (field.getType().isPrimitive()) return false; + + // Optional-like wrappers if (OPTIONAL_TYPES.stream().anyMatch(c -> c.isAssignableFrom(field.getType()))) { return true; } - if (KotlinDetector.isKotlinPresent() && KotlinDetector.isKotlinReflectPresent() - && KotlinDetector.isKotlinType(field.getDeclaringClass())) { - KProperty kotlinProperty = ReflectJvmMapping.getKotlinProperty(field); - if (kotlinProperty != null) { - return kotlinProperty.getReturnType().isMarkedNullable(); - } + + // @Nullable/@NotNull + Boolean ann = nullableFromAnnotations(field); + if (ann != null) return ann; + + // Kotlin nullability + if (kotlinUtilsOptional.isPresent() && isKotlinDeclaringClass(field)) { + Boolean kotlin = kotlinNullability(field); + if (kotlin != null) return kotlin; } + return JAVA_FIELD_NULLABLE_DEFAULT; } @@ -176,17 +191,34 @@ public static boolean fieldNullable(Field field) { * @see io.swagger.v3.oas.annotations.media.Schema#required() * @see io.swagger.v3.oas.annotations.media.Schema#requiredMode() */ - public static boolean fieldRequired(Field field, @Nullable io.swagger.v3.oas.annotations.media.Schema schema, - @Nullable Parameter parameter) { - Boolean swaggerRequired = swaggerRequired(schema, parameter); - if (swaggerRequired != null) { - return swaggerRequired; + public boolean fieldRequired(Field field, io.swagger.v3.oas.annotations.media.Schema schema, Parameter parameter) { + Boolean swagger = swaggerRequired(schema, parameter); + if (swagger != null) return swagger; + + // Optional-like wrapper → not required + if (OPTIONAL_TYPES.stream().anyMatch(c -> c.isAssignableFrom(field.getType()))) return false; + + // @Nullable/@NotNull + if (hasNullableAnnotation(field) || hasNullableOnGetter(field) || hasNullableOnCtorParam(field)) { + return false; + } + if (hasNotNullAnnotation(field) || hasNotNullOnGetter(field) || hasNotNullOnCtorParam(field)) { + return true; } - boolean annotatedNotNull = annotatedNotNull(Arrays.asList(field.getDeclaredAnnotations())); - if (annotatedNotNull) { + + // Kotlin logic + if (kotlinUtilsOptional.isPresent() && isKotlinDeclaringClass(field)) { + if (fieldNullable(field)) return false; + Boolean hasDefault = kotlinConstructorParamIsOptional(field); + if (Boolean.TRUE.equals(hasDefault)) return false; return true; } - return !fieldNullable(field); + + // Jackson @JsonProperty(required = true) + JsonProperty jp = getJsonProperty(field); + if (jp != null && jp.required()) return true; + + return false; } /** @@ -273,4 +305,197 @@ else if (OPENAPI_STRING_TYPE.equals(type)) { } } + /** + * Nullable from annotations boolean. + * + * @param field the field + * @return the boolean + */ + private static Boolean nullableFromAnnotations(Field field) { + if (hasNullableAnnotation(field)) return true; + if (hasNotNullAnnotation(field)) return false; + Method getter = findGetter(field); + if (getter != null) { + if (hasNullableAnnotation(getter)) return true; + if (hasNotNullAnnotation(getter)) return false; + } + return null; + } + + /** + * Has nullable annotation boolean. + * + * @param el the el + * @return the boolean + */ + private static boolean hasNullableAnnotation(AnnotatedElement el) { + if (el == null) return false; + for (Annotation ann : el.getAnnotations()) { + if (ANNOTATIONS_FOR_NULLABLE.contains(ann.annotationType().getSimpleName())) { + return true; + } + } + return false; + } + + + /** + * Has not null annotation boolean. + * + * @param el the el + * @return the boolean + */ + private static boolean hasNotNullAnnotation(AnnotatedElement el) { + if (el == null) { + return false; + } + for (Annotation ann : el.getAnnotations()) { + String simpleName = ann.annotationType().getSimpleName(); + if (ANNOTATIONS_FOR_REQUIRED.contains(simpleName)) { + return true; + } + } + return false; + } + + /** + * Has nullable on getter boolean. + * + * @param f the f + * @return the boolean + */ + private static boolean hasNullableOnGetter(Field f) { + Method g = findGetter(f); + return g != null && hasNullableAnnotation(g); + } + + /** + * Has not null on getter boolean. + * + * @param f the f + * @return the boolean + */ + private static boolean hasNotNullOnGetter(Field f) { + Method g = findGetter(f); + return g != null && hasNotNullAnnotation(g); + } + + /** + * Has nullable on ctor param boolean. + * + * @param f the f + * @return the boolean + */ + private static boolean hasNullableOnCtorParam(Field f) { + return ctorParamHasAnyAnnotationSimpleName(f, ANNOTATIONS_FOR_NULLABLE); + } + + /** + * Has not null on ctor param boolean. + * + * @param f the f + * @return the boolean + */ + private static boolean hasNotNullOnCtorParam(Field f) { + return ctorParamHasAnyAnnotationSimpleName(f, ANNOTATIONS_FOR_REQUIRED); + } + + /** + * Ctor param has any annotation simple name boolean. + * + * @param f the f + * @param simpleNames the simple names + * @return the boolean + */ + private static boolean ctorParamHasAnyAnnotationSimpleName(Field f, Collection simpleNames) { + if (f == null || simpleNames == null || simpleNames.isEmpty()) return false; + + final String fieldName = f.getName(); + final Class declaring = f.getDeclaringClass(); + + try { + for (Constructor ctor : declaring.getDeclaredConstructors()) { + java.lang.reflect.Parameter[] params = ctor.getParameters(); + for (java.lang.reflect.Parameter p : params) { + // A) compiled with -parameters + if (fieldName.equals(p.getName()) && paramHasAnyAnnotationSimpleName(p, simpleNames)) { + return true; + } + // B) fallback: @JsonProperty("fieldName") on the parameter + if (hasJsonPropertyName(p, fieldName) && paramHasAnyAnnotationSimpleName(p, simpleNames)) { + return true; + } + } + } + } catch (Throwable ignored) { + // best-effort only + } + return false; + } + + /** + * Param has any annotation simple name boolean. + * + * @param p the p + * @param simpleNames the simple names + * @return the boolean + */ + private static boolean paramHasAnyAnnotationSimpleName(java.lang.reflect.Parameter p, Collection simpleNames) { + for (Annotation ann : p.getAnnotations()) { + if (simpleNames.contains(ann.annotationType().getSimpleName())) { + return true; + } + } + return false; + } + + /** + * Has json property name boolean. + * + * @param p the p + * @param expected the expected + * @return the boolean + */ + private static boolean hasJsonPropertyName(java.lang.reflect.Parameter p, String expected) { + try { + JsonProperty jp = p.getAnnotation(JsonProperty.class); + return jp != null && expected.equals(jp.value()); + } catch (Throwable ignored) { + return false; + } + } + + /** + * Find getter method. + * + * @param f the f + * @return the method + */ + private static Method findGetter(Field f) { + String n = f.getName(); + String cap = Character.toUpperCase(n.charAt(0)) + n.substring(1); + String[] names = (f.getType() == boolean.class || f.getType() == Boolean.class) + ? new String[] { "is" + cap, "get" + cap } + : new String[] { "get" + cap }; + for (String m : names) { + try { + return f.getDeclaringClass().getMethod(m); + } catch (NoSuchMethodException ignored) {} + } + return null; + } + + /** + * Gets json property. + * + * @param f the f + * @return the json property + */ + private static JsonProperty getJsonProperty(Field f) { + JsonProperty jp = f.getAnnotation(JsonProperty.class); + if (jp != null) return jp; + Method g = findGetter(f); + if (g != null) return g.getAnnotation(JsonProperty.class); + return null; + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocKotlinUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocKotlinUtils.java new file mode 100644 index 000000000..19496bb56 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocKotlinUtils.java @@ -0,0 +1,117 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.core.utils; + +import java.lang.reflect.Field; + +import kotlin.jvm.JvmClassMappingKt; +import kotlin.reflect.KClass; +import kotlin.reflect.KFunction; +import kotlin.reflect.KParameter; +import kotlin.reflect.KProperty; +import kotlin.reflect.KProperty1; +import kotlin.reflect.full.KClasses; +import kotlin.reflect.jvm.ReflectJvmMapping; + +import org.springframework.core.KotlinDetector; + +/** + * The type Spring doc kotlin utils. + * + * @author bnasslahsen + */ +public class SpringDocKotlinUtils { + + /** + * Is kotlin declaring class boolean. + * + * @param f the f + * @return the boolean + */ + static boolean isKotlinDeclaringClass(Field f) { + return KotlinDetector.isKotlinPresent() + && KotlinDetector.isKotlinReflectPresent() + && KotlinDetector.isKotlinType(f.getDeclaringClass()); + } + + /** + * Kotlin marked nullable fallback boolean. + * + * @param f the f + * @return the boolean + */ + private static Boolean kotlinMarkedNullableFallback(Field f) { + try { + KClass kClass = JvmClassMappingKt.getKotlinClass(f.getDeclaringClass()); + for (Object pObj : KClasses.getMemberProperties((KClass) kClass)) { + KProperty1 p = (KProperty1) pObj; + if (p.getName().equals(f.getName())) { + return p.getReturnType().isMarkedNullable(); + } + } + } catch (Throwable ignored) {} + return null; + } + + /** + * Kotlin constructor param is optional boolean. + * + * @param f the f + * @return the boolean + */ + static Boolean kotlinConstructorParamIsOptional(Field f) { + try { + KClass kClass = JvmClassMappingKt.getKotlinClass(f.getDeclaringClass()); + KFunction primary = KClasses.getPrimaryConstructor(kClass); + if (primary != null) { + for (KParameter p : primary.getParameters()) { + if (f.getName().equals(p.getName())) { + return p.isOptional(); + } + } + } + } catch (Throwable ignored) {} + return null; + } + + /** + * Kotlin nullability boolean. + * + * @param field the field + * @return the boolean + */ + static Boolean kotlinNullability(Field field) { + if (!isKotlinDeclaringClass(field)) return null; + + KProperty prop = ReflectJvmMapping.getKotlinProperty(field); + if (prop != null) { + return prop.getReturnType().isMarkedNullable(); + } + + return kotlinMarkedNullableFallback(field); + } +} diff --git a/springdoc-openapi-starter-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java b/springdoc-openapi-starter-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java index a82543624..fee4a38b3 100644 --- a/springdoc-openapi-starter-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java +++ b/springdoc-openapi-starter-common/src/test/java/org/springdoc/api/AbstractOpenApiResourceTest.java @@ -141,7 +141,7 @@ void calculatePathFromRouterOperation() { responseBuilder, operationParser, new SpringDocConfigProperties(), - springDocProviders, new SpringDocCustomizers(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()) + springDocProviders, new SpringDocCustomizers(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(),Optional.empty(), Optional.empty()) ); final Parameter refParameter = new Parameter().$ref(PARAMETER_REFERENCE); @@ -208,7 +208,7 @@ void preLoadingModeShouldNotOverwriteServers() throws InterruptedException { requestBuilder, responseBuilder, operationParser, - properties, springDocProviders, new SpringDocCustomizers(Optional.of(singleton(openApiCustomizer)), Optional.empty(), Optional.empty(), Optional.empty()) + properties, springDocProviders, new SpringDocCustomizers(Optional.of(singleton(openApiCustomizer)), Optional.empty(), Optional.empty(), Optional.empty(),Optional.empty(), Optional.empty()) ); // wait for executor to be done @@ -240,7 +240,7 @@ void serverBaseUrlCustomisersTest() throws InterruptedException { responseBuilder, operationParser, properties, - springDocProviders, new SpringDocCustomizers(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()) + springDocProviders, new SpringDocCustomizers(Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(),Optional.empty(), Optional.empty()) ); // wait for executor to be done diff --git a/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/extractor/MethodParameterPojoExtractorTest.java b/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/extractor/MethodParameterPojoExtractorTest.java index 220b2f821..4c03ec434 100644 --- a/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/extractor/MethodParameterPojoExtractorTest.java +++ b/springdoc-openapi-starter-common/src/test/java/org/springdoc/core/extractor/MethodParameterPojoExtractorTest.java @@ -24,10 +24,12 @@ package org.springdoc.core.extractor; import java.lang.reflect.Method; +import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; +import org.springdoc.core.utils.SchemaUtils; import org.springframework.core.MethodParameter; @@ -37,6 +39,9 @@ * Tests for {@link MethodParameterPojoExtractor}. */ class MethodParameterPojoExtractorTest { + + private MethodParameterPojoExtractor methodParameterPojoExtractor = new MethodParameterPojoExtractor(new SchemaUtils(Optional.empty())); + /** * Tests for {@link MethodParameterPojoExtractor#extractFrom(Class)}. */ @@ -47,7 +52,7 @@ class extractFrom { */ @Test void ifRecordObjectShouldGetField() { - Stream actual = MethodParameterPojoExtractor.extractFrom(RecordObject.class); + Stream actual = methodParameterPojoExtractor.extractFrom(RecordObject.class); assertThat(actual) .extracting(MethodParameter::getMethod) .extracting(Method::getName) @@ -59,7 +64,7 @@ void ifRecordObjectShouldGetField() { */ @Test void ifClassObjectShouldGetMethod() { - Stream actual = MethodParameterPojoExtractor.extractFrom(ClassObject.class); + Stream actual = methodParameterPojoExtractor.extractFrom(ClassObject.class); assertThat(actual) .extracting(MethodParameter::getMethod) .extracting(Method::getName) diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java index e86328fe7..4240e22af 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/MultipleOpenApiResource.java @@ -161,7 +161,7 @@ private OpenApiResource buildWebFluxOpenApiResource(GroupedOpenApi item) { operationParser, springDocConfigProperties, springDocProviders, new SpringDocCustomizers(Optional.of(item.getOpenApiCustomizers()), Optional.of(item.getOperationCustomizers()), - Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters())) + Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters()), Optional.empty(), Optional.empty()) ); else return new OpenApiActuatorResource(item.getGroup(), @@ -171,7 +171,7 @@ springDocProviders, new SpringDocCustomizers(Optional.of(item.getOpenApiCustomiz operationParser, springDocConfigProperties, springDocProviders, new SpringDocCustomizers(Optional.of(item.getOpenApiCustomizers()), Optional.of(item.getOperationCustomizers()), - Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters()))); + Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters()), Optional.empty(), Optional.empty())); } /** diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java index 4ba8d73ee..520a87605 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java @@ -33,6 +33,7 @@ import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.providers.ActuatorProvider; import org.springdoc.core.providers.SpringDocProviders; @@ -110,18 +111,20 @@ OpenApiWebfluxResource openApiResource(ObjectFactory openAPIBuil * * @param parameterBuilder the parameter builder * @param requestBodyService the request body builder - * @param parameterCustomizers the parameter customizers + * @param customizers the customizers * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer + * @param methodParameterPojoExtractor the method parameter pojo extractor * @return the request builder */ @Bean @ConditionalOnMissingBean @Lazy(false) RequestService requestBuilder(GenericParameterService parameterBuilder, RequestBodyService requestBodyService, - Optional> parameterCustomizers, - SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) { + SpringDocCustomizers customizers, + SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + MethodParameterPojoExtractor methodParameterPojoExtractor) { return new RequestService(parameterBuilder, requestBodyService, - parameterCustomizers, localSpringDocParameterNameDiscoverer); + customizers, localSpringDocParameterNameDiscoverer,methodParameterPojoExtractor); } /** diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java index ba2a5055c..31b3caae4 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java @@ -30,7 +30,9 @@ import java.util.Optional; import org.springdoc.core.customizers.ParameterCustomizer; +import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.service.AbstractRequestService; import org.springdoc.core.service.GenericParameterService; import org.springdoc.core.service.RequestBodyService; @@ -62,12 +64,14 @@ public class RequestService extends AbstractRequestService { * * @param parameterBuilder the parameter builder * @param requestBodyService the request body builder - * @param parameterCustomizers the parameter customizers + * @param customizers the parameter customizers * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer + * @param methodParameterPojoExtractor the method parameter pojo extractor */ public RequestService(GenericParameterService parameterBuilder, RequestBodyService requestBodyService, - Optional> parameterCustomizers, - SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) { - super(parameterBuilder, requestBodyService, parameterCustomizers, localSpringDocParameterNameDiscoverer); + SpringDocCustomizers customizers, + SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + MethodParameterPojoExtractor methodParameterPojoExtractor) { + super(parameterBuilder, requestBodyService, customizers, localSpringDocParameterNameDiscoverer,methodParameterPojoExtractor); } } diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/MultipleOpenApiResource.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/MultipleOpenApiResource.java index 27d1a0f79..af1471c5a 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/MultipleOpenApiResource.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/MultipleOpenApiResource.java @@ -161,7 +161,7 @@ private OpenApiResource buildWebMvcOpenApiResource(GroupedOpenApi item) { operationParser, springDocConfigProperties, springDocProviders, new SpringDocCustomizers(Optional.of(item.getOpenApiCustomizers()), Optional.of(item.getOperationCustomizers()), - Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters())) + Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters()), Optional.empty(), Optional.empty()) ); else @@ -172,7 +172,7 @@ private OpenApiResource buildWebMvcOpenApiResource(GroupedOpenApi item) { operationParser, springDocConfigProperties, springDocProviders, new SpringDocCustomizers(Optional.of(item.getOpenApiCustomizers()), Optional.of(item.getOperationCustomizers()), - Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters())) + Optional.of(item.getRouterOperationCustomizers()), Optional.of(item.getOpenApiMethodFilters()), Optional.empty(), Optional.empty()) ); } diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java index a699e89ec..645e18e0b 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java @@ -33,6 +33,7 @@ import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.providers.ActuatorProvider; import org.springdoc.core.providers.SpringDocProviders; @@ -120,18 +121,20 @@ OpenApiWebMvcResource openApiResource(ObjectFactory openAPIBuild * * @param parameterBuilder the parameter builder * @param requestBodyService the request body builder - * @param parameterCustomizers the parameter customizers + * @param springDocCustomizers the spring doc customizers * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer + * @param methodParameterPojoExtractor the method parameter pojo extractor * @return the request builder */ @Bean @ConditionalOnMissingBean @Lazy(false) RequestService requestBuilder(GenericParameterService parameterBuilder, RequestBodyService requestBodyService, - Optional> parameterCustomizers, - SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) { + SpringDocCustomizers springDocCustomizers, + SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + MethodParameterPojoExtractor methodParameterPojoExtractor) { return new RequestService(parameterBuilder, requestBodyService, - parameterCustomizers, localSpringDocParameterNameDiscoverer); + springDocCustomizers, localSpringDocParameterNameDiscoverer, methodParameterPojoExtractor); } /** diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java index 1cd860f43..81c88d845 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java @@ -30,7 +30,9 @@ import java.util.Optional; import org.springdoc.core.customizers.ParameterCustomizer; +import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.service.AbstractRequestService; import org.springdoc.core.service.GenericParameterService; import org.springdoc.core.service.RequestBodyService; @@ -58,12 +60,14 @@ public class RequestService extends AbstractRequestService { * * @param parameterBuilder the parameter builder * @param requestBodyService the request body builder - * @param parameterCustomizers the parameter customizers + * @param springDocCustomizers the spring doc customizers * @param localSpringDocParameterNameDiscoverer the local spring doc parameter name discoverer + * @param methodParameterPojoExtractor the method parameter pojo extractor */ public RequestService(GenericParameterService parameterBuilder, RequestBodyService requestBodyService, - Optional> parameterCustomizers, - SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer) { - super(parameterBuilder, requestBodyService, parameterCustomizers, localSpringDocParameterNameDiscoverer); + SpringDocCustomizers springDocCustomizers, + SpringDocParameterNameDiscoverer localSpringDocParameterNameDiscoverer, + MethodParameterPojoExtractor methodParameterPojoExtractor) { + super(parameterBuilder, requestBodyService, springDocCustomizers, localSpringDocParameterNameDiscoverer,methodParameterPojoExtractor); } } diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app21/SpringDocApp21Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app21/SpringDocApp21Test.kt new file mode 100644 index 000000000..cb5ae006b --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app21/SpringDocApp21Test.kt @@ -0,0 +1,73 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.api.v31.app21 + +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.enums.Explode +import io.swagger.v3.oas.annotations.media.ArraySchema +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.Valid +import org.springdoc.core.annotations.ParameterObject +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RestController +import test.org.springdoc.api.v31.AbstractKotlinSpringDocMVCTest + +class SpringDocApp21Test : AbstractKotlinSpringDocMVCTest() { + @SpringBootApplication + class DemoApplication +} + + +@RestController +class HelloController { + @GetMapping("/hello") + fun hello(@Valid baseSearchParameters: BaseSearchParameters) = + ResponseEntity.ok("Hello, World!") +} + +@ParameterObject +data class BaseSearchParameters( + val filters: Filters = Filters() +) + +@ParameterObject +data class Filters( + @field:Parameter( + description = "Description .", + explode = Explode.FALSE, + array = ArraySchema(schema = Schema(type = "string")) + ) + var brand: Set = emptySet(), + + @field:Parameter( + description = "Description ..", + explode = Explode.FALSE, + array = ArraySchema(schema = Schema(type = "string")) + ) + var service: Set = emptySet(), + + @field:Parameter( + description = "Description ...", + explode = Explode.FALSE, + array = ArraySchema(schema = Schema(type = "string")) + ) + var productGroup: Set = emptySet(), +) \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app21.json b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app21.json new file mode 100644 index 000000000..eaf4954b4 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app21.json @@ -0,0 +1,77 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/hello": { + "get": { + "tags": [ + "hello-controller" + ], + "operationId": "hello", + "parameters": [ + { + "name": "filters.brand", + "in": "query", + "description": "Description .", + "required": false, + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filters.service", + "in": "query", + "description": "Description ..", + "required": false, + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "filters.productGroup", + "in": "query", + "description": "Description ...", + "required": false, + "explode": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": {} +} From dcdb1b762a30cfe9cea47742497902ae20d36a15 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 11:59:01 +0200 Subject: [PATCH 14/45] @io.swagger.v3.oas.annotations.parameters.RequestBody does not work well with @RequestPart. Fixes #3071 --- .../core/service/RequestBodyService.java | 68 ++++++----------- .../api/v31/app119/HelloController.java | 10 +++ .../test/resources/results/3.1.0/app119.json | 75 +++++++++++++++---- 3 files changed, 94 insertions(+), 59 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java index 7387d20be..35ec79e9b 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java @@ -257,11 +257,6 @@ public void calculateRequestBodyInfo(Components components, MethodAttributes met ParameterInfo parameterInfo, RequestBodyInfo requestBodyInfo) { RequestBody requestBody = requestBodyInfo.getRequestBody(); MethodParameter methodParameter = parameterInfo.getMethodParameter(); - // Get it from parameter level, if not present - if (requestBody == null) { - io.swagger.v3.oas.annotations.parameters.RequestBody requestBodyDoc = methodParameter.getParameterAnnotation(io.swagger.v3.oas.annotations.parameters.RequestBody.class); - requestBody = this.buildRequestBodyFromDoc(requestBodyDoc, methodAttributes, components).orElse(null); - } RequestPart requestPart = methodParameter.getParameterAnnotation(RequestPart.class); String paramName = null; @@ -273,7 +268,8 @@ public void calculateRequestBodyInfo(Components components, MethodAttributes met paramName = StringUtils.defaultIfEmpty(paramName, parameterInfo.getpName()); parameterInfo.setpName(paramName); - requestBody = buildRequestBody(requestBody, components, methodAttributes, parameterInfo, + io.swagger.v3.oas.annotations.parameters.RequestBody requestBodyDoc = methodParameter.getParameterAnnotation(io.swagger.v3.oas.annotations.parameters.RequestBody.class); + requestBody = buildRequestBody(requestBodyDoc, components, methodAttributes, parameterInfo, requestBodyInfo); requestBodyInfo.setRequestBody(requestBody); } @@ -281,33 +277,29 @@ public void calculateRequestBodyInfo(Components components, MethodAttributes met /** * Build request body. * - * @param requestBody the request body + * @param requestBodyDoc the request body * @param components the components * @param methodAttributes the method attributes * @param parameterInfo the parameter info * @param requestBodyInfo the request body info * @return the request body */ - private RequestBody buildRequestBody(RequestBody requestBody, Components components, + private RequestBody buildRequestBody(io.swagger.v3.oas.annotations.parameters.RequestBody requestBodyDoc, Components components, MethodAttributes methodAttributes, ParameterInfo parameterInfo, RequestBodyInfo requestBodyInfo) { + RequestBody requestBody = requestBodyInfo.getRequestBody(); if (requestBody == null) { requestBody = new RequestBody(); requestBodyInfo.setRequestBody(requestBody); } - if (requestBody.getContent() == null) { - Schema schema = parameterBuilder.calculateSchema(components, parameterInfo, requestBodyInfo, - methodAttributes.getJsonViewAnnotationForRequestBody()); - Map parameterEncoding = getParameterEncoding(parameterInfo); - buildContent(requestBody, methodAttributes, schema, parameterEncoding); - } - else if (!methodAttributes.isWithResponseBodySchemaDoc()) { - Schema schema = parameterBuilder.calculateSchema(components, parameterInfo, requestBodyInfo, - methodAttributes.getJsonViewAnnotationForRequestBody()); - Map parameterEncoding = getParameterEncoding(parameterInfo); - mergeContent(requestBody, methodAttributes, schema, parameterEncoding); - } + if (requestBodyDoc != null) + requestBody = this.buildRequestBodyFromDoc(requestBodyDoc, methodAttributes, components).orElse(requestBody); + + Schema schema = parameterBuilder.calculateSchema(components, parameterInfo, requestBodyInfo, + methodAttributes.getJsonViewAnnotationForRequestBody()); + Map parameterEncoding = getParameterEncoding(parameterInfo); + buildContent(requestBody, methodAttributes, schema, parameterEncoding); // Add requestBody javadoc if (StringUtils.isBlank(requestBody.getDescription()) && parameterBuilder.getJavadocProvider() != null @@ -320,18 +312,6 @@ else if (!methodAttributes.isWithResponseBodySchemaDoc()) { return requestBody; } - /** - * Merge content. - * - * @param requestBody the request body - * @param methodAttributes the method attributes - * @param parameterEncoding the parameter encoding - */ - private void mergeContent(RequestBody requestBody, MethodAttributes methodAttributes, Schema schema, Map parameterEncoding) { - Content content = requestBody.getContent(); - buildContent(requestBody, methodAttributes, schema, content, parameterEncoding); - } - /** * Build content. * @@ -341,24 +321,18 @@ private void mergeContent(RequestBody requestBody, MethodAttributes methodAttrib * @param parameterEncoding the parameter encoding */ private void buildContent(RequestBody requestBody, MethodAttributes methodAttributes, Schema schema, Map parameterEncoding) { - Content content = new Content(); - buildContent(requestBody, methodAttributes, schema, content, parameterEncoding); - } + Content content; + if (requestBody.getContent() == null) { + content = new Content(); + } + else { + content = requestBody.getContent(); + } - /** - * Build content. - * - * @param requestBody the request body - * @param methodAttributes the method attributes - * @param schema the schema - * @param content the content - * @param parameterEncoding the parameter encoding - */ - private void buildContent(RequestBody requestBody, MethodAttributes methodAttributes, Schema schema, Content content, Map parameterEncoding) { for (String value : methodAttributes.getMethodConsumes()) { MediaType mediaTypeObject = new MediaType(); - mediaTypeObject.setSchema(schema); MediaType mediaType = content.get(value); + mediaTypeObject.setSchema(schema); if (mediaType != null) { if (mediaType.getExample() != null) mediaTypeObject.setExample(mediaType.getExample()); @@ -366,6 +340,8 @@ private void buildContent(RequestBody requestBody, MethodAttributes methodAttrib mediaTypeObject.setExamples(mediaType.getExamples()); if (mediaType.getEncoding() != null) mediaTypeObject.setEncoding(mediaType.getEncoding()); + if (mediaType.getSchema() != null) + mediaTypeObject.setSchema(mediaType.getSchema()); } else if (!CollectionUtils.isEmpty(parameterEncoding)) { mediaTypeObject.setEncoding(parameterEncoding); diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app119/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app119/HelloController.java index 3bc16f670..2dbc818f8 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app119/HelloController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app119/HelloController.java @@ -31,6 +31,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; @@ -54,4 +55,13 @@ public String multiFilesInMultiPart( @RequestPart(value = "file2", required = false) @Parameter(description = "This is file2") final MultipartFile file2) { return "Hello World " + jsonRequest.getName(); } + + @PostMapping(value = "/uploadFileWithJson2", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}, produces = { + MediaType.APPLICATION_JSON_VALUE}) + public ResponseEntity uploadFileWithJson( + @Parameter(description="file") @RequestPart("file") final MultipartFile file, + @RequestBody(description = "toto", content = @Content(encoding = @Encoding(name = "jsonRequest", contentType = MediaType.APPLICATION_JSON_VALUE))) + @Parameter(description = "An extra JSON payload sent with file") @RequestPart("jsonRequest") final JsonRequest jsonRequest) { + return null; + } } \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app119.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app119.json index beaf56a5e..2553e2780 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app119.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app119.json @@ -11,6 +11,55 @@ } ], "paths": { + "/uploadFileWithJson2": { + "post": { + "tags": [ + "hello-controller" + ], + "operationId": "uploadFileWithJson", + "requestBody": { + "description": "toto", + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary", + "description": "file" + }, + "jsonRequest": { + "$ref": "#/components/schemas/JsonRequest" + } + }, + "required": [ + "file", + "jsonRequest" + ] + }, + "encoding": { + "jsonRequest": { + "contentType": "application/json" + } + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } + }, "/multi": { "post": { "tags": [ @@ -22,25 +71,25 @@ "content": { "multipart/form-data": { "schema": { - "required": [ - "params" - ], "type": "object", "properties": { + "params": { + "$ref": "#/components/schemas/JsonRequest" + }, "file1": { "type": "string", - "description": "This is file1", - "format": "binary" + "format": "binary", + "description": "This is file1" }, "file2": { "type": "string", - "description": "This is file2", - "format": "binary" - }, - "params": { - "$ref": "#/components/schemas/JsonRequest" + "format": "binary", + "description": "This is file2" } - } + }, + "required": [ + "params" + ] }, "encoding": { "params": { @@ -69,12 +118,12 @@ "schemas": { "JsonRequest": { "type": "object", + "description": "This is the configuration", "properties": { "name": { "type": "string" } - }, - "description": "This is the configuration" + } } } } From 998183e756bbc1ee92e05241fe4b4e36680dc22b Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 12:39:20 +0200 Subject: [PATCH 15/45] Duplicate key class Parameter when documenting two GET methods with same path and PathVariable, differing only by produces media type. Fixes #3073 --- .../core/service/AbstractRequestService.java | 14 +++- .../org/springdoc/api/v31/app192/Feature.java | 40 +++++++++++ .../api/v31/app192/HelloController.java | 67 ++++++++++++++++++ .../api/v31/app192/SpringDocApp192Test.java | 39 +++++++++++ .../test/resources/results/3.1.0/app192.json | 69 +++++++++++++++++++ 5 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/Feature.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/SpringDocApp192Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app192.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 7177b23be..3e6718f12 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -68,6 +68,8 @@ import io.swagger.v3.oas.models.parameters.Parameter; import io.swagger.v3.oas.models.parameters.RequestBody; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; @@ -118,6 +120,11 @@ */ public abstract class AbstractRequestService { + /** + * The constant LOGGER. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRequestService.class); + /** * The constant ACTUATOR_PKGS. */ @@ -415,7 +422,12 @@ else if (!RequestMethod.GET.equals(requestMethod) || OpenApiVersion.OPENAPI_3_1. */ private LinkedHashMap getParameterLinkedHashMap(Components components, MethodAttributes methodAttributes, List operationParameters, Map parametersDocMap) { LinkedHashMap map = operationParameters.stream().collect(Collectors.toMap(ParameterId::new, parameter -> parameter, (u, v) -> { - throw new IllegalStateException(String.format("Duplicate key %s", u)); + LOGGER.warn( + "Duplicate OpenAPI parameter detected: name='{}', in='{}'. Keeping the first found and ignoring the rest. " + + "Declare the parameter only once.", + u.getName(), u.getIn() + ); + return u; }, LinkedHashMap::new)); for (Entry entry : parametersDocMap.entrySet()) { diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/Feature.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/Feature.java new file mode 100644 index 000000000..b4d0fd017 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/Feature.java @@ -0,0 +1,40 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app192; + +public class Feature { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/HelloController.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/HelloController.java new file mode 100644 index 000000000..3fe06bf31 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/HelloController.java @@ -0,0 +1,67 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app192; + +import java.util.List; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import reactor.core.publisher.Flux; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author bnasslahsen + */ +@RestController +@RequestMapping +public class HelloController { + + @Operation(operationId = "getFeaturesJson", + parameters = + @Parameter(name = "organizationId" , description = "toto", in = ParameterIn.PATH)) + @GetMapping(value = "/{organizationId}/features", produces = MediaType.APPLICATION_JSON_VALUE) + public List getFeaturesAsJson( + @PathVariable String organizationId) { + return List.of(/* ... */); + } + + @Operation(operationId = "getFeaturesNdjson", + parameters = @Parameter(name = "organizationId", description = "titi", in = ParameterIn.PATH + )) + @GetMapping(value = "/{organizationId}/features", produces = "application/x-ndjson") + public List getFeaturesAsNdjson( + @PathVariable String organizationId) { + return null; + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/SpringDocApp192Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/SpringDocApp192Test.java new file mode 100644 index 000000000..40514a3d4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app192/SpringDocApp192Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app192; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp192Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app192" }) + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app192.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app192.json new file mode 100644 index 000000000..9e9a01cf1 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app192.json @@ -0,0 +1,69 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/{organizationId}/features": { + "get": { + "tags": [ + "hello-controller" + ], + "operationId": "getFeaturesJson", + "parameters": [ + { + "name": "organizationId", + "in": "path", + "description": "titi", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/x-ndjson": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Feature" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Feature": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } + } +} From 2c498bc33432bf1384acb5b0f1bee8217c98950b Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 13:16:56 +0200 Subject: [PATCH 16/45] upgrade swagger-ui to v5.28.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cae83f5a1..fe714321c 100644 --- a/pom.xml +++ b/pom.xml @@ -54,7 +54,7 @@ 1.5.0 2.2.36 - 5.27.1 + 5.28.0 1.13.1 0.9.1 0.15.0 From 2f222b8d462f957c1e57d7b243ac7504d035d15b Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 14:46:40 +0200 Subject: [PATCH 17/45] upgrade commons-lang3 to v3.18.0 --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index fe714321c..5acb49e6d 100644 --- a/pom.xml +++ b/pom.xml @@ -61,6 +61,7 @@ 5.0.0-M1 2.0.0-M1 + 3.18.0 From fab8f90b6a6d4ed249df814b39c19df993da1adc Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 14:51:44 +0200 Subject: [PATCH 18/45] CHANGELOG.md update --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77d42fc54..9201ecd18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.8.12] - 2025-09-01 + +### Changed + +- Upgrade swagger-ui to v5.28.0 +- Upgrade commons-lang3 to v3.18.0 + +### Fixed + +- #3073 - Duplicate key class Parameter when documenting two GET methods with same path and PathVariable. +- #3071 - @io.swagger.v3.oas.annotations.parameters.RequestBody does not work well with @RequestPart +- #3066 - Parameter is now required after upgrading to springdoc-openapi 2.8.10 + +## [3.0.0-M1] - 2025-08-20 + +### Added +- #3062 - Add Spring Boot 4.0.0-M2 support ## [2.8.10] - 2025-08-20 From accd9792f445ea4e5003651ca4aac2772696b65c Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 1 Sep 2025 18:30:44 +0200 Subject: [PATCH 19/45] With 'oneOf' the response schema contains an extra 'type: "string". Fixes #3076 --- .../springdoc/core/utils/SpringDocUtils.java | 8 +- .../api/v31/app12/SpringDocApp12Test.java | 39 ++++++++ .../configuration/WebMvcConfiguration.java | 25 ++++++ .../app12/controllers/BasicController.java | 43 +++++++++ .../CustomOpenApiWebMvcResource.java | 27 ++++++ .../springdoc/api/v31/app12/model/Cat.java | 24 +++++ .../test/resources/results/3.1.0/app12.json | 88 +++++++++++++++++++ .../test/resources/results/3.1.0/app6.json | 1 - 8 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/SpringDocApp12Test.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/configuration/WebMvcConfiguration.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/BasicController.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/CustomOpenApiWebMvcResource.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/model/Cat.java create mode 100644 springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/resources/results/3.1.0/app12.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java index ad077f1a5..3b6db06c3 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java @@ -166,7 +166,10 @@ public static boolean isComposedSchema(Schema referencedSchema) { */ public static void handleSchemaTypes(Schema schema) { if (schema != null) { - if (schema.getType() != null && CollectionUtils.isEmpty(schema.getTypes())) { + if (schema.getType() == null && schema.getTypes() == null && schema.get$ref() == null && !isComposedSchema(schema)) { + schema.addType("object"); + } + else if (schema.getType() != null && CollectionUtils.isEmpty(schema.getTypes()) && !isComposedSchema(schema)) { schema.addType(schema.getType()); } else if (schema.getItems() != null && schema.getItems().getType() != null @@ -176,9 +179,6 @@ else if (schema.getItems() != null && schema.getItems().getType() != null if (schema.getProperties() != null) { schema.getProperties().forEach((key, value) -> handleSchemaTypes(value)); } - if (schema.getType() == null && schema.getTypes() == null && schema.get$ref() == null && !isComposedSchema(schema)) { - schema.addType("object"); - } } } diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/SpringDocApp12Test.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/SpringDocApp12Test.java new file mode 100644 index 000000000..a4c125090 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/SpringDocApp12Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app12; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp12Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp { + } + +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/configuration/WebMvcConfiguration.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/configuration/WebMvcConfiguration.java new file mode 100644 index 000000000..4dc50c007 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/configuration/WebMvcConfiguration.java @@ -0,0 +1,25 @@ +package test.org.springdoc.api.v31.app12.configuration; + +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +@Configuration +public class WebMvcConfiguration { + + @Bean + MappingJackson2HttpMessageConverter getMappingJacksonHttpMessageConverter() { + MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); + converter.setSupportedMediaTypes(List.of(MediaType.APPLICATION_JSON)); + converter.setObjectMapper(new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL) + ); + + return converter; + } +} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/BasicController.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/BasicController.java new file mode 100644 index 000000000..5610fdcb6 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/BasicController.java @@ -0,0 +1,43 @@ +package test.org.springdoc.api.v31.app12.controllers; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import test.org.springdoc.api.v31.app12.model.Cat; + +import org.springframework.hateoas.MediaTypes; +import org.springframework.hateoas.RepresentationModel; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(path = "/") +public class BasicController { + + @GetMapping("/cat") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "get", description = "Provides an animal.") + public String get(Cat cat) { + return cat != null ? cat.getName() : ""; + } + + @GetMapping("/test") + @ResponseStatus(HttpStatus.OK) + @Operation(summary = "get", description = "Provides a response.") + @ApiResponse(content = @Content(mediaType = MediaTypes.HAL_JSON_VALUE, + schema = @io.swagger.v3.oas.annotations.media.Schema(oneOf = { + Integer.class + })), + responseCode = "200") + public Object get() { + return 1; + } + + // dummy + public static class Response extends RepresentationModel { + public Response(String v) {} + } +} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/CustomOpenApiWebMvcResource.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/CustomOpenApiWebMvcResource.java new file mode 100644 index 000000000..4aef520b5 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/controllers/CustomOpenApiWebMvcResource.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app12.controllers; + +import org.springdoc.core.customizers.SpringDocCustomizers; +import org.springdoc.core.properties.SpringDocConfigProperties; +import org.springdoc.core.providers.SpringDocProviders; +import org.springdoc.core.service.AbstractRequestService; +import org.springdoc.core.service.GenericResponseService; +import org.springdoc.core.service.OpenAPIService; +import org.springdoc.core.service.OperationService; +import org.springdoc.webmvc.api.OpenApiWebMvcResource; + +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class CustomOpenApiWebMvcResource extends OpenApiWebMvcResource { + + public CustomOpenApiWebMvcResource(ObjectFactory openAPIBuilderObjectFactory, + AbstractRequestService requestBuilder, + GenericResponseService responseBuilder, + OperationService operationParser, + SpringDocConfigProperties springDocConfigProperties, + SpringDocProviders springDocProviders, + SpringDocCustomizers springDocCustomizers) { + super(openAPIBuilderObjectFactory, requestBuilder, responseBuilder, operationParser, springDocConfigProperties, springDocProviders, springDocCustomizers); + } +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/model/Cat.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/model/Cat.java new file mode 100644 index 000000000..3420ba985 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/app12/model/Cat.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app12.model; + +import com.fasterxml.jackson.annotation.JsonUnwrapped; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "Represents a Cat class.") +public class Cat { + + @JsonUnwrapped + @Schema(description = "The name.", nullable = true) + private String name; + + public Cat(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/resources/results/3.1.0/app12.json b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/resources/results/3.1.0/app12.json new file mode 100644 index 000000000..99b4b00c9 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/resources/results/3.1.0/app12.json @@ -0,0 +1,88 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/test": { + "get": { + "tags": [ + "basic-controller" + ], + "summary": "get", + "description": "Provides a response.", + "operationId": "get", + "responses": { + "200": { + "description": "OK", + "content": { + "application/hal+json": { + "schema": { + "oneOf": [ + { + "type": "integer", + "format": "int32" + } + ] + } + } + } + } + } + } + }, + "/cat": { + "get": { + "tags": [ + "basic-controller" + ], + "summary": "get", + "description": "Provides an animal.", + "operationId": "get_1", + "parameters": [ + { + "name": "cat", + "in": "query", + "required": true, + "schema": { + "$ref": "#/components/schemas/Cat" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Cat": { + "type": "object", + "description": "Represents a Cat class.", + "properties": { + "name": { + "type": "string", + "description": "The name." + } + } + } + } + } +} diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app6.json b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app6.json index 8ef6012de..54d9ca1cb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app6.json +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app6.json @@ -31,7 +31,6 @@ "content": { "application/json": { "schema": { - "type": "string", "oneOf": [ { "type": "string" From 329c3f778b89465cc4748651e95054a5c5a0552c Mon Sep 17 00:00:00 2001 From: Badr NASS LAHSEN <13404829+bnasslahsen@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:20:45 +0200 Subject: [PATCH 20/45] Update pom.xml Cancel commons-lang3 upgrade. Fixes #3078 --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5acb49e6d..fe714321c 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,6 @@ 5.0.0-M1 2.0.0-M1 - 3.18.0 From 58fc114597c6c6da46cd22621ed1816aaabf3202 Mon Sep 17 00:00:00 2001 From: Badr NASS LAHSEN <13404829+bnasslahsen@users.noreply.github.com> Date: Tue, 2 Sep 2025 13:21:03 +0200 Subject: [PATCH 21/45] Update CHANGELOG.md Cancel commons-lang3 upgrade. Fixes #3078 --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9201ecd18..79a6bf8ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Upgrade swagger-ui to v5.28.0 -- Upgrade commons-lang3 to v3.18.0 ### Fixed From c401406d4299942ac4f74d5d3d51bcda8743e00a Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sun, 7 Sep 2025 00:18:54 +0200 Subject: [PATCH 22/45] Adding initial Scalar Support. Fixes #3084 --- pom.xml | 8 + springdoc-openapi-starter-common/pom.xml | 6 + .../scalar/AbstractScalarController.java | 185 ++++++++++++++++++ .../org/springdoc/scalar/ScalarConstants.java | 55 ++++++ .../ScalarDisableAutoConfiguration.java | 56 ++++++ .../main/resources/META-INF/spring.factories | 2 + .../.gitignore | 144 ++++++++++++++ .../pom.xml | 50 +++++ .../scalar/ScalarActuatorController.java | 88 +++++++++ .../webflux/scalar/ScalarConfiguration.java | 116 +++++++++++ .../scalar/ScalarWebFluxController.java | 89 +++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../webflux/scalar/AbstractCommonTest.java | 114 +++++++++++ .../scalar/AbstractSpringDocActuatorTest.java | 89 +++++++++ .../webflux/scalar/app1/HelloController.java | 36 ++++ .../scalar/app1/SpringDocApp1Test.java | 38 ++++ .../app1/SpringDocAppScalarDisabledTest.java | 41 ++++ .../webflux/scalar/app10/HelloController.java | 36 ++++ .../scalar/app10/SpringDocApp10Test.java | 54 +++++ .../scalar/app11/SpringDocApp11Test.java | 89 +++++++++ .../scalar/app12/SpringDocApp12Test.java | 48 +++++ .../scalar/app13/SpringDocApp13Test.java | 48 +++++ .../webflux/scalar/app2/HelloController.java | 36 ++++ .../scalar/app2/SpringDocApp2Test.java | 40 ++++ .../webflux/scalar/app3/HelloController.java | 36 ++++ .../scalar/app3/SpringDocApp3Test.java | 43 ++++ .../webflux/scalar/app4/HelloController.java | 44 +++++ .../scalar/app4/SpringDocApp4Test.java | 71 +++++++ .../webflux/scalar/app5/HelloController.java | 45 +++++ .../scalar/app5/SpringDocApp5Test.java | 68 +++++++ .../webflux/scalar/app6/HelloController.java | 36 ++++ .../scalar/app6/SpringDocApp6Test.java | 63 ++++++ .../webflux/scalar/app7/HelloController.java | 36 ++++ .../scalar/app7/SpringDocApp7Test.java | 62 ++++++ .../webflux/scalar/app8/HelloController.java | 45 +++++ .../scalar/app8/SpringDocApp8Test.java | 50 +++++ .../webflux/scalar/app9/HelloController.java | 36 ++++ .../scalar/app9/SpringDocApp9Test.java | 51 +++++ .../webflux/scalar/app9/WebConfig.java | 16 ++ .../src/test/resources/application-test.yml | 9 + .../src/test/resources/logback-test.xml | 6 + .../src/test/resources/results/app1 | 25 +++ .../src/test/resources/results/app10 | 25 +++ .../src/test/resources/results/app11 | 25 +++ .../src/test/resources/results/app11-1 | 25 +++ .../src/test/resources/results/app11-2 | 25 +++ .../src/test/resources/results/app12 | 25 +++ .../src/test/resources/results/app13 | 25 +++ .../src/test/resources/results/app2 | 25 +++ .../src/test/resources/results/app3 | 25 +++ .../src/test/resources/results/app4 | 25 +++ .../src/test/resources/results/app5 | 25 +++ .../src/test/resources/results/app6 | 25 +++ .../src/test/resources/results/app7 | 25 +++ .../src/test/resources/results/app8 | 25 +++ .../src/test/resources/results/app9 | 25 +++ .../.gitignore | 144 ++++++++++++++ .../pom.xml | 54 +++++ .../scalar/ScalarActuatorController.java | 88 +++++++++ .../webmvc/scalar/ScalarConfiguration.java | 117 +++++++++++ .../webmvc/scalar/ScalarWebMvcController.java | 89 +++++++++ ...ot.autoconfigure.AutoConfiguration.imports | 1 + .../webmvc/scalar/AbstractCommonTest.java | 148 ++++++++++++++ .../scalar/AbstractSpringDocActuatorTest.java | 86 ++++++++ .../webmvc/scalar/app1/HelloController.java | 37 ++++ .../webmvc/scalar/app1/SpringDocApp1Test.java | 38 ++++ .../webmvc/scalar/app10/HelloController.java | 37 ++++ .../scalar/app10/SpringDocApp10Test.java | 55 ++++++ .../webmvc/scalar/app11/HelloController.java | 46 +++++ .../scalar/app11/SpringDocApp11Test.java | 46 +++++ .../webmvc/scalar/app12/HelloController.java | 37 ++++ .../scalar/app12/SpringDocApp12Test.java | 58 ++++++ .../webmvc/scalar/app13/HelloController.java | 45 +++++ .../scalar/app13/SpringDocApp13Test.java | 50 +++++ .../webmvc/scalar/app14/HelloController.java | 37 ++++ .../scalar/app14/SpringDocApp14Test.java | 66 +++++++ .../webmvc/scalar/app15/HelloController.java | 37 ++++ .../scalar/app15/SpringDocApp15Test.java | 46 +++++ .../scalar/app16/SpringDocApp16Test.java | 87 ++++++++ .../scalar/app17/SpringDocApp17Test.java | 62 ++++++ .../scalar/app18/SpringDocApp18Test.java | 74 +++++++ .../webmvc/scalar/app19/HelloController.java | 45 +++++ .../scalar/app19/SpringDocApp19Test.java | 48 +++++ .../webmvc/scalar/app2/HelloController.java | 37 ++++ .../webmvc/scalar/app2/SpringDocApp2Test.java | 47 +++++ .../webmvc/scalar/app3/HelloController.java | 37 ++++ .../webmvc/scalar/app3/SpringDocApp3Test.java | 48 +++++ .../webmvc/scalar/app4/HelloController.java | 37 ++++ .../webmvc/scalar/app4/SpringDocApp4Test.java | 60 ++++++ .../webmvc/scalar/app5/SpringDocApp5Test.java | 38 ++++ .../webmvc/scalar/app5/SpringDocTestApp.java | 53 +++++ .../webmvc/scalar/app6/SpringDocApp6Test.java | 42 ++++ .../webmvc/scalar/app7/SpringDocApp7Test.java | 46 +++++ .../webmvc/scalar/app8/SpringApp8Test.java | 46 +++++ .../webmvc/scalar/app9/HelloController.java | 37 ++++ .../webmvc/scalar/app9/SpringDocApp9Test.java | 43 ++++ .../src/test/resources/application-test.yml | 4 + .../src/test/resources/logback-test.xml | 4 + .../src/test/resources/results/app1 | 25 +++ .../src/test/resources/results/app10 | 25 +++ .../src/test/resources/results/app11 | 25 +++ .../src/test/resources/results/app12 | 25 +++ .../src/test/resources/results/app13 | 25 +++ .../src/test/resources/results/app14 | 25 +++ .../src/test/resources/results/app15 | 25 +++ .../src/test/resources/results/app16 | 25 +++ .../src/test/resources/results/app16-1 | 25 +++ .../src/test/resources/results/app16-2 | 25 +++ .../src/test/resources/results/app17 | 25 +++ .../src/test/resources/results/app17-1 | 25 +++ .../src/test/resources/results/app17-2 | 25 +++ .../src/test/resources/results/app18 | 25 +++ .../src/test/resources/results/app18-1 | 25 +++ .../src/test/resources/results/app19 | 25 +++ .../src/test/resources/results/app2 | 25 +++ .../src/test/resources/results/app3 | 25 +++ .../src/test/resources/results/app4 | 25 +++ .../src/test/resources/results/app5 | 25 +++ .../src/test/resources/results/app6 | 25 +++ .../src/test/resources/results/app7-1 | 25 +++ .../src/test/resources/results/app7-2 | 25 +++ .../src/test/resources/results/app8 | 25 +++ 122 files changed, 5418 insertions(+) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarDisableAutoConfiguration.java create mode 100644 springdoc-openapi-starter-common/src/main/resources/META-INF/spring.factories create mode 100644 springdoc-openapi-starter-webflux-scalar/.gitignore create mode 100644 springdoc-openapi-starter-webflux-scalar/pom.xml create mode 100644 springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocApp1Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocAppScalarDisabledTest.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/SpringDocApp10Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app11/SpringDocApp11Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app12/SpringDocApp12Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app13/SpringDocApp13Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/SpringDocApp2Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/SpringDocApp3Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/SpringDocApp4Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/SpringDocApp5Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/SpringDocApp6Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/SpringDocApp8Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/HelloController.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/SpringDocApp9Test.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/WebConfig.java create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/application-test.yml create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/logback-test.xml create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 create mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 create mode 100644 springdoc-openapi-starter-webmvc-scalar/.gitignore create mode 100644 springdoc-openapi-starter-webmvc-scalar/pom.xml create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/SpringDocApp1Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/SpringDocApp10Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/SpringDocApp11Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/SpringDocApp12Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/SpringDocApp13Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/SpringDocApp14Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/SpringDocApp15Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app16/SpringDocApp16Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app17/SpringDocApp17Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app18/SpringDocApp18Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/SpringDocApp19Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/SpringDocApp2Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/SpringDocApp3Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/SpringDocApp4Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocApp5Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocTestApp.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app6/SpringDocApp6Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app7/SpringDocApp7Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app8/SpringApp8Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/SpringDocApp9Test.java create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/application-test.yml create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/logback-test.xml create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 create mode 100644 springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 diff --git a/pom.xml b/pom.xml index fe714321c..e669b679d 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,8 @@ springdoc-openapi-starter-webflux-api springdoc-openapi-starter-webmvc-ui springdoc-openapi-starter-webflux-ui + springdoc-openapi-starter-webmvc-scalar + springdoc-openapi-starter-webflux-scalar springdoc-openapi-bom @@ -61,6 +63,7 @@ 5.0.0-M1 2.0.0-M1 + 0.1.0 @@ -96,6 +99,11 @@ spring-security-oauth2-authorization-server ${spring-security-oauth2-authorization-server.version} + + com.scalar.maven + scalar + ${scalar.version} + diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index fca00c626..de11bedec 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -113,6 +113,12 @@ commons-logging test + + + com.scalar.maven + scalar + true + diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java new file mode 100644 index 000000000..0135bdfd4 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java @@ -0,0 +1,185 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.scalar; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + +import com.scalar.maven.webjar.ScalarProperties; + +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_URL; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +/** + * The type Abstract scalar controller. + * + * @author bnasslahsen This is a copy of the class ScalarController from the scalar webjar. It has been slightly modified to fit the springdoc-openapi code base. + */ +public abstract class AbstractScalarController { + + /** + * The Scalar properties. + */ + protected final ScalarProperties scalarProperties; + + /** + * The Original scalar url. + */ + protected final String originalScalarUrl; + + /** + * Instantiates a new Abstract scalar controller. + * + * @param scalarProperties the scalar properties + */ + protected AbstractScalarController(ScalarProperties scalarProperties) { + this.scalarProperties = scalarProperties; + this.originalScalarUrl = scalarProperties.getUrl(); + } + + /** + * Serves the main API reference interface. + *

This endpoint returns an HTML page that displays the Scalar API Reference + * interface. The page is configured with the OpenAPI specification URL from + * the properties.

+ * + * @param requestUrl the request url + * @return a ResponseEntity containing the HTML content for the API reference interface + * @throws IOException if the HTML template cannot be loaded + */ + protected ResponseEntity getDocs(String requestUrl) throws IOException { + // Load the template HTML + InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/scalar/index.html"); + if (inputStream == null) { + return ResponseEntity.notFound().build(); + } + + String html = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + requestUrl = decode(requestUrl); + // Replace the placeholders with actual values + String cdnUrl = buildJsBundleUrl(requestUrl); + String injectedHtml = html + .replace("__JS_BUNDLE_URL__", cdnUrl) + .replace("__CONFIGURATION__", """ + { + url: "%s" + } + """.formatted(buildApiDocsUrl(requestUrl))); + + return ResponseEntity.ok() + .contentType(MediaType.TEXT_HTML) + .body(injectedHtml); + } + + /** + * Serves the JavaScript bundle for the Scalar API Reference. + *

This endpoint returns the JavaScript file that powers the Scalar API Reference + * interface. The file is served with the appropriate MIME type.

+ * + * @return a ResponseEntity containing the JavaScript bundle + * @throws IOException if the JavaScript file cannot be loaded + */ + protected ResponseEntity getScalarJs() throws IOException { + // Load the scalar.js file + InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/scalar/" + SCALAR_JS_FILENAME); + if (inputStream == null) { + return ResponseEntity.notFound().build(); + } + + byte[] jsContent = inputStream.readAllBytes(); + + return ResponseEntity.ok() + .contentType(MediaType.valueOf("application/javascript")) + .body(jsContent); + } + + /** + * Decode string. + * + * @param requestURI the request uri + * @return the string + */ + protected String decode(String requestURI) { + return URLDecoder.decode(requestURI, StandardCharsets.UTF_8); + } + + /** + * Gets api docs url. + * + * @param requestUrl the request url + * @param apiDocsPath the api docs path + * @return the api docs url + */ + protected String buildApiDocsUrl(String requestUrl, String apiDocsPath) { + String apiDocsUrl = scalarProperties.getUrl(); + if (SCALAR_DEFAULT_URL.equals(originalScalarUrl)) { + String serverUrl = requestUrl.substring(0, requestUrl.length() - scalarProperties.getPath().length()); + apiDocsUrl = serverUrl + apiDocsPath; + } + return apiDocsUrl; + } + + /** + * Build js bundle url string. + * + * @param requestUrl the request url + * @param scalarPath the scalar path + * @return the string + */ + protected String buildJsBundleUrl(String requestUrl, String scalarPath) { + if (SCALAR_DEFAULT_URL.equals(originalScalarUrl)) { + int firstPathSlash = requestUrl.indexOf('/', requestUrl.indexOf("://") + 3); + String path = firstPathSlash >= 0 ? requestUrl.substring(firstPathSlash) : "/"; + if( path.endsWith("/")) + path = path.substring(0, path.length() - 1); + return path + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME; + } + return scalarPath + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME; + } + + /** + * Gets api docs url. + * + * @param requestUrl the request url + * @return the api docs url + */ + protected abstract String buildApiDocsUrl(String requestUrl); + + /** + * Build js bundle url string. + * + * @param requestUrl the request url + * @return the string + */ + protected abstract String buildJsBundleUrl(String requestUrl); +} diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java new file mode 100644 index 000000000..d63ce15e8 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java @@ -0,0 +1,55 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.scalar; + +/** + * The type ScalarConstants. + * + * @author bnasslahsen + */ +public class ScalarConstants { + + /** + * The constant SCALAR_DEFAULT_PATH. + */ + public static final String SCALAR_DEFAULT_PATH = "/scalar"; + + /** + * The constant SCALAR_JS_FILENAME. + */ + public static final String SCALAR_JS_FILENAME = "scalar.js"; + + /** + * The constant SCALAR_DEFAULT_URL. + */ + public static final String SCALAR_DEFAULT_URL = "https://cdn.jsdelivr.net/npm/@scalar/galaxy/dist/latest.json"; + + /** + * The constant DEFAULT_SCALAR_ACTUATOR_PATH. + */ + public static final String DEFAULT_SCALAR_ACTUATOR_PATH = "scalar"; +} diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarDisableAutoConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarDisableAutoConfiguration.java new file mode 100644 index 000000000..525856dc7 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarDisableAutoConfiguration.java @@ -0,0 +1,56 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.scalar; + +/** + * @author bnasslahsen + */ + +import org.springframework.boot.autoconfigure.AutoConfigurationImportFilter; +import org.springframework.boot.autoconfigure.AutoConfigurationMetadata; + +/** + * Disable Scalar WebJar AutoConfiguration. + */ +public class ScalarDisableAutoConfiguration implements AutoConfigurationImportFilter { + + /** + * The constant TARGET. + */ + private static final String TARGET = "com.scalar.maven.webjar.ScalarAutoConfiguration"; + + @Override + public boolean[] match(String[] candidates, AutoConfigurationMetadata metadata) { + boolean[] matches = new boolean[candidates.length]; + for (int i = 0; i < candidates.length; i++) { + String candidate = candidates[i]; + // keep everything except the target + matches[i] = !TARGET.equals(candidate); + } + return matches; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-common/src/main/resources/META-INF/spring.factories b/springdoc-openapi-starter-common/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..0b1ebd119 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\ +org.springdoc.scalar.ScalarDisableAutoConfiguration \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/.gitignore b/springdoc-openapi-starter-webflux-scalar/.gitignore new file mode 100644 index 000000000..ab21548c1 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/.gitignore @@ -0,0 +1,144 @@ +###################### +# Project Specific +###################### +/target/www/** +/src/test/javascript/coverage/ + +###################### +# Node +###################### +/node/ +node_tmp/ +node_modules/ +npm-debug.log.* +/.awcache/* +/.cache-loader/* + +###################### +# SASS +###################### +.sass-cache/ + +###################### +# Eclipse +###################### +*.pydevproject +.project +.metadata +tmp/ +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +.factorypath +/src/main/resources/rebel.xml + +# External tool builders +.externalToolBuilders/** + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + +###################### +# Intellij +###################### +.idea/ +*.iml +*.iws +*.ipr +*.ids +*.orig +classes/ +out/ + +###################### +# Visual Studio Code +###################### +.vscode/ + +###################### +# Maven +###################### +/log/ +/target/ + +###################### +# Gradle +###################### +.gradle/ +/build/ + +###################### +# Package Files +###################### +*.jar +*.war +*.ear +*.db + +###################### +# Windows +###################### +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + +###################### +# Mac OSX +###################### +.DS_Store +.svn + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +###################### +# Directories +###################### +/bin/ +/deploy/ + +###################### +# Logs +###################### +*.log* + +###################### +# Others +###################### +*.class +*.*~ +*~ +.merge_file* + +###################### +# Gradle Wrapper +###################### +!gradle/wrapper/gradle-wrapper.jar + +###################### +# Maven Wrapper +###################### +!.mvn/wrapper/maven-wrapper.jar + +###################### +# ESLint +###################### +.eslintcache \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml new file mode 100644 index 000000000..7f12626b3 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + + org.springdoc + springdoc-openapi + 3.0.0-M2-SNAPSHOT + + springdoc-openapi-starter-webflux-scalar + ${project.artifactId} + + + org.springdoc + springdoc-openapi-starter-webflux-api + ${project.version} + + + com.scalar.maven + scalar + + + + org.springframework.boot + spring-boot-actuator-autoconfigure + true + + + org.springframework.boot + spring-boot-reactor-netty + test + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.springdoc.openapi.webflux.scalar + + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java new file mode 100644 index 000000000..bb045c3b0 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java @@ -0,0 +1,88 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webflux.scalar; + +import java.io.IOException; + +import com.scalar.maven.webjar.ScalarProperties; +import io.swagger.v3.oas.annotations.Operation; +import org.springdoc.scalar.AbstractScalarController; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.web.bind.annotation.GetMapping; + +import static org.springdoc.core.utils.Constants.DEFAULT_API_DOCS_ACTUATOR_URL; +import static org.springdoc.scalar.ScalarConstants.DEFAULT_SCALAR_ACTUATOR_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +/** + * The type Swagger actuator welcome. + */ +@ControllerEndpoint(id = DEFAULT_SCALAR_ACTUATOR_PATH) +public class ScalarActuatorController extends AbstractScalarController { + + /** + * The Web endpoint properties. + */ + private final WebEndpointProperties webEndpointProperties; + + /** + * Instantiates a new Scalar actuator controller. + * + * @param scalarProperties the scalar properties + * @param webEndpointProperties the web endpoint properties + */ + protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties) { + super(scalarProperties); + this.webEndpointProperties = webEndpointProperties; + } + + @Operation(hidden = true) + @GetMapping(DEFAULT_PATH_SEPARATOR) + public ResponseEntity getDocs(ServerHttpRequest serverHttpRequest) throws IOException { + return super.getDocs(serverHttpRequest.getURI().toString()); + } + + @Operation(hidden = true) + @GetMapping(DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME) + public ResponseEntity getScalarJs() throws IOException { + return super.getScalarJs(); + } + + public String buildApiDocsUrl(String requestUrl) { + return buildApiDocsUrl(requestUrl, DEFAULT_PATH_SEPARATOR + DEFAULT_API_DOCS_ACTUATOR_URL); + } + + public String buildJsBundleUrl(String requestUrl) { + String scalarPath = webEndpointProperties.getBasePath() + scalarProperties.getPath(); + return buildJsBundleUrl(requestUrl, scalarPath); + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java new file mode 100644 index 000000000..4e267641f --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java @@ -0,0 +1,116 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webflux.scalar; + +import com.scalar.maven.webjar.ScalarProperties; +import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.properties.SpringDocConfigProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.webflux.actuate.endpoint.web.WebFluxEndpointHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.server.adapter.ForwardedHeaderTransformer; + +import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; +import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; + +/** + * The type Scalar configuration. + * + * @author bnasslahsen + */ +@Lazy(false) +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true) +@ConditionalOnWebApplication(type = Type.REACTIVE) +@ConditionalOnBean(SpringDocConfiguration.class) +@EnableConfigurationProperties(ScalarProperties.class) +@ConditionalOnProperty(prefix = "scalar", name = "enabled", havingValue = "true", matchIfMissing = true) +public class ScalarConfiguration { + + /** + * Scalar web mvc controller scalar web mvc controller. + * + * @param scalarProperties the scalar properties + * @param springDocConfigProperties the spring doc config properties + * @return the scalar web mvc controller + */ + @Bean + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @ConditionalOnMissingBean + @Lazy(false) + ScalarWebFluxController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { + return new ScalarWebFluxController(scalarProperties,springDocConfigProperties); + } + + /** + * Forwarded header transformer forwarded header transformer. + * + * @return the forwarded header transformer + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + ForwardedHeaderTransformer forwardedHeaderTransformer() { + return new ForwardedHeaderTransformer(); + } + + /** + * The type Swagger actuator welcome configuration. + */ + @ConditionalOnProperty(SPRINGDOC_USE_MANAGEMENT_PORT) + @ConditionalOnClass(WebFluxEndpointHandlerMapping.class) + @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) + static class SwaggerActuatorWelcomeConfiguration { + + /** + * Scalar actuator controller scalar actuator controller. + * + * @param properties the properties + * @param webEndpointProperties the web endpoint properties + * @return the scalar actuator controller + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { + return new ScalarActuatorController(properties,webEndpointProperties); + } + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java new file mode 100644 index 000000000..ba4149df7 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java @@ -0,0 +1,89 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webflux.scalar; + +import java.io.IOException; + +import com.scalar.maven.webjar.ScalarProperties; +import org.springdoc.core.properties.SpringDocConfigProperties; +import org.springdoc.scalar.AbstractScalarController; + +import org.springframework.http.ResponseEntity; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +/** + * The type Scalar web mvc controller. + * + * @author bnasslahsen + */ +@Controller +@RequestMapping("${scalar.path:" + SCALAR_DEFAULT_PATH + "}") +public class ScalarWebFluxController extends AbstractScalarController { + + /** + * The Spring doc config properties. + */ + private final SpringDocConfigProperties springDocConfigProperties; + + /** + * Instantiates a new Scalar web mvc controller. + * + * @param scalarProperties the scalar properties + * @param springDocConfigProperties the spring doc config properties + */ + protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { + super(scalarProperties); + this.springDocConfigProperties = springDocConfigProperties; + } + + @GetMapping + public ResponseEntity getDocs(ServerHttpRequest serverHttpRequest) throws IOException { + return super.getDocs(serverHttpRequest.getURI().toString()); + } + + @GetMapping({DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME, SCALAR_JS_FILENAME}) + public ResponseEntity getScalarJs() throws IOException { + return super.getScalarJs(); + } + + public String buildApiDocsUrl(String requestUrl) { + String apiDocsPath = springDocConfigProperties.getApiDocs().getPath(); + return buildApiDocsUrl(requestUrl, apiDocsPath); + } + + public String buildJsBundleUrl(String requestUrl) { + String scalarPath = scalarProperties.getPath(); + return buildJsBundleUrl(requestUrl, scalarPath); + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/springdoc-openapi-starter-webflux-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000..b2e7a4a88 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springdoc.webflux.scalar.ScalarConfiguration \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java new file mode 100644 index 000000000..cb3bb9daf --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java @@ -0,0 +1,114 @@ +package test.org.springdoc.webflux.scalar; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import jakarta.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.startsWith; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +@AutoConfigureWebTestClient(timeout = "3600000") +@ActiveProfiles("test") +@SpringBootTest +public abstract class AbstractCommonTest { + + @Autowired + protected WebTestClient webTestClient; + + protected String className = getClass().getSimpleName(); + + @PostConstruct + public void init() { + this.webTestClient = webTestClient.mutate() + .baseUrl("http://localhost") + .build(); + } + + protected void checkContent(String requestPath, Map headers, String resultFile) { + String expected = getContent(resultFile); + String scalarJsPath = getScalarJsPath(requestPath); + webTestClient.get() + .uri(requestPath) + .headers(applyHeaders(headers)) + .exchange() + .expectStatus().isOk() + .expectHeader().value(HttpHeaders.CONTENT_TYPE, startsWith(MediaType.TEXT_HTML_VALUE)) + .expectBody(String.class) + .value(containsString(scalarJsPath)) + .value(equalTo(expected)); + webTestClient.get() + .uri(scalarJsPath) + .headers(applyHeaders(headers)) + .exchange() + .expectStatus().isOk(); + } + + protected void checkContent(String requestPath) { + String expected = getResultFile(); + String scalarJsPath = getScalarJsPath(requestPath); + webTestClient.get().uri(requestPath) + .exchange() + .expectStatus().isOk() + .expectHeader().value(HttpHeaders.CONTENT_TYPE, startsWith(MediaType.TEXT_HTML_VALUE)) + .expectBody(String.class) + .value(containsString(scalarJsPath)) + .value(equalTo(expected)); + webTestClient.get().uri(scalarJsPath) + .exchange() + .expectStatus().isOk(); + } + + protected String getResultFile() { + String testNumber = className.replaceAll("[^0-9]", ""); + return getContent("results/app" + testNumber); + } + + protected String getContent(String fileName) { + try { + Path path = Paths.get(AbstractCommonTest.class.getClassLoader().getResource(fileName).toURI()); + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line).append("\n"); + } + return sb.toString(); + } + catch (Exception e) { + throw new RuntimeException("Failed to read file: " + fileName, e); + } + } + + protected static String getScalarJsPath(String requestPath) { + String scalarJsPath; + if(!requestPath.endsWith(DEFAULT_PATH_SEPARATOR)) + scalarJsPath = requestPath + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME; + else + scalarJsPath = requestPath + SCALAR_JS_FILENAME; + return scalarJsPath; + } + + private Consumer applyHeaders(Map headers) { + return httpHeaders -> { + if (headers != null) { + headers.forEach(httpHeaders::set); + } + }; + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java new file mode 100644 index 000000000..ad5395f29 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java @@ -0,0 +1,89 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar; + +import jakarta.annotation.PostConstruct; + +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.function.client.WebClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { + + protected WebClient webClient; + + @LocalManagementPort + private int managementPort; + + @PostConstruct + public void init() { + webClient = WebClient.builder().baseUrl("http://localhost:" + this.managementPort) + .build(); + webTestClient = webTestClient.mutate().baseUrl("http://localhost") + .build(); + } + + protected void checkContent(String requestPath) { + String scalarJsPath = getScalarJsPath(requestPath); + String contentAsString = webClient.get() + .uri(requestPath) + .accept(MediaType.TEXT_HTML) + .retrieve() + .bodyToMono(String.class) + .block(); + + assert contentAsString != null; + assertTrue(contentAsString.contains(scalarJsPath)); + checkHtmlResult(contentAsString); + + HttpStatusCode status = webClient.get() + .uri(scalarJsPath) + .exchangeToMono(resp -> resp.releaseBody().thenReturn(resp.statusCode())) + .block(); + + assertThat(status).isEqualTo(HttpStatus.OK); + } + + protected void checkContentWithWebTestClient(String requestPath) { + super.checkContent(requestPath); + } + + protected void checkHtmlResult(String htmlResult) { + String testNumber = className.replaceAll("[^0-9]", ""); + String fileName = "results/app" + testNumber; + checkHtmlResult(fileName, htmlResult); + } + + protected void checkHtmlResult(String fileName, String htmlResult) { + assertTrue(htmlResult.contains("Scalar API Reference")); + assertEquals(this.getContent(fileName), htmlResult.replace("\r", "")); + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/HelloController.java new file mode 100644 index 000000000..2322fe41e --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app1; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocApp1Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocApp1Test.java new file mode 100644 index 000000000..9f5099b7b --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocApp1Test.java @@ -0,0 +1,38 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app1; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +public class SpringDocApp1Test extends AbstractCommonTest { + + @Test + void checkContent() { + checkContent(SCALAR_DEFAULT_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocAppScalarDisabledTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocAppScalarDisabledTest.java new file mode 100644 index 000000000..6e96b0db4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app1/SpringDocAppScalarDisabledTest.java @@ -0,0 +1,41 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app1; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = "scalar.enabled=false") +public class SpringDocAppScalarDisabledTest extends AbstractCommonTest { + + @Test + void checkNotFound() { + webTestClient.get().uri(SCALAR_DEFAULT_PATH).exchange() + .expectStatus().isNotFound(); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/HelloController.java new file mode 100644 index 000000000..fef650086 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app10; + + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RequestMapping("/foo/bar") +@RestController +public class HelloController { + + @GetMapping("/test") + public String doSomethingInteresting() { + return "OK"; + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/SpringDocApp10Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/SpringDocApp10Test.java new file mode 100644 index 000000000..7fb195708 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app10/SpringDocApp10Test.java @@ -0,0 +1,54 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app10; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import test.org.springdoc.webflux.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; + + +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, + properties = { "spring.webflux.base-path=/test", + "scalar.path=/", + "server.port=9529" }) +class SpringDocApp10Test extends AbstractSpringDocActuatorTest { + + @Test + void checkContent() { + HttpStatusCode httpStatusRoot = webClient.get().uri("/test/") + .exchangeToMono(clientResponse -> Mono.just(clientResponse.statusCode())).block(); + Assertions.assertThat(httpStatusRoot).isEqualTo(HttpStatus.OK); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app11/SpringDocApp11Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app11/SpringDocApp11Test.java new file mode 100644 index 000000000..f6d8fe3ab --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app11/SpringDocApp11Test.java @@ -0,0 +1,89 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app11; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.hamcrest.Matchers.containsString; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +@TestPropertySource(properties = "server.forward-headers-strategy=framework") +public class SpringDocApp11Test extends AbstractCommonTest { + + private static final String X_FORWARD_PREFIX = "/path/prefix"; + + @Test + void checkContent() { + checkContent(SCALAR_DEFAULT_PATH); + } + + @Test + void checkContentForwardedPrefix() { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_DEFAULT_PATH, headers, "results/app11-1"); + } + + @Test + void checkContentForwardedPrefixHostProto() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX, + "X-Forwarded-Proto", "https", "X-Forwarded-Host", "proxy-host"); + checkContent(SCALAR_DEFAULT_PATH, headers, "results/app11-2"); + } + + @Test + void concurrentScalarChecks() { + CompletableFuture[] tasks = IntStream.range(0, 10) + .mapToObj(i -> CompletableFuture.runAsync(() -> { + String prefix = X_FORWARD_PREFIX + i; + + webTestClient.get() + .uri(SCALAR_DEFAULT_PATH) + .header("X-Forwarded-Prefix", prefix) + .exchange() + .expectStatus().isOk() + .expectBody(String.class) + .value(containsString(prefix + SCALAR_DEFAULT_PATH)) + .value(containsString(prefix + SCALAR_DEFAULT_PATH + + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME)); + })) + .toArray(CompletableFuture[]::new); + CompletableFuture.allOf(tasks).join(); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app12/SpringDocApp12Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app12/SpringDocApp12Test.java new file mode 100644 index 000000000..fbb3c0029 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app12/SpringDocApp12Test.java @@ -0,0 +1,48 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app12; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static test.org.springdoc.webflux.scalar.app12.SpringDocApp12Test.SCALAR_PATH; + +@TestPropertySource(properties = { + "server.forward-headers-strategy=framework", + "scalar.path="+ SCALAR_PATH +}) +public class SpringDocApp12Test extends AbstractCommonTest { + + private static final String X_FORWARD_PREFIX = "/path/prefix"; + static final String SCALAR_PATH = "/foo/documentation/scalar"; + + @Test + void checkContent() { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_PATH, headers, "results/app12"); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app13/SpringDocApp13Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app13/SpringDocApp13Test.java new file mode 100644 index 000000000..eae8994d1 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app13/SpringDocApp13Test.java @@ -0,0 +1,48 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app13; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + + +@TestPropertySource(properties = { + "server.forward-headers-strategy=framework", + "scalar.path="+ SpringDocApp13Test.SCALAR_PATH, + "springdoc.api-docs.path=/bar/openapi/v3" +}) +public class SpringDocApp13Test extends AbstractCommonTest { + + private static final String X_FORWARD_PREFIX = "/path/prefix"; + static final String SCALAR_PATH = "/foo/documentation/scalar"; + + @Test + void checkContent() { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_PATH, headers, "results/app13"); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/HelloController.java new file mode 100644 index 000000000..42db213e4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app2; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/SpringDocApp2Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/SpringDocApp2Test.java new file mode 100644 index 000000000..4570cd798 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app2/SpringDocApp2Test.java @@ -0,0 +1,40 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app2; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = "scalar.path="+ SpringDocApp2Test.SCALAR_PATH) +public class SpringDocApp2Test extends AbstractCommonTest { + + static final String SCALAR_PATH = "/batz/scalar"; + + @Test + void checkContent() { + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/HelloController.java new file mode 100644 index 000000000..e0eccc6d7 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app3; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/SpringDocApp3Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/SpringDocApp3Test.java new file mode 100644 index 000000000..03e7f98b4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app3/SpringDocApp3Test.java @@ -0,0 +1,43 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app3; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = { + "scalar.path="+ SpringDocApp3Test.SCALAR_PATH, + "springdoc.api-docs.path=/documentation/v3/api-docs" +}) +public class SpringDocApp3Test extends AbstractCommonTest { + + static final String SCALAR_PATH = "/batz/scalar"; + + @Test + void checkContent() { + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/HelloController.java new file mode 100644 index 000000000..5b348397c --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/HelloController.java @@ -0,0 +1,44 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app4; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/SpringDocApp4Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/SpringDocApp4Test.java new file mode 100644 index 000000000..fc0ddedd5 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app4/SpringDocApp4Test.java @@ -0,0 +1,71 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app4; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import test.org.springdoc.webflux.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.use-management-port=true", + "management.server.port=9592", + "management.endpoints.web.base-path="+ SpringDocApp4Test.ACTUATOR_BASE_PATH }) +class SpringDocApp4Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/application"; + + static final String SCALAR_PATH = ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() { + webTestClient.get().uri(SCALAR_DEFAULT_PATH) + .exchange() + .expectStatus().isNotFound(); + } + + @Test + void checkContent() { + HttpStatusCode httpStatusMono = webClient.get().uri("/application/scalar") + .exchangeToMono(clientResponse -> Mono.just(clientResponse.statusCode())).block(); + assertThat(httpStatusMono).isEqualTo(HttpStatus.OK); + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/HelloController.java new file mode 100644 index 000000000..8f94b0c00 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/HelloController.java @@ -0,0 +1,45 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app5; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import org.springdoc.core.models.GroupedOpenApi; + +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + + @Bean + public GroupedOpenApi userOpenApi() { + return GroupedOpenApi.builder() + .group("users") + .packagesToScan("test.org.springdoc.api.v30.app145") + .build(); + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/SpringDocApp5Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/SpringDocApp5Test.java new file mode 100644 index 000000000..9b4dc31e5 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app5/SpringDocApp5Test.java @@ -0,0 +1,68 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app5; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; +import test.org.springdoc.webflux.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", "springdoc.use-management-port=true", + "management.server.port=9593", "management.endpoints.web.base-path="+ SpringDocApp5Test.ACTUATOR_BASE_PATH }) +class SpringDocApp5Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/application"; + + static final String SCALAR_PATH = ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() { + webTestClient.get().uri(SCALAR_DEFAULT_PATH) + .exchange() + .expectStatus().isNotFound(); + } + + @Test + void checkContent() { + HttpStatusCode httpStatusMono = webClient.get().uri("/application/scalar") + .exchangeToMono(clientResponse -> Mono.just(clientResponse.statusCode())).block(); + assertThat(httpStatusMono).isEqualTo(HttpStatus.OK); + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/HelloController.java new file mode 100644 index 000000000..4b7cfc634 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app6; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/SpringDocApp6Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/SpringDocApp6Test.java new file mode 100644 index 000000000..83bf8797c --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app6/SpringDocApp6Test.java @@ -0,0 +1,63 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app6; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.use-management-port=true", + "management.server.port=9594", + "management.server.base-path="+ SpringDocApp6Test.ACTUATOR_BASE_PATH, + "management.endpoints.web.base-path="+ SpringDocApp6Test.MANAGEMENT_BASE_PATH }) +class SpringDocApp6Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/test"; + static final String MANAGEMENT_BASE_PATH = "/application"; + static final String REQUEST_PATH = ACTUATOR_BASE_PATH + MANAGEMENT_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() { + webTestClient.get().uri(SCALAR_DEFAULT_PATH) + .exchange() + .expectStatus().isNotFound(); + } + + @Test + void checkContent() { + checkContent(REQUEST_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/HelloController.java new file mode 100644 index 000000000..757e2cd93 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app7; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java new file mode 100644 index 000000000..4a266e561 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java @@ -0,0 +1,62 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app7; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.show-actuator=true", + "management.server.port=9596", + "management.server.base-path=/test", + "management.endpoints.web.base-path=/application" }) +class SpringDocApp7Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/test"; + static final String MANAGEMENT_BASE_PATH = "/application"; + static final String REQUEST_PATH = ACTUATOR_BASE_PATH + MANAGEMENT_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() { + HttpStatusCode status = webClient.get() + .uri(REQUEST_PATH) + .exchangeToMono(resp -> resp.releaseBody().thenReturn(resp.statusCode())) + .block(); + assertThat(status).isEqualTo(HttpStatus.NOT_FOUND); + } + + @Test + void checkContent() { + checkContentWithWebTestClient(SCALAR_DEFAULT_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/HelloController.java new file mode 100644 index 000000000..dfb8ef9b0 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/HelloController.java @@ -0,0 +1,45 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app8; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import org.springdoc.core.models.GroupedOpenApi; + +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + + @Bean + public GroupedOpenApi userOpenApi() { + return GroupedOpenApi.builder() + .group("users") + .packagesToScan("test.org.springdoc.api.v30.app145") + .build(); + } +} diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/SpringDocApp8Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/SpringDocApp8Test.java new file mode 100644 index 000000000..c8f0afa75 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app8/SpringDocApp8Test.java @@ -0,0 +1,50 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app8; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + + +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, + properties = { "server.port=9519", + "scalar.path="+ DEFAULT_PATH_SEPARATOR }) +class SpringDocApp8Test extends AbstractCommonTest { + + @Test + void checkContent() { + checkContent(DEFAULT_PATH_SEPARATOR); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/HelloController.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/HelloController.java new file mode 100644 index 000000000..90b92b1b5 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/HelloController.java @@ -0,0 +1,36 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webflux.scalar.app9; + + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RequestMapping("/foo/bar") +@RestController +public class HelloController { + + @GetMapping("/test") + public String doSomethingInteresting() { + return "OK"; + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/SpringDocApp9Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/SpringDocApp9Test.java new file mode 100644 index 000000000..9045395c7 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/SpringDocApp9Test.java @@ -0,0 +1,51 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webflux.scalar.app9; + + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webflux.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static test.org.springdoc.webflux.scalar.app9.WebConfig.BASE_PATH; + + +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, + properties = { "server.port=9520" }) +class SpringDocApp9Test extends AbstractCommonTest { + + @Test + void checkContent() { + checkContent(BASE_PATH + SCALAR_DEFAULT_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/WebConfig.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/WebConfig.java new file mode 100644 index 000000000..c74c940ed --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app9/WebConfig.java @@ -0,0 +1,16 @@ +package test.org.springdoc.webflux.scalar.app9; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.PathMatchConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +public class WebConfig implements WebFluxConfigurer { + + static final String BASE_PATH = "/test"; + @Override + public void configurePathMatching(PathMatchConfigurer configurer) { + configurer.addPathPrefix(BASE_PATH, t -> true); + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/application-test.yml b/springdoc-openapi-starter-webflux-scalar/src/test/resources/application-test.yml new file mode 100644 index 000000000..544f357e4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/application-test.yml @@ -0,0 +1,9 @@ +spring: + main: + banner-mode: "off" + lazy-initialization: true +logging: + level: + root: ERROR + pattern: + console: '%m%n' \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/logback-test.xml b/springdoc-openapi-starter-webflux-scalar/src/test/resources/logback-test.xml new file mode 100644 index 000000000..a715d5a44 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/logback-test.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 new file mode 100644 index 000000000..19e300d37 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 new file mode 100644 index 000000000..dfbe8d55c --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 new file mode 100644 index 000000000..6b9b9273d --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 new file mode 100644 index 000000000..9501a81ca --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 new file mode 100644 index 000000000..b3de119ee --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 new file mode 100644 index 000000000..008c75abc --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 new file mode 100644 index 000000000..8a5017e08 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 new file mode 100644 index 000000000..57691e413 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 new file mode 100644 index 000000000..bba87d100 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 new file mode 100644 index 000000000..dc17a8ec8 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 new file mode 100644 index 000000000..98d5fe303 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 new file mode 100644 index 000000000..d2c196024 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 new file mode 100644 index 000000000..6b9b9273d --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 new file mode 100644 index 000000000..5d3ff1550 --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 new file mode 100644 index 000000000..dfbe8d55c --- /dev/null +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/.gitignore b/springdoc-openapi-starter-webmvc-scalar/.gitignore new file mode 100644 index 000000000..ab21548c1 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/.gitignore @@ -0,0 +1,144 @@ +###################### +# Project Specific +###################### +/target/www/** +/src/test/javascript/coverage/ + +###################### +# Node +###################### +/node/ +node_tmp/ +node_modules/ +npm-debug.log.* +/.awcache/* +/.cache-loader/* + +###################### +# SASS +###################### +.sass-cache/ + +###################### +# Eclipse +###################### +*.pydevproject +.project +.metadata +tmp/ +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +.factorypath +/src/main/resources/rebel.xml + +# External tool builders +.externalToolBuilders/** + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath + +###################### +# Intellij +###################### +.idea/ +*.iml +*.iws +*.ipr +*.ids +*.orig +classes/ +out/ + +###################### +# Visual Studio Code +###################### +.vscode/ + +###################### +# Maven +###################### +/log/ +/target/ + +###################### +# Gradle +###################### +.gradle/ +/build/ + +###################### +# Package Files +###################### +*.jar +*.war +*.ear +*.db + +###################### +# Windows +###################### +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + +###################### +# Mac OSX +###################### +.DS_Store +.svn + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +###################### +# Directories +###################### +/bin/ +/deploy/ + +###################### +# Logs +###################### +*.log* + +###################### +# Others +###################### +*.class +*.*~ +*~ +.merge_file* + +###################### +# Gradle Wrapper +###################### +!gradle/wrapper/gradle-wrapper.jar + +###################### +# Maven Wrapper +###################### +!.mvn/wrapper/maven-wrapper.jar + +###################### +# ESLint +###################### +.eslintcache \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml new file mode 100644 index 000000000..f7e32058d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -0,0 +1,54 @@ + + 4.0.0 + + org.springdoc + springdoc-openapi + 3.0.0-M2-SNAPSHOT + + springdoc-openapi-starter-webmvc-scalar + ${project.artifactId} + + + org.springdoc + springdoc-openapi-starter-webmvc-api + ${project.version} + + + com.scalar.maven + scalar + + + jakarta.servlet + jakarta.servlet-api + provided + + + org.springframework.boot + spring-boot-starter-actuator + true + + + org.springframework.boot + spring-boot-tomcat + test + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + org.springdoc.openapi.webmvc.scalar + + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java new file mode 100644 index 000000000..7ea602b14 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java @@ -0,0 +1,88 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webmvc.scalar; + +import java.io.IOException; + +import com.scalar.maven.webjar.ScalarProperties; +import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.HttpServletRequest; +import org.springdoc.scalar.AbstractScalarController; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; + +import static org.springdoc.core.utils.Constants.DEFAULT_API_DOCS_ACTUATOR_URL; +import static org.springdoc.scalar.ScalarConstants.DEFAULT_SCALAR_ACTUATOR_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +/** + * The type Swagger actuator welcome. + */ +@ControllerEndpoint(id = DEFAULT_SCALAR_ACTUATOR_PATH) +public class ScalarActuatorController extends AbstractScalarController { + + /** + * The Web endpoint properties. + */ + private final WebEndpointProperties webEndpointProperties; + + /** + * Instantiates a new Scalar actuator controller. + * + * @param scalarProperties the scalar properties + * @param webEndpointProperties the web endpoint properties + */ + protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties) { + super(scalarProperties); + this.webEndpointProperties = webEndpointProperties; + } + + @Operation(hidden = true) + @GetMapping(DEFAULT_PATH_SEPARATOR) + public ResponseEntity getDocs(HttpServletRequest request) throws IOException { + return super.getDocs(request.getRequestURL().toString()); + } + + @Operation(hidden = true) + @GetMapping(DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME) + public ResponseEntity getScalarJs() throws IOException { + return super.getScalarJs(); + } + + public String buildApiDocsUrl(String requestUrl) { + return buildApiDocsUrl(requestUrl, DEFAULT_PATH_SEPARATOR + DEFAULT_API_DOCS_ACTUATOR_URL); + } + + public String buildJsBundleUrl(String requestUrl) { + String scalarPath = webEndpointProperties.getBasePath() + scalarProperties.getPath(); + return buildJsBundleUrl(requestUrl, scalarPath); + } +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java new file mode 100644 index 000000000..bc90d4f67 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java @@ -0,0 +1,117 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webmvc.scalar; + +import com.scalar.maven.webjar.ScalarProperties; +import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.properties.SpringDocConfigProperties; + +import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; +import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; +import org.springframework.boot.actuate.autoconfigure.web.server.ManagementPortType; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.boot.webmvc.actuate.endpoint.web.WebMvcEndpointHandlerMapping; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; +import org.springframework.web.filter.ForwardedHeaderFilter; + +import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; +import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; + +/** + * The type Scalar configuration. + * + * @author bnasslahsen + */ +@Lazy(false) +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true) +@ConditionalOnWebApplication(type = Type.SERVLET) +@ConditionalOnBean(SpringDocConfiguration.class) +@EnableConfigurationProperties(ScalarProperties.class) +@ConditionalOnProperty(prefix = "scalar", name = "enabled", havingValue = "true", matchIfMissing = true) +public class ScalarConfiguration { + + /** + * Scalar web mvc controller scalar web mvc controller. + * + * @param scalarProperties the scalar properties + * @param springDocConfigProperties the spring doc config properties + * @return the scalar web mvc controller + */ + @Bean + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @ConditionalOnMissingBean + @Lazy(false) + ScalarWebMvcController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { + return new ScalarWebMvcController(scalarProperties,springDocConfigProperties); + } + + /** + * Forwarded header filter filter registration bean. + * + * @return the filter registration bean + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + public FilterRegistrationBean forwardedHeaderFilter() { + return new FilterRegistrationBean<>(new ForwardedHeaderFilter()); + } + + /** + * The type Swagger actuator welcome configuration. + */ + @ConditionalOnProperty(SPRINGDOC_USE_MANAGEMENT_PORT) + @ConditionalOnClass(WebMvcEndpointHandlerMapping.class) + @ConditionalOnManagementPort(ManagementPortType.DIFFERENT) + static class SwaggerActuatorWelcomeConfiguration { + + /** + * Scalar actuator controller scalar actuator controller. + * + * @param properties the properties + * @param webEndpointProperties the web endpoint properties + * @return the scalar actuator controller + */ + @Bean + @ConditionalOnMissingBean + @Lazy(false) + ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { + return new ScalarActuatorController(properties,webEndpointProperties); + } + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java new file mode 100644 index 000000000..f357970a1 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java @@ -0,0 +1,89 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.webmvc.scalar; + +import java.io.IOException; + +import com.scalar.maven.webjar.ScalarProperties; +import jakarta.servlet.http.HttpServletRequest; +import org.springdoc.core.properties.SpringDocConfigProperties; +import org.springdoc.scalar.AbstractScalarController; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +/** + * The type Scalar web mvc controller. + * + * @author bnasslahsen + */ +@Controller +@RequestMapping("${scalar.path:" + SCALAR_DEFAULT_PATH + "}") +public class ScalarWebMvcController extends AbstractScalarController { + + /** + * The Spring doc config properties. + */ + private final SpringDocConfigProperties springDocConfigProperties; + + /** + * Instantiates a new Scalar web mvc controller. + * + * @param scalarProperties the scalar properties + * @param springDocConfigProperties the spring doc config properties + */ + protected ScalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { + super(scalarProperties); + this.springDocConfigProperties = springDocConfigProperties; + } + + @GetMapping + public ResponseEntity getDocs(HttpServletRequest request) throws IOException { + return super.getDocs(request.getRequestURL().toString()); + } + + @GetMapping({DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME, SCALAR_JS_FILENAME}) + public ResponseEntity getScalarJs() throws IOException { + return super.getScalarJs(); + } + + public String buildApiDocsUrl(String requestUrl) { + String apiDocsPath = springDocConfigProperties.getApiDocs().getPath(); + return buildApiDocsUrl(requestUrl, apiDocsPath); + } + + public String buildJsBundleUrl(String requestUrl) { + String scalarPath = scalarProperties.getPath(); + return buildJsBundleUrl(requestUrl, scalarPath); + } +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/springdoc-openapi-starter-webmvc-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 000000000..5da33ec31 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +org.springdoc.webmvc.scalar.ScalarConfiguration diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java new file mode 100644 index 000000000..96cc74da3 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java @@ -0,0 +1,148 @@ +package test.org.springdoc.webmvc.scalar; + +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +@AutoConfigureMockMvc +@ActiveProfiles("test") +@SpringBootTest +public abstract class AbstractCommonTest { + + @Autowired + protected MockMvc mockMvc; + + protected String className = getClass().getSimpleName(); + + protected String getContent(String fileName) { + try { + Path path = Paths.get(AbstractCommonTest.class.getClassLoader().getResource(fileName).toURI()); + List lines = Files.readAllLines(path, StandardCharsets.UTF_8); + StringBuilder sb = new StringBuilder(); + for (String line : lines) { + sb.append(line).append("\n"); + } + return sb.toString(); + } + catch (Exception e) { + throw new RuntimeException("Failed to read file: " + fileName, e); + } + } + + + protected void checkContent(String requestPath) throws Exception { + String expected = getResultFile(); + String scalarJsPath = getScalarJsPath(requestPath); + + mockMvc.perform(get(requestPath)) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.header().string(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_VALUE)) + .andExpect(content().string(containsString(scalarJsPath))) + .andExpect(content().string(equalTo(expected))); + mockMvc.perform(get(scalarJsPath)) + .andExpect(status().isOk()); + } + + protected void checkContent(String requestPath, Map headers, String resultFile) throws Exception { + String expected = getContent(resultFile); + String scalarJsPath = getScalarJsPath(requestPath); + + // build the request with headers + MockHttpServletRequestBuilder requestBuilder = get(requestPath); + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + requestBuilder.header(entry.getKey(), entry.getValue()); + } + } + + mockMvc.perform(requestBuilder) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.header().string(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_VALUE)) + .andExpect(content().string(containsString(scalarJsPath))) + .andExpect(content().string(equalTo(expected))); + + // build the scalar.js request with headers + MockHttpServletRequestBuilder scalarRequestBuilder = get(scalarJsPath); + if (headers != null) { + for (Map.Entry entry : headers.entrySet()) { + scalarRequestBuilder.header(entry.getKey(), entry.getValue()); + } + } + + mockMvc.perform(scalarRequestBuilder) + .andExpect(status().isOk()); + } + + + protected void checkContent(String requestPath, String contextPath) throws Exception { + String expected = getResultFile(); + String scalarJsPath = getScalarJsPath(requestPath); + + mockMvc.perform(get(requestPath).contextPath(contextPath)) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.header().string(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_VALUE)) + .andExpect(content().string(containsString(scalarJsPath))) + .andExpect(content().string(equalTo(expected))); + mockMvc.perform(get(scalarJsPath).contextPath(contextPath)) + .andExpect(status().isOk()); + } + + protected void checkContent(String requestPath, String contextPath, String servletPath) throws Exception { + String expected = getResultFile(); + String scalarJsPath = getScalarJsPath(requestPath); + contextPath = sanitizePath(contextPath); + servletPath = sanitizePath(servletPath); + + mockMvc.perform(get(requestPath).contextPath(contextPath).servletPath(servletPath)) + .andExpect(status().isOk()) + .andExpect(MockMvcResultMatchers.header().string(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_HTML_VALUE)) + .andExpect(content().string(containsString(scalarJsPath))) + .andExpect(content().string(equalTo(expected))); + mockMvc.perform(get(scalarJsPath).contextPath(contextPath).servletPath(servletPath)) + .andExpect(status().isOk()); + } + + protected String getResultFile() { + String testNumber = className.replaceAll("[^0-9]", ""); + return getContent("results/app" + testNumber); + } + + private String sanitizePath(String path) { + if (path == null) { + return null; + } + return path.endsWith("/") + ? path.substring(0, path.length() - 1) + : path; + } + + protected static String getScalarJsPath(String requestPath) { + String scalarJsPath; + if(!requestPath.endsWith(DEFAULT_PATH_SEPARATOR)) + scalarJsPath = requestPath + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME; + else + scalarJsPath = requestPath + SCALAR_JS_FILENAME; + return scalarJsPath; + } +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java new file mode 100644 index 000000000..2cc3531d0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java @@ -0,0 +1,86 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2019-2024 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webmvc.scalar; + + + +import java.net.http.HttpClient; + +import jakarta.annotation.PostConstruct; + +import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.client.JdkClientHttpRequestFactory; +import org.springframework.web.client.RestClient; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public abstract class AbstractSpringDocActuatorTest extends AbstractCommonTest { + + protected RestClient actuatorRestClient; + + @LocalManagementPort + private int managementPort; + + @PostConstruct + void init() { + HttpClient jdkClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + this.actuatorRestClient = RestClient.builder() + .requestFactory(new JdkClientHttpRequestFactory(jdkClient)) + .baseUrl("http://localhost:" + managementPort) + .build(); + } + + protected void checkContent(String requestPath) throws Exception { + String scalarJsPath = getScalarJsPath(requestPath); + String contentAsString = actuatorRestClient.get().uri(requestPath).retrieve().body(String.class); + assert contentAsString != null; + assertTrue(contentAsString.contains(scalarJsPath)); + checkHtmlResult(contentAsString); + HttpStatusCode status = actuatorRestClient.get() + .uri(scalarJsPath) + .retrieve() + .toBodilessEntity() + .getStatusCode(); + assertThat(status).isEqualTo(HttpStatus.OK); + } + + protected void checkHtmlResult(String htmlResult) { + String testNumber = className.replaceAll("[^0-9]", ""); + String fileName = "results/app" + testNumber; + checkHtmlResult( fileName, htmlResult); + } + + protected void checkHtmlResult(String fileName, String htmlResult) { + assertTrue(htmlResult.contains("Scalar API Reference")); + assertEquals(this.getContent(fileName), htmlResult.replace("\r", "")); + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/HelloController.java new file mode 100644 index 000000000..243cca1f2 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app1; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/SpringDocApp1Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/SpringDocApp1Test.java new file mode 100644 index 000000000..4421fb588 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app1/SpringDocApp1Test.java @@ -0,0 +1,38 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app1; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +public class SpringDocApp1Test extends AbstractCommonTest { + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_DEFAULT_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/HelloController.java new file mode 100644 index 000000000..5525a5bda --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app10; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/SpringDocApp10Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/SpringDocApp10Test.java new file mode 100644 index 000000000..4190b7804 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app10/SpringDocApp10Test.java @@ -0,0 +1,55 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app10; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", "springdoc.use-management-port=true", + "management.server.port=9492", "management.endpoints.web.base-path="+ SpringDocApp10Test.ACTUATOR_BASE_PATH }) +class SpringDocApp10Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/application"; + static final String REQUEST_PATH = ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() throws Exception { + mockMvc.perform(get(SCALAR_DEFAULT_PATH)) + .andExpect(status().isNotFound()); + } + + @Test + void checkContent() throws Exception { + super.checkContent(REQUEST_PATH); + } + + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/HelloController.java new file mode 100644 index 000000000..3e4fc2dd1 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/HelloController.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app11; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import org.springdoc.core.models.GroupedOpenApi; + +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + + @Bean + public GroupedOpenApi userOpenApi() { + return GroupedOpenApi.builder() + .group("users") + .packagesToScan("test.org.springdoc.api.v30.app145") + .build(); + } +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/SpringDocApp11Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/SpringDocApp11Test.java new file mode 100644 index 000000000..f3e5ee3b4 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app11/SpringDocApp11Test.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app11; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", "springdoc.use-management-port=true", + "management.server.port=9493", "management.endpoints.web.base-path="+ SpringDocApp11Test.ACTUATOR_BASE_PATH }) +class SpringDocApp11Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/application"; + static final String REQUEST_PATH = ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void testIndex() throws Exception { + super.checkContent(REQUEST_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/HelloController.java new file mode 100644 index 000000000..1000a96d8 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app12; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/SpringDocApp12Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/SpringDocApp12Test.java new file mode 100644 index 000000000..61f3f39bf --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app12/SpringDocApp12Test.java @@ -0,0 +1,58 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app12; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.use-management-port=true", + "management.server.port=9494", + "management.server.base-path="+ SpringDocApp12Test.BASE_PATH, + "management.endpoints.web.base-path="+ SpringDocApp12Test.ACTUATOR_BASE_PATH }) +class SpringDocApp12Test extends AbstractSpringDocActuatorTest { + + static final String BASE_PATH = "/test"; + static final String ACTUATOR_BASE_PATH = "/application"; + static final String REQUEST_PATH = BASE_PATH + ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkNotFound() throws Exception { + mockMvc.perform(get(ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH)) + .andExpect(status().isNotFound()); + } + + @Test + void checkContent() throws Exception { + super.checkContent(REQUEST_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/HelloController.java new file mode 100644 index 000000000..2cfeff0a6 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/HelloController.java @@ -0,0 +1,45 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app13; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; +import org.springdoc.core.models.GroupedOpenApi; + +import org.springframework.context.annotation.Bean; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + + @Bean + public GroupedOpenApi userOpenApi() { + return GroupedOpenApi.builder() + .group("users") + .packagesToScan("test.org.springdoc.api.v30.app145") + .build(); + } +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/SpringDocApp13Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/SpringDocApp13Test.java new file mode 100644 index 000000000..cd8a2e856 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app13/SpringDocApp13Test.java @@ -0,0 +1,50 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app13; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.use-management-port=true", + "management.server.port=9495", + "management.server.base-path=/test", + "management.endpoints.web.base-path=/application" }) +class SpringDocApp13Test extends AbstractSpringDocActuatorTest { + + static final String BASE_PATH = "/test"; + static final String ACTUATOR_BASE_PATH = "/application"; + static final String REQUEST_PATH = BASE_PATH + ACTUATOR_BASE_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + super.checkContent(REQUEST_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/HelloController.java new file mode 100644 index 000000000..2fe3d1e4f --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app14; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/SpringDocApp14Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/SpringDocApp14Test.java new file mode 100644 index 000000000..b6f3620bd --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app14/SpringDocApp14Test.java @@ -0,0 +1,66 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app14; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.web.client.HttpClientErrorException; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Fail.fail; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "management.endpoints.web.exposure.include=*", + "springdoc.show-actuator=true", + "management.server.port=9496", + "server.servlet.context-path=/sample", + "management.server.base-path=/test", + "management.endpoints.web.base-path=/application" }) +class SpringDocApp14Test extends AbstractSpringDocActuatorTest { + + static final String ACTUATOR_BASE_PATH = "/test"; + static final String CONTEXT_PATH = "/sample"; + static final String MANAGEMENT_BASE_PATH = "/application"; + static final String REQUEST_PATH = CONTEXT_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + checkContent( REQUEST_PATH, CONTEXT_PATH); + } + + @Test + void checkNotFound() throws Exception { + try { + actuatorRestClient.get().uri(ACTUATOR_BASE_PATH + MANAGEMENT_BASE_PATH + SCALAR_DEFAULT_PATH).retrieve().body(String.class);; + fail("Expected 404 Not Found"); + } catch (HttpClientErrorException e) { + assertThat(e.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/HelloController.java new file mode 100644 index 000000000..a21f9e962 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app15; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/SpringDocApp15Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/SpringDocApp15Test.java new file mode 100644 index 000000000..d46be38ff --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app15/SpringDocApp15Test.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app15; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = { + "server.servlet.context-path=" + SpringDocApp15Test.CONTEXT_PATH, + "spring.mvc.servlet.path=" + SpringDocApp15Test.SERVLET_PATH +}) +public class SpringDocApp15Test extends AbstractCommonTest { + + static final String CONTEXT_PATH = "/"; + static final String SERVLET_PATH = "/"; + + @Test + void checkContent() throws Exception { + checkContent( SCALAR_DEFAULT_PATH, CONTEXT_PATH, SERVLET_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app16/SpringDocApp16Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app16/SpringDocApp16Test.java new file mode 100644 index 000000000..58d0f03a3 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app16/SpringDocApp16Test.java @@ -0,0 +1,87 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app16; + +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.stream.IntStream; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.hamcrest.Matchers.containsString; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; + +@TestPropertySource(properties = { + "server.forward-headers-strategy=framework" +}) +public class SpringDocApp16Test extends AbstractCommonTest { + + private static final String X_FORWARD_PREFIX = "/path/prefix"; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_DEFAULT_PATH); + } + + @Test + void checkContentForwardedPrefix() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_DEFAULT_PATH, headers,"results/app16-1" ); + } + + @Test + void checkContentForwardedPrefixHostProto() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX, + "X-Forwarded-Proto", "https", "X-Forwarded-Host", "proxy-host" ); + checkContent(SCALAR_DEFAULT_PATH, headers,"results/app16-2" ); + } + + @Test + void shouldReturnCorrectInitializerJSWhenChangingForwardedPrefixHeader() throws Exception { + var tasks = IntStream.range(0, 10).mapToObj(i -> CompletableFuture.runAsync(() -> { + try { + mockMvc.perform(get(SCALAR_DEFAULT_PATH) + .header("X-Forwarded-Prefix", X_FORWARD_PREFIX + i)) + .andExpect(status().isOk()) + .andExpect(content().string( + containsString(X_FORWARD_PREFIX + i + SCALAR_DEFAULT_PATH) + )) + .andExpect(content().string( + containsString(X_FORWARD_PREFIX + i + SCALAR_DEFAULT_PATH + DEFAULT_PATH_SEPARATOR + SCALAR_JS_FILENAME ) + )); + } + catch (Exception e) { + throw new RuntimeException(e); + } + })).toArray(CompletableFuture[]::new); + CompletableFuture.allOf(tasks).join(); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app17/SpringDocApp17Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app17/SpringDocApp17Test.java new file mode 100644 index 000000000..3aae106f1 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app17/SpringDocApp17Test.java @@ -0,0 +1,62 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app17; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = { + "server.forward-headers-strategy=framework", + "scalar.path="+ SpringDocApp17Test.SCALAR_PATH + +}) +public class SpringDocApp17Test extends AbstractCommonTest { + + static final String PREFIX = "/documentation"; + static final String X_FORWARD_PREFIX = "/path/prefix"; + static final String SCALAR_PATH = PREFIX + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_PATH); + } + + @Test + void checkContentForwardedPrefix() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_PATH, headers,"results/app17-1" ); + } + + @Test + void checkContentForwardedPrefixHostProto() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX, + "X-Forwarded-Proto", "https", "X-Forwarded-Host", "proxy-host" ); + checkContent(SCALAR_PATH, headers,"results/app17-2" ); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app18/SpringDocApp18Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app18/SpringDocApp18Test.java new file mode 100644 index 000000000..b91e6e0f2 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app18/SpringDocApp18Test.java @@ -0,0 +1,74 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webmvc.scalar.app18; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static test.org.springdoc.webmvc.scalar.app18.SpringDocApp18Test.SCALAR_PATH; + +@TestPropertySource(properties = { + "server.forward-headers-strategy=framework", + "scalar.path="+SCALAR_PATH, + "springdoc.api-docs.path=/bar/openapi/v3" +}) +public class SpringDocApp18Test extends AbstractCommonTest { + + private static final String X_FORWARD_PREFIX = "/path/prefix"; + + private static final String API_DOCS_URL = "/bar/openapi/v3"; + + static final String SCALAR_PATH = "/foo/documentation/scalar"; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_PATH); + } + + @Test + void shouldServeOpenapiJsonUnderCustomPath() throws Exception { + mockMvc.perform(get(API_DOCS_URL) + .header("X-Forwarded-Prefix", X_FORWARD_PREFIX)) + .andExpect(status().isOk()); + } + + @Test + void checkContentBehindProxy() throws Exception { + Map headers = Map.of("X-Forwarded-Prefix", X_FORWARD_PREFIX); + checkContent(SCALAR_PATH, headers,"results/app18-1" ); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/HelloController.java new file mode 100644 index 000000000..bf5686f47 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/HelloController.java @@ -0,0 +1,45 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webmvc.scalar.app19; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/SpringDocApp19Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/SpringDocApp19Test.java new file mode 100644 index 000000000..eaf0bcac3 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app19/SpringDocApp19Test.java @@ -0,0 +1,48 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.webmvc.scalar.app19; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = "scalar.path="+ SpringDocApp19Test.SCALAR_PATH) +public class SpringDocApp19Test extends AbstractCommonTest { + + static final String SCALAR_PATH = "/" ; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/HelloController.java new file mode 100644 index 000000000..9c1f1b0b7 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app2; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/SpringDocApp2Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/SpringDocApp2Test.java new file mode 100644 index 000000000..905b33aa2 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app2/SpringDocApp2Test.java @@ -0,0 +1,47 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app2; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.core.utils.Constants.DEFAULT_API_DOCS_URL; +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = { + "scalar.path="+ SpringDocApp2Test.SCALAR_PATH, + "springdoc.api-docs.path="+ SpringDocApp2Test.PREFIX + DEFAULT_API_DOCS_URL, +}) +public class SpringDocApp2Test extends AbstractCommonTest { + + static final String PREFIX = "/documentation"; + static final String SCALAR_PATH = PREFIX + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/HelloController.java new file mode 100644 index 000000000..d32b81219 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app3; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/SpringDocApp3Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/SpringDocApp3Test.java new file mode 100644 index 000000000..b74a2661d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app3/SpringDocApp3Test.java @@ -0,0 +1,48 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app3; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = { + "spring.mvc.pathmatch.matching-strategy=ant_path_matcher", + "scalar.path="+ SpringDocApp3Test.SCALAR_PATH, + "server.servlet.context-path="+ SpringDocApp3Test.CONTEXT_PATH, + "spring.mvc.servlet.path="+ SpringDocApp3Test.SERVLET_PATH +}) +public class SpringDocApp3Test extends AbstractCommonTest { + + static final String CONTEXT_PATH = "/context-path"; + static final String SERVLET_PATH = "/servlet-path"; + static final String SCALAR_PATH = "/test/scalar"; + static final String REQUEST_PATH = CONTEXT_PATH + SERVLET_PATH + SCALAR_PATH; + + @Test + void checkContent() throws Exception { + checkContent( REQUEST_PATH, CONTEXT_PATH, SERVLET_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp { + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/HelloController.java new file mode 100644 index 000000000..28964d93d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app4; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/SpringDocApp4Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/SpringDocApp4Test.java new file mode 100644 index 000000000..0d2f81a7b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app4/SpringDocApp4Test.java @@ -0,0 +1,60 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app4; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractSpringDocActuatorTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@DirtiesContext +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { "spring.jackson.property-naming-strategy=UPPER_CAMEL_CASE", "springdoc.show-actuator=true", + "management.endpoints.web.base-path=/management", + "server.servlet.context-path="+ SpringDocApp4Test.CONTEXT_PATH, "management.server.port=9401", "management.server.base-path="+ SpringDocApp4Test.CONTEXT_PATH }) +public class SpringDocApp4Test extends AbstractSpringDocActuatorTest { + + static final String CONTEXT_PATH = "/demo/api"; + static final String REQUEST_PATH = CONTEXT_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + checkContent(REQUEST_PATH, CONTEXT_PATH); + } + + @Test + void checkApi() throws Exception { + mockMvc.perform(get("/demo/api/v3/api-docs/springdocDefault").contextPath("/demo/api")) + .andExpect(status().isOk()); + mockMvc.perform(get("/demo/api/v3/api-docs/x-actuator").contextPath("/demo/api")) + .andExpect(status().isOk()); + } + + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocApp5Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocApp5Test.java new file mode 100644 index 000000000..43c0d2908 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocApp5Test.java @@ -0,0 +1,38 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app5; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static test.org.springdoc.webmvc.scalar.app5.SpringDocApp5Test.API_DOCS_URL; + +@TestPropertySource(properties = "scalar.url=" + API_DOCS_URL) +public class SpringDocApp5Test extends AbstractCommonTest { + + static final String API_DOCS_URL = "http://myserver:8080/v3/api-docs"; + + @Test + void checkContent() throws Exception { + checkContent(SCALAR_DEFAULT_PATH); + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocTestApp.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocTestApp.java new file mode 100644 index 000000000..7965cb75e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app5/SpringDocTestApp.java @@ -0,0 +1,53 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app5; + + +import org.springdoc.core.models.GroupedOpenApi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class SpringDocTestApp { + + public static void main(String[] args) { + SpringApplication.run(SpringDocTestApp.class, args); + } + + @Bean + public GroupedOpenApi storeOpenApi() { + String paths[] = { "/store/**" }; + return GroupedOpenApi.builder() + .group("stores") + .pathsToMatch(paths) + .build(); + } + + @Bean + public GroupedOpenApi groupOpenApi() { + String paths[] = { "/pet/**" }; + return GroupedOpenApi.builder() + .group("pets") + .pathsToMatch(paths) + .build(); + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app6/SpringDocApp6Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app6/SpringDocApp6Test.java new file mode 100644 index 000000000..239e03c83 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app6/SpringDocApp6Test.java @@ -0,0 +1,42 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app6; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = "server.servlet.context-path=" + SpringDocApp6Test.CONTEXT_PATH) +public class SpringDocApp6Test extends AbstractCommonTest { + + static final String CONTEXT_PATH = "/context-path"; + static final String REQUEST_PATH = CONTEXT_PATH + SCALAR_DEFAULT_PATH; + + @Test + void checkContent() throws Exception { + checkContent(REQUEST_PATH, CONTEXT_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app7/SpringDocApp7Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app7/SpringDocApp7Test.java new file mode 100644 index 000000000..439fdca7e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app7/SpringDocApp7Test.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app7; + +import java.util.Map; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; + +@TestPropertySource(properties = { "server.forward-headers-strategy=framework" }) +public class SpringDocApp7Test extends AbstractCommonTest { + + @Test + void checkContent() throws Exception { + Map headers = Map.of("X-Forwarded-Proto", "https", "X-Forwarded-Host", "host1"); + checkContent(SCALAR_DEFAULT_PATH, headers,"results/app7-1" ); + headers = Map.of("X-Forwarded-Proto", "http", "X-Forwarded-Host", "host2:8080"); + checkContent(SCALAR_DEFAULT_PATH, headers,"results/app7-2" ); + } + + @SpringBootApplication + static class SpringDocTestApp { + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app8/SpringApp8Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app8/SpringApp8Test.java new file mode 100644 index 000000000..d1c2fac15 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app8/SpringApp8Test.java @@ -0,0 +1,46 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app8; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +@TestPropertySource(properties = { + "spring.mvc.pathmatch.matching-strategy=ant_path_matcher", + "scalar.path="+ SpringApp8Test.SCALAR_PATH, + "spring.mvc.servlet.path="+ SpringApp8Test.SERVLET_PATH +}) +public class SpringApp8Test extends AbstractCommonTest { + + static final String CONTEXT_PATH = "/context-path"; + static final String SERVLET_PATH = "/servlet-path"; + static final String SCALAR_PATH = "/test/scalar"; + static final String REQUEST_PATH = CONTEXT_PATH + SERVLET_PATH + SCALAR_PATH; + + @Test + void checkContent() throws Exception { + checkContent(REQUEST_PATH, CONTEXT_PATH, SERVLET_PATH); + } + + @SpringBootApplication + static class SpringDocTestApp {} +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/HelloController.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/HelloController.java new file mode 100644 index 000000000..e1cf21877 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/HelloController.java @@ -0,0 +1,37 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app9; + + +import jakarta.validation.Valid; +import jakarta.validation.constraints.Size; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + @GetMapping(value = "/persons") + public void persons(@Valid @RequestParam @Size(min = 4, max = 6) String name) { + + } + +} diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/SpringDocApp9Test.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/SpringDocApp9Test.java new file mode 100644 index 000000000..834c2b6b0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/app9/SpringDocApp9Test.java @@ -0,0 +1,43 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.webmvc.scalar.app9; + +import org.junit.jupiter.api.Test; +import test.org.springdoc.webmvc.scalar.AbstractCommonTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.test.context.TestPropertySource; + +import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@TestPropertySource(properties = "scalar.enabled=false") +public class SpringDocApp9Test extends AbstractCommonTest { + + @Test + void checkNotFound() throws Exception { + mockMvc.perform(get(SCALAR_DEFAULT_PATH)) + .andExpect(status().isNotFound()); + } + + @SpringBootApplication + static class SpringDocTestApp {} + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/application-test.yml b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/application-test.yml new file mode 100644 index 000000000..4cff35ff8 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/application-test.yml @@ -0,0 +1,4 @@ +spring: + main: + banner-mode: "off" + lazy-initialization: true diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/logback-test.xml b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/logback-test.xml new file mode 100644 index 000000000..608cb302d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/logback-test.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 new file mode 100644 index 000000000..19e300d37 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 new file mode 100644 index 000000000..f5c061728 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 new file mode 100644 index 000000000..8b67f74a0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 new file mode 100644 index 000000000..143bdbe0d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 new file mode 100644 index 000000000..35f039756 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 new file mode 100644 index 000000000..4c16125c7 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 new file mode 100644 index 000000000..19e300d37 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 new file mode 100644 index 000000000..19e300d37 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 new file mode 100644 index 000000000..9501a81ca --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 new file mode 100644 index 000000000..b3de119ee --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 new file mode 100644 index 000000000..283140e4d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 new file mode 100644 index 000000000..54c4dbde7 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 new file mode 100644 index 000000000..f57db2773 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 new file mode 100644 index 000000000..5a8152f2d --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 new file mode 100644 index 000000000..58a9afb5c --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 new file mode 100644 index 000000000..5d3ff1550 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 new file mode 100644 index 000000000..0b10a2dde --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 new file mode 100644 index 000000000..fdc75a528 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 new file mode 100644 index 000000000..f62a9805b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 new file mode 100644 index 000000000..ae093c742 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 new file mode 100644 index 000000000..de88d5e88 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 new file mode 100644 index 000000000..4966e1084 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 new file mode 100644 index 000000000..13dfec43b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 new file mode 100644 index 000000000..b84405624 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 @@ -0,0 +1,25 @@ + + + + Scalar API Reference + + + + + +
+ + + + + + + + \ No newline at end of file From cabf49b53665db8604de2c3947bc17273c1543bb Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sun, 7 Sep 2025 12:22:52 +0200 Subject: [PATCH 23/45] Add logic to skipPublishing Tests to Maven Central --- pom.xml | 2 ++ springdoc-openapi-bom/pom.xml | 10 ++++++++++ springdoc-openapi-tests/pom.xml | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index e669b679d..066727ede 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,7 @@ 2.0.0-M1 0.1.0 + false @@ -219,6 +220,7 @@ central true published + ${skipPublishing} diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 7ccb85196..348839104 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -35,6 +35,16 @@ springdoc-openapi-starter-webflux-ui ${project.version} + + org.springdoc + springdoc-openapi-starter-webmvc-scalar + ${project.version} + + + org.springdoc + springdoc-openapi-starter-webflux-scalar + ${project.version} + diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 64ce976f1..7bc60bcdf 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -10,6 +10,10 @@ springdoc-openapi-tests ${project.artifactId} + + true + + springdoc-openapi-security-tests springdoc-openapi-groovy-tests From efe384430d92da8bbff8abd6dd7a3507e599dfb4 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sun, 7 Sep 2025 17:13:32 +0200 Subject: [PATCH 24/45] dependency review --- CHANGELOG.md | 14 ++++++++++++++ pom.xml | 12 +++++++++++- springdoc-openapi-starter-common/pom.xml | 1 - springdoc-openapi-starter-webmvc-scalar/pom.xml | 2 +- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79a6bf8ec..5407a1007 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.8.13] - 2025-09-07 + +### Added + +- #3084 - Add Scalar Support + +### Changed + +- Upgrade swagger-ui to v5.28.1 + +### Fixed + +- #3076 - With oneOf the response schema contains an extra type: string + ## [2.8.12] - 2025-09-01 ### Changed diff --git a/pom.xml b/pom.xml index 066727ede..22d66f6a9 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.5.0 2.2.36 - 5.28.0 + 5.28.1 1.13.1 0.9.1 0.15.0 @@ -105,6 +105,16 @@ scalar ${scalar.version} + + com.github.therapi + therapi-runtime-javadoc + ${therapi-runtime-javadoc.version} + + + com.github.therapi + therapi-runtime-javadoc-scribe + ${therapi-runtime-javadoc.version} +
diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index de11bedec..3de0a8675 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -47,7 +47,6 @@ com.github.therapi therapi-runtime-javadoc - ${therapi-runtime-javadoc.version} true diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index f7e32058d..471a504b0 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -26,7 +26,7 @@ org.springframework.boot - spring-boot-starter-actuator + spring-boot-actuator-autoconfigure true From dca06c7b92b938e379f89e22afaecbafe54c6061 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Mon, 27 Oct 2025 23:55:17 +0100 Subject: [PATCH 25/45] Changes report for#3105, #3090 --- pom.xml | 4 +- .../scalar/AbstractScalarController.java | 159 ++++++++++++++++++ .../org/springdoc/scalar/ScalarConstants.java | 2 +- .../springdoc/api/v30/app130/TrackerData.java | 2 +- .../springdoc/api/v30/app29/TrackerData.java | 2 +- .../springdoc/api/v30/app4/TrackerData.java | 2 +- .../springdoc/api/v31/app130/TrackerData.java | 2 +- .../springdoc/api/v31/app29/TrackerData.java | 2 +- .../springdoc/api/v31/app4/TrackerData.java | 2 +- .../test/resources/results/3.1.0/app164.json | 10 +- .../test/resources/results/3.1.0/app26.json | 7 +- .../springdoc/api/v30/app130/TrackerData.java | 2 +- .../springdoc/api/v30/app29/TrackerData.java | 2 +- .../springdoc/api/v30/app4/TrackerData.java | 2 +- .../springdoc/api/v31/app130/TrackerData.java | 2 +- .../springdoc/api/v31/app29/TrackerData.java | 2 +- .../springdoc/api/v31/app4/TrackerData.java | 2 +- .../test/resources/results/3.1.0/app26.json | 8 +- 18 files changed, 183 insertions(+), 31 deletions(-) diff --git a/pom.xml b/pom.xml index 22d66f6a9..40d6fe369 100644 --- a/pom.xml +++ b/pom.xml @@ -55,7 +55,7 @@ 0.7.0 1.5.0 - 2.2.36 + 2.2.38 5.28.1 1.13.1 0.9.1 @@ -63,7 +63,7 @@ 5.0.0-M1 2.0.0-M1 - 0.1.0 + 0.3.12 false diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java index 0135bdfd4..68120fd52 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java @@ -30,8 +30,11 @@ import java.io.InputStream; import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.Collectors; import com.scalar.maven.webjar.ScalarProperties; +import com.scalar.maven.webjar.ScalarProperties.ScalarSource; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -182,4 +185,160 @@ protected String buildJsBundleUrl(String requestUrl, String scalarPath) { * @return the string */ protected abstract String buildJsBundleUrl(String requestUrl); + + /** + * Builds the configuration JSON for the Scalar API Reference. + * + * @return the configuration JSON as a string + */ + private String buildConfigurationJson() { + StringBuilder config = new StringBuilder(); + config.append("{"); + + // Add URL + config.append("\n url: \"").append(escapeJson(scalarProperties.getUrl())).append("\""); + + // Add sources + if (scalarProperties.getSources() != null && !scalarProperties.getSources().isEmpty()) { + config.append(",\n sources: ").append(buildSourcesJsonArray(scalarProperties.getSources())); + } + + // Add showSidebar + if (!scalarProperties.isShowSidebar()) { + config.append(",\n showSidebar: false"); + } + + // Add hideModels + if (scalarProperties.isHideModels()) { + config.append(",\n hideModels: true"); + } + + // Add hideTestRequestButton + if (scalarProperties.isHideTestRequestButton()) { + config.append(",\n hideTestRequestButton: true"); + } + + // Add darkMode + if (scalarProperties.isDarkMode()) { + config.append(",\n darkMode: true"); + } + + // Add hideDarkModeToggle + if (scalarProperties.isHideDarkModeToggle()) { + config.append(",\n hideDarkModeToggle: true"); + } + + // Add customCss + if (scalarProperties.getCustomCss() != null && !scalarProperties.getCustomCss().trim().isEmpty()) { + config.append(",\n customCss: \"").append(escapeJson(scalarProperties.getCustomCss())).append("\""); + } + + // Add theme + if (scalarProperties.getTheme() != null && !"default".equals(scalarProperties.getTheme())) { + config.append(",\n theme: \"").append(escapeJson(scalarProperties.getTheme())).append("\""); + } + + // Add layout + if (scalarProperties.getLayout() != null && !"modern".equals(scalarProperties.getLayout())) { + config.append(",\n layout: \"").append(escapeJson(scalarProperties.getLayout())).append("\""); + } + + // Add hideSearch + if (scalarProperties.isHideSearch()) { + config.append(",\n hideSearch: true"); + } + + // Add documentDownloadType + if (scalarProperties.getDocumentDownloadType() != null && !"both".equals(scalarProperties.getDocumentDownloadType())) { + config.append(",\n documentDownloadType: \"").append(escapeJson(scalarProperties.getDocumentDownloadType())).append("\""); + } + + config.append("\n}"); + return config.toString(); + } + + /** + * Escapes a string for JSON output. + * + * @param input the input string + * @return the escaped string + */ + private String escapeJson(String input) { + if (input == null) { + return ""; + } + return input.replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t"); + } + + /** + * Builds the JSON for the OpenAPI reference sources + * + * @param sources list of OpenAPI reference sources + * @return the sources as a JSON string + */ + private String buildSourcesJsonArray(List sources) { + final StringBuilder builder = new StringBuilder("["); + + // Filter out sources with invalid urls + final List filteredSources = sources.stream() + .filter(source -> isNotNullOrBlank(source.getUrl())) + .collect(Collectors.toList()); + + // Append each source to json array + for (int i = 0; i < filteredSources.size(); i++) { + final ScalarSource source = filteredSources.get(i); + + final String sourceJson = buildSourceJson(source); + builder.append("\n").append(sourceJson); + + if (i != filteredSources.size() - 1) { + builder.append(","); + } + } + + builder.append("\n]"); + return builder.toString(); + } + + /** + * Builds the JSON for an OpenAPI reference source + * + * @param source the OpenAPI reference source + * @return the source as a JSON string + */ + private String buildSourceJson(ScalarSource source) { + final StringBuilder builder = new StringBuilder("{"); + + builder.append("\n url: \"").append(escapeJson(source.getUrl())).append("\""); + + + if (isNotNullOrBlank(source.getTitle())) { + builder.append(",\n title: \"").append(escapeJson(source.getTitle())).append("\""); + } + + if (isNotNullOrBlank(source.getSlug())) { + builder.append(",\n slug: \"").append(escapeJson(source.getSlug())).append("\""); + } + + if (source.isDefault() != null) { + builder.append(",\n default: ").append(source.isDefault()); + } + + builder.append("\n}"); + return builder.toString(); + } + + /** + * Returns whether a String is not null or blank + * + * @param input the string + * @return whether the string is not null or blank + */ + private boolean isNotNullOrBlank(String input) { + return input != null && !input.isBlank(); + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java index d63ce15e8..c694f2132 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java @@ -46,7 +46,7 @@ public class ScalarConstants { /** * The constant SCALAR_DEFAULT_URL. */ - public static final String SCALAR_DEFAULT_URL = "https://cdn.jsdelivr.net/npm/@scalar/galaxy/dist/latest.json"; + public static final String SCALAR_DEFAULT_URL = "https://registry.scalar.com/@scalar/apis/galaxy/latest?format=json"; /** * The constant DEFAULT_SCALAR_ACTUATOR_PATH. diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java index 9cd3a16f1..b5f616388 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java @@ -40,7 +40,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java index 0abb9b905..eb9e7c2e1 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java @@ -40,7 +40,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java index 02c7e8cdc..602e8d9b2 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java @@ -39,7 +39,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java index ed62069e8..2ce333c31 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java @@ -40,7 +40,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java index fb238b51d..b8ae9d058 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java @@ -40,7 +40,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java index 09e60a18f..caa99e91a 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java @@ -39,7 +39,7 @@ public class TrackerData { @JsonProperty("timestamp") Instant timestamp; - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app164.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app164.json index 9ffea82bc..41edae960 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app164.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app164.json @@ -49,10 +49,12 @@ "booleanValueAsFourthParameter": { "type": "boolean" }, - "listBlah": { - "type": "array", - "items": { - "description": "test" + "listBlah" : { + "type" : "array", + "description" : "test", + "items" : { + "type" : "string", + "description" : "test" } } } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app26.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app26.json index e6b09672d..e78e87c20 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app26.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app26.json @@ -64,14 +64,9 @@ "type": "object", "properties": { "thing": { + "type": "string", "description": "Hello", "oneOf": [ - { - "$ref": "#/components/schemas/Foo" - }, - { - "$ref": "#/components/schemas/Bar" - }, { "$ref": "#/components/schemas/Foo" }, diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java index 2c72827d9..845a374e7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app130/TrackerData.java @@ -54,7 +54,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java index 27b4694dd..a15da9298 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app29/TrackerData.java @@ -54,7 +54,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java index 16f67f3b7..3eb49ef22 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app4/TrackerData.java @@ -53,7 +53,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java index cb22d8d33..bc9f7ab2e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app130/TrackerData.java @@ -54,7 +54,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java index c79bef79c..237e8c020 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app29/TrackerData.java @@ -54,7 +54,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java index 040eb091a..b927d304c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app4/TrackerData.java @@ -53,7 +53,7 @@ class TrackerData { /** * The Value. */ - @Schema(name = "value", type = "number", format = "double", description = "The data value", required = true, example = "19.0") + @Schema(name = "value", types = "number", format = "double", description = "The data value", required = true, example = "19.0") @JsonProperty("value") Double value; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app26.json b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app26.json index 52c639196..b9783ba5b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app26.json +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/resources/results/3.1.0/app26.json @@ -78,14 +78,9 @@ "description": "The type My model.", "properties": { "thing": { + "type": "string", "description": "Hello", "oneOf": [ - { - "$ref": "#/components/schemas/Foo" - }, - { - "$ref": "#/components/schemas/Bar" - }, { "$ref": "#/components/schemas/Foo" }, @@ -99,3 +94,4 @@ } } } + \ No newline at end of file From 1b4e260805e7b9ae909a9e135de4124c4b4c5858 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Wed, 29 Oct 2025 12:30:41 +0100 Subject: [PATCH 26/45] changes report #3107 --- .../org/springdoc/api/AbstractOpenApiResource.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index 3c016f624..21881a163 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -346,6 +346,17 @@ private void getOpenApi() { * @param locale the locale * @return the open api */ + protected OpenAPI getOpenApi(Locale locale) { + return this.getOpenApi(null, locale); + } + + /** + * Gets open api. + * + * @param serverBaseUrl the server base url + * @param locale the locale + * @return the open api + */ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { this.reentrantLock.lock(); try { From 05d45182d4b85a56bbaf0fdf27000c8efc85675a Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Thu, 30 Oct 2025 00:36:22 +0100 Subject: [PATCH 27/45] swagger-ui update to version 5.30.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 40d6fe369..3e73dc271 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ 1.5.0 2.2.38 - 5.28.1 + 5.30.0 1.13.1 0.9.1 0.15.0 From 9b2b393bf255df11e832bdb4c2b9f1c4b48106e1 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Thu, 30 Oct 2025 02:56:11 +0100 Subject: [PATCH 28/45] [Bug] NPE in KotlinDeprecatedPropertyCustomizer - resolvedSchema is null. Fixes #3121 --- .../KotlinDeprecatedPropertyCustomizer.kt | 2 +- .../api/v31/app22/SpringDocApp22Test.kt | 58 +++++++++++++++++++ .../test/resources/results/3.1.0/app22.json | 50 ++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt create mode 100644 springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app22.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/KotlinDeprecatedPropertyCustomizer.kt b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/KotlinDeprecatedPropertyCustomizer.kt index 3e397242d..98b7a9e71 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/KotlinDeprecatedPropertyCustomizer.kt +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/KotlinDeprecatedPropertyCustomizer.kt @@ -64,7 +64,7 @@ class KotlinDeprecatedPropertyCustomizer( prop.hasAnnotation() if (deprecatedAnnotation != null) { val fieldName = prop.name - if (resolvedSchema.`$ref` != null) { + if (resolvedSchema!=null && resolvedSchema.`$ref` != null) { val schema = context.getDefinedModels()[resolvedSchema.`$ref`.substring( Components.COMPONENTS_SCHEMAS_REF.length diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt new file mode 100644 index 000000000..af0bd3c61 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt @@ -0,0 +1,58 @@ +/* + * + * * Copyright 2019-2020 the original author or authors. + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + */ + +package test.org.springdoc.api.v31.app22 + +import com.fasterxml.jackson.annotation.JsonUnwrapped +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.enums.Explode +import io.swagger.v3.oas.annotations.media.ArraySchema +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.Valid +import org.springdoc.core.annotations.ParameterObject +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import test.org.springdoc.api.v31.AbstractKotlinSpringDocMVCTest + +class SpringDocApp22Test : AbstractKotlinSpringDocMVCTest() { + @SpringBootApplication + class DemoApplication +} + + + +@RestController +@RequestMapping("/test") +@SpringBootApplication +class DemoApp { + @GetMapping + fun getTestData(): Foo = Foo(bar = Bar(baz = "test")) +} + +data class Foo( + @field:JsonUnwrapped + val bar: Bar, +) + +data class Bar( + @Deprecated("This is deprecated") + val baz: String, +) diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app22.json b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app22.json new file mode 100644 index 000000000..2f59eedc7 --- /dev/null +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/resources/results/3.1.0/app22.json @@ -0,0 +1,50 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/test": { + "get": { + "tags": [ + "demo-app" + ], + "operationId": "getTestData", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/Foo" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Foo": { + "type": "object", + "properties": { + "baz": { + "type": "string" + } + }, + "required": [ + "baz" + ] + } + } + } +} From 36e63d71da15c91cda200abe3d8d5ef05aee0486 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 31 Oct 2025 23:00:04 +0100 Subject: [PATCH 29/45] Add support for Spring Boot 4.0.0-RC1.Fixes #3095 --- pom.xml | 6 +- .../configuration/SpringDocConfiguration.java | 6 +- .../SpringDocDataRestConfiguration.java | 4 +- .../SpringDocKotlinConfiguration.kt | 3 - .../core/data/DataRestResponseService.java | 6 +- .../core/data/SpringDocJackson2HalModule.java | 51 ++ .../core/providers/DataRestHalProvider.java | 7 +- .../core/providers/HateoasHalProvider.java | 7 +- .../SpringDataWebPropertiesProvider.java | 8 +- .../SpringRepositoryRestResourceProvider.java | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 11 +- .../SpringDocWebFluxConfiguration.java | 2 - .../webflux/core/service/RequestService.java | 4 - .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../api/v30/AbstractSpringDocTest.java | 4 +- .../api/v30/app189/SpringDocApp189Test.java | 2 +- .../api/v30/app190/SpringDocApp190Test.java | 2 +- .../v30/app190/SpringDocApp190bisTest.java | 2 +- .../api/v30/app81/SpringDocApp81Test.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 4 +- .../api/v31/app189/SpringDocApp189Test.java | 2 +- .../api/v31/app190/SpringDocApp190Test.java | 2 +- .../v31/app190/SpringDocApp190bisTest.java | 2 +- .../api/v31/app81/SpringDocApp81Test.java | 2 +- .../pom.xml | 10 + .../webflux/scalar/AbstractCommonTest.java | 2 +- .../scalar/AbstractSpringDocActuatorTest.java | 2 +- .../scalar/app7/SpringDocApp7Test.java | 6 +- .../src/test/resources/results/app7 | 4 +- .../src/test/resources/results/app8 | 4 +- .../src/test/resources/results/app9 | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 10 + .../org/springdoc/ui/AbstractCommonTest.java | 2 +- .../ui/AbstractSpringDocActuatorTest.java | 2 +- .../springdoc/ui/AbstractSpringDocTest.java | 2 +- .../ui/app18/SpringDocApp18Test.java | 2 +- .../ui/app19/SpringDocApp19Test.java | 2 +- .../ui/app20/SpringDocApp20Test.java | 2 +- .../ui/app23/SpringDocApp23Test.java | 2 +- .../SpringDocBehindProxyBasePathTest.java | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 10 + .../SpringDocWebMvcConfiguration.java | 2 - .../webmvc/core/service/RequestService.java | 4 - .../org/springdoc/api/AbstractCommonTest.java | 2 +- .../api/v30/app1/InventoryApiController.java | 2 +- .../api/v30/app199/HelloController.java | 8 +- .../api/v30/app215/SpringDocApp215Test.java | 2 +- .../v30/app215/SpringDocApp215bisTest.java | 2 +- .../api/v31/app1/InventoryApiController.java | 2 +- .../api/v31/app199/HelloController.java | 8 +- .../api/v31/app215/SpringDocApp215Test.java | 2 +- .../v31/app215/SpringDocApp215bisTest.java | 2 +- .../api/v31/app245/SpringDocApp245Test.java | 2 +- .../test/resources/results/3.0.1/app143.json | 31 + .../test/resources/results/3.0.1/app196.json | 31 + .../test/resources/results/3.0.1/app48.json | 2 +- .../test/resources/results/3.1.0/app143.json | 31 + .../test/resources/results/3.1.0/app196.json | 31 + .../test/resources/results/3.1.0/app48.json | 2 +- .../pom.xml | 10 + .../webmvc/scalar/AbstractCommonTest.java | 2 +- .../scalar/AbstractSpringDocActuatorTest.java | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 10 + .../org/springdoc/ui/AbstractCommonTest.java | 2 +- .../ui/AbstractSpringDocActuatorTest.java | 2 +- .../pom.xml | 5 + .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../v30/AbstractSpringDocActuatorTest.java | 2 +- .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v30/app146/SpringDocApp146Test.java | 4 +- .../api/v30/app186/SpringDocApp186Test.java | 4 +- .../api/v30/app76/SpringDocTestApp.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../v31/AbstractSpringDocActuatorTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../api/v31/app146/SpringDocApp146Test.java | 4 +- .../api/v31/app186/SpringDocApp186Test.java | 4 +- .../api/v31/app76/SpringDocTestApp.java | 2 +- .../resources/results/3.0.1/app146-2.json | 2 +- .../test/resources/results/3.0.1/app186.json | 2 +- .../resources/results/3.1.0/app146-2.json | 2 +- .../test/resources/results/3.1.0/app186.json | 2 +- .../pom.xml | 5 + .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../v30/AbstractSpringDocActuatorTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../v31/AbstractSpringDocActuatorTest.java | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v30/app14/SpringDocApp14Test.java | 5 +- .../api/v30/app32/SpringDocApp32Test.java | 4 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../api/v31/app14/SpringDocApp14Test.java | 4 +- .../api/v31/app32/SpringDocApp32Test.java | 4 +- .../pom.xml | 5 + .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../v30/AbstractSpringDocFunctionTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../v31/AbstractSpringDocFunctionTest.java | 2 +- .../pom.xml | 5 + .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../test/resources/results/3.0.1/app1.json | 618 ++++++++------ .../test/resources/results/3.1.0/app1.json | 753 ++++++++++-------- .../springdoc-openapi-hateoas-tests/pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v30/app1/InventoryApiController.java | 2 +- .../app172/JavadocPropertyCustomizerTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../api/v31/app1/InventoryApiController.java | 2 +- .../app172/JavadocPropertyCustomizerTest.java | 2 +- .../pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../api/v30/AbstractKotlinSpringDocTest.kt | 4 +- .../api/v31/AbstractKotlinSpringDocTest.kt | 4 +- .../pom.xml | 5 + .../api/v30/AbstractKotlinSpringDocMVCTest.kt | 2 +- .../api/v31/AbstractKotlinSpringDocMVCTest.kt | 2 +- .../api/v31/app22/SpringDocApp22Test.kt | 7 - .../springdoc-openapi-security-tests/pom.xml | 5 + .../api/v30/AbstractSpringDocTest.java | 4 +- .../api/v31/AbstractSpringDocTest.java | 4 +- 130 files changed, 1222 insertions(+), 741 deletions(-) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/SpringDocJackson2HalModule.java diff --git a/pom.xml b/pom.xml index 3e73dc271..ac23478c9 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 4.0.0-M2 + 4.0.0-RC1 @@ -56,12 +56,12 @@ 1.5.0 2.2.38 - 5.30.0 + 5.30.1 1.13.1 0.9.1 0.15.0 5.0.0-M1 - 2.0.0-M1 + 2.0.0-M2 0.3.12 false diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index 3c5edd005..cd8397d13 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -115,7 +115,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.autoconfigure.web.format.WebConversionService; -import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties; +import org.springframework.boot.data.autoconfigure.web.DataWebProperties; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -589,7 +589,7 @@ WebConversionServiceProvider webConversionServiceProvider() { /** * The type Spring doc spring data web properties provider. */ - @ConditionalOnClass(SpringDataWebProperties.class) + @ConditionalOnClass(DataWebProperties.class) static class SpringDocSpringDataWebPropertiesProvider { /** * Spring data web properties provider spring data web properties provider. @@ -600,7 +600,7 @@ static class SpringDocSpringDataWebPropertiesProvider { @Bean @ConditionalOnMissingBean @Lazy(false) - SpringDataWebPropertiesProvider springDataWebPropertiesProvider(Optional optionalSpringDataWebProperties) { + SpringDataWebPropertiesProvider springDataWebPropertiesProvider(Optional optionalSpringDataWebProperties) { return new SpringDataWebPropertiesProvider(optionalSpringDataWebProperties); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java index e93abd2aa..62d2cbd83 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocDataRestConfiguration.java @@ -28,7 +28,6 @@ import java.util.Optional; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springdoc.core.configuration.hints.SpringDocDataRestHints; import org.springdoc.core.converters.models.DefaultPageable; import org.springdoc.core.data.DataRestOperationService; @@ -42,12 +41,11 @@ import org.springdoc.core.providers.ObjectMapperProvider; import org.springdoc.core.providers.SpringRepositoryRestResourceProvider; import org.springdoc.core.service.AbstractRequestService; -import org.springdoc.core.service.GenericParameterService; import org.springdoc.core.service.GenericResponseService; import org.springdoc.core.service.OpenAPIService; import org.springdoc.core.service.OperationService; -import org.springdoc.core.service.RequestBodyService; import org.springdoc.core.utils.SpringDocDataRestUtils; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt index e5bc8f0c0..8a1a4c06e 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocKotlinConfiguration.kt @@ -27,9 +27,7 @@ package org.springdoc.core.configuration import org.springdoc.core.converters.KotlinInlineClassUnwrappingConverter -import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer import org.springdoc.core.customizers.KotlinDeprecatedPropertyCustomizer -import org.springdoc.core.extractor.DelegatingMethodParameter import org.springdoc.core.providers.ObjectMapperProvider import org.springdoc.core.utils.Constants import org.springdoc.core.utils.SpringDocKotlinUtils @@ -44,7 +42,6 @@ import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Lazy import kotlin.coroutines.Continuation -import kotlin.reflect.full.primaryConstructor /** * The type Spring doc kotlin configuration. diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestResponseService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestResponseService.java index ba5674861..6f01bd545 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestResponseService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestResponseService.java @@ -297,16 +297,14 @@ private Type getTypeForCollectionModel(Class returnedEntityType, boolean pagingR */ private Type getTypeForWildcardType(RequestMethod requestMethod, DataRestRepository dataRestRepository, Class returnedEntityType, ParameterizedType parameterizedType) { WildcardType wildcardType = (WildcardType) parameterizedType.getActualTypeArguments()[0]; + Class type = findType(requestMethod, dataRestRepository); if (wildcardType.getUpperBounds()[0] instanceof ParameterizedType wildcardTypeUpperBound) { if (RepresentationModel.class.equals(wildcardTypeUpperBound.getRawType())) { - Class type = findType(requestMethod, dataRestRepository); if (MapModel.class.equals(type)) return ResolvableType.forClassWithGenerics(ResponseEntity.class, type).getType(); - else - return resolveGenericType(ResponseEntity.class, type, returnedEntityType); } } - return null; + return resolveGenericType(ResponseEntity.class, type, returnedEntityType); } /** diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/SpringDocJackson2HalModule.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/SpringDocJackson2HalModule.java new file mode 100644 index 000000000..876f37a27 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/SpringDocJackson2HalModule.java @@ -0,0 +1,51 @@ +package org.springdoc.core.data; + +import com.fasterxml.jackson.core.Version; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; + +import org.springframework.hateoas.CollectionModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.RepresentationModel; +import org.springframework.hateoas.mediatype.hal.CollectionModelMixin; +import org.springframework.hateoas.mediatype.hal.LinkMixin; +import org.springframework.hateoas.mediatype.hal.RepresentationModelMixin; +import org.springframework.util.Assert; + +/** + * Jackson 2 module implementation + * + * @author bnasslahsen + */ +public class SpringDocJackson2HalModule extends SimpleModule { + + private static final long serialVersionUID = 7806951456457932384L; + + /** + * Instantiates a new Spring doc jackson 2 hal module. + */ + public SpringDocJackson2HalModule() { + + super("json-hal-module", new Version(1, 0, 0, null, "org.springframework.hateoas", "spring-hateoas")); + + setMixInAnnotation(Link.class, LinkMixin.class); + setMixInAnnotation(RepresentationModel.class, RepresentationModelMixin.class); + setMixInAnnotation(CollectionModel.class, CollectionModelMixin.class); + } + + + /** + * Is already registered in boolean. + * + * @param mapper the mapper + * @return the boolean + */ + public static boolean isAlreadyRegisteredIn(ObjectMapper mapper) { + + Assert.notNull(mapper, "ObjectMapper must not be null!"); + return LinkMixin.class.equals(mapper.findMixInClassFor(Link.class)); + } + + + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java index 07ba0ca28..285ae261e 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/DataRestHalProvider.java @@ -28,10 +28,11 @@ import java.util.Optional; +import org.springdoc.core.data.SpringDocJackson2HalModule; + import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; import org.springframework.data.rest.core.config.RepositoryRestConfiguration; -import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; /** * The type Data rest hal provider. @@ -62,8 +63,8 @@ public DataRestHalProvider(Optional repositoryRestC public void afterPropertiesSet() { if (!isHalEnabled()) return; - if (!Jackson2HalModule.isAlreadyRegisteredIn(objectMapperProvider.jsonMapper())) - objectMapperProvider.jsonMapper().registerModule(new Jackson2HalModule()); + if (!SpringDocJackson2HalModule.isAlreadyRegisteredIn(objectMapperProvider.jsonMapper())) + objectMapperProvider.jsonMapper().registerModule(new SpringDocJackson2HalModule()); } @Override diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java index 33bae4b07..1f3d29a19 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java @@ -29,9 +29,10 @@ import java.util.List; import java.util.Optional; +import org.springdoc.core.data.SpringDocJackson2HalModule; + import org.springframework.beans.factory.InitializingBean; import org.springframework.boot.hateoas.autoconfigure.HateoasProperties; -import org.springframework.hateoas.mediatype.hal.Jackson2HalModule; import org.springframework.lang.NonNull; import org.springframework.util.ReflectionUtils; @@ -103,8 +104,8 @@ public void afterPropertiesSet() { return; } var mapper = objectMapperProvider.jsonMapper(); - if (!Jackson2HalModule.isAlreadyRegisteredIn(mapper)) { - mapper.registerModule(new Jackson2HalModule()); + if (!SpringDocJackson2HalModule.isAlreadyRegisteredIn(mapper)) { + mapper.registerModule(new SpringDocJackson2HalModule()); } } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java index 527cf940d..c4fb7df6d 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringDataWebPropertiesProvider.java @@ -27,7 +27,7 @@ import java.util.Optional; -import org.springframework.boot.data.autoconfigure.web.SpringDataWebProperties; +import org.springframework.boot.data.autoconfigure.web.DataWebProperties; /** @@ -41,14 +41,14 @@ public class SpringDataWebPropertiesProvider { /** * The Optional spring data web properties. */ - private final Optional optionalSpringDataWebProperties; + private final Optional optionalSpringDataWebProperties; /** * Instantiates a new Spring data web properties provider. * * @param optionalSpringDataWebProperties the optional spring data web properties */ - public SpringDataWebPropertiesProvider(Optional optionalSpringDataWebProperties) { + public SpringDataWebPropertiesProvider(Optional optionalSpringDataWebProperties) { this.optionalSpringDataWebProperties = optionalSpringDataWebProperties; } @@ -57,7 +57,7 @@ public SpringDataWebPropertiesProvider(Optional optiona * * @return the spring data web properties */ - public SpringDataWebProperties getSpringDataWebProperties() { + public DataWebProperties getSpringDataWebProperties() { return optionalSpringDataWebProperties.orElse(null); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringRepositoryRestResourceProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringRepositoryRestResourceProvider.java index e918da933..285794791 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringRepositoryRestResourceProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringRepositoryRestResourceProvider.java @@ -34,7 +34,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.models.OpenAPI; import org.apache.commons.lang3.reflect.MethodUtils; @@ -45,6 +44,7 @@ import org.springdoc.core.data.DataRestRouterOperationService; import org.springdoc.core.fn.RouterOperation; import org.springdoc.core.utils.SpringDocDataRestUtils; +import tools.jackson.databind.ObjectMapper; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 01355244d..c08b5791d 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -29,7 +29,16 @@ true - + + org.springframework.boot + spring-boot-starter-webflux-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java index 520a87605..51cf71e4b 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java @@ -26,11 +26,9 @@ package org.springdoc.webflux.core.configuration; -import java.util.List; import java.util.Optional; import org.springdoc.core.configuration.SpringDocConfiguration; -import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.MethodParameterPojoExtractor; diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java index 31b3caae4..5b25ea28d 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/service/RequestService.java @@ -26,10 +26,6 @@ package org.springdoc.webflux.core.service; -import java.util.List; -import java.util.Optional; - -import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.MethodParameterPojoExtractor; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index d3971928b..9593f2b80 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 4bc88c5b6..de0d8b638 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -29,8 +29,8 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.ServerResponse; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app189/SpringDocApp189Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app189/SpringDocApp189Test.java index 963246ffc..576108fd5 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app189/SpringDocApp189Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app189/SpringDocApp189Test.java @@ -33,7 +33,7 @@ import org.springdoc.core.utils.Constants; import test.org.springdoc.api.v30.AbstractCommonTest; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190Test.java index ffddeaa31..677ccec9a 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190Test.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v30.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190bisTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190bisTest.java index 315adf934..a8ae55df7 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190bisTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app190/SpringDocApp190bisTest.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v30.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app81/SpringDocApp81Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app81/SpringDocApp81Test.java index e94029c81..91d3e1efe 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app81/SpringDocApp81Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/app81/SpringDocApp81Test.java @@ -40,7 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.method.HandlerMethod; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 02935cfae..3ca0d9afd 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index 46c464754..8367ecae5 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -29,8 +29,8 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.ServerResponse; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app189/SpringDocApp189Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app189/SpringDocApp189Test.java index 157a05810..c022c0e06 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app189/SpringDocApp189Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app189/SpringDocApp189Test.java @@ -33,7 +33,7 @@ import org.springdoc.core.utils.Constants; import test.org.springdoc.api.v31.AbstractCommonTest; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190Test.java index 72a37f2fa..a9730f7ca 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190Test.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v31.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190bisTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190bisTest.java index 1d423a52f..37ae5f0e4 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190bisTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app190/SpringDocApp190bisTest.java @@ -31,7 +31,7 @@ import test.org.springdoc.api.v31.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app81/SpringDocApp81Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app81/SpringDocApp81Test.java index d65ec8cbf..884fac494 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app81/SpringDocApp81Test.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app81/SpringDocApp81Test.java @@ -40,7 +40,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.context.annotation.ComponentScan; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.web.method.HandlerMethod; diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index 7f12626b3..21f7a6af1 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -30,6 +30,16 @@ spring-boot-reactor-netty test + + org.springframework.boot + spring-boot-starter-webflux-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java index cb3bb9daf..78f050427 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java @@ -11,8 +11,8 @@ import jakarta.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java index ad5395f29..3c9318fda 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractSpringDocActuatorTest.java @@ -26,7 +26,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.MediaType; diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java index 4a266e561..97c92bb1e 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/app7/SpringDocApp7Test.java @@ -23,6 +23,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; @@ -30,8 +31,9 @@ import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_PATH; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - properties = { "management.endpoints.web.exposure.include=*", +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, + properties = { "server.port=55527", + "management.endpoints.web.exposure.include=*", "springdoc.show-actuator=true", "management.server.port=9596", "management.server.base-path=/test", diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 index 6b9b9273d..fb40ef696 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 @@ -17,9 +17,9 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 index 5d3ff1550..10573c433 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 @@ -17,9 +17,9 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 index dfbe8d55c..73c9ba06a 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 @@ -17,7 +17,7 @@ diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index cb93775fc..b0262c9a7 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -34,6 +34,16 @@ spring-boot-reactor-netty test + + org.springframework.boot + spring-boot-starter-webflux-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java index 007cb67ed..9840fe38f 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java index f5e12c34d..493614214 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java @@ -26,7 +26,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java index a46a53f80..5b8c02fc7 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocTest.java @@ -28,7 +28,7 @@ import org.springdoc.webflux.ui.SwaggerConfig; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java index 51c000ef8..1a16f01e3 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app18/SpringDocApp18Test.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java index c8a88bc31..52172b241 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app19/SpringDocApp19Test.java @@ -32,7 +32,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java index c1d7902e1..71c9a4a82 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app20/SpringDocApp20Test.java @@ -33,7 +33,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java index bbff5133c..2f8949afb 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app23/SpringDocApp23Test.java @@ -33,7 +33,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java index ec0045029..9134b91df 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/app33/SpringDocBehindProxyBasePathTest.java @@ -26,7 +26,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.boot.web.server.test.LocalServerPort; +import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.context.annotation.Import; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index c9eff3a32..251bdf314 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -39,6 +39,16 @@ money-api test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java index 645e18e0b..b05038ad6 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java @@ -26,11 +26,9 @@ package org.springdoc.webmvc.core.configuration; -import java.util.List; import java.util.Optional; import org.springdoc.core.configuration.SpringDocConfiguration; -import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.MethodParameterPojoExtractor; diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java index 81c88d845..cd55fad59 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/service/RequestService.java @@ -26,10 +26,6 @@ package org.springdoc.webmvc.core.service; -import java.util.List; -import java.util.Optional; - -import org.springdoc.core.customizers.ParameterCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.MethodParameterPojoExtractor; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/AbstractCommonTest.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/AbstractCommonTest.java index 34d647911..b45f9c65e 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/AbstractCommonTest.java @@ -6,7 +6,7 @@ import java.nio.file.Paths; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java index 3c88f7816..370eaec39 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java @@ -26,12 +26,12 @@ import java.util.List; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java index a2304bf49..bbc58fc0f 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app199/HelloController.java @@ -26,10 +26,10 @@ import java.util.LinkedHashMap; import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.examples.Example; import org.springdoc.core.customizers.OperationCustomizer; +import org.springdoc.core.providers.ObjectMapperProvider; import test.org.springdoc.api.v30.app199.CustomExceptionHandler.MyInternalException; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +45,7 @@ public class HelloController { @Autowired - ObjectMapper defaultObjectMapper; + ObjectMapperProvider objectMapperProvider; @GetMapping( value = "/first", @@ -83,7 +83,7 @@ public OperationCustomizer operationCustomizer() { examples.put( "First case example", new Example().value( - defaultObjectMapper.valueToTree( + objectMapperProvider.jsonMapper().valueToTree( new ErrorDto("An ErrorDto sample specific to /first endpoint") ) ) @@ -94,7 +94,7 @@ public OperationCustomizer operationCustomizer() { examples.put( "Second case example", new Example().value( - defaultObjectMapper.valueToTree( + objectMapperProvider.jsonMapper().valueToTree( new ErrorDto("An ErrorDto sample specific to /second endpoint") ) ) diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215Test.java index 4b3afc615..efb8d1ba9 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215Test.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215Test.java @@ -23,7 +23,7 @@ import test.org.springdoc.api.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215bisTest.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215bisTest.java index bca4e230f..84b478079 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215bisTest.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app215/SpringDocApp215bisTest.java @@ -23,7 +23,7 @@ import test.org.springdoc.api.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java index eea9f4b39..919cae88c 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java @@ -26,12 +26,12 @@ import java.util.List; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app199/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app199/HelloController.java index c68bdd2e9..0e19db67a 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app199/HelloController.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app199/HelloController.java @@ -26,10 +26,10 @@ import java.util.LinkedHashMap; import java.util.Map; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.examples.Example; import org.springdoc.core.customizers.OperationCustomizer; +import org.springdoc.core.providers.ObjectMapperProvider; import test.org.springdoc.api.v31.app199.CustomExceptionHandler.MyInternalException; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +45,7 @@ public class HelloController { @Autowired - ObjectMapper defaultObjectMapper; + ObjectMapperProvider objectMapperProvider; @GetMapping( value = "/first", @@ -83,7 +83,7 @@ public OperationCustomizer operationCustomizer() { examples.put( "First case example", new Example().value( - defaultObjectMapper.valueToTree( + objectMapperProvider.jsonMapper().valueToTree( new ErrorDto("An ErrorDto sample specific to /first endpoint") ) ) @@ -94,7 +94,7 @@ public OperationCustomizer operationCustomizer() { examples.put( "Second case example", new Example().value( - defaultObjectMapper.valueToTree( + objectMapperProvider.jsonMapper().valueToTree( new ErrorDto("An ErrorDto sample specific to /second endpoint") ) ) diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215Test.java index 4c78c3ea9..5281d5abc 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215Test.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215Test.java @@ -23,7 +23,7 @@ import test.org.springdoc.api.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215bisTest.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215bisTest.java index 3d9320d20..7baa14e25 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215bisTest.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app215/SpringDocApp215bisTest.java @@ -23,7 +23,7 @@ import test.org.springdoc.api.AbstractCommonTest; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest; import org.springframework.context.annotation.ComponentScan; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLE_DEFAULT_API_DOCS; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app245/SpringDocApp245Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app245/SpringDocApp245Test.java index c6d8a3e17..19b9fb158 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app245/SpringDocApp245Test.java +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app245/SpringDocApp245Test.java @@ -3,8 +3,8 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.web.servlet.MockMvc; import static org.hamcrest.Matchers.is; diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json index e38b026a6..904951914 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app143.json @@ -69,6 +69,37 @@ } } } + }, + "/actuator/health": { + "get": { + "tags": [ + "Actuator" + ], + "summary": "Actuator web endpoint 'health'", + "operationId": "health", + "responses": { + "200": { + "description": "OK", + "content": { + "application/vnd.spring-boot.actuator.v3+json": { + "schema": { + "type": "object" + } + }, + "application/vnd.spring-boot.actuator.v2+json": { + "schema": { + "type": "object" + } + }, + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json index d0d508dbe..0b39821f1 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app196.json @@ -89,6 +89,37 @@ } } } + }, + "/actuator/health": { + "get": { + "tags": [ + "Actuator" + ], + "summary": "Actuator web endpoint 'health'", + "operationId": "health", + "responses": { + "200": { + "description": "OK", + "content": { + "application/vnd.spring-boot.actuator.v3+json": { + "schema": { + "type": "object" + } + }, + "application/vnd.spring-boot.actuator.v2+json": { + "schema": { + "type": "object" + } + }, + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app48.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app48.json index e266216e7..8ccc0790c 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app48.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app48.json @@ -49,7 +49,7 @@ } }, "413": { - "description": "Payload Too Large", + "description": "Content Too Large", "content": { "*/*": { "schema": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json index 3fafb1fc6..394ce3f0d 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app143.json @@ -69,6 +69,37 @@ } } } + }, + "/actuator/health": { + "get": { + "tags": [ + "Actuator" + ], + "summary": "Actuator web endpoint 'health'", + "operationId": "health", + "responses": { + "200": { + "description": "OK", + "content": { + "application/vnd.spring-boot.actuator.v3+json": { + "schema": { + "type": "object" + } + }, + "application/vnd.spring-boot.actuator.v2+json": { + "schema": { + "type": "object" + } + }, + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json index 02623c8cd..a5ca0bd5a 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app196.json @@ -89,6 +89,37 @@ } } } + }, + "/actuator/health": { + "get": { + "tags": [ + "Actuator" + ], + "summary": "Actuator web endpoint 'health'", + "operationId": "health", + "responses": { + "200": { + "description": "OK", + "content": { + "application/vnd.spring-boot.actuator.v3+json": { + "schema": { + "type": "object" + } + }, + "application/vnd.spring-boot.actuator.v2+json": { + "schema": { + "type": "object" + } + }, + "application/json": { + "schema": { + "type": "object" + } + } + } + } + } + } } }, "components": { diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app48.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app48.json index 9cfa30067..45f7b67f2 100644 --- a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app48.json +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app48.json @@ -49,7 +49,7 @@ } }, "413": { - "description": "Payload Too Large", + "description": "Content Too Large", "content": { "*/*": { "schema": { diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index 471a504b0..0c5f21726 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -34,6 +34,16 @@ spring-boot-tomcat test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java index 96cc74da3..0a28bc9e6 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractCommonTest.java @@ -8,8 +8,8 @@ import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java index 2cc3531d0..040704cfd 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/java/test/org/springdoc/webmvc/scalar/AbstractSpringDocActuatorTest.java @@ -30,7 +30,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatusCode; import org.springframework.http.client.JdkClientHttpRequestFactory; diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index b8dc2eaca..2704cff89 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -39,6 +39,16 @@ spring-boot-tomcat test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-health + test + diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java index 1fc6b9609..60b675a97 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java @@ -7,7 +7,7 @@ import java.util.List; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java index ccbe9aa31..93208b5c7 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-starter-webmvc-ui/src/test/java/test/org/springdoc/ui/AbstractSpringDocActuatorTest.java @@ -29,7 +29,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.web.client.RestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 0165f2282..f29d64ea9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -16,6 +16,11 @@ ${project.version} test + + org.springframework.boot + spring-boot-starter-webflux-test + test + org.springframework.boot diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 277bb0704..6cf91d3bb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -36,7 +36,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java index 28a5f6c36..2684acc75 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java @@ -28,7 +28,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index d41e7dfb3..8dbd3d2eb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -29,7 +29,7 @@ import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; @WebFluxTest diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app146/SpringDocApp146Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app146/SpringDocApp146Test.java index 42743fbad..b99abb3f6 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app146/SpringDocApp146Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app146/SpringDocApp146Test.java @@ -24,10 +24,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.ComponentScan; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, properties = { "management.endpoints.web.exposure.include=*", + "server.port=62386", "springdoc.show-actuator=true", "management.server.port=9286", "management.endpoints.web.exposure.exclude=functions, shutdown", diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java index 882079630..844173d90 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app186/SpringDocApp186Test.java @@ -34,14 +34,16 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; import static org.springdoc.core.utils.Constants.ALL_PATTERN; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) @TestPropertySource(properties = { "springdoc.show-actuator=true", + "server.port=62233", "springdoc.group-configs[0].group=group-actuator-as-properties", "springdoc.group-configs[0].paths-to-match=${management.endpoints.web.base-path:/actuator}/**", "management.endpoints.enabled-by-default=true", diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java index 9f96d7936..288c08c4e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/app76/SpringDocTestApp.java @@ -32,9 +32,9 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointAutoConfiguration; import org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server.NettyReactiveManagementContextAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.context.annotation.Bean; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 68d085e65..1c55a8f72 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -36,7 +36,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java index 10d8ad439..bca2f653a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java @@ -28,7 +28,7 @@ import jakarta.annotation.PostConstruct; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.test.context.TestPropertySource; import org.springframework.web.reactive.function.client.WebClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index f2399e0fa..5a50778cc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -29,7 +29,7 @@ import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; @WebFluxTest diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app146/SpringDocApp146Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app146/SpringDocApp146Test.java index cfd9aec48..827f6e8a6 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app146/SpringDocApp146Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app146/SpringDocApp146Test.java @@ -24,11 +24,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.ComponentScan; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT, properties = { "management.endpoints.web.exposure.include=*", "springdoc.show-actuator=true", + "server.port=62352", "management.server.port=9386", "management.endpoints.web.exposure.exclude=functions, shutdown", "management.server.base-path=/test", diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app186/SpringDocApp186Test.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app186/SpringDocApp186Test.java index c0c45c86b..4d13ca6fe 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app186/SpringDocApp186Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app186/SpringDocApp186Test.java @@ -34,14 +34,16 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; import static org.springdoc.core.utils.Constants.ALL_PATTERN; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) @TestPropertySource(properties = { "springdoc.show-actuator=true", + "server.port=62138", "springdoc.group-configs[0].group=group-actuator-as-properties", "springdoc.group-configs[0].paths-to-match=${management.endpoints.web.base-path:/actuator}/**", "management.endpoints.enabled-by-default=true", diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java index 9dda7255c..a5c10f5ca 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/app76/SpringDocTestApp.java @@ -32,9 +32,9 @@ import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration; -import org.springframework.boot.actuate.autoconfigure.health.HealthEndpointAutoConfiguration; import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.health.autoconfigure.actuate.endpoint.HealthEndpointAutoConfiguration; import org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server.NettyReactiveManagementContextAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.actuate.web.WebFluxEndpointManagementContextConfiguration; import org.springframework.context.annotation.Bean; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-2.json index e7c346c11..863fc0b28 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app146-2.json @@ -6,7 +6,7 @@ }, "servers": [ { - "url": "", + "url": "http://localhost:62386", "description": "Generated server url" } ], diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json index 5e00105ad..aaa4fe5e3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.0.1/app186.json @@ -6,7 +6,7 @@ }, "servers": [ { - "url": "", + "url": "http://localhost:62233", "description": "Generated server url" } ], diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-2.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-2.json index 909227c33..4570e1158 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-2.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app146-2.json @@ -6,7 +6,7 @@ }, "servers": [ { - "url": "", + "url": "http://localhost:62352", "description": "Generated server url" } ], diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json index 5293fc60a..39cd6ee1f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/resources/results/3.1.0/app186.json @@ -6,7 +6,7 @@ }, "servers": [ { - "url": "", + "url": "http://localhost:62138", "description": "Generated server url" } ], diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 73517670f..65ea0bf2c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -16,6 +16,11 @@ ${project.version} test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + org.springframework.boot diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 5ee550fd6..ae0c82114 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -32,7 +32,7 @@ import java.nio.file.Paths; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java index 74866402b..6708d9ee8 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocActuatorTest.java @@ -32,7 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 6d0e196e4..0c734bf7e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -32,7 +32,7 @@ import java.nio.file.Paths; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java index 6a0a3cf6d..451441bad 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocActuatorTest.java @@ -32,7 +32,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.web.server.test.LocalManagementPort; +import org.springframework.boot.test.web.server.LocalManagementPort; import org.springframework.http.client.JdkClientHttpRequestFactory; import org.springframework.test.context.TestPropertySource; import org.springframework.web.client.RestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index ecd2212d5..b0caa286c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -15,6 +15,11 @@ ${project.version} test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + org.springframework.boot spring-boot-starter-data-rest diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 5b16ec13c..cc248e576 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java index 7b1910299..05586452b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app14/SpringDocApp14Test.java @@ -37,11 +37,12 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.DataRestAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; + @TestPropertySource(properties = { "spring.data.web.pageable.default-page-size=25", "spring.data.web.pageable.page-parameter=pages", "spring.data.web.pageable.size-parameter=sizes", @@ -49,7 +50,7 @@ "spring.data.web.pageable.prefix=prefix_", "spring.data.web.sort.sort-parameter=sorts" }) @EnableAutoConfiguration(exclude = { - RepositoryRestMvcAutoConfiguration.class, SpringDocDataRestConfiguration.class + DataRestAutoConfiguration.class, SpringDocDataRestConfiguration.class }) public class SpringDocApp14Test extends AbstractSpringDocTest { diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java index 3367c8c72..c811e3f2a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v30/app32/SpringDocApp32Test.java @@ -37,14 +37,14 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.DataRestAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; @TestPropertySource(properties = "spring.data.web.sort.sort-parameter=sorts") @EnableAutoConfiguration(exclude = { - RepositoryRestMvcAutoConfiguration.class, SpringDocDataRestConfiguration.class + DataRestAutoConfiguration.class, SpringDocDataRestConfiguration.class }) public class SpringDocApp32Test extends AbstractSpringDocTest { diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index 29bbac4aa..b2699f9d7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java index c3a0894f1..68a389471 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app14/SpringDocApp14Test.java @@ -37,7 +37,7 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.DataRestAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; @@ -49,7 +49,7 @@ "spring.data.web.pageable.prefix=prefix_", "spring.data.web.sort.sort-parameter=sorts" }) @EnableAutoConfiguration(exclude = { - RepositoryRestMvcAutoConfiguration.class, SpringDocDataRestConfiguration.class + DataRestAutoConfiguration.class, SpringDocDataRestConfiguration.class }) public class SpringDocApp14Test extends AbstractSpringDocTest { diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java index 2fa66d651..9bdb4460c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/src/test/java/test/org/springdoc/api/v31/app32/SpringDocApp32Test.java @@ -37,14 +37,14 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.data.rest.autoconfigure.RepositoryRestMvcAutoConfiguration; +import org.springframework.boot.data.rest.autoconfigure.DataRestAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.test.context.TestPropertySource; @TestPropertySource(properties = "spring.data.web.sort.sort-parameter=sorts") @EnableAutoConfiguration(exclude = { - RepositoryRestMvcAutoConfiguration.class, SpringDocDataRestConfiguration.class + DataRestAutoConfiguration.class, SpringDocDataRestConfiguration.class }) public class SpringDocApp32Test extends AbstractSpringDocTest { diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 5c08707fe..5cc8d343c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -21,5 +21,10 @@ spring-cloud-starter-function-webflux test + + org.springframework.boot + spring-boot-starter-webflux-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index d3971928b..9593f2b80 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java index e3571ca2f..37c9e6ea4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 02935cfae..3ca0d9afd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java index e48afa7ee..afacd5f56 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index d6087473e..eac7fd3e4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -21,6 +21,11 @@ ${project.version} test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 09a2b91d9..bc7f23669 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -32,7 +32,7 @@ import java.nio.file.Paths; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 3daa13438..75bf1affc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -32,7 +32,7 @@ import java.nio.file.Paths; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index ed80697a4..8f63c09db 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -24,6 +24,11 @@ jakarta.servlet-api test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + org.springframework.data diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 391bc0d6e..681cc004f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v31/AbstractSpringDocTest.java index f759ee5af..3822f569c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/groovy/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.0.1/app1.json b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.0.1/app1.json index 542bdaf73..c00762825 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.0.1/app1.json +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.0.1/app1.json @@ -307,6 +307,9 @@ "CSTNode": { "type": "object", "properties": { + "description": { + "type": "string" + }, "empty": { "type": "boolean" }, @@ -325,18 +328,15 @@ "type": "integer", "format": "int32" }, + "anExpression": { + "type": "boolean" + }, "meaning": { "type": "integer", "format": "int32" }, "rootText": { "type": "string" - }, - "anExpression": { - "type": "boolean" - }, - "description": { - "type": "string" } } }, @@ -361,9 +361,6 @@ "$ref": "#/components/schemas/CachedMethod" } }, - "cachedSuperClass": { - "$ref": "#/components/schemas/CachedClass" - }, "hierarchy": { "type": "array", "items": { @@ -424,13 +421,12 @@ "void": { "type": "boolean" }, - "superClassDistance": { - "type": "integer", - "format": "int32" - }, "typeDescription": { "type": "string" }, + "cachedSuperClass": { + "$ref": "#/components/schemas/CachedClass" + }, "newMetaMethods": { "type": "array", "items": { @@ -439,6 +435,10 @@ }, "callSiteLoader": { "$ref": "#/components/schemas/CallSiteClassLoader" + }, + "superClassDistance": { + "type": "integer", + "format": "int32" } } }, @@ -1490,13 +1490,37 @@ } } }, + "name": { + "type": "string" + }, "modifiers": { "type": "integer", "format": "int32" }, + "synthetic": { + "type": "boolean" + }, "cachedClass": { "$ref": "#/components/schemas/CachedClass" }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" + }, "vargsMethod": { "type": "boolean" } @@ -1512,12 +1536,6 @@ "type": "integer", "format": "int32" }, - "final": { - "type": "boolean" - }, - "static": { - "type": "boolean" - }, "cachedField": { "type": "object", "properties": { @@ -1584,6 +1602,27 @@ } } } + }, + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" } } }, @@ -2187,9 +2226,6 @@ "synthetic": { "type": "boolean" }, - "static": { - "type": "boolean" - }, "declaringClass": { "$ref": "#/components/schemas/CachedClass" }, @@ -2200,22 +2236,31 @@ "paramTypes": { "$ref": "#/components/schemas/ParameterTypes" }, - "public": { + "default": { "type": "boolean" }, - "protected": { + "abstract": { "type": "boolean" }, - "default": { + "cacheable": { "type": "boolean" }, - "abstract": { + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { "type": "boolean" }, "private": { "type": "boolean" }, - "cacheable": { + "packagePrivate": { "type": "boolean" }, "vargsMethod": { @@ -2600,11 +2645,11 @@ "cachedClass": { "$ref": "#/components/schemas/CachedClass" }, - "modifiedExpando": { - "$ref": "#/components/schemas/ExpandoMetaClass" - }, "metaClassForClass": { "$ref": "#/components/schemas/MetaClass" + }, + "modifiedExpando": { + "$ref": "#/components/schemas/ExpandoMetaClass" } } }, @@ -2991,9 +3036,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": { @@ -3028,41 +3070,18 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": { - "$ref": "#/components/schemas/ModuleNode" - }, - "compileUnit": { - "$ref": "#/components/schemas/CompileUnit" - }, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": { "$ref": "#/components/schemas/ClassNode" }, - "innerClasses": { - "type": "object" - }, "permittedSubclasses": { "type": "array", "items": { "$ref": "#/components/schemas/ClassNode" } }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -3075,8 +3094,11 @@ "redirect": { "$ref": "#/components/schemas/ClassNode" }, - "annotated": { - "type": "boolean" + "innerClasses": { + "type": "object" + }, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -3084,8 +3106,29 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } + }, + "module": { + "$ref": "#/components/schemas/ModuleNode" }, "interface": { "type": "boolean" @@ -3126,23 +3169,26 @@ "text": { "type": "string" }, - "redirectNode": { - "type": "boolean" + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit" }, "outerClass": { "$ref": "#/components/schemas/ClassNode" }, - "allInterfaces": { - "uniqueItems": true, + "redirectNode": { + "type": "boolean" + }, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/ClassNode" + "$ref": "#/components/schemas/MethodNode" } }, - "allDeclaredMethods": { + "allInterfaces": { + "uniqueItems": true, "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/ClassNode" } }, "abstractMethods": { @@ -3154,6 +3200,9 @@ "genericsPlaceHolder": { "type": "boolean" }, + "plainNodeReference": { + "$ref": "#/components/schemas/ClassNode" + }, "primaryClassNode": { "type": "boolean" }, @@ -3166,30 +3215,18 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ClassNode" - } - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "plainNodeReference": { - "$ref": "#/components/schemas/ClassNode" - }, - "objectInitializerStatements": { + "outerClasses": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/ClassNode" } }, - "derivedFromGroovyObject": { - "type": "boolean" - }, "unresolvedSuperClass": { "$ref": "#/components/schemas/ClassNode" }, @@ -3199,13 +3236,15 @@ "$ref": "#/components/schemas/ClassNode" } }, - "recordComponentNodes": { + "objectInitializerStatements": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/Statement" } }, + "derivedFromGroovyObject": { + "type": "boolean" + }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -3686,16 +3725,16 @@ "scriptBody": { "type": "boolean" }, + "annotationDefault": { + "type": "boolean", + "writeOnly": true + }, "firstStatement": { "$ref": "#/components/schemas/Statement" }, "staticConstructor": { "type": "boolean" }, - "annotationDefault": { - "type": "boolean", - "writeOnly": true - }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -3735,13 +3774,13 @@ "configuration": { "$ref": "#/components/schemas/CompilerConfiguration" }, - "lastError": { - "$ref": "#/components/schemas/Message" - }, "errorCount": { "type": "integer", "format": "int32" }, + "lastError": { + "$ref": "#/components/schemas/Message" + }, "warningCount": { "type": "integer", "format": "int32" @@ -5112,6 +5151,12 @@ "enum": { "type": "boolean" }, + "initialExpression": { + "$ref": "#/components/schemas/Expression" + }, + "inStaticContext": { + "type": "boolean" + }, "final": { "type": "boolean" }, @@ -5130,15 +5175,8 @@ "private": { "type": "boolean" }, - "initialExpression": { - "$ref": "#/components/schemas/Expression" - }, - "inStaticContext": { - "type": "boolean" - }, "closureSharedVariable": { - "type": "boolean", - "deprecated": true + "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" @@ -5744,9 +5782,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": { @@ -5775,41 +5810,12 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": { - "$ref": "#/components/schemas/ModuleNode" - }, - "compileUnit": { - "$ref": "#/components/schemas/CompileUnit" - }, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": { "$ref": "#/components/schemas/ClassNode" }, - "innerClasses": { - "type": "object" - }, - "permittedSubclasses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ClassNode" - } - }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -5822,8 +5828,11 @@ "redirect": { "$ref": "#/components/schemas/ClassNode" }, - "annotated": { - "type": "boolean" + "innerClasses": { + "type": "object" + }, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -5831,8 +5840,26 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } }, "outerClass": { "$ref": "#/components/schemas/ClassNode" @@ -5840,11 +5867,14 @@ "anonymous": { "type": "boolean" }, + "variableScope": { + "$ref": "#/components/schemas/VariableScope" + }, "outerMostClass": { "$ref": "#/components/schemas/ClassNode" }, - "variableScope": { - "$ref": "#/components/schemas/VariableScope" + "module": { + "$ref": "#/components/schemas/ModuleNode" }, "interface": { "type": "boolean" @@ -5885,20 +5915,23 @@ "text": { "type": "string" }, + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit" + }, "redirectNode": { "type": "boolean" }, - "allInterfaces": { - "uniqueItems": true, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/ClassNode" + "$ref": "#/components/schemas/MethodNode" } }, - "allDeclaredMethods": { + "allInterfaces": { + "uniqueItems": true, "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/ClassNode" } }, "abstractMethods": { @@ -5910,6 +5943,9 @@ "genericsPlaceHolder": { "type": "boolean" }, + "plainNodeReference": { + "$ref": "#/components/schemas/ClassNode" + }, "primaryClassNode": { "type": "boolean" }, @@ -5922,30 +5958,18 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ClassNode" - } - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "plainNodeReference": { - "$ref": "#/components/schemas/ClassNode" - }, - "objectInitializerStatements": { + "outerClasses": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/ClassNode" } }, - "derivedFromGroovyObject": { - "type": "boolean" - }, "unresolvedSuperClass": { "$ref": "#/components/schemas/ClassNode" }, @@ -5955,13 +5979,15 @@ "$ref": "#/components/schemas/ClassNode" } }, - "recordComponentNodes": { + "objectInitializerStatements": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/Statement" } }, + "derivedFromGroovyObject": { + "type": "boolean" + }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -6065,28 +6091,37 @@ "descriptor": { "type": "string" }, - "static": { - "type": "boolean" - }, "declaringClass": { "$ref": "#/components/schemas/CachedClass" }, - "public": { + "default": { "type": "boolean" }, - "protected": { + "abstract": { "type": "boolean" }, - "default": { + "cacheable": { "type": "boolean" }, - "abstract": { + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { "type": "boolean" }, "private": { "type": "boolean" }, - "cacheable": { + "packagePrivate": { "type": "boolean" }, "vargsMethod": { @@ -6110,6 +6145,27 @@ "modifiers": { "type": "integer", "format": "int32" + }, + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" } } }, @@ -6229,16 +6285,16 @@ "scriptBody": { "type": "boolean" }, + "annotationDefault": { + "type": "boolean", + "writeOnly": true + }, "firstStatement": { "$ref": "#/components/schemas/Statement" }, "staticConstructor": { "type": "boolean" }, - "annotationDefault": { - "type": "boolean", - "writeOnly": true - }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -6304,9 +6360,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": { @@ -6335,41 +6388,18 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": { - "$ref": "#/components/schemas/ModuleNode" - }, - "compileUnit": { - "$ref": "#/components/schemas/CompileUnit" - }, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": { "$ref": "#/components/schemas/ClassNode" }, - "innerClasses": { - "type": "object" - }, "permittedSubclasses": { "type": "array", "items": { "$ref": "#/components/schemas/ClassNode" } }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -6382,8 +6412,11 @@ "redirect": { "$ref": "#/components/schemas/ClassNode" }, - "annotated": { - "type": "boolean" + "innerClasses": { + "type": "object" + }, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -6391,8 +6424,29 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } + }, + "module": { + "$ref": "#/components/schemas/ModuleNode" }, "interface": { "type": "boolean" @@ -6433,23 +6487,26 @@ "text": { "type": "string" }, - "redirectNode": { - "type": "boolean" + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit" }, "outerClass": { "$ref": "#/components/schemas/ClassNode" }, - "allInterfaces": { - "uniqueItems": true, + "redirectNode": { + "type": "boolean" + }, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/ClassNode" + "$ref": "#/components/schemas/MethodNode" } }, - "allDeclaredMethods": { + "allInterfaces": { + "uniqueItems": true, "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/ClassNode" } }, "abstractMethods": { @@ -6461,6 +6518,9 @@ "genericsPlaceHolder": { "type": "boolean" }, + "plainNodeReference": { + "$ref": "#/components/schemas/ClassNode" + }, "primaryClassNode": { "type": "boolean" }, @@ -6473,30 +6533,18 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ClassNode" - } - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "plainNodeReference": { - "$ref": "#/components/schemas/ClassNode" - }, - "objectInitializerStatements": { + "outerClasses": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/ClassNode" } }, - "derivedFromGroovyObject": { - "type": "boolean" - }, "unresolvedSuperClass": { "$ref": "#/components/schemas/ClassNode" }, @@ -6506,13 +6554,15 @@ "$ref": "#/components/schemas/ClassNode" } }, - "recordComponentNodes": { + "objectInitializerStatements": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/Statement" } }, + "derivedFromGroovyObject": { + "type": "boolean" + }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -6766,12 +6816,36 @@ "type": "integer", "format": "int32" }, + "implicit": { + "type": "boolean" + }, + "receiver": { + "type": "boolean" + }, "initialExpression": { "$ref": "#/components/schemas/Expression" }, "closureSharedVariable": { "type": "boolean" }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "volatile": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, @@ -6847,6 +6921,10 @@ "field": { "$ref": "#/components/schemas/FieldNode" }, + "modifiers": { + "type": "integer", + "format": "int32" + }, "getterBlock": { "$ref": "#/components/schemas/Statement" }, @@ -6859,46 +6937,50 @@ "setterName": { "type": "string" }, - "modifiers": { - "type": "integer", - "format": "int32" - }, "type": { "$ref": "#/components/schemas/ClassNode" }, "name": { "type": "string" }, - "static": { - "type": "boolean" - }, - "public": { - "type": "boolean" - }, - "private": { - "type": "boolean" - }, "dynamicTyped": { "type": "boolean" }, "originType": { "$ref": "#/components/schemas/ClassNode" }, + "initialExpression": { + "$ref": "#/components/schemas/Expression" + }, + "inStaticContext": { + "type": "boolean" + }, "getterNameOrDefault": { "type": "string" }, "setterNameOrDefault": { "type": "string" }, - "initialExpression": { - "$ref": "#/components/schemas/Expression" + "final": { + "type": "boolean" }, - "inStaticContext": { + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "volatile": { + "type": "boolean" + }, + "private": { "type": "boolean" }, "closureSharedVariable": { - "type": "boolean", - "deprecated": true + "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" @@ -7015,6 +7097,9 @@ "anExpression": { "type": "boolean" }, + "description": { + "type": "string" + }, "type": { "type": "integer", "format": "int32" @@ -7033,9 +7118,6 @@ }, "rootText": { "type": "string" - }, - "description": { - "type": "string" } } }, @@ -7155,14 +7237,14 @@ "rootText": { "type": "string" }, + "description": { + "type": "string" + }, "empty": { "type": "boolean" }, "anExpression": { "type": "boolean" - }, - "description": { - "type": "string" } } }, @@ -7176,9 +7258,27 @@ "type": "integer", "format": "int32" }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, "type": { "$ref": "#/components/schemas/ClassNode" }, + "volatile": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, "dynamicTyped": { "type": "boolean" }, @@ -7223,9 +7323,6 @@ "root": { "type": "boolean" }, - "declaredVariablesIterator": { - "type": "object" - }, "referencedLocalVariablesCount": { "type": "integer", "format": "int32" @@ -7235,6 +7332,9 @@ }, "referencedClassVariablesIterator": { "type": "object" + }, + "declaredVariablesIterator": { + "type": "object" } } }, @@ -7251,4 +7351,4 @@ } } } -} +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.1.0/app1.json b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.1.0/app1.json index 2b05ad912..2ce193ff3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.1.0/app1.json +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/src/test/resources/results/3.1.0/app1.json @@ -141,13 +141,13 @@ "type": "boolean" }, "instance": {}, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -286,6 +286,9 @@ "CSTNode": { "type": "object", "properties": { + "description": { + "type": "string" + }, "empty": { "type": "boolean" }, @@ -296,25 +299,22 @@ "type": "integer", "format": "int32" }, - "meaning": { + "startLine": { "type": "integer", "format": "int32" }, - "rootText": { - "type": "string" + "startColumn": { + "type": "integer", + "format": "int32" }, "anExpression": { "type": "boolean" }, - "startLine": { - "type": "integer", - "format": "int32" - }, - "startColumn": { + "meaning": { "type": "integer", "format": "int32" }, - "description": { + "rootText": { "type": "string" } } @@ -340,7 +340,6 @@ "$ref": "#/components/schemas/CachedMethod" } }, - "cachedSuperClass": {}, "hierarchy": { "type": "array", "items": { @@ -398,6 +397,7 @@ "typeDescription": { "type": "string" }, + "cachedSuperClass": {}, "newMetaMethods": { "type": "array", "items": {} @@ -1327,11 +1327,35 @@ } } }, + "name": { + "type": "string" + }, "modifiers": { "type": "integer", "format": "int32" }, + "synthetic": { + "type": "boolean" + }, "cachedClass": {}, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" + }, "vargsMethod": { "type": "boolean" } @@ -1347,12 +1371,6 @@ "type": "integer", "format": "int32" }, - "final": { - "type": "boolean" - }, - "static": { - "type": "boolean" - }, "cachedField": { "type": "object", "properties": { @@ -1411,6 +1429,27 @@ "items": {} } } + }, + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" } } }, @@ -1938,9 +1977,6 @@ "synthetic": { "type": "boolean" }, - "static": { - "type": "boolean" - }, "declaringClass": {}, "paramsCount": { "type": "integer", @@ -1949,22 +1985,31 @@ "paramTypes": { "$ref": "#/components/schemas/ParameterTypes" }, - "public": { + "default": { "type": "boolean" }, - "protected": { + "abstract": { "type": "boolean" }, - "default": { + "cacheable": { "type": "boolean" }, - "abstract": { + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { "type": "boolean" }, "private": { "type": "boolean" }, - "cacheable": { + "packagePrivate": { "type": "boolean" }, "vargsMethod": { @@ -2319,13 +2364,13 @@ "weakMetaClass": { "$ref": "#/components/schemas/MetaClass" }, + "cachedClass": {}, "metaClassForClass": { "$ref": "#/components/schemas/MetaClass" }, "modifiedExpando": { "$ref": "#/components/schemas/ExpandoMetaClass" - }, - "cachedClass": {} + } } }, "ClassLoaderForClassArtifacts": { @@ -2679,9 +2724,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": {} @@ -2714,37 +2756,16 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": { - "$ref": "#/components/schemas/ModuleNode" - }, - "compileUnit": { - "$ref": "#/components/schemas/CompileUnit" - }, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": {}, - "innerClasses": {}, "permittedSubclasses": { "type": "array", "items": { "$ref": "#/components/schemas/ClassNode" } }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -2755,8 +2776,9 @@ "redirect": { "writeOnly": true }, - "annotated": { - "type": "boolean" + "innerClasses": {}, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -2764,8 +2786,29 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } + }, + "module": { + "$ref": "#/components/schemas/ModuleNode" }, "interface": { "type": "boolean" @@ -2806,25 +2849,29 @@ "text": { "type": "string" }, - "unresolvedSuperClass": {}, - "objectInitializerStatements": { + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit", + "deprecated": true + }, + "outerClass": {}, + "redirectNode": { + "type": "boolean" + }, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/MethodNode" } }, - "unresolvedInterfaces": { + "allInterfaces": { "type": "array", - "items": {} - }, - "derivedFromGroovyObject": { - "type": "boolean" + "items": {}, + "uniqueItems": true }, - "recordComponentNodes": { + "abstractMethods": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/MethodNode" } }, "genericsPlaceHolder": { @@ -2843,47 +2890,40 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": {} - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "abstractMethods": { + "outerClasses": { "type": "array", - "items": { - "$ref": "#/components/schemas/MethodNode" - } + "items": {} }, - "allInterfaces": { + "unresolvedSuperClass": {}, + "unresolvedInterfaces": { "type": "array", - "items": {}, - "uniqueItems": true + "items": {} }, - "allDeclaredMethods": { + "objectInitializerStatements": { "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/Statement" } }, - "outerClass": {}, - "redirectNode": { + "derivedFromGroovyObject": { "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -3190,11 +3230,7 @@ "bytecodePostprocessor": { "$ref": "#/components/schemas/BytecodeProcessor" }, - "targetBytecodeIfValid": { - "type": "string", - "writeOnly": true - }, - "runtimeGroovydocEnabled": { + "indyEnabled": { "type": "boolean" }, "targetDirectorySafe": { @@ -3215,7 +3251,11 @@ "groovydocEnabled": { "type": "boolean" }, - "indyEnabled": { + "targetBytecodeIfValid": { + "type": "string", + "writeOnly": true + }, + "runtimeGroovydocEnabled": { "type": "boolean" } } @@ -3319,6 +3359,15 @@ "text": { "type": "string" }, + "voidMethod": { + "type": "boolean" + }, + "packageScope": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, "annotationDefault": { "type": "boolean", "writeOnly": true @@ -3329,25 +3378,16 @@ "staticConstructor": { "type": "boolean" }, - "voidMethod": { - "type": "boolean" - }, - "packageScope": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -3376,14 +3416,14 @@ "configuration": { "$ref": "#/components/schemas/CompilerConfiguration" }, - "warningCount": { + "errorCount": { "type": "integer", "format": "int32" }, "lastError": { "$ref": "#/components/schemas/Message" }, - "errorCount": { + "warningCount": { "type": "integer", "format": "int32" } @@ -3440,6 +3480,10 @@ "type": "integer", "format": "int32" }, + "groovyObject": { + "type": "boolean" + }, + "classInfo": {}, "upProperties": { "type": "array", "items": { @@ -4472,11 +4516,7 @@ } }, "writeOnly": true - }, - "groovyObject": { - "type": "boolean" - }, - "classInfo": {} + } } }, "Expression": { @@ -4510,13 +4550,13 @@ "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -4585,6 +4625,12 @@ "enum": { "type": "boolean" }, + "initialExpression": { + "$ref": "#/components/schemas/Expression" + }, + "inStaticContext": { + "type": "boolean" + }, "final": { "type": "boolean" }, @@ -4604,25 +4650,18 @@ "type": "boolean" }, "closureSharedVariable": { - "type": "boolean", - "deprecated": true - }, - "initialExpression": { - "$ref": "#/components/schemas/Expression" - }, - "inStaticContext": { "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -5103,13 +5142,13 @@ "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -5160,9 +5199,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": {} @@ -5189,33 +5225,10 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": {}, - "compileUnit": {}, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": {}, - "innerClasses": {}, - "permittedSubclasses": { - "type": "array", - "items": { - "$ref": "#/components/schemas/ClassNode" - } - }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -5226,8 +5239,9 @@ "redirect": { "writeOnly": true }, - "annotated": { - "type": "boolean" + "innerClasses": {}, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -5235,17 +5249,36 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } }, "outerClass": {}, "anonymous": { "type": "boolean" }, - "outerMostClass": {}, "variableScope": { "$ref": "#/components/schemas/VariableScope" }, + "outerMostClass": {}, + "module": {}, "interface": { "type": "boolean" }, @@ -5285,25 +5318,28 @@ "text": { "type": "string" }, - "unresolvedSuperClass": {}, - "objectInitializerStatements": { + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit", + "deprecated": true + }, + "redirectNode": { + "type": "boolean" + }, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/MethodNode" } }, - "unresolvedInterfaces": { + "allInterfaces": { "type": "array", - "items": {} - }, - "derivedFromGroovyObject": { - "type": "boolean" + "items": {}, + "uniqueItems": true }, - "recordComponentNodes": { + "abstractMethods": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/MethodNode" } }, "genericsPlaceHolder": { @@ -5322,46 +5358,40 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": {} - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "abstractMethods": { + "outerClasses": { "type": "array", - "items": { - "$ref": "#/components/schemas/MethodNode" - } + "items": {} }, - "allInterfaces": { + "unresolvedSuperClass": {}, + "unresolvedInterfaces": { "type": "array", - "items": {}, - "uniqueItems": true + "items": {} }, - "allDeclaredMethods": { + "objectInitializerStatements": { "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/Statement" } }, - "redirectNode": { + "derivedFromGroovyObject": { "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -5410,18 +5440,18 @@ "MetaClassRegistry": { "type": "object", "properties": { - "metaClassRegistryChangeEventListeners": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MetaClassRegistryChangeEventListener" - } - }, "metaClassCreationHandler": { "$ref": "#/components/schemas/MetaClassCreationHandle" }, "metaClassCreationHandle": { "$ref": "#/components/schemas/MetaClassCreationHandle", "writeOnly": true + }, + "metaClassRegistryChangeEventListeners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MetaClassRegistryChangeEventListener" + } } } }, @@ -5451,28 +5481,40 @@ "descriptor": { "type": "string" }, - "static": { - "type": "boolean" - }, "declaringClass": { "$ref": "#/components/schemas/CachedClass" }, - "public": { + "default": { "type": "boolean" }, - "protected": { + "abstract": { "type": "boolean" }, - "default": { + "cacheable": { "type": "boolean" }, - "abstract": { + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { "type": "boolean" }, "private": { "type": "boolean" }, - "cacheable": { + "packagePrivate": { + "type": "boolean" + }, + "vargsMethod": { "type": "boolean" }, "parametersTypes": { @@ -5481,9 +5523,6 @@ "$ref": "#/components/schemas/CachedClass" }, "writeOnly": true - }, - "vargsMethod": { - "type": "boolean" } } }, @@ -5496,6 +5535,27 @@ "modifiers": { "type": "integer", "format": "int32" + }, + "synthetic": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "packagePrivate": { + "type": "boolean" } } }, @@ -5598,6 +5658,15 @@ "text": { "type": "string" }, + "voidMethod": { + "type": "boolean" + }, + "packageScope": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, "annotationDefault": { "type": "boolean", "writeOnly": true @@ -5608,25 +5677,16 @@ "staticConstructor": { "type": "boolean" }, - "voidMethod": { - "type": "boolean" - }, - "packageScope": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -5677,9 +5737,6 @@ "type": "integer", "format": "int32" }, - "syntheticPublic": { - "type": "boolean" - }, "interfaces": { "type": "array", "items": {} @@ -5706,37 +5763,16 @@ "type": "object", "additionalProperties": { "$ref": "#/components/schemas/FieldNode" - } - }, - "module": { - "$ref": "#/components/schemas/ModuleNode" - }, - "compileUnit": { - "$ref": "#/components/schemas/CompileUnit" - }, - "staticClass": { - "type": "boolean" - }, - "scriptBody": { - "type": "boolean" - }, - "script": { - "type": "boolean" + }, + "deprecated": true }, "superClass": {}, - "innerClasses": {}, "permittedSubclasses": { "type": "array", "items": { "$ref": "#/components/schemas/ClassNode" } }, - "typeAnnotations": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AnnotationNode" - } - }, "recordComponents": { "type": "array", "items": { @@ -5747,8 +5783,9 @@ "redirect": { "writeOnly": true }, - "annotated": { - "type": "boolean" + "innerClasses": {}, + "enclosingMethod": { + "$ref": "#/components/schemas/MethodNode" }, "genericsTypes": { "type": "array", @@ -5756,8 +5793,29 @@ "$ref": "#/components/schemas/GenericsType" } }, - "enclosingMethod": { - "$ref": "#/components/schemas/MethodNode" + "script": { + "type": "boolean" + }, + "scriptBody": { + "type": "boolean" + }, + "staticClass": { + "type": "boolean" + }, + "syntheticPublic": { + "type": "boolean" + }, + "annotated": { + "type": "boolean" + }, + "typeAnnotations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AnnotationNode" + } + }, + "module": { + "$ref": "#/components/schemas/ModuleNode" }, "interface": { "type": "boolean" @@ -5798,25 +5856,29 @@ "text": { "type": "string" }, - "unresolvedSuperClass": {}, - "objectInitializerStatements": { + "compileUnit": { + "$ref": "#/components/schemas/CompileUnit", + "deprecated": true + }, + "outerClass": {}, + "redirectNode": { + "type": "boolean" + }, + "allDeclaredMethods": { "type": "array", "items": { - "$ref": "#/components/schemas/Statement" + "$ref": "#/components/schemas/MethodNode" } }, - "unresolvedInterfaces": { + "allInterfaces": { "type": "array", - "items": {} - }, - "derivedFromGroovyObject": { - "type": "boolean" + "items": {}, + "uniqueItems": true }, - "recordComponentNodes": { + "abstractMethods": { "type": "array", - "deprecated": true, "items": { - "$ref": "#/components/schemas/RecordComponentNode" + "$ref": "#/components/schemas/MethodNode" } }, "genericsPlaceHolder": { @@ -5835,47 +5897,40 @@ "$ref": "#/components/schemas/MethodNode" } }, - "outerClasses": { - "type": "array", - "items": {} - }, "nameWithoutPackage": { "type": "string" }, "annotationDefinition": { "type": "boolean" }, - "abstractMethods": { + "outerClasses": { "type": "array", - "items": { - "$ref": "#/components/schemas/MethodNode" - } + "items": {} }, - "allInterfaces": { + "unresolvedSuperClass": {}, + "unresolvedInterfaces": { "type": "array", - "items": {}, - "uniqueItems": true + "items": {} }, - "allDeclaredMethods": { + "objectInitializerStatements": { "type": "array", "items": { - "$ref": "#/components/schemas/MethodNode" + "$ref": "#/components/schemas/Statement" } }, - "outerClass": {}, - "redirectNode": { + "derivedFromGroovyObject": { "type": "boolean" }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -5971,10 +6026,10 @@ "context": { "$ref": "#/components/schemas/SourceUnit" }, + "scriptClassDummy": {}, "scriptBaseClassFromConfig": { "writeOnly": true }, - "scriptClassDummy": {}, "text": { "type": "string" }, @@ -6030,13 +6085,13 @@ "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "sourcePosition": { "$ref": "#/components/schemas/ASTNode", "writeOnly": true @@ -6098,22 +6153,46 @@ "type": "integer", "format": "int32" }, - "closureSharedVariable": { + "implicit": { + "type": "boolean" + }, + "receiver": { "type": "boolean" }, "initialExpression": { "$ref": "#/components/schemas/Expression" }, + "closureSharedVariable": { + "type": "boolean" + }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "volatile": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -6172,6 +6251,10 @@ "field": { "$ref": "#/components/schemas/FieldNode" }, + "modifiers": { + "type": "integer", + "format": "int32" + }, "getterBlock": { "$ref": "#/components/schemas/Statement" }, @@ -6184,53 +6267,57 @@ "setterName": { "type": "string" }, - "modifiers": { - "type": "integer", - "format": "int32" - }, "type": {}, "name": { "type": "string" }, - "static": { + "dynamicTyped": { "type": "boolean" }, - "public": { - "type": "boolean" + "originType": {}, + "initialExpression": { + "$ref": "#/components/schemas/Expression" }, - "private": { + "inStaticContext": { "type": "boolean" }, - "closureSharedVariable": { - "type": "boolean", - "deprecated": true - }, "getterNameOrDefault": { "type": "string" }, "setterNameOrDefault": { "type": "string" }, - "initialExpression": { - "$ref": "#/components/schemas/Expression" + "final": { + "type": "boolean" }, - "inStaticContext": { + "static": { "type": "boolean" }, - "dynamicTyped": { + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, + "volatile": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "closureSharedVariable": { "type": "boolean" }, - "originType": {}, "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -6294,13 +6381,13 @@ "instance": { "$ref": "#/components/schemas/AnnotatedNode" }, + "groovydoc": { + "$ref": "#/components/schemas/Groovydoc" + }, "hasNoRealSourcePosition": { "type": "boolean", "writeOnly": true }, - "groovydoc": { - "$ref": "#/components/schemas/Groovydoc" - }, "text": { "type": "string" }, @@ -6326,26 +6413,26 @@ "anExpression": { "type": "boolean" }, + "description": { + "type": "string" + }, "type": { "type": "integer", "format": "int32" }, - "meaning": { + "startLine": { "type": "integer", "format": "int32" }, - "rootText": { - "type": "string" - }, - "startLine": { + "startColumn": { "type": "integer", "format": "int32" }, - "startColumn": { + "meaning": { "type": "integer", "format": "int32" }, - "description": { + "rootText": { "type": "string" } } @@ -6459,14 +6546,14 @@ "rootText": { "type": "string" }, + "description": { + "type": "string" + }, "empty": { "type": "boolean" }, "anExpression": { "type": "boolean" - }, - "description": { - "type": "string" } } }, @@ -6480,20 +6567,38 @@ "type": "integer", "format": "int32" }, + "final": { + "type": "boolean" + }, + "static": { + "type": "boolean" + }, + "public": { + "type": "boolean" + }, + "protected": { + "type": "boolean" + }, "type": {}, - "closureSharedVariable": { + "volatile": { + "type": "boolean" + }, + "private": { + "type": "boolean" + }, + "dynamicTyped": { "type": "boolean" }, + "originType": {}, "initialExpression": { "$ref": "#/components/schemas/Expression" }, "inStaticContext": { "type": "boolean" }, - "dynamicTyped": { + "closureSharedVariable": { "type": "boolean" - }, - "originType": {} + } } }, "VariableScope": { @@ -6541,4 +6646,4 @@ } } } -} +} \ No newline at end of file diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 0f61eee5c..51e4f4e3e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -30,6 +30,11 @@ h2 test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index c8d201c91..9bdf875b0 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index d1bacf084..2015dea9c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 527b11947..4d3f1ecf3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -33,6 +33,11 @@ money-api test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 292bde79a..79c7ce5a5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java index 953c32ce1..2c89c9814 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app1/InventoryApiController.java @@ -28,12 +28,12 @@ import java.util.List; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app172/JavadocPropertyCustomizerTest.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app172/JavadocPropertyCustomizerTest.java index 8972831a9..51eca7b4a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app172/JavadocPropertyCustomizerTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v30/app172/JavadocPropertyCustomizerTest.java @@ -89,7 +89,7 @@ void setup() { @Nested class setJavadocDescription { @Test - @EnabledForJreRange(min = JRE.JAVA_17) + @EnabledForJreRange(min = JRE.JAVA_17, max = JRE.JAVA_26) void ifRecordObjectShouldGetField() throws IOException, ClassNotFoundException, IntrospectionException { File recordObject = new File(tempDir, "RecordObject.java"); try (PrintWriter writer = new PrintWriter(new FileWriter(recordObject))) { diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index 43bc8b281..316274360 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -35,8 +35,8 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java index 7d327375a..4c5a6ac6f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app1/InventoryApiController.java @@ -28,12 +28,12 @@ import java.util.List; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.v3.oas.annotations.Parameter; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app172/JavadocPropertyCustomizerTest.java b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app172/JavadocPropertyCustomizerTest.java index ce4f24f76..620a335b2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app172/JavadocPropertyCustomizerTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/src/test/java/test/org/springdoc/api/v31/app172/JavadocPropertyCustomizerTest.java @@ -89,7 +89,7 @@ void setup() { @Nested class setJavadocDescription { @Test - @EnabledForJreRange(min = JRE.JAVA_17) + @EnabledForJreRange(min = JRE.JAVA_17, max = JRE.JAVA_26) void ifRecordObjectShouldGetField() throws IOException, ClassNotFoundException, IntrospectionException { File recordObject = new File(tempDir, "RecordObject.java"); try (PrintWriter writer = new PrintWriter(new FileWriter(recordObject))) { diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 76e14c215..923882a0b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -35,6 +35,11 @@ spring-boot-starter-reactor-netty test + + org.springframework.boot + spring-boot-starter-webflux-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 3a452543e..beb335daa 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -37,7 +37,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index dfbac974f..6e55e4c87 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -37,7 +37,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest; +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt index b4e83808c..ad749605a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt @@ -31,8 +31,8 @@ import org.skyscreamer.jsonassert.JSONAssert import org.slf4j.LoggerFactory import org.springdoc.core.utils.Constants import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import org.springframework.test.web.reactive.server.WebTestClient diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt index 51c1660e8..9e596a4e5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt @@ -31,8 +31,8 @@ import org.skyscreamer.jsonassert.JSONAssert import org.slf4j.LoggerFactory import org.springdoc.core.utils.Constants import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient -import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest +import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest +import org.springframework.boot.webtestclient.AutoConfigureWebTestClient import org.springframework.test.context.ActiveProfiles import org.springframework.test.web.reactive.server.WebTestClient import java.nio.charset.StandardCharsets diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 1a8418245..4b4fd12d9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -30,6 +30,11 @@ jakarta.servlet-api test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocMVCTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocMVCTest.kt index 127784ef9..571544110 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocMVCTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocMVCTest.kt @@ -30,8 +30,8 @@ import org.junit.jupiter.api.Test import org.skyscreamer.jsonassert.JSONAssert import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import org.springframework.test.web.servlet.MockMvc diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocMVCTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocMVCTest.kt index dcc6a839e..512d70628 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocMVCTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocMVCTest.kt @@ -30,8 +30,8 @@ import org.junit.jupiter.api.Test import org.skyscreamer.jsonassert.JSONAssert import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc import org.springframework.test.context.ActiveProfiles import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.request.MockMvcRequestBuilders diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt index af0bd3c61..3b216179e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/src/test/kotlin/test/org/springdoc/api/v31/app22/SpringDocApp22Test.kt @@ -19,14 +19,7 @@ package test.org.springdoc.api.v31.app22 import com.fasterxml.jackson.annotation.JsonUnwrapped -import io.swagger.v3.oas.annotations.Parameter -import io.swagger.v3.oas.annotations.enums.Explode -import io.swagger.v3.oas.annotations.media.ArraySchema -import io.swagger.v3.oas.annotations.media.Schema -import jakarta.validation.Valid -import org.springdoc.core.annotations.ParameterObject import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index fbd2fd2c5..03c020a65 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -39,5 +39,10 @@ jjwt test + + org.springframework.boot + spring-boot-starter-webmvc-test + test + diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index 6c931c2c8..f7703bddd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -36,9 +36,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index 3a23f2acc..cffac9c99 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -36,9 +36,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.servlet.MockMvc; From 15300ba6651fefb81a0af41f306a455cd5841708 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 31 Oct 2025 23:43:12 +0100 Subject: [PATCH 30/45] javadoc update --- .../api/AbstractOpenApiResource.java | 4 +-- .../configuration/SpringDocConfiguration.java | 13 +++++--- .../SpringDocHateoasConfiguration.java | 4 --- .../CollectionModelContentConverter.java | 5 --- .../converters/PolymorphicModelConverter.java | 10 ++++++ .../customizers/GlobalOpenApiCustomizer.java | 1 - .../GlobalOperationComponentsCustomizer.java | 2 +- .../GlobalOperationCustomizer.java | 1 - .../core/customizers/OpenApiCustomizer.java | 1 - .../core/customizers/OperationCustomizer.java | 1 - .../customizers/SpringDocCustomizers.java | 29 ++++++++++------- .../extractor/DelegatingMethodParameter.java | 6 ++-- .../MethodParameterPojoExtractor.java | 2 ++ .../filters/GlobalOpenApiMethodFilter.java | 1 - .../core/filters/OpenApiMethodFilter.java | 1 - .../core/service/AbstractRequestService.java | 8 ++--- .../core/service/GenericParameterService.java | 8 ++--- .../core/service/OpenAPIService.java | 32 +++++++++---------- .../core/utils/PropertyResolverUtils.java | 3 +- .../org/springdoc/core/utils/SchemaUtils.java | 14 ++++---- .../core/utils/SpringDocAnnotationsUtils.java | 9 ++++++ .../springdoc/core/utils/SpringDocUtils.java | 4 +++ .../core/utils/SpringSecurityUtils.java | 9 ++++++ .../webflux/api/OpenApiResource.java | 1 + .../scalar/ScalarActuatorController.java | 7 ++++ .../scalar/ScalarWebFluxController.java | 7 ++++ .../scalar/ScalarActuatorController.java | 7 ++++ .../webmvc/scalar/ScalarWebMvcController.java | 7 ++++ .../springdoc/api/v31/AbstractCommonTest.java | 22 +++++++++++++ 29 files changed, 150 insertions(+), 69 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index 21881a163..c08a1a735 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -354,7 +354,7 @@ protected OpenAPI getOpenApi(Locale locale) { * Gets open api. * * @param serverBaseUrl the server base url - * @param locale the locale + * @param locale the locale * @return the open api */ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { @@ -1023,7 +1023,7 @@ protected Set getDefaultAllowedHttpMethods() { * Customise operation. * * @param operation the operation - * @param components + * @param components the components * @param handlerMethod the handler method * @return the operation */ diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index cd8397d13..bfaf56a1a 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -191,6 +191,11 @@ static BeanFactoryPostProcessor springdocBeanFactoryPostProcessor2() { return SpringdocBeanFactoryConfigurer::initBeanFactoryPostProcessor; } + /** + * Init extra schemas object. + * + * @return the object + */ @Bean @Lazy(false) @ConditionalOnProperty(name = SPRINGDOC_ENABLE_EXTRA_SCHEMAS, matchIfMissing = true) @@ -386,10 +391,10 @@ SecurityService securityParser(PropertyResolverUtils propertyResolverUtils) { /** * Parameter builder generic parameter builder. * - * @param propertyResolverUtils the property resolver utils - * @param optionalWebConversionServiceProvider the optional web conversion service provider - * @param objectMapperProvider the object mapper provider - * @param javadocProvider the javadoc provider + * @param propertyResolverUtils the property resolver utils + * @param optionalWebConversionServiceProvider the optional web conversion service provider + * @param objectMapperProvider the object mapper provider + * @param javadocProvider the javadoc provider * @return the generic parameter builder */ @Bean diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java index abccc4996..867a2f9a8 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java @@ -28,8 +28,6 @@ import java.util.Optional; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; import org.springdoc.core.converters.CollectionModelContentConverter; import org.springdoc.core.converters.HateoasLinksConverter; import org.springdoc.core.customizers.GlobalOpenApiCustomizer; @@ -48,7 +46,6 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; -import org.springframework.hateoas.Links; import org.springframework.hateoas.server.LinkRelationProvider; /** @@ -99,7 +96,6 @@ CollectionModelContentConverter collectionModelContentConverter(HateoasHalProvid * @param halProvider the hal provider * @param springDocConfigProperties the spring doc config properties * @return the open api customizer - * @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider) org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalLinkListSerializer#serialize(Links, JsonGenerator, SerializerProvider) */ @Bean(Constants.LINKS_SCHEMA_CUSTOMIZER) @ConditionalOnMissingBean(name = Constants.LINKS_SCHEMA_CUSTOMIZER) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/CollectionModelContentConverter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/CollectionModelContentConverter.java index e630c06f0..8eb4e3850 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/CollectionModelContentConverter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/CollectionModelContentConverter.java @@ -26,11 +26,8 @@ package org.springdoc.core.converters; -import java.util.Collection; import java.util.Iterator; -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.type.CollectionType; import com.fasterxml.jackson.databind.type.TypeBindings; import io.swagger.v3.core.converter.AnnotatedType; @@ -48,8 +45,6 @@ * Override resolved schema as there is a custom serializer that converts the data to a map before serializing it. * * @author bnasslahsen - * @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer - * @see org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider) org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider)org.springframework.hateoas.mediatype.hal.Jackson2HalModule.HalResourcesSerializer#serialize(Collection, JsonGenerator, SerializerProvider) */ public class CollectionModelContentConverter implements ModelConverter { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java index 31ad67cd7..a334ace80 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/converters/PolymorphicModelConverter.java @@ -260,6 +260,10 @@ private record BeanPropertyBiDefinition( /** * Retrieves an annotation of the specified type from either the serialization or * deserialization property definition (field, getter, setter), returning the first available match. + * + * @param the type parameter + * @param acls the acls + * @return the any annotation */ public A getAnyAnnotation(Class acls) { A anyForSerializationAnnotation = getAnyAnnotation(forSerialization, acls); @@ -271,6 +275,10 @@ public A getAnyAnnotation(Class acls) { /** * Checks if any annotation of the specified type exists across serialization * or deserialization property definitions. + * + * @param the type parameter + * @param acls the acls + * @return the boolean */ public boolean isAnyAnnotated(Class acls) { return getAnyAnnotation(acls) != null; @@ -278,6 +286,8 @@ public boolean isAnyAnnotated(Class acls) { /** * Type determined from the primary member for the property being built. + * + * @return the primary type */ public JavaType getPrimaryType() { JavaType forSerializationType = null; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOpenApiCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOpenApiCustomizer.java index f0338854c..97e489d49 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOpenApiCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOpenApiCustomizer.java @@ -31,7 +31,6 @@ * customize Open api on default OpenAPI description and groups. * * @author christophejan - * @see OpenApiCustomizer default OpenAPI description but not groups */ public interface GlobalOpenApiCustomizer extends OpenApiCustomizer { } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationComponentsCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationComponentsCustomizer.java index 3e09a9e51..2fd5aaaf6 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationComponentsCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationComponentsCustomizer.java @@ -37,7 +37,6 @@ * description and groups * * @author christophejan - * @see OperationCustomizer operations on default OpenAPI description but not groups */ public interface GlobalOperationComponentsCustomizer extends GlobalOperationCustomizer { @@ -45,6 +44,7 @@ public interface GlobalOperationComponentsCustomizer extends GlobalOperationCust * Customize operation. * * @param operation input operation + * @param components the components * @param handlerMethod original handler method * @return customized operation */ diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java index 0793af2df..74b5ff54d 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/GlobalOperationCustomizer.java @@ -32,7 +32,6 @@ * description and groups * * @author christophejan - * @see OperationCustomizer operations on default OpenAPI description but not groups */ public interface GlobalOperationCustomizer extends OperationCustomizer { } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomizer.java index 40f0be199..609667004 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OpenApiCustomizer.java @@ -33,7 +33,6 @@ * Open api on default OpenAPI description but not on groups * * @author bnasslahsen - * @see GlobalOpenApiCustomizer default OpenAPI description and groups */ @FunctionalInterface public interface OpenApiCustomizer { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java index c52f16052..a2dc9cb48 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/OperationCustomizer.java @@ -36,7 +36,6 @@ * groups * * @author bnasslahsen - * @see GlobalOperationCustomizer operations on default OpenAPI description and groups */ @FunctionalInterface public interface OperationCustomizer { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java index eb30251a1..d5b503abd 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/SpringDocCustomizers.java @@ -104,17 +104,20 @@ public class SpringDocCustomizers implements ApplicationContextAware, Initializi * The Parameter customizers. */ private final Optional> parameterCustomizers; + /** * Instantiates a new Spring doc customizers. * - * @param openApiCustomizers the open api customizers - * @param operationCustomizers the operation customizers - * @param routerOperationCustomizers the router operation customizers - * @param dataRestRouterOperationCustomizers the data rest router operation customizers - * @param methodFilters the method filters - * @param globalOpenApiCustomizers the global open api customizers - * @param globalOperationCustomizers the global operation customizers - * @param globalOpenApiMethodFilters the global open api method filters + * @param openApiCustomizers the open api customizers + * @param operationCustomizers the operation customizers + * @param routerOperationCustomizers the router operation customizers + * @param dataRestRouterOperationCustomizers the data rest router operation customizers + * @param methodFilters the method filters + * @param globalOpenApiCustomizers the global open api customizers + * @param globalOperationCustomizers the global operation customizers + * @param globalOpenApiMethodFilters the global open api method filters + * @param optionalDelegatingMethodParameterCustomizers the optional delegating method parameter customizers + * @param parameterCustomizers the parameter customizers */ public SpringDocCustomizers(Optional> openApiCustomizers, Optional> operationCustomizers, @@ -139,10 +142,12 @@ public SpringDocCustomizers(Optional> openApiCustomizers, /** * Instantiates a new Spring doc customizers. * - * @param openApiCustomizers the open api customizers - * @param operationCustomizers the operation customizers - * @param routerOperationCustomizers the router operation customizers - * @param openApiMethodFilters the open api method filters + * @param openApiCustomizers the open api customizers + * @param operationCustomizers the operation customizers + * @param routerOperationCustomizers the router operation customizers + * @param openApiMethodFilters the open api method filters + * @param optionalDelegatingMethodParameterCustomizers the optional delegating method parameter customizers + * @param parameterCustomizers the parameter customizers */ public SpringDocCustomizers(Optional> openApiCustomizers, Optional> operationCustomizers, Optional> routerOperationCustomizers, Optional> openApiMethodFilters, Optional> optionalDelegatingMethodParameterCustomizers, Optional> parameterCustomizers) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java index 665481047..5b696010c 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/DelegatingMethodParameter.java @@ -112,6 +112,7 @@ public class DelegatingMethodParameter extends MethodParameter { * @param additionalParameterAnnotations the additional parameter annotations * @param methodAnnotations the method annotations * @param isParameterObject the is parameter object + * @param field the field * @param isNotRequired the is required */ DelegatingMethodParameter(MethodParameter delegate, String parameterName, Annotation[] additionalParameterAnnotations, Annotation[] methodAnnotations, boolean isParameterObject, Field field, boolean isNotRequired) { @@ -132,6 +133,7 @@ public class DelegatingMethodParameter extends MethodParameter { * @param parameters the parameters * @param optionalDelegatingMethodParameterCustomizers the optional list delegating method parameter customizer * @param methodParameterPojoExtractor the method parameter pojo extractor + * @param defaultFlatParamObject the default flat param object * @return the method parameter [ ] */ public static MethodParameter[] customize(String[] pNames, MethodParameter[] parameters, @@ -166,7 +168,7 @@ public static MethodParameter[] customize(String[] pNames, MethodParameter[] par * @param methodParameter the method parameter * @param containingClass a specific containing class (potentially a subclass of the declaring class, e.g. substituting a type variable) A copy of spring withContainingClass, to keep compatibility with older spring versions * @return the method parameter - * @see #getParameterType() #getParameterType()#getParameterType() + * @see #getParameterType() #getParameterType()#getParameterType()#getParameterType()#getParameterType() */ public static MethodParameter changeContainingClass(MethodParameter methodParameter, @Nullable Class containingClass) { MethodParameter result = methodParameter.clone(); @@ -308,7 +310,7 @@ public boolean isParameterObject() { * Gets field. If Is parameter object. then The Field should be not null * * @return the field - * @see #isParameterObject + * @see #isParameterObject #isParameterObject#isParameterObject */ @Nullable public Field getField() { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java index df103ed44..c0bf043bd 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/extractor/MethodParameterPojoExtractor.java @@ -127,6 +127,8 @@ public class MethodParameterPojoExtractor { /** * Instantiates a new Method parameter pojo extractor. + * + * @param schemaUtils the schema utils */ public MethodParameterPojoExtractor(SchemaUtils schemaUtils) { this.schemaUtils = schemaUtils; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java index 90a48fbfb..4580207be 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/GlobalOpenApiMethodFilter.java @@ -32,7 +32,6 @@ * and groups. * * @author michael.clarke - * @see OpenApiMethodFilter methods in default OpenAPI description but not groups */ @FunctionalInterface public interface GlobalOpenApiMethodFilter extends OpenApiMethodFilter { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java index 563278014..3dd0f3fd1 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/filters/OpenApiMethodFilter.java @@ -34,7 +34,6 @@ * but not groups * * @author michael.clarke - * @see GlobalOpenApiMethodFilter methods in default OpenAPI description and groups */ @FunctionalInterface public interface OpenApiMethodFilter { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 3e6718f12..0e6dcfe00 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -224,7 +224,7 @@ protected AbstractRequestService(GenericParameterService parameterBuilder, Reque this.defaultFlatParamObject = parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties().isDefaultFlatParamObject(); this.defaultSupportFormData = parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties().isDefaultSupportFormData(); } - + /** * Add request wrapper to ignore. * @@ -293,9 +293,9 @@ public static Collection getHeaders(MethodAttributes methodAttributes * @param methodAttributes the method attributes * @param openAPI the open api * @return the operation - * @see org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) - * @see ParameterCustomizer#customize(Parameter, MethodParameter) - * @see org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) + * @see org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) + * @see ParameterCustomizer#customize(Parameter, MethodParameter) ParameterCustomizer#customize(Parameter, MethodParameter) + * @see org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) */ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod, Operation operation, MethodAttributes methodAttributes, OpenAPI openAPI) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java index 60140a40e..ebb63f801 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java @@ -147,10 +147,10 @@ public class GenericParameterService { /** * Instantiates a new Generic parameter builder. * - * @param propertyResolverUtils the property resolver utils - * @param optionalWebConversionServiceProvider the optional web conversion service provider - * @param objectMapperProvider the object mapper provider - * @param javadocProviderOptional the javadoc provider + * @param propertyResolverUtils the property resolver utils + * @param optionalWebConversionServiceProvider the optional web conversion service provider + * @param objectMapperProvider the object mapper provider + * @param javadocProviderOptional the javadoc provider */ public GenericParameterService(PropertyResolverUtils propertyResolverUtils, Optional optionalWebConversionServiceProvider, ObjectMapperProvider objectMapperProvider, Optional javadocProviderOptional) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java index 3d356693b..9df03fd8b 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/OpenAPIService.java @@ -532,13 +532,13 @@ private Optional getOpenAPIDefinition() { } - /** - * Gets webhooks from given classes. - * - * @param classes Array of classes to scan for webhooks. - * @return An array of {@link Webhooks} annotations found in the given classes. - */ - public Webhooks[] getWebhooks(Class[] classes) { + /** + * Gets webhooks from given classes. + * + * @param classes Array of classes to scan for webhooks. + * @return An array of {@link Webhooks} annotations found in the given classes. + */ + public Webhooks[] getWebhooks(Class[] classes) { List allWebhooks = new ArrayList<>(); for (Class clazz : classes) { @@ -555,15 +555,15 @@ public Webhooks[] getWebhooks(Class[] classes) { } - /** - * Retrieves all classes related to webhooks. - * This method scans for classes annotated with {@link Webhooks} or {@link Webhook}, - * first checking Spring-managed beans and then falling back to classpath scanning - * if no annotated beans are found. - * - * @return An array of classes related to webhooks. - */ - public Class[] getWebhooksClasses() { + /** + * Retrieves all classes related to webhooks. + * This method scans for classes annotated with {@link Webhooks} or {@link Webhook}, + * first checking Spring-managed beans and then falling back to classpath scanning + * if no annotated beans are found. + * + * @return An array of classes related to webhooks. + */ + public Class[] getWebhooksClasses() { Set> allWebhookClassesToScan = new HashSet<>(); // First: scan Spring-managed beans diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/PropertyResolverUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/PropertyResolverUtils.java index d8f3149d7..42c6c5238 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/PropertyResolverUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/PropertyResolverUtils.java @@ -117,8 +117,7 @@ public String resolve(String parameterProperty, Locale locale) { * If the input text is {@code null}, the method returns {@code null}. * * @param text The original string with possible leading indentation. - * @return The string with the smallest common leading indentation removed from each line, - * or {@code null} if the input text is {@code null}. + * @return The string with the smallest common leading indentation removed from each line, or {@code null} if the input text is {@code null}. */ public String trimIndent(String text) { if (text == null) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java index 70f641e32..e34b8b532 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SchemaUtils.java @@ -56,7 +56,7 @@ public class SchemaUtils { /** * The constant ANNOTATIONS_FOR_REQUIRED. */ - // using string litterals to support both validation-api v1 and v2 +// using string litterals to support both validation-api v1 and v2 public static final List ANNOTATIONS_FOR_REQUIRED = Arrays.asList("NotNull", "NonNull", "NotBlank", "NotEmpty"); @@ -116,9 +116,9 @@ public static boolean swaggerVisible(@Nullable io.swagger.v3.oas.annotations.med * @param schema the schema * @param parameter the parameter * @return the boolean or {@code null} - * @see Parameter#required() - * @see io.swagger.v3.oas.annotations.media.Schema#required() - * @see io.swagger.v3.oas.annotations.media.Schema#requiredMode() + * @see Parameter#required() Parameter#required() + * @see io.swagger.v3.oas.annotations.media.Schema#required() io.swagger.v3.oas.annotations.media.Schema#required() + * @see io.swagger.v3.oas.annotations.media.Schema#requiredMode() io.swagger.v3.oas.annotations.media.Schema#requiredMode() */ @Nullable public static Boolean swaggerRequired(@Nullable io.swagger.v3.oas.annotations.media.Schema schema, @@ -187,9 +187,9 @@ public boolean fieldNullable(Field field) { * @param schema the schema * @param parameter the parameter * @return the boolean - * @see Parameter#required() - * @see io.swagger.v3.oas.annotations.media.Schema#required() - * @see io.swagger.v3.oas.annotations.media.Schema#requiredMode() + * @see Parameter#required() Parameter#required() + * @see io.swagger.v3.oas.annotations.media.Schema#required() io.swagger.v3.oas.annotations.media.Schema#required() + * @see io.swagger.v3.oas.annotations.media.Schema#requiredMode() io.swagger.v3.oas.annotations.media.Schema#requiredMode() */ public boolean fieldRequired(Field field, io.swagger.v3.oas.annotations.media.Schema schema, Parameter parameter) { Boolean swagger = swaggerRequired(schema, parameter); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java index 35a001e34..ad78bbc23 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocAnnotationsUtils.java @@ -490,6 +490,15 @@ public static Object resolveDefaultValue(String defaultValueStr, ObjectMapper ob return defaultValue; } + /** + * Gets headers. + * + * @param annotationHeaders the annotation headers + * @param components the components + * @param jsonViewAnnotation the json view annotation + * @param openapi31 the openapi 31 + * @return the headers + */ public static Optional> getHeaders(io.swagger.v3.oas.annotations.headers.Header[] annotationHeaders, Components components, JsonView jsonViewAnnotation, boolean openapi31) { Optional> headerMap = AnnotationsUtils.getHeaders(annotationHeaders, components, jsonViewAnnotation, openapi31); if (openapi31) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java index 3b6db06c3..1e1fb8bc2 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocUtils.java @@ -534,6 +534,8 @@ public SpringDocUtils addParentType(String... parentTypes) { /** * Init extra schemas. + * + * @return the spring doc utils */ public SpringDocUtils initExtraSchemas() { customClasses().put("java.time.Duration", PrimitiveType.STRING); @@ -579,6 +581,7 @@ public SpringDocUtils resetExtraSchemas() { * @param the type parameter * @param source the source * @param targetType the target type + * @param mapper the mapper * @return the t */ public static T cloneViaJson(Object source, Class targetType, ObjectMapper mapper) { @@ -600,6 +603,7 @@ public static T cloneViaJson(Object source, Class targetType, ObjectMapp * @param the type parameter * @param source the source * @param typeRef the type ref + * @param mapper the mapper * @return the t */ public static T cloneViaJson(Object source, TypeReference typeRef, ObjectMapper mapper) { diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java index 51f5a16af..aa2dcbf9c 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringSecurityUtils.java @@ -32,10 +32,19 @@ import org.springframework.web.util.pattern.PathPattern; /** + * The type Spring security utils. + * * @author bnasslahsen */ public final class SpringSecurityUtils { + /** + * Gets path. + * + * @param pathPatternRequestMatcher the path pattern request matcher + * @return the path + * @throws IllegalAccessException the illegal access exception + */ public static String getPath(PathPatternRequestMatcher pathPatternRequestMatcher) throws IllegalAccessException { PathPattern pathPattern = (PathPattern) FieldUtils.readField( pathPatternRequestMatcher, diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java index d0f3eb0b9..4a04368bc 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java @@ -232,6 +232,7 @@ protected void getWebFluxRouterFunctionPaths(Locale locale, OpenAPI openAPI) { * @param serverHttpRequest the server http request * @param apiDocsUrl the api docs url * @param locale the locale + * @return the string */ protected String calculateServerUrl(ServerHttpRequest serverHttpRequest, String apiDocsUrl, Locale locale) { initOpenAPIBuilder(locale); diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java index bb045c3b0..4f254dafe 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java @@ -65,6 +65,13 @@ protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpoin this.webEndpointProperties = webEndpointProperties; } + /** + * Gets docs. + * + * @param serverHttpRequest the server http request + * @return the docs + * @throws IOException the io exception + */ @Operation(hidden = true) @GetMapping(DEFAULT_PATH_SEPARATOR) public ResponseEntity getDocs(ServerHttpRequest serverHttpRequest) throws IOException { diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java index ba4149df7..85597fb82 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java @@ -67,6 +67,13 @@ protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocCo this.springDocConfigProperties = springDocConfigProperties; } + /** + * Gets docs. + * + * @param serverHttpRequest the server http request + * @return the docs + * @throws IOException the io exception + */ @GetMapping public ResponseEntity getDocs(ServerHttpRequest serverHttpRequest) throws IOException { return super.getDocs(serverHttpRequest.getURI().toString()); diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java index 7ea602b14..23ae45d36 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java @@ -65,6 +65,13 @@ protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpoin this.webEndpointProperties = webEndpointProperties; } + /** + * Gets docs. + * + * @param request the request + * @return the docs + * @throws IOException the io exception + */ @Operation(hidden = true) @GetMapping(DEFAULT_PATH_SEPARATOR) public ResponseEntity getDocs(HttpServletRequest request) throws IOException { diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java index f357970a1..c41d6112c 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java @@ -67,6 +67,13 @@ protected ScalarWebMvcController(ScalarProperties scalarProperties, SpringDocCon this.springDocConfigProperties = springDocConfigProperties; } + /** + * Gets docs. + * + * @param request the request + * @return the docs + * @throws IOException the io exception + */ @GetMapping public ResponseEntity getDocs(HttpServletRequest request) throws IOException { return super.getDocs(request.getRequestURL().toString()); diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 1c55a8f72..e2a6bf29e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -44,16 +44,31 @@ import static org.skyscreamer.jsonassert.JSONAssert.assertEquals; +/** + * The type Abstract common test. + */ @AutoConfigureWebTestClient(timeout = "3600000") @ActiveProfiles("test") @TestPropertySource(properties = { "management.endpoints.enabled-by-default=false" }) public abstract class AbstractCommonTest { + /** + * The constant LOGGER. + */ protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCommonTest.class); + /** + * The Web test client. + */ @Autowired protected WebTestClient webTestClient; + /** + * Gets content. + * + * @param fileName the file name + * @return the content + */ protected String getContent(String fileName) { try { Path path = Paths.get(AbstractCommonTest.class.getClassLoader().getResource(fileName).toURI()); @@ -65,6 +80,13 @@ protected String getContent(String fileName) { } } + /** + * Test app. + * + * @param testId the test id + * @param groupName the group name + * @throws Exception the exception + */ protected void testApp(String testId, String groupName) throws Exception { String result = null; try { From 37a6fefd3a6ec2c76c323b5e5dc8411481039a6b Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 1 Nov 2025 21:43:59 +0100 Subject: [PATCH 31/45] Changes report: Add logs to notify when SpringDocs/Scalar is enabled because SpringDocs/Scalar is enabled by default (#3090) #3122 --- .../configuration/SpringDocConfiguration.java | 14 ++++ .../core/events/SpringDocAppInitializer.java | 75 +++++++++++++++++++ .../org/springdoc/core/utils/Constants.java | 5 ++ .../webflux/scalar/ScalarConfiguration.java | 33 +++++++- .../springdoc/webflux/ui/SwaggerConfig.java | 28 +++++++ .../webmvc/scalar/ScalarConfiguration.java | 42 +++++++++-- .../springdoc/webmvc/ui/SwaggerConfig.java | 28 +++++++ 7 files changed, 215 insertions(+), 10 deletions(-) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index bfaf56a1a..2b8882808 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -76,6 +76,7 @@ import org.springdoc.core.customizers.ServerBaseUrlCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; +import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.extractor.MethodParameterPojoExtractor; import org.springdoc.core.filters.GlobalOpenApiMethodFilter; import org.springdoc.core.filters.OpenApiMethodFilter; @@ -724,4 +725,17 @@ SchemaUtils schemaUtils(Optional springDocKotlinUtils){ MethodParameterPojoExtractor methodParameterPojoExtractor(SchemaUtils schemaUtils){ return new MethodParameterPojoExtractor(schemaUtils); } + + /** + * Spring doc app initializer spring doc app initializer. + * + * @param springDocConfigProperties the spring doc config properties + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocAppInitializer") + @Lazy(false) + SpringDocAppInitializer springDocAppInitializer(SpringDocConfigProperties springDocConfigProperties){ + return new SpringDocAppInitializer(springDocConfigProperties.getApiDocs().getPath(), SPRINGDOC_ENABLED); + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java new file mode 100644 index 000000000..f1a02b05b --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java @@ -0,0 +1,75 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package org.springdoc.core.events; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.context.event.EventListener; + +/** + * The type Spring doc app initializer. + * + * @author bnasslahsen + */ +public class SpringDocAppInitializer { + + /** + * The Endpoint. + */ + private final String endpoint; + + /** + * The Property. + */ + private final String property; + + /** + * The constant LOGGER. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(SpringDocAppInitializer.class); + + /** + * Instantiates a new Spring doc app initializer. + * + * @param endpoint the endpoint + * @param property the property + */ + public SpringDocAppInitializer(String endpoint, String property) { + this.endpoint = endpoint; + this.property = property; + } + + /** + * Init. + */ + @EventListener(ApplicationReadyEvent.class) + public void init() { + LOGGER.warn("SpringDoc {} endpoint is enabled by default. To disable it in production, set the property '{}=false'", endpoint, property); + } +} diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/Constants.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/Constants.java index 3e0b065ae..2a2e916f7 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/Constants.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/Constants.java @@ -439,6 +439,11 @@ public final class Constants { */ public static final String SPRINGDOC_EXPLICIT_OBJECT_SCHEMA = "springdoc.explicit-object-schema"; + /** + * The constant SCALAR_ENABLED. + */ + public static final String SCALAR_ENABLED= "scalar.enabled"; + /** * Instantiates a new Constants. */ diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java index 4e267641f..acc15b13f 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java @@ -28,6 +28,7 @@ import com.scalar.maven.webjar.ScalarProperties; import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; @@ -46,8 +47,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.web.server.adapter.ForwardedHeaderTransformer; -import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; +import static org.springdoc.core.utils.Constants.SCALAR_ENABLED; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; +import static org.springdoc.scalar.ScalarConstants.DEFAULT_SCALAR_ACTUATOR_PATH; /** * The type Scalar configuration. @@ -56,11 +58,10 @@ */ @Lazy(false) @Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true) +@ConditionalOnProperty(name = SCALAR_ENABLED, matchIfMissing = true) @ConditionalOnWebApplication(type = Type.REACTIVE) @ConditionalOnBean(SpringDocConfiguration.class) @EnableConfigurationProperties(ScalarProperties.class) -@ConditionalOnProperty(prefix = "scalar", name = "enabled", havingValue = "true", matchIfMissing = true) public class ScalarConfiguration { /** @@ -90,6 +91,20 @@ ForwardedHeaderTransformer forwardedHeaderTransformer() { return new ForwardedHeaderTransformer(); } + /** + * Spring doc app initializer spring doc app initializer. + * + * @param scalarProperties the spring doc config properties + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocScalarInitializer") + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @Lazy(false) + SpringDocAppInitializer springDocScalarInitializer(ScalarProperties scalarProperties){ + return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED); + } + /** * The type Swagger actuator welcome configuration. */ @@ -111,6 +126,18 @@ static class SwaggerActuatorWelcomeConfiguration { ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { return new ScalarActuatorController(properties,webEndpointProperties); } + + /** + * Spring doc scalar initializer spring doc app initializer. + * + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocScalarInitializer") + @Lazy(false) + SpringDocAppInitializer springDocScalarInitializer(){ + return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED); + } } } diff --git a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java index efeeb99e1..3ef7c6169 100644 --- a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java @@ -29,6 +29,7 @@ import java.util.Optional; import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springdoc.core.properties.SwaggerUiOAuthProperties; @@ -53,6 +54,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.web.reactive.config.WebFluxConfigurer; +import static org.springdoc.core.utils.Constants.DEFAULT_SWAGGER_UI_ACTUATOR_PATH; import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_ROOT_PATH; @@ -182,6 +184,20 @@ SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swagge return new SwaggerResourceResolver(swaggerUiConfigProperties); } + /** + * Spring doc swagger initializer spring doc swagger initializer. + * + * @param swaggerUiConfigProperties the swagger ui config properties + * @return the spring doc swagger initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @Lazy(false) + SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED); + } + /** * The type Swagger actuator welcome configuration. * @@ -207,5 +223,17 @@ SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerU WebEndpointProperties webEndpointProperties) { return new SwaggerWelcomeActuator(swaggerUiConfig, springDocConfigProperties, webEndpointProperties); } + + /** + * Spring doc swagger initializer spring doc app initializer. + * + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") + @Lazy(false) + SpringDocAppInitializer springDocSwaggerInitializer() { + return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED); + } } } diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java index bc90d4f67..dec8fcdc1 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java @@ -21,13 +21,14 @@ * * * * * * * * * - * + * */ package org.springdoc.webmvc.scalar; import com.scalar.maven.webjar.ScalarProperties; import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; @@ -47,8 +48,9 @@ import org.springframework.context.annotation.Lazy; import org.springframework.web.filter.ForwardedHeaderFilter; -import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; +import static org.springdoc.core.utils.Constants.SCALAR_ENABLED; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; +import static org.springdoc.scalar.ScalarConstants.DEFAULT_SCALAR_ACTUATOR_PATH; /** * The type Scalar configuration. @@ -57,11 +59,10 @@ */ @Lazy(false) @Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = SPRINGDOC_SWAGGER_UI_ENABLED, matchIfMissing = true) +@ConditionalOnProperty(name = SCALAR_ENABLED, matchIfMissing = true) @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnBean(SpringDocConfiguration.class) @EnableConfigurationProperties(ScalarProperties.class) -@ConditionalOnProperty(prefix = "scalar", name = "enabled", havingValue = "true", matchIfMissing = true) public class ScalarConfiguration { /** @@ -76,7 +77,7 @@ public class ScalarConfiguration { @ConditionalOnMissingBean @Lazy(false) ScalarWebMvcController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { - return new ScalarWebMvcController(scalarProperties,springDocConfigProperties); + return new ScalarWebMvcController(scalarProperties, springDocConfigProperties); } /** @@ -91,6 +92,20 @@ public FilterRegistrationBean forwardedHeaderFilter() { return new FilterRegistrationBean<>(new ForwardedHeaderFilter()); } + /** + * Spring doc app initializer spring doc app initializer. + * + * @param scalarProperties the spring doc config properties + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocScalarInitializer") + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @Lazy(false) + SpringDocAppInitializer springDocScalarInitializer(ScalarProperties scalarProperties) { + return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED); + } + /** * The type Swagger actuator welcome configuration. */ @@ -109,8 +124,21 @@ static class SwaggerActuatorWelcomeConfiguration { @Bean @ConditionalOnMissingBean @Lazy(false) - ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { - return new ScalarActuatorController(properties,webEndpointProperties); + ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { + return new ScalarActuatorController(properties, webEndpointProperties); + } + + + /** + * Spring doc scalar initializer spring doc app initializer. + * + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocScalarInitializer") + @Lazy(false) + SpringDocAppInitializer springDocScalarInitializer() { + return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED); } } diff --git a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java index b4203efa8..307c102c4 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java @@ -29,6 +29,7 @@ import java.util.Optional; import org.springdoc.core.configuration.SpringDocConfiguration; +import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springdoc.core.properties.SwaggerUiOAuthProperties; @@ -51,6 +52,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import static org.springdoc.core.utils.Constants.DEFAULT_SWAGGER_UI_ACTUATOR_PATH; import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_MANAGEMENT_PORT; import static org.springdoc.core.utils.Constants.SPRINGDOC_USE_ROOT_PATH; @@ -170,6 +172,20 @@ SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swagge return new SwaggerResourceResolver(swaggerUiConfigProperties); } + /** + * Spring doc swagger initializer spring doc swagger initializer. + * + * @param swaggerUiConfigProperties the swagger ui config properties + * @return the spring doc swagger initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") + @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) + @Lazy(false) + SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED); + } + /** * The type Swagger actuator welcome configuration. */ @@ -192,5 +208,17 @@ static class SwaggerActuatorWelcomeConfiguration { SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, WebEndpointProperties webEndpointProperties) { return new SwaggerWelcomeActuator(swaggerUiConfig, springDocConfigProperties, webEndpointProperties); } + + /** + * Spring doc swagger initializer spring doc app initializer. + * + * @return the spring doc app initializer + */ + @Bean + @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") + @Lazy(false) + SpringDocAppInitializer springDocSwaggerInitializer() { + return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED); + } } } From c7ed1475f2fd6824f7d26e42ed105ab15200b75f Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sun, 2 Nov 2025 20:53:44 +0100 Subject: [PATCH 32/45] Changes report: Add logs to notify when SpringDocs/Scalar is enabled because SpringDocs/Scalar is enabled by default (#3090) #3122 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5407a1007..e71124f9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.0.0-RC1] - 2025-11-02 + +### Added +- #3095 - Add support for Spring Boot 4.0.0-RC1 + +## [2.8.14] - 2025-11-02 + +### Added + +- #3090 - Add logs to notify when SpringDocs/Scalar is enabled because SpringDocs/Scalar is enabled by default + +### Changed + +- Upgrade swagger-ui to v5.30.1 +- Upgrade swagger-core to v2.2.38 +- Upgrade spring-boot to v3.5.7 +- Upgrade commons-lang3 to v3.18.0 +- Upgrade scalar to v0.3.12 + +### Fixed + +- #3107 - Fix:compatible with lower version of getOpenApi(). +- #3121 - NPE in KotlinDeprecatedPropertyCustomizer - resolvedSchema is null + ## [2.8.13] - 2025-09-07 ### Added From 933ce43bf961f204d9e2dd13900a5381acf125d2 Mon Sep 17 00:00:00 2001 From: jenkins Date: Sun, 2 Nov 2025 19:59:16 +0000 Subject: [PATCH 33/45] [maven-release-plugin] prepare release v3.0.0-RC1 --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-scalar/pom.xml | 6 ++---- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-scalar/pom.xml | 6 ++---- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 21 files changed, 24 insertions(+), 28 deletions(-) diff --git a/pom.xml b/pom.xml index ac23478c9..9b614166d 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - HEAD + v3.0.0-RC1 diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 348839104..0fcd42a83 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 3de0a8675..57e7a24a7 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index c08b5791d..899182c4e 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index 21f7a6af1..6760da933 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -1,11 +1,9 @@ - + 4.0.0 org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webflux-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index b0262c9a7..4332a70cb 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 251bdf314..3001ef55a 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index 0c5f21726..511607f8e 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -1,11 +1,9 @@ - + 4.0.0 org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webmvc-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 2704cff89..c2a360bfc 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 7bc60bcdf..b932c8905 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index f29d64ea9..fc71a9ca9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 65ea0bf2c..a1fbb2541 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index b0caa286c..ca52ec2f9 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 5cc8d343c..3f8fadb6f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index eac7fd3e4..5f06b4673 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index 8f63c09db..d5e19b4f2 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 51e4f4e3e..441958465 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 4d3f1ecf3..06348194f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 923882a0b..0d2bf466c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 4b4fd12d9..c7601ccd5 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index 03c020a65..bdd4d4598 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-M2-SNAPSHOT + 3.0.0-RC1 springdoc-openapi-security-tests ${project.artifactId} From 6e8a2800d438e80727b51404b9a01ef7dd3c8622 Mon Sep 17 00:00:00 2001 From: jenkins Date: Sun, 2 Nov 2025 19:59:19 +0000 Subject: [PATCH 34/45] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-scalar/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-scalar/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 21 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index 9b614166d..335f23487 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - v3.0.0-RC1 + HEAD diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 0fcd42a83..c461127f5 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 57e7a24a7..fb1ae80de 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 899182c4e..a0a9d1abc 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index 6760da933..c84da2a40 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webflux-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index 4332a70cb..9fa3f63e9 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 3001ef55a..5dd9f3577 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index 511607f8e..29179ea84 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webmvc-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index c2a360bfc..ba4e17be6 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index b932c8905..f3f036f50 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index fc71a9ca9..441e8196f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index a1fbb2541..be68398cc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index ca52ec2f9..9b83f8eb8 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 3f8fadb6f..0a3913753 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index 5f06b4673..0679ec918 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index d5e19b4f2..ecdda2f90 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 441958465..e7050de67 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 06348194f..6dc226dec 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 0d2bf466c..2e95577cb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index c7601ccd5..a3e6e12be 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index bdd4d4598..51bf48cbc 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC1 + 3.0.0-RC2-SNAPSHOT springdoc-openapi-security-tests ${project.artifactId} From 02934593a9751a76ebe6542af0d5babc55e04519 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Sat, 8 Nov 2025 21:50:45 +0100 Subject: [PATCH 35/45] Spring Framework 7 - API versioning support #2975 --- pom.xml | 14 +- .../api/AbstractOpenApiResource.java | 58 ++++--- .../QuerydslPredicateOperationCustomizer.java | 2 +- .../data/DataRestRouterOperationService.java | 2 +- .../springdoc/core/fn/RouterOperation.java | 42 ++++- .../core/models/MethodAttributes.java | 94 +++++++++--- .../core/providers/SpringWebProvider.java | 57 +++++++ .../core/service/AbstractRequestService.java | 37 +++-- .../core/service/GenericParameterService.java | 26 +++- .../core/utils/SpringDocDataRestUtils.java | 2 +- .../core/versions/HeaderVersionStrategy.java | 61 ++++++++ .../versions/MediaTypeVersionStrategy.java | 91 +++++++++++ .../core/versions/PathVersionStrategy.java | 97 ++++++++++++ .../versions/QueryParamVersionStrategy.java | 88 +++++++++++ .../versions/SpringDocApiVersionType.java | 33 ++++ .../versions/SpringDocVersionStrategy.java | 114 ++++++++++++++ .../webflux/api/OpenApiResource.java | 7 +- .../SpringDocWebFluxConfiguration.java | 6 +- .../core/providers/SpringWebFluxProvider.java | 67 +++++++- .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../api/v30/AbstractSpringDocTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../api/v31/AbstractSpringDocTest.java | 2 +- .../api/v31/app193/SpringDocApp193Test.java | 39 +++++ .../v31/app193/config/ApiVersionParser.java | 24 +++ .../api/v31/app193/config/WebConfig.java | 23 +++ .../springdoc/api/v31/app193/user/User.java | 10 ++ .../api/v31/app193/user/UserController.java | 47 ++++++ .../api/v31/app193/user/UserDTOv1.java | 4 + .../api/v31/app193/user/UserDTOv2.java | 4 + .../api/v31/app193/user/UserMapper.java | 83 ++++++++++ .../api/v31/app193/user/UserRepository.java | 27 ++++ .../api/v31/app194/SpringDocApp194Test.java | 39 +++++ .../v31/app194/config/ApiVersionParser.java | 24 +++ .../api/v31/app194/config/WebConfig.java | 21 +++ .../springdoc/api/v31/app194/user/User.java | 10 ++ .../api/v31/app194/user/UserController.java | 39 +++++ .../api/v31/app194/user/UserDTOv1.java | 4 + .../api/v31/app194/user/UserDTOv2.java | 4 + .../api/v31/app194/user/UserMapper.java | 83 ++++++++++ .../api/v31/app194/user/UserRepository.java | 27 ++++ .../api/v31/app195/SpringDocApp195Test.java | 39 +++++ .../v31/app195/config/ApiVersionParser.java | 24 +++ .../api/v31/app195/config/WebConfig.java | 21 +++ .../springdoc/api/v31/app195/user/User.java | 10 ++ .../api/v31/app195/user/UserController.java | 46 ++++++ .../api/v31/app195/user/UserDTOv1.java | 4 + .../api/v31/app195/user/UserDTOv2.java | 4 + .../api/v31/app195/user/UserMapper.java | 83 ++++++++++ .../api/v31/app195/user/UserRepository.java | 27 ++++ .../api/v31/app196/SpringDocApp196Test.java | 39 +++++ .../v31/app196/config/ApiVersionParser.java | 24 +++ .../api/v31/app196/config/WebConfig.java | 20 +++ .../springdoc/api/v31/app196/user/User.java | 10 ++ .../api/v31/app196/user/UserController.java | 46 ++++++ .../api/v31/app196/user/UserDTOv1.java | 4 + .../api/v31/app196/user/UserDTOv2.java | 4 + .../api/v31/app196/user/UserMapper.java | 83 ++++++++++ .../api/v31/app196/user/UserRepository.java | 27 ++++ .../api/v31/app64/WebConfiguration.java | 17 ++ .../test/resources/results/3.0.1/app75.json | 3 + .../test/resources/results/3.0.1/app88.json | 3 + .../test/resources/results/3.1.0/app193.json | 83 ++++++++++ .../test/resources/results/3.1.0/app194.json | 80 ++++++++++ .../test/resources/results/3.1.0/app195.json | 99 ++++++++++++ .../test/resources/results/3.1.0/app196.json | 100 ++++++++++++ .../test/resources/results/3.1.0/app75.json | 5 +- .../test/resources/results/3.1.0/app88.json | 5 +- .../webflux/scalar/AbstractCommonTest.java | 2 +- .../springdoc/webflux/ui/SwaggerConfig.java | 7 +- .../org/springdoc/ui/AbstractCommonTest.java | 2 +- .../springdoc/webmvc/api/OpenApiResource.java | 17 +- .../SpringDocWebMvcConfiguration.java | 6 +- .../core/providers/SpringWebMvcProvider.java | 70 ++++++++- .../api/v31/app248/SpringDocApp248Test.java | 11 ++ .../v31/app248/config/ApiVersionParser.java | 24 +++ .../api/v31/app248/config/WebConfig.java | 23 +++ .../springdoc/api/v31/app248/user/User.java | 10 ++ .../api/v31/app248/user/UserController.java | 47 ++++++ .../api/v31/app248/user/UserDTOv1.java | 4 + .../api/v31/app248/user/UserDTOv2.java | 4 + .../api/v31/app248/user/UserMapper.java | 83 ++++++++++ .../api/v31/app248/user/UserRepository.java | 27 ++++ .../api/v31/app249/SpringDocApp249Test.java | 11 ++ .../v31/app249/config/ApiVersionParser.java | 24 +++ .../api/v31/app249/config/WebConfig.java | 21 +++ .../springdoc/api/v31/app249/user/User.java | 10 ++ .../api/v31/app249/user/UserController.java | 39 +++++ .../api/v31/app249/user/UserDTOv1.java | 4 + .../api/v31/app249/user/UserDTOv2.java | 4 + .../api/v31/app249/user/UserMapper.java | 83 ++++++++++ .../api/v31/app249/user/UserRepository.java | 27 ++++ .../api/v31/app250/SpringDocApp250Test.java | 11 ++ .../v31/app250/config/ApiVersionParser.java | 24 +++ .../api/v31/app250/config/WebConfig.java | 21 +++ .../springdoc/api/v31/app250/user/User.java | 10 ++ .../api/v31/app250/user/UserController.java | 46 ++++++ .../api/v31/app250/user/UserDTOv1.java | 4 + .../api/v31/app250/user/UserDTOv2.java | 4 + .../api/v31/app250/user/UserMapper.java | 83 ++++++++++ .../api/v31/app250/user/UserRepository.java | 27 ++++ .../api/v31/app251/SpringDocApp251Test.java | 11 ++ .../v31/app251/config/ApiVersionParser.java | 23 +++ .../api/v31/app251/config/WebConfig.java | 20 +++ .../springdoc/api/v31/app251/user/User.java | 10 ++ .../api/v31/app251/user/UserController.java | 46 ++++++ .../api/v31/app251/user/UserDTOv1.java | 4 + .../api/v31/app251/user/UserDTOv2.java | 4 + .../api/v31/app251/user/UserMapper.java | 83 ++++++++++ .../api/v31/app251/user/UserRepository.java | 27 ++++ .../api/v31/app252/SpringDocApp252Test.java | 11 ++ .../api/v31/app252/config/AppConfig.java | 35 +++++ .../api/v31/app252/config/WebConfig.java | 36 +++++ .../api/v31/app252/repository/Account.java | 20 +++ .../app252/repository/AccountRepository.java | 41 +++++ .../api/v31/app252/repository/Statement.java | 25 +++ .../repository/StatementRepository.java | 54 +++++++ .../api/v31/app252/web/AccountController.java | 48 ++++++ .../v31/app252/web/StatementController.java | 52 +++++++ .../test/resources/results/3.1.0/app248.json | 83 ++++++++++ .../test/resources/results/3.1.0/app249.json | 80 ++++++++++ .../test/resources/results/3.1.0/app250.json | 99 ++++++++++++ .../test/resources/results/3.1.0/app251.json | 100 ++++++++++++ .../test/resources/results/3.1.0/app252.json | 145 ++++++++++++++++++ .../springdoc/webmvc/ui/SwaggerConfig.java | 8 +- .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../springdoc/api/v30/AbstractCommonTest.java | 2 +- .../v30/AbstractSpringDocFunctionTest.java | 2 +- .../springdoc/api/v31/AbstractCommonTest.java | 2 +- .../v31/AbstractSpringDocFunctionTest.java | 2 +- .../api/v30/AbstractKotlinSpringDocTest.kt | 2 +- .../api/v31/AbstractKotlinSpringDocTest.kt | 2 +- 133 files changed, 4098 insertions(+), 101 deletions(-) create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/HeaderVersionStrategy.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/MediaTypeVersionStrategy.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/PathVersionStrategy.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/QueryParamVersionStrategy.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocApiVersionType.java create mode 100644 springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocVersionStrategy.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/SpringDocApp193Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/User.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserController.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/SpringDocApp194Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/User.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserController.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/SpringDocApp195Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/User.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserController.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/SpringDocApp196Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/User.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserController.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app64/WebConfiguration.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app193.json create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app194.json create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app195.json create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app196.json create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/User.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/SpringDocApp249Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/User.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/SpringDocApp250Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/User.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/SpringDocApp251Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/ApiVersionParser.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/User.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv1.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv2.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserMapper.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/SpringDocApp252Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/AppConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/WebConfig.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Account.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/AccountRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Statement.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/StatementRepository.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/AccountController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/StatementController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app248.json create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app249.json create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app250.json create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app251.json create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app252.json diff --git a/pom.xml b/pom.xml index 335f23487..c2350abbf 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 4.0.0-RC1 + 4.0.0-SNAPSHOT @@ -65,6 +65,7 @@ 0.3.12 false + 7.0.0-SNAPSHOT @@ -248,4 +249,15 @@ + + + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + true + + + diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java index c08a1a735..7ded98db0 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/api/AbstractOpenApiResource.java @@ -43,7 +43,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; +import java.util.Locale.LanguageRange; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -111,6 +113,7 @@ import org.springdoc.core.utils.PropertyResolverUtils; import org.springdoc.core.utils.SpringDocAnnotationsUtils; import org.springdoc.core.utils.SpringDocUtils; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.ObjectFactory; @@ -369,7 +372,7 @@ protected OpenAPI getOpenApi(String serverBaseUrl, Locale locale) { .filter(controller -> (AnnotationUtils.findAnnotation(controller.getValue().getClass(), Hidden.class) == null)) .filter(controller -> !isHiddenRestControllers(controller.getValue().getClass())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1)); + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a1, a2) -> a1)); Map findControllerAdvice = openAPIService.getControllerAdviceMap(); if (OpenApiVersion.OPENAPI_3_1 == springDocConfigProperties.getApiDocs().getVersion()) { @@ -434,7 +437,7 @@ private Locale selectLocale(Locale inputLocale) { List allowedLocales = springDocConfigProperties.getAllowedLocales(); if (!CollectionUtils.isEmpty(allowedLocales)) { Locale bestMatchingAllowedLocale = Locale.lookup( - Locale.LanguageRange.parse(inputLocale.toLanguageTag()), + LanguageRange.parse(inputLocale.toLanguageTag()), allowedLocales.stream().map(Locale::forLanguageTag).toList() ); @@ -568,7 +571,9 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router String[] methodProduces = routerOperation.getProduces(); String[] headers = routerOperation.getHeaders(); Map queryParams = routerOperation.getQueryParams(); - + SpringDocVersionStrategy springDocVersionStrategy = routerOperation.getSpringDocVersionStrategy(); + if (springDocVersionStrategy != null) + queryParams = springDocVersionStrategy.updateQueryParams(queryParams); Components components = openAPI.getComponents(); Paths paths = openAPI.getPaths(); @@ -590,7 +595,7 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router RequestMapping reqMappingClass = AnnotatedElementUtils.findMergedAnnotation(handlerMethod.getBeanType(), RequestMapping.class); - MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers, locale); + MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers, springDocVersionStrategy, locale); methodAttributes.setMethodOverloaded(existingOperation != null); //Use the javadoc return if present if (javadocProvider != null) { @@ -655,7 +660,7 @@ protected void calculatePath(HandlerMethod handlerMethod, RouterOperation router } } - Set apiCallbacks = AnnotatedElementUtils.findMergedRepeatableAnnotations(method, io.swagger.v3.oas.annotations.callbacks.Callback.class); + Set apiCallbacks = AnnotatedElementUtils.findMergedRepeatableAnnotations(method, Callback.class); // callbacks buildCallbacks(openAPI, methodAttributes, operation, apiCallbacks); @@ -757,7 +762,9 @@ protected void calculatePath(RouterOperation routerOperation, Locale locale, Ope String[] methodProduces = routerOperation.getProduces(); String[] headers = routerOperation.getHeaders(); Map queryParams = routerOperation.getQueryParams(); - + SpringDocVersionStrategy springDocVersionStrategy = routerOperation.getSpringDocVersionStrategy(); + if(springDocVersionStrategy != null) + queryParams = springDocVersionStrategy.updateQueryParams(queryParams); Paths paths = openAPI.getPaths(); Map operationMap = null; if (paths.containsKey(operationPath)) { @@ -766,7 +773,7 @@ protected void calculatePath(RouterOperation routerOperation, Locale locale, Ope } for (RequestMethod requestMethod : routerOperation.getMethods()) { Operation existingOperation = getExistingOperation(operationMap, requestMethod); - MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers, locale); + MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), methodConsumes, methodProduces, headers, springDocVersionStrategy, locale); methodAttributes.setMethodOverloaded(existingOperation != null); Operation operation = getOperation(routerOperation, existingOperation); if (apiOperation != null) @@ -812,19 +819,20 @@ private RouterOperation customizeDataRestRouterOperation(RouterOperation routerO /** * Calculate path. * - * @param handlerMethod the handler method - * @param operationPath the operation path - * @param requestMethods the request methods - * @param consumes the consumes - * @param produces the produces - * @param headers the headers - * @param params the params - * @param locale the locale - * @param openAPI the open api + * @param handlerMethod the handler method + * @param operationPath the operation path + * @param requestMethods the request methods + * @param consumes the consumes + * @param produces the produces + * @param headers the headers + * @param params the params + * @param versionStrategy the version strategy + * @param locale the locale + * @param openAPI the open api */ protected void calculatePath(HandlerMethod handlerMethod, String operationPath, - Set requestMethods, String[] consumes, String[] produces, String[] headers, String[] params, Locale locale, OpenAPI openAPI) { - this.calculatePath(handlerMethod, new RouterOperation(operationPath, requestMethods.toArray(new RequestMethod[requestMethods.size()]), consumes, produces, headers, params), locale, openAPI); + Set requestMethods, String[] consumes, String[] produces, String[] headers, String[] params, SpringDocVersionStrategy versionStrategy, Locale locale, OpenAPI openAPI) { + this.calculatePath(handlerMethod, new RouterOperation(operationPath, requestMethods.toArray(new RequestMethod[requestMethods.size()]), consumes, produces, headers, params, versionStrategy), locale, openAPI); } /** @@ -1227,10 +1235,16 @@ private void fillParametersList(Operation operation, Map queryPa } }); if (!CollectionUtils.isEmpty(queryParams)) { - for (Map.Entry entry : queryParams.entrySet()) { - io.swagger.v3.oas.models.parameters.Parameter parameter = new io.swagger.v3.oas.models.parameters.Parameter(); - parameter.setName(entry.getKey()); - parameter.setSchema(new StringSchema()._default(entry.getValue())); + Map versionDefaultMap = null; + if(methodAttributes.getSpringDocVersionStrategy() != null) + versionDefaultMap= methodAttributes.getSpringDocVersionStrategy().getVersionDefaultMap(); + for (Entry entry : queryParams.entrySet()) { + Parameter parameter = new Parameter(); + String name = entry.getKey(); + String value = entry.getValue(); + String defaultValue = (versionDefaultMap != null) ? versionDefaultMap.get(name) : value; + parameter.setName(name); + parameter.setSchema(new StringSchema()._default(defaultValue)._enum(Collections.singletonList(value))); parameter.setRequired(true); parameter.setIn(ParameterIn.QUERY.toString()); GenericParameterService.mergeParameter(parametersList, parameter); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java index add34935f..12a12fede 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/customizers/QuerydslPredicateOperationCustomizer.java @@ -54,11 +54,11 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; +import org.springframework.data.core.TypeInformation; import org.springframework.data.querydsl.binding.QuerydslBinderCustomizer; import org.springframework.data.querydsl.binding.QuerydslBindings; import org.springframework.data.querydsl.binding.QuerydslBindingsFactory; import org.springframework.data.querydsl.binding.QuerydslPredicate; -import org.springframework.data.util.TypeInformation; import org.springframework.util.CollectionUtils; import org.springframework.web.method.HandlerMethod; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRouterOperationService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRouterOperationService.java index bd37f965a..7e2d1c95b 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRouterOperationService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/data/DataRestRouterOperationService.java @@ -285,7 +285,7 @@ else if (ControllerType.PROPERTY.equals(controllerType)) MethodResourceMapping methodResourceMapping, HandlerMethod handlerMethod, RequestMethod requestMethod, ResourceMetadata resourceMetadata, String operationPath, ControllerType controllerType) { - RouterOperation routerOperation = new RouterOperation(operationPath, new RequestMethod[] { requestMethod }, null, null, null, null); + RouterOperation routerOperation = new RouterOperation(operationPath, new RequestMethod[] { requestMethod }, null, null, null, null,null); MethodAttributes methodAttributes = new MethodAttributes(springDocConfigProperties.getDefaultConsumesMediaType(), springDocConfigProperties.getDefaultProducesMediaType(), dataRestRepository.getLocale()); methodAttributes.calculateConsumesProduces(handlerMethod.getMethod()); routerOperation.setConsumes(methodAttributes.getMethodConsumes()); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/fn/RouterOperation.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/fn/RouterOperation.java index 693547609..cdec2edaa 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/fn/RouterOperation.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/fn/RouterOperation.java @@ -35,6 +35,7 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.springdoc.core.fn.builders.operation.Builder; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springframework.web.bind.annotation.RequestMethod; @@ -107,6 +108,11 @@ public class RouterOperation implements Comparable { */ private io.swagger.v3.oas.models.Operation operationModel; + /** + * The Spring doc version strategy. + */ + private SpringDocVersionStrategy springDocVersionStrategy; + /** * Instantiates a new Router operation. */ @@ -154,20 +160,22 @@ public RouterOperation(org.springdoc.core.annotations.RouterOperation routerOper /** * Instantiates a new Router operation. * - * @param path the path - * @param methods the methods - * @param consumes the consumes - * @param produces the produces - * @param headers the headers - * @param params the params - */ - public RouterOperation(String path, RequestMethod[] methods, String[] consumes, String[] produces, String[] headers, String[] params) { + * @param path the path + * @param methods the methods + * @param consumes the consumes + * @param produces the produces + * @param headers the headers + * @param params the params + * @param springDocVersionStrategy the version strategy + */ + public RouterOperation(String path, RequestMethod[] methods, String[] consumes, String[] produces, String[] headers, String[] params, SpringDocVersionStrategy springDocVersionStrategy) { this.path = path; this.methods = methods; this.consumes = consumes; this.produces = produces; this.headers = headers; this.params = params; + this.springDocVersionStrategy = springDocVersionStrategy; } /** @@ -422,6 +430,24 @@ public void setOperationModel(io.swagger.v3.oas.models.Operation operationModel) this.operationModel = operationModel; } + /** + * Gets version strategy. + * + * @return the version strategy + */ + public SpringDocVersionStrategy getSpringDocVersionStrategy() { + return springDocVersionStrategy; + } + + /** + * Sets version strategy. + * + * @param springDocVersionStrategy the version strategy + */ + public void setVersionStrategy(SpringDocVersionStrategy springDocVersionStrategy) { + this.springDocVersionStrategy = springDocVersionStrategy; + } + @Override public int compareTo(RouterOperation routerOperation) { int result = path.compareTo(routerOperation.getPath()); diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java index 8baac19d9..2c9bf6cec 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java @@ -41,6 +41,9 @@ import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; +import org.springdoc.core.versions.HeaderVersionStrategy; +import org.springdoc.core.versions.MediaTypeVersionStrategy; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.web.bind.annotation.DeleteMapping; @@ -136,6 +139,11 @@ public class MethodAttributes { */ private boolean useReturnTypeSchema; + /** + * The Spring doc version strategy. + */ + private SpringDocVersionStrategy springDocVersionStrategy; + /** * Instantiates a new Method attributes. * @@ -174,14 +182,17 @@ public MethodAttributes(String defaultConsumesMediaType, String defaultProducesM * @param methodConsumes the method consumes * @param methodProduces the method produces * @param headers the headers + * @param springDocVersionStrategy the spring doc version strategy * @param locale the locale */ - public MethodAttributes(String defaultConsumesMediaType, String defaultProducesMediaType, String[] methodConsumes, String[] methodProduces, String[] headers, Locale locale) { + public MethodAttributes(String defaultConsumesMediaType, String defaultProducesMediaType, String[] methodConsumes, String[] methodProduces, String[] headers, + SpringDocVersionStrategy springDocVersionStrategy, Locale locale) { this.defaultConsumesMediaType = defaultConsumesMediaType; this.defaultProducesMediaType = defaultProducesMediaType; this.methodProduces = methodProduces; this.methodConsumes = methodConsumes; this.locale = locale; + this.springDocVersionStrategy = springDocVersionStrategy; setHeaders(headers); } @@ -296,6 +307,10 @@ else if (reqMappingClass != null) { private void fillMethods(String[] produces, String[] consumes, String[] headers) { if (ArrayUtils.isNotEmpty(produces)) { methodProduces = mergeArrays(methodProduces, produces); + if (springDocVersionStrategy instanceof MediaTypeVersionStrategy mediaTypeVersionStrategy + && mediaTypeVersionStrategy.getVersion() != null) { + methodProduces = mediaTypeVersionStrategy.buildProduces(); + } } else if (ArrayUtils.isNotEmpty(classProduces)) { methodProduces = mergeArrays(methodProduces, classProduces); @@ -318,13 +333,13 @@ else if (ArrayUtils.isEmpty(methodConsumes)) { } /** - * If there is any method type(s) present, then these will override the class type(s). - * See ... for details + * If there is any method type(s) present, then these will override the class type(s). + * See ... for details * - * @param methodTypes the method types - * @param classTypes the class types - * @return the string [ ] containing the types that can be used for the method - */ + * @param methodTypes the method types + * @param classTypes the class types + * @return the string [ ] containing the types that can be used for the method + */ private String[] calculateMethodMediaTypes(@Nullable String[] methodTypes, String[] classTypes) { if (ArrayUtils.isNotEmpty(methodTypes)) { return methodTypes; @@ -340,9 +355,45 @@ private String[] calculateMethodMediaTypes(@Nullable String[] methodTypes, Strin * @return the string [ ] */ private String[] mergeArrays(@Nullable String[] array1, String[] array2) { - Set uniqueValues = array1 == null ? new LinkedHashSet<>() : Arrays.stream(array1).collect(Collectors.toCollection(LinkedHashSet::new)); - uniqueValues.addAll(Arrays.asList(array2)); - return uniqueValues.toArray(new String[0]); + Set merged = array1 == null + ? new LinkedHashSet<>() + : Arrays.stream(array1).collect(Collectors.toCollection(LinkedHashSet::new)); + + merged.addAll(Arrays.asList(array2)); + + // Apply dynamic version filtering if versionStrategy is active + if (springDocVersionStrategy != null + && springDocVersionStrategy instanceof MediaTypeVersionStrategy mediaTypeVersionStrategy + && mediaTypeVersionStrategy.getVersion() != null) { + + // Remove unversioned media types if versioned variants exist + Set baseTypesWithVersion = merged.stream() + .filter(mt -> mt.contains(";")) + .filter(this::containsVersionParameter) + .map(mt -> mt.split(";", 2)[0]) + .collect(Collectors.toSet()); + + merged.removeIf(mt -> baseTypesWithVersion.contains(mt) && !mt.contains(";")); + } + + return merged.toArray(new String[0]); + } + + /** + * Contains version parameter boolean. + * + * @param mediaType the media type + * @return the boolean + */ + private boolean containsVersionParameter(String mediaType) { + String[] parts = mediaType.split(";"); + for (int i = 1; i < parts.length; i++) { + String param = parts[i].trim().toLowerCase(); + if (param.startsWith("version=") || param.startsWith("v=") || param.contains("version=")) { + return true; + } + } + return false; } /** @@ -447,6 +498,11 @@ private void setHeaders(String[] headers) { this.headers.put(keyValueHeader[0], StringUtils.EMPTY); } } + + if (springDocVersionStrategy instanceof HeaderVersionStrategy headerVersionStrategy + && headerVersionStrategy.getVersion() != null) { + this.headers.put(headerVersionStrategy.getHeaderName(), headerVersionStrategy.getVersion()); + } } /** @@ -471,15 +527,6 @@ public Map getGenericMapResponse() { return genericMapResponse; } - /** - * Is with response body schema doc boolean. - * - * @return the boolean - */ - public boolean isWithResponseBodySchemaDoc() { - return withResponseBodySchemaDoc; - } - /** * Sets with response body schema doc. * @@ -545,4 +592,13 @@ public boolean isUseReturnTypeSchema() { public void setUseReturnTypeSchema(boolean useReturnTypeSchema) { this.useReturnTypeSchema = useReturnTypeSchema; } + + /** + * Gets spring doc version strategy. + * + * @return the spring doc version strategy + */ + public SpringDocVersionStrategy getSpringDocVersionStrategy() { + return springDocVersionStrategy; + } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringWebProvider.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringWebProvider.java index aebda82b2..71e9e2417 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringWebProvider.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/SpringWebProvider.java @@ -25,14 +25,21 @@ */ package org.springdoc.core.providers; +import java.util.HashMap; import java.util.Map; import java.util.Set; +import org.apache.commons.lang3.ArrayUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springdoc.core.properties.SpringDocConfigProperties; +import org.springdoc.core.versions.SpringDocApiVersionType; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.util.CollectionUtils; /** * The type Spring web provider. @@ -41,6 +48,11 @@ */ public abstract class SpringWebProvider implements ApplicationContextAware { + /** + * The constant LOGGER. + */ + protected static final Logger LOGGER = LoggerFactory.getLogger(SpringWebProvider.class); + /** * The Application context. */ @@ -51,6 +63,11 @@ public abstract class SpringWebProvider implements ApplicationContextAware { */ protected Map handlerMethods; + /** + * The Spring doc version strategy map. + */ + protected final Map springDocVersionStrategyMap = new HashMap<>(); + /** * Gets handler methods. * @@ -74,6 +91,46 @@ public abstract class SpringWebProvider implements ApplicationContextAware { */ public abstract Set getActivePatterns(Object requestMappingInfo); + /** + * Gets spring doc version strategy. + * + * @param version the version + * @param params the params + * @return the spring doc version strategy + */ + public SpringDocVersionStrategy getSpringDocVersionStrategy(String version, String[] params) { + SpringDocVersionStrategy springDocVersionStrategy = null; + if (!CollectionUtils.isEmpty(springDocVersionStrategyMap)) { + if (springDocVersionStrategyMap.size() == 1) + springDocVersionStrategy = springDocVersionStrategyMap.values().iterator().next(); + else + springDocVersionStrategy = resolveApiVersionStrategy(version, params); + springDocVersionStrategy.updateVersion(version, params); + } + return springDocVersionStrategy; + } + + /** + * Resolve api version strategy spring doc version strategy. + * + * @param version the version + * @param params the params + * @return the spring doc version strategy + */ + private SpringDocVersionStrategy resolveApiVersionStrategy(String version, String[] params) { + if (version != null) { + if (springDocVersionStrategyMap.containsKey(SpringDocApiVersionType.PATH)) + return springDocVersionStrategyMap.get(SpringDocApiVersionType.PATH); + else if (springDocVersionStrategyMap.containsKey(SpringDocApiVersionType.HEADER)) + return springDocVersionStrategyMap.get(SpringDocApiVersionType.HEADER); + else if (springDocVersionStrategyMap.containsKey(SpringDocApiVersionType.MEDIA_TYPE)) + return springDocVersionStrategyMap.get(SpringDocApiVersionType.MEDIA_TYPE); + } + if (ArrayUtils.isNotEmpty(params) && springDocVersionStrategyMap.containsKey(SpringDocApiVersionType.QUERY_PARAM)) + return springDocVersionStrategyMap.get(SpringDocApiVersionType.QUERY_PARAM); + return springDocVersionStrategyMap.values().iterator().next(); + } + @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java index 0e6dcfe00..0dce0206f 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/AbstractRequestService.java @@ -72,6 +72,7 @@ import org.slf4j.LoggerFactory; import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer; import org.springdoc.core.customizers.ParameterCustomizer; +import org.springdoc.core.customizers.PropertyCustomizer; import org.springdoc.core.customizers.SpringDocCustomizers; import org.springdoc.core.discoverer.SpringDocParameterNameDiscoverer; import org.springdoc.core.extractor.DelegatingMethodParameter; @@ -124,7 +125,7 @@ public abstract class AbstractRequestService { * The constant LOGGER. */ private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRequestService.class); - + /** * The constant ACTUATOR_PKGS. */ @@ -132,7 +133,7 @@ public abstract class AbstractRequestService { "org.springframework.boot.webmvc.actuate", "org.springframework.boot.webflux.actuate" ); - + /** * The constant PARAM_TYPES_TO_IGNORE. */ @@ -264,19 +265,31 @@ public static boolean isRequestTypeToIgnore(Class rawClass) { */ @SuppressWarnings("unchecked") public static Collection getHeaders(MethodAttributes methodAttributes, Map map) { + Map versionDefaultMap = null; + if (methodAttributes.getSpringDocVersionStrategy() != null) + versionDefaultMap = methodAttributes.getSpringDocVersionStrategy().getVersionDefaultMap(); for (Entry entry : methodAttributes.getHeaders().entrySet()) { StringSchema schema = new StringSchema(); - if (StringUtils.isNotEmpty(entry.getValue())) - schema.addEnumItem(entry.getValue()); - Parameter parameter = new Parameter().in(ParameterIn.HEADER.toString()).name(entry.getKey()).schema(schema); + String headerName = entry.getKey(); + String headerValue = entry.getValue(); + if (StringUtils.isNotEmpty(headerValue)) + schema.addEnumItem(headerValue); + String defaultValue = null; + if(versionDefaultMap != null) { + defaultValue = versionDefaultMap.get(headerName); + schema._default(defaultValue); + } + Parameter parameter = new Parameter().in(ParameterIn.HEADER.toString()).name(headerName).schema(schema); ParameterId parameterId = new ParameterId(parameter); if (map.containsKey(parameterId)) { parameter = map.get(parameterId); List existingEnum = null; if (parameter.getSchema() != null && !CollectionUtils.isEmpty(parameter.getSchema().getEnum())) existingEnum = parameter.getSchema().getEnum(); - if (StringUtils.isNotEmpty(entry.getValue()) && (existingEnum == null || !existingEnum.contains(entry.getValue()))) - parameter.getSchema().addEnumItemObject(entry.getValue()); + if (StringUtils.isNotEmpty(headerValue) && (existingEnum == null || !existingEnum.contains(headerValue))) + parameter.getSchema().addEnumItemObject(headerValue); + if (defaultValue != null && (existingEnum == null || !existingEnum.contains(defaultValue))) + parameter.getSchema().addEnumItemObject(defaultValue); parameter.setSchema(parameter.getSchema()); } map.put(parameterId, parameter); @@ -293,9 +306,9 @@ public static Collection getHeaders(MethodAttributes methodAttributes * @param methodAttributes the method attributes * @param openAPI the open api * @return the operation - * @see org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) + * @see DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) org.springdoc.core.customizers.DelegatingMethodParameterCustomizer#customizeList(MethodParameter, List) * @see ParameterCustomizer#customize(Parameter, MethodParameter) ParameterCustomizer#customize(Parameter, MethodParameter) - * @see org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) + * @see PropertyCustomizer#customize(Schema, AnnotatedType) org.springdoc.core.customizers.PropertyCustomizer#customize(Schema, AnnotatedType) */ public Operation build(HandlerMethod handlerMethod, RequestMethod requestMethod, Operation operation, MethodAttributes methodAttributes, OpenAPI openAPI) { @@ -530,7 +543,7 @@ private boolean isRequestBodyWithMapType(MethodParameter parameter) { if (ACTUATOR_PKGS.stream().anyMatch(pkg::startsWith)) { return false; } - + // Check for @RequestBody annotation org.springframework.web.bind.annotation.RequestBody requestBody = parameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestBody.class); if (requestBody == null) { @@ -549,7 +562,7 @@ private boolean isRequestBodyWithMapType(MethodParameter parameter) { */ private boolean isRequestPartWithMapType(MethodParameter parameter) { // Check for @RequestPart annotation - org.springframework.web.bind.annotation.RequestPart requestPart = parameter.getParameterAnnotation(org.springframework.web.bind.annotation.RequestPart.class); + RequestPart requestPart = parameter.getParameterAnnotation(RequestPart.class); if (requestPart == null) { return false; } @@ -693,7 +706,7 @@ public void applyBeanValidatorAnnotations(final MethodParameter methodParameter, java.lang.reflect.AnnotatedType[] typeArgs = paramType.getAnnotatedActualTypeArguments(); for (java.lang.reflect.AnnotatedType typeArg : typeArgs) { List genericAnnotations = Arrays.stream(typeArg.getAnnotations()).toList(); - Schema schemaItemsClone = cloneViaJson(schema.getItems(), Schema.class, ObjectMapperProvider.createJson(parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties())); + Schema schemaItemsClone = cloneViaJson(schema.getItems(), Schema.class, ObjectMapperProvider.createJson(parameterBuilder.getPropertyResolverUtils().getSpringDocConfigProperties())); schema.items(schemaItemsClone); SchemaUtils.applyValidationsToSchema(schema.getItems(), genericAnnotations, openapiVersion); } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java index ebb63f801..4d04070ce 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/GenericParameterService.java @@ -57,6 +57,7 @@ import io.swagger.v3.oas.models.media.FileSchema; import io.swagger.v3.oas.models.media.ObjectSchema; import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.parameters.Parameter; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.reflect.FieldUtils; @@ -237,7 +238,7 @@ public static void mergeParameter(Parameter paramCalcul, Parameter paramDoc) { paramDoc.setAllowReserved(paramCalcul.getAllowReserved()); if (StringUtils.isBlank(paramDoc.get$ref())) - paramDoc.set$ref(paramDoc.get$ref()); + paramDoc.set$ref(paramCalcul.get$ref()); if (paramDoc.getSchema() == null && paramDoc.getContent() == null) paramDoc.setSchema(paramCalcul.getSchema()); @@ -253,6 +254,29 @@ public static void mergeParameter(Parameter paramCalcul, Parameter paramDoc) { if (paramDoc.getExplode() == null) paramDoc.setExplode(paramCalcul.getExplode()); + + if (paramDoc.getSchema() instanceof StringSchema existingSchema && + paramCalcul.getSchema() instanceof StringSchema newSchema) { + + List existingEnums = existingSchema.getEnum() != null + ? new ArrayList<>(existingSchema.getEnum()) + : new ArrayList<>(); + + List newEnums = newSchema.getEnum(); + + if (newEnums != null && !newEnums.isEmpty()) { + for (String val : newEnums) { + if (!existingEnums.contains(val)) { + existingEnums.add(val); + } + } + existingSchema.setEnum(existingEnums); + } + + if (newSchema.getDefault() != null) { + existingSchema.setDefault(newSchema.getDefault()); + } + } } /** diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java index 6ffef2802..43f3c9870 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/utils/SpringDocDataRestUtils.java @@ -52,6 +52,7 @@ import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.responses.ApiResponses; +import org.springframework.data.core.TypeInformation; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.PersistentProperty; import org.springframework.data.mapping.SimpleAssociationHandler; @@ -61,7 +62,6 @@ import org.springframework.data.rest.core.mapping.ResourceMappings; import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.rest.webmvc.RestMediaTypes; -import org.springframework.data.util.TypeInformation; import org.springframework.hateoas.server.LinkRelationProvider; import org.springframework.util.CollectionUtils; diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/HeaderVersionStrategy.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/HeaderVersionStrategy.java new file mode 100644 index 000000000..28895bc93 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/HeaderVersionStrategy.java @@ -0,0 +1,61 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +/** + * The type Header version strategy. + * + * @author bnasslahsen + */ +public class HeaderVersionStrategy extends SpringDocVersionStrategy { + + /** + * The Header name. + */ + private final String headerName; + + + /** + * Instantiates a new Header version strategy. + * + * @param headerName the header name + */ + public HeaderVersionStrategy(String headerName, String defaultVersion) { + super(defaultVersion); + this.headerName = headerName; + if(defaultVersion != null) + versionDefaultMap.put(headerName, defaultVersion); + } + + /** + * Gets header name. + * + * @return the header name + */ + public String getHeaderName() { + return headerName; + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/MediaTypeVersionStrategy.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/MediaTypeVersionStrategy.java new file mode 100644 index 000000000..f43e5406a --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/MediaTypeVersionStrategy.java @@ -0,0 +1,91 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +import org.springframework.http.MediaType; + +/** + * The type Media type version strategy. + * + * @author bnasslahsen + */ +public class MediaTypeVersionStrategy extends SpringDocVersionStrategy { + + /** + * The Media type. + */ + private final MediaType mediaType; + + /** + * The Parameter name. + */ + private final String parameterName; + + /** + * Instantiates a new Media type version strategy. + * + * @param mediaType the media type + * @param parameterName the parameter name + */ + public MediaTypeVersionStrategy(MediaType mediaType, String parameterName, String defaultVersion) { + super(defaultVersion); + this.mediaType = mediaType; + this.parameterName = parameterName; + if(defaultVersion != null) + versionDefaultMap.put(parameterName, defaultVersion); + } + + /** + * Gets media type. + * + * @return the media type + */ + public MediaType getMediaType() { + return mediaType; + } + + /** + * Gets parameter name. + * + * @return the parameter name + */ + public String getParameterName() { + return parameterName; + } + + /** + * Build produces string [ ]. + * + * @return the string [ ] + */ + public String[] buildProduces() { + String type = mediaType.getType(); + String subtype = mediaType.getSubtype(); + String produces = String.format("%s/%s;%s=%s", type, subtype, parameterName, version); + return new String[] { produces }; + } + +} diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/PathVersionStrategy.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/PathVersionStrategy.java new file mode 100644 index 000000000..495d96ea2 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/PathVersionStrategy.java @@ -0,0 +1,97 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +import java.util.ArrayList; +import java.util.List; + +/** + * The type Path version strategy. + * + * @author bnasslahsen + */ +public class PathVersionStrategy extends SpringDocVersionStrategy { + + /** + * The Path segment index. + */ + private final int pathSegmentIndex; + + /** + * Instantiates a new Path version strategy. + * + * @param pathSegmentIndex the path segment index + */ + public PathVersionStrategy(int pathSegmentIndex, String defaultVersion) { + super(defaultVersion); + this.pathSegmentIndex = pathSegmentIndex; + } + + /** + * Gets path segment index. + * + * @return the path segment index + */ + public int getPathSegmentIndex() { + return pathSegmentIndex; + } + + + @Override + public String updateOperationPath(String operationPath, String version) { + if (operationPath == null || version == null) { + return operationPath; + } + String[] segments = operationPath.split("/"); + List updatedSegments = new ArrayList<>(); + int segmentCount = 0; + + for (String segment : segments) { + if (segment.isEmpty()) { + continue; + } + + if (segmentCount == pathSegmentIndex) { + String newSegment = version; + if (segment.contains("{")) { + // Extract static prefix before placeholder + int placeholderStart = segment.indexOf('{'); + String prefix = segment.substring(0, placeholderStart); + newSegment = prefix + version; + } + updatedSegments.add(newSegment); + } else { + updatedSegments.add(segment); + } + segmentCount++; + } + return "/" + String.join("/", updatedSegments); + } + +} + + + diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/QueryParamVersionStrategy.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/QueryParamVersionStrategy.java new file mode 100644 index 000000000..03eef82d2 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/QueryParamVersionStrategy.java @@ -0,0 +1,88 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * The type Query param version strategy. + * + * @author bnasslahsen + */ +public class QueryParamVersionStrategy extends SpringDocVersionStrategy { + + /** + * The Parameter name. + */ + private final String parameterName; + + /** + * Instantiates a new Query param version strategy. + * + * @param parameterName the parameter name + */ + public QueryParamVersionStrategy(String parameterName, String defaultVersion) { + super(defaultVersion); + this.parameterName = parameterName; + if(defaultVersion != null) + versionDefaultMap.put(parameterName, defaultVersion); + } + + /** + * Gets parameter name. + * + * @return the parameter name + */ + public String getParameterName() { + return parameterName; + } + + + @Override + public void updateVersion(String version, String[] params) { + for (String param : params) { + if (param.contains("=")) { + String[] paramValues = param.split("=", 2); + String paramName = paramValues[0]; + String paramValue = paramValues[1]; + if (parameterName.equals(paramName)) { + setVersion(paramValue); + break; + } + } + } + } + + @Override + public Map updateQueryParams(Map queryParams) { + if (queryParams == null) + queryParams = new LinkedHashMap<>(); + if(version !=null) + queryParams.put(parameterName, version); + return queryParams; + } +} diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocApiVersionType.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocApiVersionType.java new file mode 100644 index 000000000..5afbb1204 --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocApiVersionType.java @@ -0,0 +1,33 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +/** + * @author bnasslahsen + */ +public enum SpringDocApiVersionType { + PATH, HEADER, QUERY_PARAM, MEDIA_TYPE +} \ No newline at end of file diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocVersionStrategy.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocVersionStrategy.java new file mode 100644 index 000000000..91d1482dc --- /dev/null +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/versions/SpringDocVersionStrategy.java @@ -0,0 +1,114 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ +package org.springdoc.core.versions; + +import java.util.HashMap; +import java.util.Map; + +/** + * The interface Spring doc version strategy. + * + * @author bnasslahsen + */ +public abstract class SpringDocVersionStrategy { + + /** + * The Version. + */ + protected String version; + + /** + * The Default version. + */ + protected final String defaultVersion; + + /** + * The Default values. + */ + protected Map versionDefaultMap = new HashMap<>(); + + /** + * Instantiates a new Spring doc version strategy. + * + * @param defaultVersion the default version + */ + protected SpringDocVersionStrategy(String defaultVersion) { + this.defaultVersion = defaultVersion; + } + + /** + * Gets version. + * + * @return the version + */ + public String getVersion() { + return version; + } + + /** + * Sets version. + * + * @param version the version + */ + public void setVersion(String version) { + this.version = version; + } + + /** + * Update version. + * + * @param version the version + * @param params the params + */ + public void updateVersion(String version, String[] params) { + setVersion(version); + } + + /** + * Update query params map. + * + * @param queryParams the query params + * @return the map + */ + public Map updateQueryParams(Map queryParams) { + return queryParams; + } + + /** + * Gets operation path. + * + * @param operationPath the operation path + * @param version the version + * @return the operation path + */ + public String updateOperationPath(String operationPath, String version) { + return operationPath; + } + + public Map getVersionDefaultMap() { + return versionDefaultMap; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java index 4a04368bc..641bc4b87 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/api/OpenApiResource.java @@ -49,6 +49,7 @@ import org.springdoc.core.service.GenericResponseService; import org.springdoc.core.service.OpenAPIService; import org.springdoc.core.service.OperationService; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springdoc.webflux.core.visitor.RouterFunctionVisitor; import reactor.core.publisher.Mono; @@ -187,13 +188,17 @@ protected void calculatePath(Map restControllers, Map requestMethods = requestMappingInfo.getMethodsCondition().getMethods(); // default allowed requestmethods if (requestMethods.isEmpty()) requestMethods = this.getDefaultAllowedHttpMethods(); - calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, params, locale, openAPI); + SpringDocVersionStrategy springDocVersionStrategy = springWebProvider.getSpringDocVersionStrategy(version, params); + if(springDocVersionStrategy != null) + operationPath = springDocVersionStrategy.updateOperationPath(operationPath, version); + calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, params,springDocVersionStrategy, locale, openAPI); } } } diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java index 51cf71e4b..832b1281c 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/configuration/SpringDocWebFluxConfiguration.java @@ -65,6 +65,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.web.reactive.accept.ApiVersionStrategy; import static org.springdoc.core.utils.Constants.SPRINGDOC_ENABLED; @@ -143,13 +144,14 @@ GenericResponseService responseBuilder(OperationService operationService, Spring /** * Spring web provider spring web provider. * + * @param apiVersionStrategyOptional the api version strategy optional * @return the spring web provider */ @Bean @ConditionalOnMissingBean @Lazy(false) - SpringWebProvider springWebProvider() { - return new SpringWebFluxProvider(); + SpringWebProvider springWebProvider(Optional apiVersionStrategyOptional) { + return new SpringWebFluxProvider(apiVersionStrategyOptional); } /** diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/SpringWebFluxProvider.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/SpringWebFluxProvider.java index 1acca1186..5f8e62875 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/SpringWebFluxProvider.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/providers/SpringWebFluxProvider.java @@ -25,20 +25,37 @@ */ package org.springdoc.webflux.core.providers; +import java.lang.reflect.Field; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedHashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.reflect.FieldUtils; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.providers.SpringWebProvider; +import org.springdoc.core.versions.HeaderVersionStrategy; +import org.springdoc.core.versions.MediaTypeVersionStrategy; +import org.springdoc.core.versions.PathVersionStrategy; +import org.springdoc.core.versions.QueryParamVersionStrategy; +import org.springdoc.core.versions.SpringDocApiVersionType; +import org.springframework.http.MediaType; import org.springframework.util.CollectionUtils; import org.springframework.web.method.HandlerMethod; +import org.springframework.web.reactive.accept.ApiVersionResolver; +import org.springframework.web.reactive.accept.ApiVersionStrategy; +import org.springframework.web.reactive.accept.DefaultApiVersionStrategy; +import org.springframework.web.reactive.accept.HeaderApiVersionResolver; +import org.springframework.web.reactive.accept.MediaTypeParamApiVersionResolver; +import org.springframework.web.reactive.accept.PathApiVersionResolver; +import org.springframework.web.reactive.accept.QueryApiVersionResolver; import org.springframework.web.reactive.result.condition.PatternsRequestCondition; import org.springframework.web.reactive.result.method.AbstractHandlerMethodMapping; import org.springframework.web.reactive.result.method.RequestMappingInfo; @@ -53,6 +70,55 @@ */ public class SpringWebFluxProvider extends SpringWebProvider { + /** + * Instantiates a new Spring web flux provider. + * + * @param apiVersionStrategyOptional the api version strategy optional + */ + public SpringWebFluxProvider(Optional apiVersionStrategyOptional) { + apiVersionStrategyOptional.ifPresent(apiVersionStrategy -> { + try { + DefaultApiVersionStrategy defaultApiVersionStrategy = (DefaultApiVersionStrategy) apiVersionStrategy; + String defaultVersion = null; + if(defaultApiVersionStrategy.getDefaultVersion() !=null) + defaultVersion = defaultApiVersionStrategy.getDefaultVersion().toString(); + Field field = FieldUtils.getDeclaredField(DefaultApiVersionStrategy.class, "versionResolvers", true); + final List versionResolvers = (List) field.get(defaultApiVersionStrategy); + for (ApiVersionResolver apiVersionResolver : versionResolvers) { + if (apiVersionResolver instanceof MediaTypeParamApiVersionResolver mediaTypeParamApiVersionResolver) { + field = FieldUtils.getDeclaredField(MediaTypeParamApiVersionResolver.class, "compatibleMediaType", true); + MediaType mediaType = (MediaType) field.get(mediaTypeParamApiVersionResolver); + field = FieldUtils.getDeclaredField(MediaTypeParamApiVersionResolver.class, "parameterName", true); + String parameterName = (String) field.get(mediaTypeParamApiVersionResolver); + MediaTypeVersionStrategy mediaTypeStrategy = new MediaTypeVersionStrategy(mediaType, parameterName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.MEDIA_TYPE, mediaTypeStrategy); + } + else if (apiVersionResolver instanceof PathApiVersionResolver pathApiVersionResolver) { + field = FieldUtils.getDeclaredField(PathApiVersionResolver.class, "pathSegmentIndex", true); + Integer pathSegmentIndex = (Integer) field.get(pathApiVersionResolver); + PathVersionStrategy pathVersionStrategy = new PathVersionStrategy(pathSegmentIndex, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.PATH, pathVersionStrategy); + } + else if (apiVersionResolver instanceof HeaderApiVersionResolver headerApiVersionResolver) { + field = FieldUtils.getDeclaredField(HeaderApiVersionResolver.class, "headerName", true); + String headerName = (String) field.get(headerApiVersionResolver); + HeaderVersionStrategy headerVersionStrategy = new HeaderVersionStrategy(headerName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.HEADER, headerVersionStrategy); + } + else if (apiVersionResolver instanceof QueryApiVersionResolver queryApiVersionResolver) { + field = FieldUtils.getDeclaredField(QueryApiVersionResolver.class, "queryParamName", true); + String queryParamName = (String) field.get(queryApiVersionResolver); + QueryParamVersionStrategy queryParamVersionStrategy = new QueryParamVersionStrategy(queryParamName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.QUERY_PARAM, queryParamVersionStrategy); + } + } + } + catch (IllegalAccessException e) { + LOGGER.warn(e.getMessage()); + } + }); + } + /** * Finds path prefix. * @@ -88,7 +154,6 @@ public Set getActivePatterns(Object requestMapping) { .map(PathPattern::getPatternString).collect(Collectors.toCollection(LinkedHashSet::new)); } - /** * Gets handler methods. * diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 9593f2b80..db8238969 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java index de0d8b638..26b8ab2d2 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocTest.java @@ -30,7 +30,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.ServerResponse; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 3ca0d9afd..3f29f5d89 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java index 8367ecae5..66cd00188 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocTest.java @@ -30,7 +30,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.web.reactive.server.EntityExchangeResult; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.ServerResponse; diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/SpringDocApp193Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/SpringDocApp193Test.java new file mode 100644 index 000000000..edcafb302 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/SpringDocApp193Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app193; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp193Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app193" }) + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/ApiVersionParser.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/ApiVersionParser.java new file mode 100644 index 000000000..166b61383 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app193.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/WebConfig.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/WebConfig.java new file mode 100644 index 000000000..b0f9dea59 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/config/WebConfig.java @@ -0,0 +1,23 @@ +package test.org.springdoc.api.v31.app193.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.reactive.config.ApiVersionConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +/** + * @author bnasslahsen + */ +@Configuration +public class WebConfig implements WebFluxConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .setVersionRequired(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .useMediaTypeParameter(MediaType.APPLICATION_JSON, "version") + .setVersionParser(new ApiVersionParser()); + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/User.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/User.java new file mode 100644 index 000000000..e28a5b320 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app193.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserController.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserController.java new file mode 100644 index 000000000..21a7b046f --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserController.java @@ -0,0 +1,47 @@ +package test.org.springdoc.api.v31.app193.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING MEDIA TYPE (Content Negotiation) ======================================= + + @GetMapping(value = "/users/media", version = "1.0", produces = "application/json") + public List getUsersMediaV1() { + log.info("Find All Users using media type versioning: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users/media", version = "2.0", produces = MediaType.APPLICATION_JSON_VALUE) + public List getUsersMediaV2() { + log.info("Find All Users using media type versioning: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv1.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv1.java new file mode 100644 index 000000000..9ba026b48 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app193.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv2.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv2.java new file mode 100644 index 000000000..ab84172f6 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app193.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserMapper.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserMapper.java new file mode 100644 index 000000000..e1818822f --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app193.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserRepository.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserRepository.java new file mode 100644 index 000000000..61eba9c29 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app193/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app193.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/SpringDocApp194Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/SpringDocApp194Test.java new file mode 100644 index 000000000..9788a7cd2 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/SpringDocApp194Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app194; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp194Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app194" }) + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/ApiVersionParser.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/ApiVersionParser.java new file mode 100644 index 000000000..78c38fd37 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app194.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/WebConfig.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/WebConfig.java new file mode 100644 index 000000000..102e18416 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/config/WebConfig.java @@ -0,0 +1,21 @@ +package test.org.springdoc.api.v31.app194.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.ApiVersionConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +public class WebConfig implements WebFluxConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .usePathSegment(1) + .detectSupportedVersions(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .setVersionRequired(false) + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/User.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/User.java new file mode 100644 index 000000000..1768bf7a3 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app194.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserController.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserController.java new file mode 100644 index 000000000..21a1ab3b3 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserController.java @@ -0,0 +1,39 @@ +package test.org.springdoc.api.v31.app194.user; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING PATH SEGMENT ====================================================== + + @GetMapping(value = "/{version}/users", version = "1.0") + public List findAllv1() { + log.info("Finding all users v1"); + return userRepository.findAll(); + } + + @GetMapping(value = "/{version}/users", version = "2.0") + public List findAllv2() { + log.info("Finding all users v2"); + return userRepository.findAll(); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv1.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv1.java new file mode 100644 index 000000000..2a6ea9d64 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app194.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv2.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv2.java new file mode 100644 index 000000000..e3b381f9d --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app194.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserMapper.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserMapper.java new file mode 100644 index 000000000..a0552e4b4 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app194.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserRepository.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserRepository.java new file mode 100644 index 000000000..45d41de23 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app194/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app194.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/SpringDocApp195Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/SpringDocApp195Test.java new file mode 100644 index 000000000..05bbe3f44 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/SpringDocApp195Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app195; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp195Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app195" }) + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/ApiVersionParser.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/ApiVersionParser.java new file mode 100644 index 000000000..179d04557 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app195.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/WebConfig.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/WebConfig.java new file mode 100644 index 000000000..1b6154082 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/config/WebConfig.java @@ -0,0 +1,21 @@ +package test.org.springdoc.api.v31.app195.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.ApiVersionConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +public class WebConfig implements WebFluxConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .detectSupportedVersions(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .setVersionRequired(false) + .useRequestHeader("X-API-Version") + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/User.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/User.java new file mode 100644 index 000000000..f10aa2e34 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app195.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserController.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserController.java new file mode 100644 index 000000000..7fe63304a --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserController.java @@ -0,0 +1,46 @@ +package test.org.springdoc.api.v31.app195.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING REQUEST HEADER ====================================================== + + @GetMapping(value = "/users", version = "1.0") + public List getUsersV1() { + log.info("Find All Users using request header: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users", version = "2.0") + public List getUsersV2() { + log.info("Find All Users using request header: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv1.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv1.java new file mode 100644 index 000000000..da39f3017 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app195.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv2.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv2.java new file mode 100644 index 000000000..e381e4c0e --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app195.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserMapper.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserMapper.java new file mode 100644 index 000000000..bdc4a736a --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app195.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserRepository.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserRepository.java new file mode 100644 index 000000000..690a1fcdc --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app195/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app195.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/SpringDocApp196Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/SpringDocApp196Test.java new file mode 100644 index 000000000..9ec2ba77e --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/SpringDocApp196Test.java @@ -0,0 +1,39 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app196; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +public class SpringDocApp196Test extends AbstractSpringDocTest { + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc", "test.org.springdoc.api.v31.app196" }) + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/ApiVersionParser.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/ApiVersionParser.java new file mode 100644 index 000000000..6a4fddce9 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app196.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/WebConfig.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/WebConfig.java new file mode 100644 index 000000000..fd5d199d3 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/config/WebConfig.java @@ -0,0 +1,20 @@ +package test.org.springdoc.api.v31.app196.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.ApiVersionConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +@Configuration +public class WebConfig implements WebFluxConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .setVersionRequired(false) + .addSupportedVersions("1.0","v2") + .setDefaultVersion("1.0") + .useQueryParam("version") + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/User.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/User.java new file mode 100644 index 000000000..4eff6d48d --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app196.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserController.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserController.java new file mode 100644 index 000000000..59a5dea94 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserController.java @@ -0,0 +1,46 @@ +package test.org.springdoc.api.v31.app196.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING REQUEST PARAMETER (Query Parameter) =================================== + + @GetMapping(value = "/users/list", params = "version=1.0") + public List listUsersV1() { + log.info("Find All Users using request header: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users/list", params = "version=v2") + public List listUsersV2() { + log.info("Find All Users using request header: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv1.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv1.java new file mode 100644 index 000000000..0159d09da --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app196.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv2.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv2.java new file mode 100644 index 000000000..1413f0f35 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app196.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserMapper.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserMapper.java new file mode 100644 index 000000000..ba64a768d --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app196.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserRepository.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserRepository.java new file mode 100644 index 000000000..ded9db774 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app196/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app196.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app64/WebConfiguration.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app64/WebConfiguration.java new file mode 100644 index 000000000..37ace0881 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app64/WebConfiguration.java @@ -0,0 +1,17 @@ +package test.org.springdoc.api.v31.app64; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.reactive.config.ApiVersionConfigurer; +import org.springframework.web.reactive.config.WebFluxConfigurer; + +/** + * @author bnasslahsen + */ +@Configuration +public class WebConfiguration implements WebFluxConfigurer { + + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer.setVersionRequired(false); + configurer.useQueryParam("API-Version"); + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app75.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app75.json index c8280b78f..acc0a55dc 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app75.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app75.json @@ -22,6 +22,9 @@ "required": true, "schema": { "type": "string", + "enum": [ + "value" + ], "default": "value" } }, diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app88.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app88.json index 485bf016d..d84ef9dff 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app88.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.0.1/app88.json @@ -22,6 +22,9 @@ "required": true, "schema": { "type": "string", + "enum": [ + "value" + ], "default": "value" } }, diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app193.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app193.json new file mode 100644 index 000000000..6138f1ccf --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app193.json @@ -0,0 +1,83 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/api/users/media": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "getUsersMediaV2", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;version=2.0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + }, + "application/json;version=1.0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app194.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app194.json new file mode 100644 index 000000000..523f08b83 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app194.json @@ -0,0 +1,80 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/api/2.0/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "findAllv2", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "/api/1.0/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "findAllv1", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app195.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app195.json new file mode 100644 index 000000000..7170ac8b6 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app195.json @@ -0,0 +1,99 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/api/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "getUsersV2", + "parameters": [ + { + "name": "X-API-Version", + "in": "header", + "schema": { + "type": "string", + "default": "1.0", + "enum": [ + "2.0", + "1.0" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app196.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app196.json new file mode 100644 index 000000000..4f75b3c7e --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app196.json @@ -0,0 +1,100 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/api/users/list": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "listUsersV2", + "parameters": [ + { + "name": "version", + "in": "query", + "required": true, + "schema": { + "type": "string", + "default": "1.0", + "enum": [ + "v2", + "1.0" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app75.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app75.json index 48a13cd8f..9944778a3 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app75.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app75.json @@ -22,7 +22,10 @@ "required": true, "schema": { "type": "string", - "default": "value" + "default": "value", + "enum": [ + "value" + ] } }, { diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app88.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app88.json index 02a8ac4be..99ef2381f 100644 --- a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app88.json +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app88.json @@ -22,7 +22,10 @@ "required": true, "schema": { "type": "string", - "default": "value" + "default": "value", + "enum": [ + "value" + ] } }, { diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java index 78f050427..8b7c6a14b 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-scalar/src/test/java/test/org/springdoc/webflux/scalar/AbstractCommonTest.java @@ -12,7 +12,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.context.ActiveProfiles; diff --git a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java index 3ef7c6169..53e597149 100644 --- a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java @@ -52,6 +52,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.web.reactive.accept.ApiVersionStrategy; import org.springframework.web.reactive.config.WebFluxConfigurer; import static org.springdoc.core.utils.Constants.DEFAULT_SWAGGER_UI_ACTUATOR_PATH; @@ -84,7 +85,7 @@ public class SwaggerConfig implements WebFluxConfigurer { @ConditionalOnMissingBean @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) - SwaggerWelcomeWebFlux swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, SpringWebProvider springWebProvider) { + SwaggerWelcomeWebFlux swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, @Lazy SpringWebProvider springWebProvider) { return new SwaggerWelcomeWebFlux(swaggerUiConfig, springDocConfigProperties, springWebProvider); } @@ -160,8 +161,8 @@ SwaggerIndexTransformer indexPageTransformer(SwaggerUiConfigProperties swaggerUi @Bean @ConditionalOnMissingBean @Lazy(false) - SpringWebProvider springWebProvider() { - return new SpringWebFluxProvider(); + SpringWebProvider springWebProvider(Optional apiVersionStrategyOptional) { + return new SpringWebFluxProvider(apiVersionStrategyOptional); } /** diff --git a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java index 9840fe38f..0c090188d 100644 --- a/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java +++ b/springdoc-openapi-starter-webflux-ui/src/test/java/test/org/springdoc/ui/AbstractCommonTest.java @@ -10,7 +10,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java index 6d2465ba8..20f2a5e7b 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/api/OpenApiResource.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.TreeMap; @@ -54,6 +55,7 @@ import org.springdoc.core.service.GenericResponseService; import org.springdoc.core.service.OpenAPIService; import org.springdoc.core.service.OperationService; +import org.springdoc.core.versions.SpringDocVersionStrategy; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.ObjectFactory; @@ -73,7 +75,7 @@ * @author bnasslahsen, Azige */ public abstract class OpenApiResource extends AbstractOpenApiResource { - + /** * Instantiates a new Open api resource. * @@ -163,7 +165,7 @@ protected void getPaths(Map restControllers, Locale locale, Open AbstractOpenApiResource.addRestControllers(additionalRestClasses); map.putAll(mapDataRest); }); - + Optional actuatorProviderOptional = springDocProviders.getActuatorProvider(); if (actuatorProviderOptional.isPresent() && springDocConfigProperties.isShowActuator()) { Map actuatorMap = actuatorProviderOptional.get().getMethods(); @@ -205,8 +207,8 @@ protected void calculatePath(Map restControllers, Map methodTreeMap = new TreeMap<>(byReversedRequestMappingInfos()); methodTreeMap.putAll(map); Optional springWebProviderOptional = springDocProviders.getSpringWebProvider(); - springWebProviderOptional.ifPresent(springWebProvider -> { - for (Map.Entry entry : methodTreeMap.entrySet()) { + springWebProviderOptional.ifPresent( springWebProvider -> { + for (Entry entry : methodTreeMap.entrySet()) { RequestMappingInfo requestMappingInfo = entry.getKey(); HandlerMethod handlerMethod = entry.getValue(); Set patterns = springWebProvider.getActivePatterns(requestMappingInfo); @@ -218,13 +220,18 @@ protected void calculatePath(Map restControllers, Map requestMethods = requestMappingInfo.getMethodsCondition().getMethods(); // default allowed requestmethods if (requestMethods.isEmpty()) requestMethods = this.getDefaultAllowedHttpMethods(); - calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, params, locale, openAPI); + SpringDocVersionStrategy springDocVersionStrategy = springWebProvider.getSpringDocVersionStrategy(version, params); + if(springDocVersionStrategy != null) + operationPath = springDocVersionStrategy.updateOperationPath(operationPath, version); + + calculatePath(handlerMethod, operationPath, requestMethods, consumes, produces, headers, params, springDocVersionStrategy, locale, openAPI); } } } diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java index b05038ad6..19df09647 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/configuration/SpringDocWebMvcConfiguration.java @@ -66,6 +66,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.web.accept.ApiVersionStrategy; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @@ -138,13 +139,14 @@ RequestService requestBuilder(GenericParameterService parameterBuilder, RequestB /** * Spring web provider spring web provider. * + * @param apiVersionStrategyOptional the api version strategy optional * @return the spring web provider */ @Bean @ConditionalOnMissingBean @Lazy(false) - SpringWebProvider springWebProvider() { - return new SpringWebMvcProvider(); + SpringWebProvider springWebProvider(Optional apiVersionStrategyOptional) { + return new SpringWebMvcProvider(apiVersionStrategyOptional); } /** diff --git a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/SpringWebMvcProvider.java b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/SpringWebMvcProvider.java index b532a73c3..7a7fe9354 100644 --- a/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/SpringWebMvcProvider.java +++ b/springdoc-openapi-starter-webmvc-api/src/main/java/org/springdoc/webmvc/core/providers/SpringWebMvcProvider.java @@ -25,18 +25,35 @@ */ package org.springdoc.webmvc.core.providers; +import java.lang.reflect.Field; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.reflect.FieldUtils; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.core.providers.SpringWebProvider; +import org.springdoc.core.versions.HeaderVersionStrategy; +import org.springdoc.core.versions.MediaTypeVersionStrategy; +import org.springdoc.core.versions.PathVersionStrategy; +import org.springdoc.core.versions.QueryParamVersionStrategy; +import org.springdoc.core.versions.SpringDocApiVersionType; +import org.springframework.http.MediaType; import org.springframework.util.CollectionUtils; +import org.springframework.web.accept.ApiVersionResolver; +import org.springframework.web.accept.ApiVersionStrategy; +import org.springframework.web.accept.DefaultApiVersionStrategy; +import org.springframework.web.accept.HeaderApiVersionResolver; +import org.springframework.web.accept.MediaTypeParamApiVersionResolver; +import org.springframework.web.accept.PathApiVersionResolver; +import org.springframework.web.accept.QueryApiVersionResolver; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping; import org.springframework.web.servlet.mvc.condition.PathPatternsRequestCondition; @@ -51,6 +68,55 @@ */ public class SpringWebMvcProvider extends SpringWebProvider { + /** + * Instantiates a new Spring web mvc provider. + * + * @param apiVersionStrategyOptional the api version strategy optional + */ + public SpringWebMvcProvider(Optional apiVersionStrategyOptional) { + apiVersionStrategyOptional.ifPresent(apiVersionStrategy -> { + try { + DefaultApiVersionStrategy defaultApiVersionStrategy = (DefaultApiVersionStrategy) apiVersionStrategy; + String defaultVersion = null; + if(defaultApiVersionStrategy.getDefaultVersion() !=null) + defaultVersion = defaultApiVersionStrategy.getDefaultVersion().toString(); + Field field = FieldUtils.getDeclaredField(DefaultApiVersionStrategy.class, "versionResolvers", true); + final List versionResolvers = (List) field.get(defaultApiVersionStrategy); + for (ApiVersionResolver apiVersionResolver : versionResolvers) { + if (apiVersionResolver instanceof MediaTypeParamApiVersionResolver mediaTypeParamApiVersionResolver) { + field = FieldUtils.getDeclaredField(MediaTypeParamApiVersionResolver.class, "compatibleMediaType", true); + MediaType mediaType = (MediaType) field.get(mediaTypeParamApiVersionResolver); + field = FieldUtils.getDeclaredField(MediaTypeParamApiVersionResolver.class, "parameterName", true); + String parameterName = (String) field.get(mediaTypeParamApiVersionResolver); + MediaTypeVersionStrategy mediaTypeStrategy = new MediaTypeVersionStrategy(mediaType, parameterName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.MEDIA_TYPE, mediaTypeStrategy); + } + else if (apiVersionResolver instanceof PathApiVersionResolver pathApiVersionResolver) { + field = FieldUtils.getDeclaredField(PathApiVersionResolver.class, "pathSegmentIndex", true); + Integer pathSegmentIndex = (Integer) field.get(pathApiVersionResolver); + PathVersionStrategy pathVersionStrategy = new PathVersionStrategy(pathSegmentIndex, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.PATH, pathVersionStrategy); + } + else if (apiVersionResolver instanceof HeaderApiVersionResolver headerApiVersionResolver) { + field = FieldUtils.getDeclaredField(HeaderApiVersionResolver.class, "headerName", true); + String headerName = (String) field.get(headerApiVersionResolver); + HeaderVersionStrategy headerVersionStrategy = new HeaderVersionStrategy(headerName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.HEADER, headerVersionStrategy); + } + else if (apiVersionResolver instanceof QueryApiVersionResolver queryApiVersionResolver) { + field = FieldUtils.getDeclaredField(QueryApiVersionResolver.class, "queryParamName", true); + String queryParamName = (String) field.get(queryApiVersionResolver); + QueryParamVersionStrategy queryParamVersionStrategy = new QueryParamVersionStrategy(queryParamName, defaultVersion); + springDocVersionStrategyMap.put(SpringDocApiVersionType.QUERY_PARAM, queryParamVersionStrategy); + } + } + } + catch (IllegalAccessException e) { + LOGGER.warn(e.getMessage()); + } + }); + } + /** * Finds path prefix. * @@ -93,7 +159,6 @@ public Set getActivePatterns(Object requestMapping) { return patterns; } - /** * Gets handler methods. * @@ -107,8 +172,9 @@ public Map getHandlerMethods() { .map(AbstractHandlerMethodMapping::getHandlerMethods) .map(Map::entrySet) .flatMap(Collection::stream) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a1, a2) -> a1, LinkedHashMap::new)); + .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a1, a2) -> a1, LinkedHashMap::new)); } return this.handlerMethods; } + } diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java new file mode 100644 index 000000000..45461c3ba --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/SpringDocApp248Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.v31.app248; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp248Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/ApiVersionParser.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/ApiVersionParser.java new file mode 100644 index 000000000..106f47f5b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app248.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/WebConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/WebConfig.java new file mode 100644 index 000000000..51c5f0fcc --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/config/WebConfig.java @@ -0,0 +1,23 @@ +package test.org.springdoc.api.v31.app248.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @author bnasslahsen + */ +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .setVersionRequired(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .useMediaTypeParameter(MediaType.APPLICATION_JSON, "version") + .setVersionParser(new ApiVersionParser()); + } +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/User.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/User.java new file mode 100644 index 000000000..f501389ed --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app248.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserController.java new file mode 100644 index 000000000..5dd2216c4 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserController.java @@ -0,0 +1,47 @@ +package test.org.springdoc.api.v31.app248.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING MEDIA TYPE (Content Negotiation) ======================================= + + @GetMapping(value = "/users/media", version = "1.0", produces = "application/json") + public List getUsersMediaV1() { + log.info("Find All Users using media type versioning: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users/media", version = "2.0", produces = MediaType.APPLICATION_JSON_VALUE) + public List getUsersMediaV2() { + log.info("Find All Users using media type versioning: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv1.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv1.java new file mode 100644 index 000000000..4095422a5 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app248.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv2.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv2.java new file mode 100644 index 000000000..3e9892a40 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app248.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserMapper.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserMapper.java new file mode 100644 index 000000000..31207a589 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app248.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserRepository.java new file mode 100644 index 000000000..b98ec5f76 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app248/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app248.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/SpringDocApp249Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/SpringDocApp249Test.java new file mode 100644 index 000000000..4bf8235c0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/SpringDocApp249Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.v31.app249; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp249Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/ApiVersionParser.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/ApiVersionParser.java new file mode 100644 index 000000000..e842f664b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app249.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/WebConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/WebConfig.java new file mode 100644 index 000000000..6fa733c41 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/config/WebConfig.java @@ -0,0 +1,21 @@ +package test.org.springdoc.api.v31.app249.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .usePathSegment(1) + .detectSupportedVersions(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .setVersionRequired(false) + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/User.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/User.java new file mode 100644 index 000000000..78092199f --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app249.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserController.java new file mode 100644 index 000000000..1464665e0 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserController.java @@ -0,0 +1,39 @@ +package test.org.springdoc.api.v31.app249.user; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING PATH SEGMENT ====================================================== + + @GetMapping(value = "/v{api}/users", version = "1.0") + public List findAllv1() { + log.info("Finding all users v1"); + return userRepository.findAll(); + } + + @GetMapping(value = "/{version}/users", version = "2.0") + public List findAllv2() { + log.info("Finding all users v2"); + return userRepository.findAll(); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv1.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv1.java new file mode 100644 index 000000000..75fc7eb89 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app249.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv2.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv2.java new file mode 100644 index 000000000..a1883833e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app249.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserMapper.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserMapper.java new file mode 100644 index 000000000..57258f6c5 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app249.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserRepository.java new file mode 100644 index 000000000..42f7e1a2b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app249/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app249.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/SpringDocApp250Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/SpringDocApp250Test.java new file mode 100644 index 000000000..2dc545c19 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/SpringDocApp250Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.v31.app250; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp250Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/ApiVersionParser.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/ApiVersionParser.java new file mode 100644 index 000000000..652cfc591 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/ApiVersionParser.java @@ -0,0 +1,24 @@ +package test.org.springdoc.api.v31.app250.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + // allows us to use /api/v2/users instead of /api/2.0/users + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/WebConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/WebConfig.java new file mode 100644 index 000000000..2220e2d1f --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/config/WebConfig.java @@ -0,0 +1,21 @@ +package test.org.springdoc.api.v31.app250.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .detectSupportedVersions(false) + .addSupportedVersions("1.0","2.0") + .setDefaultVersion("1.0") + .setVersionRequired(false) + .useRequestHeader("X-API-Version") + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/User.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/User.java new file mode 100644 index 000000000..dd1fdec1e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app250.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserController.java new file mode 100644 index 000000000..a1c1fc72e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserController.java @@ -0,0 +1,46 @@ +package test.org.springdoc.api.v31.app250.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING REQUEST HEADER ====================================================== + + @GetMapping(value = "/users", version = "1.0") + public List getUsersV1() { + log.info("Find All Users using request header: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users", version = "2.0") + public List getUsersV2() { + log.info("Find All Users using request header: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv1.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv1.java new file mode 100644 index 000000000..32b17a53c --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app250.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv2.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv2.java new file mode 100644 index 000000000..ff4bd7b2c --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app250.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserMapper.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserMapper.java new file mode 100644 index 000000000..9ab5218ec --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app250.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserRepository.java new file mode 100644 index 000000000..64163c587 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app250/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app250.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/SpringDocApp251Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/SpringDocApp251Test.java new file mode 100644 index 000000000..bc5991f41 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/SpringDocApp251Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.v31.app251; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp251Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/ApiVersionParser.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/ApiVersionParser.java new file mode 100644 index 000000000..1817e4eda --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/ApiVersionParser.java @@ -0,0 +1,23 @@ +package test.org.springdoc.api.v31.app251.config; + +public class ApiVersionParser implements org.springframework.web.accept.ApiVersionParser { + + @Override + public Comparable parseVersion(String version) { + // Remove "v" prefix if it exists (v1 becomes 1, v2 becomes 2) + if (version.startsWith("v") || version.startsWith("V")) { + version = version.substring(1); + } + + if("api-docs".equals(version) || "index.html".equals(version) + || "swagger-ui-bundle.js".equals(version) + || "swagger-ui.css".equals(version) + || "index.css".equals(version) + || "swagger-ui-standalone-preset.js".equals(version) + || "favicon-32x32.png".equals(version) + || "favicon-16x16.png".equals(version) + || "swagger-initializer.js".equals(version)) + return null; + return version; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/WebConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/WebConfig.java new file mode 100644 index 000000000..6e41d7902 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/config/WebConfig.java @@ -0,0 +1,20 @@ +package test.org.springdoc.api.v31.app251.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .setVersionRequired(false) + .addSupportedVersions("1.0","v2") + .setDefaultVersion("1.0") + .useQueryParam("version") + .setVersionParser(new ApiVersionParser()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/User.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/User.java new file mode 100644 index 000000000..b3d3e4495 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/User.java @@ -0,0 +1,10 @@ +package test.org.springdoc.api.v31.app251.user; + +public record User( + Integer id, + String name, + String email + + // a lot more fields here +) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserController.java new file mode 100644 index 000000000..950ef4eac --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserController.java @@ -0,0 +1,46 @@ +package test.org.springdoc.api.v31.app251.user; + +import java.util.List; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api") +public class UserController { + + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserRepository userRepository; + private final UserMapper userMapper; + + public UserController(UserRepository userRepository, UserMapper userMapper) { + this.userRepository = userRepository; + this.userMapper = userMapper; + } + + // USING REQUEST PARAMETER (Query Parameter) =================================== + + @GetMapping(value = "/users/list", params = "version=1.0") + public List listUsersV1() { + log.info("Find All Users using request header: {}", "v1"); + return userRepository.findAll() + .stream() + .map(userMapper::toV1) + .collect(Collectors.toList()); + } + + @GetMapping(value = "/users/list", params = "version=v2") + public List listUsersV2() { + log.info("Find All Users using request header: {}", "v2"); + return userRepository.findAll() + .stream() + .map(userMapper::toV2) + .collect(Collectors.toList()); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv1.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv1.java new file mode 100644 index 000000000..4f5f4f77b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv1.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app251.user; + +public record UserDTOv1(Integer id, String name, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv2.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv2.java new file mode 100644 index 000000000..617d96fad --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserDTOv2.java @@ -0,0 +1,4 @@ +package test.org.springdoc.api.v31.app251.user; + +public record UserDTOv2(Integer id, String firstName,String lastName, String email) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserMapper.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserMapper.java new file mode 100644 index 000000000..2e1764e75 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserMapper.java @@ -0,0 +1,83 @@ +package test.org.springdoc.api.v31.app251.user; + +import org.springframework.stereotype.Component; + +/* + * you could also use a library like MapStruct + */ +@Component +public class UserMapper { + + // User to DTOs + public UserDTOv1 toV1(User user) { + return new UserDTOv1( + user.id(), + user.name(), + user.email() + ); + } + + public UserDTOv2 toV2(User user) { + String[] nameParts = splitName(user.name()); + return new UserDTOv2( + user.id(), + nameParts[0], // firstName + nameParts[1], // lastName + user.email() + ); + } + + // DTOs to User + public User fromV1(UserDTOv1 dto) { + return new User( + dto.id(), + dto.name(), + dto.email() + ); + } + + public User fromV2(UserDTOv2 dto) { + String combinedName = combineName(dto.firstName(), dto.lastName()); + return new User( + dto.id(), + combinedName, + dto.email() + ); + } + + // Helper methods + private String[] splitName(String fullName) { + if (fullName == null || fullName.trim().isEmpty()) { + return new String[]{"", ""}; + } + + String trimmed = fullName.trim(); + int lastSpaceIndex = trimmed.lastIndexOf(' '); + + if (lastSpaceIndex == -1) { + // Single word name - put it as firstName + return new String[]{trimmed, ""}; + } + + // Split at last space (handles middle names better) + // "John Smith Jr" -> "John Smith" and "Jr" + // "Mary Ann Smith" -> "Mary Ann" and "Smith" + return new String[]{ + trimmed.substring(0, lastSpaceIndex), + trimmed.substring(lastSpaceIndex + 1) + }; + } + + private String combineName(String firstName, String lastName) { + firstName = firstName != null ? firstName.trim() : ""; + lastName = lastName != null ? lastName.trim() : ""; + + if (firstName.isEmpty()) { + return lastName; + } + if (lastName.isEmpty()) { + return firstName; + } + return firstName + " " + lastName; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserRepository.java new file mode 100644 index 000000000..ba5b1675c --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app251/user/UserRepository.java @@ -0,0 +1,27 @@ +package test.org.springdoc.api.v31.app251.user; + +import java.util.ArrayList; +import java.util.List; + +import jakarta.annotation.PostConstruct; + +import org.springframework.stereotype.Repository; + +@Repository +public class UserRepository { + + private final List users = new ArrayList<>(); + + public List findAll() { + return users; + } + + public User findById(Integer id) { + return users.stream().filter(u -> u.id().equals(id)).findFirst().orElse(null); + } + + @PostConstruct + private void init() { + users.add(new User(1,"Dan Vega","danvega@gmail.com")); + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/SpringDocApp252Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/SpringDocApp252Test.java new file mode 100644 index 000000000..bb4ebfce3 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/SpringDocApp252Test.java @@ -0,0 +1,11 @@ +package test.org.springdoc.api.v31.app252; + +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp252Test extends AbstractSpringDocTest { + + @SpringBootApplication + static class SpringDocTestApp {} +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/AppConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/AppConfig.java new file mode 100644 index 000000000..2fcc989c9 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/AppConfig.java @@ -0,0 +1,35 @@ +package test.org.springdoc.api.v31.app252.config; + +import java.math.BigDecimal; +import java.util.Map; + +import test.org.springdoc.api.v31.app252.repository.Account; +import test.org.springdoc.api.v31.app252.repository.AccountRepository; +import test.org.springdoc.api.v31.app252.repository.Statement; +import test.org.springdoc.api.v31.app252.repository.Statement.Type; +import test.org.springdoc.api.v31.app252.repository.StatementRepository; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; + +/** + * @author bnasslahsen + */ +@Configuration +public class AppConfig { + + @Bean + AccountRepository accountRepository() { + return new AccountRepository(Map.of("1", new Account("1", "Checking"))); + } + + @Bean + StatementRepository statementRepository() { + MultiValueMap statements = new LinkedMultiValueMap<>(); + statements.add("1", new Statement(250, Type.CREDIT)); + statements.add("1", new Statement(110, Type.DEBIT)); + return new StatementRepository(statements); + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/WebConfig.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/WebConfig.java new file mode 100644 index 000000000..ab2a797ca --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/config/WebConfig.java @@ -0,0 +1,36 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ApiVersionConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void configureApiVersioning(ApiVersionConfigurer configurer) { + configurer + .detectSupportedVersions(false) + .addSupportedVersions("1.1.0","1.2.0") + .setDefaultVersion("1.1.0") + .setVersionRequired(false) + .useRequestHeader("X-Api-Version"); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Account.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Account.java new file mode 100644 index 000000000..2d19d4ce7 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Account.java @@ -0,0 +1,20 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.repository; + +public record Account(String id, String name) { +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/AccountRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/AccountRepository.java new file mode 100644 index 000000000..4fd32f555 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/AccountRepository.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.repository; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; + +public class AccountRepository { + + private final Map accounts; + + public AccountRepository(Map accounts) { + this.accounts = new HashMap<>(accounts); + } + + public Account getAccount(String id) { + Account account = accounts.get(id); + if (account == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + return account; + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Statement.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Statement.java new file mode 100644 index 000000000..85add0c55 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/Statement.java @@ -0,0 +1,25 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.repository; + +public record Statement(int amount, Type type) { + + public enum Type { + DEBIT, CREDIT + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/StatementRepository.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/StatementRepository.java new file mode 100644 index 000000000..a2bf0d31b --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/repository/StatementRepository.java @@ -0,0 +1,54 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.repository; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.http.HttpStatus; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.server.ResponseStatusException; + +public class StatementRepository { + + private final MultiValueMap statementsByAccount; + + public StatementRepository(MultiValueMap statements) { + this.statementsByAccount = new LinkedMultiValueMap<>(statements); + } + + public List getStatementsForAccount(String id) { + List list = statementsByAccount.get(id); + if (list == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + return list; + } + + public List getStatementsForAccountAndType(String id, Statement.Type type) { + List statements = statementsByAccount.get(id); + if (statements == null) { + throw new ResponseStatusException(HttpStatus.NOT_FOUND); + } + List filteredStatements = statements.stream().filter(statement -> + statement.type() == type + ).collect(Collectors.toUnmodifiableList()); + + return filteredStatements; + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/AccountController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/AccountController.java new file mode 100644 index 000000000..3fa7ea719 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/AccountController.java @@ -0,0 +1,48 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.web; + + +import test.org.springdoc.api.v31.app252.repository.Account; +import test.org.springdoc.api.v31.app252.repository.AccountRepository; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/accounts") +public class AccountController { + + private final AccountRepository repository; + + public AccountController(AccountRepository repository) { + this.repository = repository; + } + + @GetMapping(value = "/{id}", version = "1.0.0") + Account getAccount(@PathVariable String id) { + return repository.getAccount(id); + } + + @GetMapping(path = "/{id}", version = "1.1.0") + Account getAccount1_1(@PathVariable String id) { + return repository.getAccount(id); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/StatementController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/StatementController.java new file mode 100644 index 000000000..b00f0bb16 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v31/app252/web/StatementController.java @@ -0,0 +1,52 @@ +/* + * Copyright 2002-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package test.org.springdoc.api.v31.app252.web; + +import java.util.List; + + +import test.org.springdoc.api.v31.app252.repository.Statement; +import test.org.springdoc.api.v31.app252.repository.StatementRepository; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/accounts/{id}/statements") +public class StatementController { + + private final StatementRepository repository; + + public StatementController(StatementRepository repository) { + this.repository = repository; + } + + @GetMapping + List getStatements(@PathVariable String id) { + return repository.getStatementsForAccount(id); + } + + @GetMapping(version = "1.2.0") + List getStatements1_2(@PathVariable String id, @RequestParam(required = false) Statement.Type type) { + + return repository.getStatementsForAccountAndType(id, type); + } + +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app248.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app248.json new file mode 100644 index 000000000..40b3da993 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app248.json @@ -0,0 +1,83 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/api/users/media": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "getUsersMediaV2", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json;version=2.0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + }, + "application/json;version=1.0": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app249.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app249.json new file mode 100644 index 000000000..d4178bcb7 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app249.json @@ -0,0 +1,80 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/api/2.0/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "findAllv2", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "/api/v1.0/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "findAllv1", + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app250.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app250.json new file mode 100644 index 000000000..653ae94ea --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app250.json @@ -0,0 +1,99 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/api/users": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "getUsersV2", + "parameters": [ + { + "name": "X-API-Version", + "in": "header", + "schema": { + "type": "string", + "default": "1.0", + "enum": [ + "2.0", + "1.0" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app251.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app251.json new file mode 100644 index 000000000..b60372b42 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app251.json @@ -0,0 +1,100 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/api/users/list": { + "get": { + "tags": [ + "user-controller" + ], + "operationId": "listUsersV2", + "parameters": [ + { + "name": "version", + "in": "query", + "required": true, + "schema": { + "type": "string", + "default": "1.0", + "enum": [ + "v2", + "1.0" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "oneOf": [ + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv1" + } + }, + { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDTOv2" + } + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "UserDTOv2": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "UserDTOv1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int32" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app252.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app252.json new file mode 100644 index 000000000..78e6c7300 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.1.0/app252.json @@ -0,0 +1,145 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "http://localhost", + "description": "Generated server url" + } + ], + "paths": { + "/accounts/{id}": { + "get": { + "tags": [ + "account-controller" + ], + "operationId": "getAccount1_1", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "X-Api-Version", + "in": "header", + "schema": { + "type": "string", + "default": "1.1.0", + "enum": [ + "1.1.0", + "1.0.0" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/Account" + } + } + } + } + } + } + }, + "/accounts/{id}/statements": { + "get": { + "tags": [ + "statement-controller" + ], + "operationId": "getStatements", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "X-Api-Version", + "in": "header", + "schema": { + "type": "string", + "default": "1.1.0", + "enum": [ + "1.2.0", + "1.1.0" + ] + } + }, + { + "name": "type", + "in": "query", + "required": false, + "schema": { + "type": "string", + "enum": [ + "DEBIT", + "CREDIT" + ] + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Statement" + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Account": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "Statement": { + "type": "object", + "properties": { + "amount": { + "type": "integer", + "format": "int32" + }, + "type": { + "type": "string", + "enum": [ + "DEBIT", + "CREDIT" + ] + } + } + } + } + } +} diff --git a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java index 307c102c4..f4472fa59 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java @@ -51,6 +51,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; +import org.springframework.web.accept.ApiVersionStrategy; import static org.springdoc.core.utils.Constants.DEFAULT_SWAGGER_UI_ACTUATOR_PATH; import static org.springdoc.core.utils.Constants.SPRINGDOC_SWAGGER_UI_ENABLED; @@ -82,20 +83,21 @@ public class SwaggerConfig { @ConditionalOnMissingBean @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) - SwaggerWelcomeWebMvc swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, SpringWebProvider springWebProvider) { + SwaggerWelcomeWebMvc swaggerWelcome(SwaggerUiConfigProperties swaggerUiConfig, SpringDocConfigProperties springDocConfigProperties, @Lazy SpringWebProvider springWebProvider) { return new SwaggerWelcomeWebMvc(swaggerUiConfig, springDocConfigProperties, springWebProvider); } /** * Spring web provider spring web provider. * + * @param apiVersionStrategyOptional the api version strategy optional * @return the spring web provider */ @Bean @ConditionalOnMissingBean @Lazy(false) - SpringWebProvider springWebProvider() { - return new SpringWebMvcProvider(); + SpringWebProvider springWebProvider(Optional apiVersionStrategyOptional) { + return new SpringWebMvcProvider(apiVersionStrategyOptional); } /** diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 6cf91d3bb..5af760463 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -36,7 +36,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index e2a6bf29e..191509402 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -36,7 +36,7 @@ import org.springdoc.core.utils.Constants; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java index 9593f2b80..db8238969 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java index 37c9e6ea4..9538ea60d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v30/AbstractSpringDocFunctionTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java index 3ca0d9afd..3f29f5d89 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractCommonTest.java @@ -35,7 +35,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.web.reactive.server.WebTestClient; diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java index afacd5f56..bb23c9668 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/src/test/java/test/org/springdoc/api/v31/AbstractSpringDocFunctionTest.java @@ -30,7 +30,7 @@ import org.junit.jupiter.api.Test; import org.springdoc.core.utils.Constants; -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient; +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient; import org.springframework.cloud.function.context.test.FunctionalSpringBootTest; import org.springframework.test.web.reactive.server.EntityExchangeResult; diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt index ad749605a..9e0f53c0c 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v30/AbstractKotlinSpringDocTest.kt @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory import org.springdoc.core.utils.Constants import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.TestPropertySource import org.springframework.test.web.reactive.server.WebTestClient diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt index 9e596a4e5..6607d33cb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/src/test/kotlin/test/org/springdoc/api/v31/AbstractKotlinSpringDocTest.kt @@ -32,7 +32,7 @@ import org.slf4j.LoggerFactory import org.springdoc.core.utils.Constants import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.webflux.test.autoconfigure.WebFluxTest -import org.springframework.boot.webtestclient.AutoConfigureWebTestClient +import org.springframework.boot.webtestclient.autoconfigure.AutoConfigureWebTestClient import org.springframework.test.context.ActiveProfiles import org.springframework.test.web.reactive.server.WebTestClient import java.nio.charset.StandardCharsets From 007977e2a87125c130273ab197ea9113e3503c97 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Tue, 11 Nov 2025 13:50:53 +0100 Subject: [PATCH 36/45] feat: static resources for webflux #3123 --- .../core/visitor/RouterFunctionVisitor.java | 19 ++- .../api/v31/app197/SpringDocApp197Test.java | 113 ++++++++++++++++++ .../src/test/resources/icons/icon.svg | 3 + .../test/resources/results/3.1.0/app197.json | 40 +++++++ 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app197/SpringDocApp197Test.java create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/icons/icon.svg create mode 100644 springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app197.json diff --git a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java index d3cfb4e5f..756358115 100644 --- a/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java +++ b/springdoc-openapi-starter-webflux-api/src/main/java/org/springdoc/webflux/core/visitor/RouterFunctionVisitor.java @@ -26,19 +26,24 @@ package org.springdoc.webflux.core.visitor; +import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Set; import java.util.function.Function; import org.springdoc.core.fn.AbstractRouterFunctionVisitor; import reactor.core.publisher.Mono; import org.springframework.core.io.Resource; +import org.springframework.http.HttpMethod; +import org.springframework.util.ReflectionUtils; import org.springframework.web.reactive.function.server.HandlerFunction; import org.springframework.web.reactive.function.server.RequestPredicate; import org.springframework.web.reactive.function.server.RequestPredicates; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.util.pattern.PathPattern; /** * The type Router function visitor. @@ -67,7 +72,19 @@ public void endNested(RequestPredicate predicate) { @Override public void resources(Function> lookupFunction) { - // Not yet needed + if ("PathResourceLookupFunction".equals(lookupFunction.getClass().getSimpleName())) { + Field patternField = ReflectionUtils.findField(lookupFunction.getClass(), "pattern"); + if (patternField != null) { + ReflectionUtils.makeAccessible(patternField); + Object patternFieldValue = ReflectionUtils.getField(patternField, lookupFunction); + if (patternFieldValue instanceof PathPattern patternCastedValue) { + this.currentRouterFunctionDatas = new ArrayList<>(); + this.path(patternCastedValue.getPatternString()); + this.commonRoute(); + this.method(Set.of(HttpMethod.GET)); + } + } + } } @Override diff --git a/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app197/SpringDocApp197Test.java b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app197/SpringDocApp197Test.java new file mode 100644 index 000000000..cb80d75dd --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/java/test/org/springdoc/api/v31/app197/SpringDocApp197Test.java @@ -0,0 +1,113 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v31.app197; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.headers.Header; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import org.junit.jupiter.api.Test; +import org.springdoc.core.annotations.RouterOperation; +import reactor.core.publisher.Mono; +import test.org.springdoc.api.v31.AbstractSpringDocTest; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.CacheControl; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.reactive.function.server.EntityResponse; +import org.springframework.web.reactive.function.server.HandlerFilterFunction; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class SpringDocApp197Test extends AbstractSpringDocTest { + + @Test + void getIconResource() { + webTestClient.get().uri("/icons/icon.svg").exchange() + .expectStatus().isOk() + .expectHeader().cacheControl(CacheControl.maxAge(Duration.ofHours(24))) + .expectBody().consumeWith(response -> { + byte[] body = response.getResponseBody(); + assertNotNull(body); + String bodyValue = new String(body, StandardCharsets.UTF_8); + assertThat(bodyValue).contains(""); + }); + } + + @Test + void getUnknownResource() { + webTestClient.get().uri("/icons/unknown.svg").exchange() + .expectStatus().isNotFound(); + } + + @SpringBootApplication + @ComponentScan(basePackages = { "org.springdoc" }) + static class SpringDocTestApp { + + @Bean + @RouterOperation( + method = RequestMethod.GET, + operation = @Operation( + operationId = "getIcon", + summary = "Get icons resource.", + responses = @ApiResponse( + responseCode = "200", content = @Content(mediaType = "image/svg+xml"), description = "icon resource", + headers = @Header(name = HttpHeaders.CACHE_CONTROL, required = true, description = "Cache-Control for icons", schema = @Schema(type = "string")) + ) + ) + ) + public RouterFunction getIconsResourceWithCacheControl() { + return RouterFunctions + .resources("/icons/**", new ClassPathResource("icons/")) + .filter(HandlerFilterFunction.ofResponseProcessor(this::injectCacheControlHeader)); + } + + private Mono injectCacheControlHeader(ServerResponse serverResponse) { + if (serverResponse instanceof EntityResponse entityResponse) { + return EntityResponse.fromObject(entityResponse.entity()) + .header(HttpHeaders.CACHE_CONTROL, CacheControl.maxAge(24, TimeUnit.HOURS).getHeaderValue()) + .build().cast(ServerResponse.class); + } + return Mono.just(serverResponse); + } + + } + +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/icons/icon.svg b/springdoc-openapi-starter-webflux-api/src/test/resources/icons/icon.svg new file mode 100644 index 000000000..6d210d9f2 --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/icons/icon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app197.json b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app197.json new file mode 100644 index 000000000..c738d9efd --- /dev/null +++ b/springdoc-openapi-starter-webflux-api/src/test/resources/results/3.1.0/app197.json @@ -0,0 +1,40 @@ +{ + "openapi": "3.1.0", + "info": { + "title": "OpenAPI definition", + "version": "v0" + }, + "servers": [ + { + "url": "", + "description": "Generated server url" + } + ], + "paths": { + "/icons/**": { + "get": { + "operationId": "getIcon", + "summary": "Get icons resource.", + "responses": { + "200": { + "description": "icon resource", + "content": { + "image/svg+xml": {} + }, + "headers": { + "Cache-Control": { + "description": "Cache-Control for icons", + "required": true, + "style":"simple", + "schema": { + "type": "string" + } + } + } + } + } + } + } + }, + "components": {} +} From e444deee5a023e564be98f9cac395715e1b49ce3 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Tue, 11 Nov 2025 13:58:37 +0100 Subject: [PATCH 37/45] Changes report: Regression where content type from swagger @RequestBody does not take precedence #3133 --- .../core/models/MethodAttributes.java | 9 ++ .../core/service/RequestBodyService.java | 4 +- .../api/v30/app244/HelloController.java | 86 +++++++++++ .../api/v30/app244/SpringDocApp244Test.java | 35 +++++ .../test/resources/results/3.0.1/app244.json | 134 ++++++++++++++++++ 5 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/HelloController.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/SpringDocApp244Test.java create mode 100644 springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app244.json diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java index 2c9bf6cec..59e6da6df 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/models/MethodAttributes.java @@ -470,6 +470,15 @@ public void setJsonViewAnnotationForRequestBody(JsonView jsonViewAnnotationForRe this.jsonViewAnnotationForRequestBody = jsonViewAnnotationForRequestBody; } + /** + * Is with response body schema doc boolean. + * + * @return the boolean + */ + public boolean isWithResponseBodySchemaDoc() { + return withResponseBodySchemaDoc; + } + /** * Gets headers. * diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java index 35ec79e9b..1b8bdd309 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/service/RequestBodyService.java @@ -299,7 +299,9 @@ private RequestBody buildRequestBody(io.swagger.v3.oas.annotations.parameters.Re Schema schema = parameterBuilder.calculateSchema(components, parameterInfo, requestBodyInfo, methodAttributes.getJsonViewAnnotationForRequestBody()); Map parameterEncoding = getParameterEncoding(parameterInfo); - buildContent(requestBody, methodAttributes, schema, parameterEncoding); + // If a content type is explicitly stated with a @RequestBody annotation, yield to that content type + if (!methodAttributes.isWithResponseBodySchemaDoc()) + buildContent(requestBody, methodAttributes, schema, parameterEncoding); // Add requestBody javadoc if (StringUtils.isBlank(requestBody.getDescription()) && parameterBuilder.getJavadocProvider() != null diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/HelloController.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/HelloController.java new file mode 100644 index 000000000..2d16db3c8 --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/HelloController.java @@ -0,0 +1,86 @@ +/* + * + * * + * * * + * * * * + * * * * * + * * * * * * Copyright 2019-2025 the original author or authors. + * * * * * * + * * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * * you may not use this file except in compliance with the License. + * * * * * * You may obtain a copy of the License at + * * * * * * + * * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * * + * * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * * See the License for the specific language governing permissions and + * * * * * * limitations under the License. + * * * * * + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v30.app244; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import org.springdoc.core.annotations.ParameterObject; + +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HelloController { + + public record Greeting(String hi, String bye) { + } + + @PostMapping(value = "v1/greet", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) + public void endpoint(@RequestBody @ModelAttribute Greeting greeting) { + + } + + @PostMapping(value = "v2/greet") + public void endpoint2(@ParameterObject @ModelAttribute Greeting greeting) { + + } + + @PostMapping(value = "v3/greet") + @RequestBody( + content = @Content( + mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + schema = @Schema(implementation = Greeting.class) + )) + public void endpoint3(Greeting greeting) { + + } + + @PostMapping(value = "v4/greet") + public void endpoint4( + @RequestBody(content = @Content( + mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + schema = @Schema(implementation = Greeting.class))) + @ModelAttribute Greeting greeting) { + + } + + @PostMapping(value = "v5/greet") + @Operation( + requestBody = @RequestBody(content = @Content( + mediaType = MediaType.APPLICATION_FORM_URLENCODED_VALUE, + schema = @Schema(implementation = Greeting.class)) + )) + public void endpoint5(@ModelAttribute Greeting greeting) { + + } + +} + diff --git a/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/SpringDocApp244Test.java b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/SpringDocApp244Test.java new file mode 100644 index 000000000..2261ea5bb --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/java/test/org/springdoc/api/v30/app244/SpringDocApp244Test.java @@ -0,0 +1,35 @@ +/* + * + * * + * * * + * * * * + * * * * * Copyright 2025 the original author or authors. + * * * * * + * * * * * Licensed under the Apache License, Version 2.0 (the "License"); + * * * * * you may not use this file except in compliance with the License. + * * * * * You may obtain a copy of the License at + * * * * * + * * * * * https://www.apache.org/licenses/LICENSE-2.0 + * * * * * + * * * * * Unless required by applicable law or agreed to in writing, software + * * * * * distributed under the License is distributed on an "AS IS" BASIS, + * * * * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * * * * See the License for the specific language governing permissions and + * * * * * limitations under the License. + * * * * + * * * + * * + * + */ + +package test.org.springdoc.api.v30.app244; + +import test.org.springdoc.api.v30.AbstractSpringDocV30Test; + +import org.springframework.boot.autoconfigure.SpringBootApplication; + +public class SpringDocApp244Test extends AbstractSpringDocV30Test { + + @SpringBootApplication + static class SpringDocTestApp {} +} \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app244.json b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app244.json new file mode 100644 index 000000000..bbc136c6e --- /dev/null +++ b/springdoc-openapi-starter-webmvc-api/src/test/resources/results/3.0.1/app244.json @@ -0,0 +1,134 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "OpenAPI definition", + "version" : "v0" + }, + "servers" : [ { + "url" : "http://localhost", + "description" : "Generated server url" + } ], + "paths" : { + "/v5/greet" : { + "post" : { + "tags" : [ "hello-controller" ], + "operationId" : "endpoint5", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK" + } + } + } + }, + "/v4/greet" : { + "post" : { + "tags" : [ "hello-controller" ], + "operationId" : "endpoint4", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK" + } + } + } + }, + "/v3/greet" : { + "post" : { + "tags" : [ "hello-controller" ], + "operationId" : "endpoint3", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK" + } + } + } + }, + "/v2/greet" : { + "post" : { + "tags" : [ "hello-controller" ], + "operationId" : "endpoint2", + "parameters" : [ { + "name" : "hi", + "in" : "query", + "required" : false, + "schema" : { + "type" : "string" + } + }, { + "name" : "bye", + "in" : "query", + "required" : false, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK" + } + } + } + }, + "/v1/greet" : { + "post" : { + "tags" : [ "hello-controller" ], + "operationId" : "endpoint", + "requestBody" : { + "content" : { + "application/x-www-form-urlencoded" : { + "schema" : { + "$ref" : "#/components/schemas/Greeting" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK" + } + } + } + } + }, + "components" : { + "schemas" : { + "Greeting" : { + "type" : "object", + "properties" : { + "hi" : { + "type" : "string" + }, + "bye" : { + "type" : "string" + } + } + } + } + } +} \ No newline at end of file From 95c3b87318b42a1994f08da75f7555424da2149e Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Tue, 11 Nov 2025 14:44:52 +0100 Subject: [PATCH 38/45] Warning messages when docs are explicitly enabled. Fixes #3131 --- .../configuration/SpringDocConfiguration.java | 2 +- .../core/events/SpringDocAppInitializer.java | 16 ++++++++++++---- .../properties/SpringDocConfigProperties.java | 2 +- .../properties/SwaggerUiConfigProperties.java | 2 +- .../webflux/scalar/ScalarConfiguration.java | 6 +++--- .../org/springdoc/webflux/ui/SwaggerConfig.java | 6 +++--- .../webmvc/scalar/ScalarConfiguration.java | 6 +++--- .../org/springdoc/webmvc/ui/SwaggerConfig.java | 6 +++--- 8 files changed, 27 insertions(+), 19 deletions(-) diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java index 2b8882808..e01cd6e00 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocConfiguration.java @@ -736,6 +736,6 @@ MethodParameterPojoExtractor methodParameterPojoExtractor(SchemaUtils schemaUtil @ConditionalOnMissingBean(name = "springDocAppInitializer") @Lazy(false) SpringDocAppInitializer springDocAppInitializer(SpringDocConfigProperties springDocConfigProperties){ - return new SpringDocAppInitializer(springDocConfigProperties.getApiDocs().getPath(), SPRINGDOC_ENABLED); + return new SpringDocAppInitializer(springDocConfigProperties.getApiDocs().getPath(), SPRINGDOC_ENABLED, springDocConfigProperties.getApiDocs().isEnabled()); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java index f1a02b05b..83fa21557 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/events/SpringDocAppInitializer.java @@ -49,6 +49,11 @@ public class SpringDocAppInitializer { */ private final String property; + /** + * The Springdoc enabled. + */ + private final boolean springdocEnabled; + /** * The constant LOGGER. */ @@ -57,12 +62,14 @@ public class SpringDocAppInitializer { /** * Instantiates a new Spring doc app initializer. * - * @param endpoint the endpoint - * @param property the property + * @param endpoint the endpoint + * @param property the property + * @param springdocEnabled the springdoc enabled */ - public SpringDocAppInitializer(String endpoint, String property) { + public SpringDocAppInitializer(String endpoint, String property, boolean springdocEnabled) { this.endpoint = endpoint; this.property = property; + this.springdocEnabled = springdocEnabled; } /** @@ -70,6 +77,7 @@ public SpringDocAppInitializer(String endpoint, String property) { */ @EventListener(ApplicationReadyEvent.class) public void init() { - LOGGER.warn("SpringDoc {} endpoint is enabled by default. To disable it in production, set the property '{}=false'", endpoint, property); + if(!this.springdocEnabled) + LOGGER.warn("SpringDoc {} endpoint is enabled by default. To disable it in production, set the property '{}=false'", endpoint, property); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SpringDocConfigProperties.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SpringDocConfigProperties.java index d27787f51..1ea92f1ff 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SpringDocConfigProperties.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SpringDocConfigProperties.java @@ -1434,7 +1434,7 @@ public static class ApiDocs { /** * Whether to generate and serve an OpenAPI document. */ - private boolean enabled = true; + private boolean enabled; /** * The Resolve schema properties. diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SwaggerUiConfigProperties.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SwaggerUiConfigProperties.java index dd3544909..c3e95e6f3 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SwaggerUiConfigProperties.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/core/properties/SwaggerUiConfigProperties.java @@ -96,7 +96,7 @@ public class SwaggerUiConfigProperties extends AbstractSwaggerUiConfigProperties /** * Whether to generate and serve an OpenAPI document. */ - private boolean enabled = true; + private boolean enabled; /** * The Use root path. diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java index acc15b13f..94e742abb 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java @@ -102,7 +102,7 @@ ForwardedHeaderTransformer forwardedHeaderTransformer() { @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) SpringDocAppInitializer springDocScalarInitializer(ScalarProperties scalarProperties){ - return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED); + return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED, scalarProperties.isEnabled()); } /** @@ -135,8 +135,8 @@ ScalarActuatorController scalarActuatorController(ScalarProperties properties, @Bean @ConditionalOnMissingBean(name = "springDocScalarInitializer") @Lazy(false) - SpringDocAppInitializer springDocScalarInitializer(){ - return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED); + SpringDocAppInitializer springDocScalarInitializer(ScalarProperties scalarProperties){ + return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED, scalarProperties.isEnabled()); } } diff --git a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java index 53e597149..f9f1eddb2 100644 --- a/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webflux-ui/src/main/java/org/springdoc/webflux/ui/SwaggerConfig.java @@ -196,7 +196,7 @@ SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swagge @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { - return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED); + return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED, swaggerUiConfigProperties.isEnabled()); } /** @@ -233,8 +233,8 @@ SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerU @Bean @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") @Lazy(false) - SpringDocAppInitializer springDocSwaggerInitializer() { - return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED); + SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED, swaggerUiConfigProperties.isEnabled()); } } } diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java index dec8fcdc1..6007bc42f 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java @@ -103,7 +103,7 @@ public FilterRegistrationBean forwardedHeaderFilter() { @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) SpringDocAppInitializer springDocScalarInitializer(ScalarProperties scalarProperties) { - return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED); + return new SpringDocAppInitializer(scalarProperties.getPath(), SCALAR_ENABLED, scalarProperties.isEnabled()); } /** @@ -137,8 +137,8 @@ ScalarActuatorController scalarActuatorController(ScalarProperties properties, W @Bean @ConditionalOnMissingBean(name = "springDocScalarInitializer") @Lazy(false) - SpringDocAppInitializer springDocScalarInitializer() { - return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED); + SpringDocAppInitializer springDocScalarInitializer(ScalarProperties properties) { + return new SpringDocAppInitializer(DEFAULT_SCALAR_ACTUATOR_PATH, SCALAR_ENABLED, properties.isEnabled()); } } diff --git a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java index f4472fa59..3a1aac8bd 100644 --- a/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java +++ b/springdoc-openapi-starter-webmvc-ui/src/main/java/org/springdoc/webmvc/ui/SwaggerConfig.java @@ -185,7 +185,7 @@ SwaggerResourceResolver swaggerResourceResolver(SwaggerUiConfigProperties swagge @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @Lazy(false) SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { - return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED); + return new SpringDocAppInitializer(swaggerUiConfigProperties.getPath(), SPRINGDOC_SWAGGER_UI_ENABLED, swaggerUiConfigProperties.isEnabled()); } /** @@ -219,8 +219,8 @@ SwaggerWelcomeActuator swaggerActuatorWelcome(SwaggerUiConfigProperties swaggerU @Bean @ConditionalOnMissingBean(name = "springDocSwaggerInitializer") @Lazy(false) - SpringDocAppInitializer springDocSwaggerInitializer() { - return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED); + SpringDocAppInitializer springDocSwaggerInitializer(SwaggerUiConfigProperties swaggerUiConfigProperties) { + return new SpringDocAppInitializer(DEFAULT_SWAGGER_UI_ACTUATOR_PATH, SPRINGDOC_SWAGGER_UI_ENABLED, swaggerUiConfigProperties.isEnabled()); } } } From 9b3dd90e2ac8783d767b13fb646e9ec6b9ee13a6 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Tue, 11 Nov 2025 15:03:21 +0100 Subject: [PATCH 39/45] Remove dependency on the latest spring-framework SNAPSHOT. --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index c2350abbf..268de9371 100644 --- a/pom.xml +++ b/pom.xml @@ -65,7 +65,6 @@ 0.3.12 false - 7.0.0-SNAPSHOT From 4b95d0e658359156bcaf1d15a892ef718c776cef Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Tue, 11 Nov 2025 18:46:16 +0100 Subject: [PATCH 40/45] scalar upgrade to version 0.4.3 --- pom.xml | 7 +- springdoc-openapi-starter-common/pom.xml | 4 + .../scalar/AbstractScalarController.java | 205 +++--------------- .../org/springdoc/scalar/ScalarConstants.java | 8 +- .../scalar/ScalarActuatorController.java | 6 +- .../webflux/scalar/ScalarConfiguration.java | 11 +- .../scalar/ScalarWebFluxController.java | 6 +- .../src/test/resources/results/app1 | 9 +- .../src/test/resources/results/app10 | 25 --- .../src/test/resources/results/app11 | 11 +- .../src/test/resources/results/app11-1 | 9 +- .../src/test/resources/results/app11-2 | 9 +- .../src/test/resources/results/app12 | 11 +- .../src/test/resources/results/app13 | 11 +- .../src/test/resources/results/app2 | 9 +- .../src/test/resources/results/app3 | 9 +- .../src/test/resources/results/app4 | 9 +- .../src/test/resources/results/app5 | 9 +- .../src/test/resources/results/app6 | 9 +- .../src/test/resources/results/app7 | 9 +- .../src/test/resources/results/app8 | 9 +- .../src/test/resources/results/app9 | 9 +- .../scalar/ScalarActuatorController.java | 7 +- .../webmvc/scalar/ScalarConfiguration.java | 11 +- .../webmvc/scalar/ScalarWebMvcController.java | 6 +- .../src/test/resources/results/app1 | 9 +- .../src/test/resources/results/app10 | 9 +- .../src/test/resources/results/app11 | 9 +- .../src/test/resources/results/app12 | 9 +- .../src/test/resources/results/app13 | 9 +- .../src/test/resources/results/app14 | 9 +- .../src/test/resources/results/app15 | 9 +- .../src/test/resources/results/app16 | 9 +- .../src/test/resources/results/app16-1 | 9 +- .../src/test/resources/results/app16-2 | 9 +- .../src/test/resources/results/app17 | 9 +- .../src/test/resources/results/app17-1 | 9 +- .../src/test/resources/results/app17-2 | 9 +- .../src/test/resources/results/app18 | 9 +- .../src/test/resources/results/app18-1 | 9 +- .../src/test/resources/results/app19 | 11 +- .../src/test/resources/results/app2 | 11 +- .../src/test/resources/results/app3 | 11 +- .../src/test/resources/results/app4 | 11 +- .../src/test/resources/results/app5 | 9 +- .../src/test/resources/results/app6 | 9 +- .../src/test/resources/results/app7-1 | 9 +- .../src/test/resources/results/app7-2 | 9 +- .../src/test/resources/results/app8 | 9 +- 49 files changed, 194 insertions(+), 458 deletions(-) delete mode 100644 springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 diff --git a/pom.xml b/pom.xml index 268de9371..ddda92636 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 5.0.0-M1 2.0.0-M2 - 0.3.12 + 0.4.3 false @@ -123,11 +123,6 @@ spring-boot-starter-test test - - org.springframework.boot - spring-boot-jackson - test - diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index fb1ae80de..7a5d3b021 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -20,6 +20,10 @@ io.swagger.core.v3 swagger-core-jakarta + + org.springframework.boot + spring-boot-jackson + org.springframework.boot spring-boot-configuration-processor diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java index 68120fd52..af83251b5 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/AbstractScalarController.java @@ -28,17 +28,18 @@ import java.io.IOException; import java.io.InputStream; -import java.net.URLDecoder; import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.stream.Collectors; import com.scalar.maven.webjar.ScalarProperties; -import com.scalar.maven.webjar.ScalarProperties.ScalarSource; +import com.scalar.maven.webjar.internal.ScalarConfiguration; +import com.scalar.maven.webjar.internal.ScalarConfigurationMapper; +import tools.jackson.core.JacksonException; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import static org.springdoc.scalar.ScalarConstants.HTML_TEMPLATE_PATH; import static org.springdoc.scalar.ScalarConstants.SCALAR_DEFAULT_URL; import static org.springdoc.scalar.ScalarConstants.SCALAR_JS_FILENAME; import static org.springframework.util.AntPathMatcher.DEFAULT_PATH_SEPARATOR; @@ -60,14 +61,21 @@ public abstract class AbstractScalarController { */ protected final String originalScalarUrl; + /** + * The Object mapper. + */ + private final ObjectMapper objectMapper; + /** * Instantiates a new Abstract scalar controller. * * @param scalarProperties the scalar properties + * @param objectMapper the object mapper */ - protected AbstractScalarController(ScalarProperties scalarProperties) { + protected AbstractScalarController(ScalarProperties scalarProperties, ObjectMapper objectMapper) { this.scalarProperties = scalarProperties; this.originalScalarUrl = scalarProperties.getUrl(); + this.objectMapper = objectMapper; } /** @@ -82,22 +90,18 @@ protected AbstractScalarController(ScalarProperties scalarProperties) { */ protected ResponseEntity getDocs(String requestUrl) throws IOException { // Load the template HTML - InputStream inputStream = getClass().getResourceAsStream("/META-INF/resources/webjars/scalar/index.html"); + InputStream inputStream = getClass().getResourceAsStream(HTML_TEMPLATE_PATH); if (inputStream == null) { - return ResponseEntity.notFound().build(); + throw new IOException("HTML template not found at: " + HTML_TEMPLATE_PATH); } String html = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); - requestUrl = decode(requestUrl); + // Replace the placeholders with actual values - String cdnUrl = buildJsBundleUrl(requestUrl); + String bundleUrl = buildJsBundleUrl(requestUrl); String injectedHtml = html - .replace("__JS_BUNDLE_URL__", cdnUrl) - .replace("__CONFIGURATION__", """ - { - url: "%s" - } - """.formatted(buildApiDocsUrl(requestUrl))); + .replace("__JS_BUNDLE_URL__", bundleUrl) + .replace("__CONFIGURATION__", buildConfigurationJson(buildApiDocsUrl(requestUrl))); return ResponseEntity.ok() .contentType(MediaType.TEXT_HTML) @@ -126,16 +130,6 @@ protected ResponseEntity getScalarJs() throws IOException { .body(jsContent); } - /** - * Decode string. - * - * @param requestURI the request uri - * @return the string - */ - protected String decode(String requestURI) { - return URLDecoder.decode(requestURI, StandardCharsets.UTF_8); - } - /** * Gets api docs url. * @@ -186,159 +180,20 @@ protected String buildJsBundleUrl(String requestUrl, String scalarPath) { */ protected abstract String buildJsBundleUrl(String requestUrl); - /** - * Builds the configuration JSON for the Scalar API Reference. - * - * @return the configuration JSON as a string - */ - private String buildConfigurationJson() { - StringBuilder config = new StringBuilder(); - config.append("{"); - - // Add URL - config.append("\n url: \"").append(escapeJson(scalarProperties.getUrl())).append("\""); - - // Add sources - if (scalarProperties.getSources() != null && !scalarProperties.getSources().isEmpty()) { - config.append(",\n sources: ").append(buildSourcesJsonArray(scalarProperties.getSources())); - } - - // Add showSidebar - if (!scalarProperties.isShowSidebar()) { - config.append(",\n showSidebar: false"); - } - - // Add hideModels - if (scalarProperties.isHideModels()) { - config.append(",\n hideModels: true"); - } - - // Add hideTestRequestButton - if (scalarProperties.isHideTestRequestButton()) { - config.append(",\n hideTestRequestButton: true"); - } - - // Add darkMode - if (scalarProperties.isDarkMode()) { - config.append(",\n darkMode: true"); - } - - // Add hideDarkModeToggle - if (scalarProperties.isHideDarkModeToggle()) { - config.append(",\n hideDarkModeToggle: true"); - } - - // Add customCss - if (scalarProperties.getCustomCss() != null && !scalarProperties.getCustomCss().trim().isEmpty()) { - config.append(",\n customCss: \"").append(escapeJson(scalarProperties.getCustomCss())).append("\""); - } - - // Add theme - if (scalarProperties.getTheme() != null && !"default".equals(scalarProperties.getTheme())) { - config.append(",\n theme: \"").append(escapeJson(scalarProperties.getTheme())).append("\""); - } - - // Add layout - if (scalarProperties.getLayout() != null && !"modern".equals(scalarProperties.getLayout())) { - config.append(",\n layout: \"").append(escapeJson(scalarProperties.getLayout())).append("\""); - } - - // Add hideSearch - if (scalarProperties.isHideSearch()) { - config.append(",\n hideSearch: true"); - } - - // Add documentDownloadType - if (scalarProperties.getDocumentDownloadType() != null && !"both".equals(scalarProperties.getDocumentDownloadType())) { - config.append(",\n documentDownloadType: \"").append(escapeJson(scalarProperties.getDocumentDownloadType())).append("\""); - } - - config.append("\n}"); - return config.toString(); - } - - /** - * Escapes a string for JSON output. + /** + * Build configuration json string. * - * @param input the input string - * @return the escaped string - */ - private String escapeJson(String input) { - if (input == null) { - return ""; - } - return input.replace("\\", "\\\\") - .replace("\"", "\\\"") - .replace("\n", "\\n") - .replace("\r", "\\r") - .replace("\t", "\\t"); - } - - /** - * Builds the JSON for the OpenAPI reference sources - * - * @param sources list of OpenAPI reference sources - * @return the sources as a JSON string - */ - private String buildSourcesJsonArray(List sources) { - final StringBuilder builder = new StringBuilder("["); - - // Filter out sources with invalid urls - final List filteredSources = sources.stream() - .filter(source -> isNotNullOrBlank(source.getUrl())) - .collect(Collectors.toList()); - - // Append each source to json array - for (int i = 0; i < filteredSources.size(); i++) { - final ScalarSource source = filteredSources.get(i); - - final String sourceJson = buildSourceJson(source); - builder.append("\n").append(sourceJson); - - if (i != filteredSources.size() - 1) { - builder.append(","); - } - } - - builder.append("\n]"); - return builder.toString(); - } - - /** - * Builds the JSON for an OpenAPI reference source - * - * @param source the OpenAPI reference source - * @return the source as a JSON string + * @param requestUrl the request url + * @return the string */ - private String buildSourceJson(ScalarSource source) { - final StringBuilder builder = new StringBuilder("{"); - - builder.append("\n url: \"").append(escapeJson(source.getUrl())).append("\""); - - - if (isNotNullOrBlank(source.getTitle())) { - builder.append(",\n title: \"").append(escapeJson(source.getTitle())).append("\""); + private String buildConfigurationJson(String requestUrl) { + try { + this.scalarProperties.setUrl(requestUrl); + ScalarConfiguration config = ScalarConfigurationMapper.map(scalarProperties); + return objectMapper.writeValueAsString(config); } - - if (isNotNullOrBlank(source.getSlug())) { - builder.append(",\n slug: \"").append(escapeJson(source.getSlug())).append("\""); - } - - if (source.isDefault() != null) { - builder.append(",\n default: ").append(source.isDefault()); + catch (JacksonException e) { + throw new RuntimeException("Failed to serialize Scalar configuration", e); } - - builder.append("\n}"); - return builder.toString(); - } - - /** - * Returns whether a String is not null or blank - * - * @param input the string - * @return whether the string is not null or blank - */ - private boolean isNotNullOrBlank(String input) { - return input != null && !input.isBlank(); } } diff --git a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java index c694f2132..729e32db7 100644 --- a/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java +++ b/springdoc-openapi-starter-common/src/main/java/org/springdoc/scalar/ScalarConstants.java @@ -46,10 +46,16 @@ public class ScalarConstants { /** * The constant SCALAR_DEFAULT_URL. */ - public static final String SCALAR_DEFAULT_URL = "https://registry.scalar.com/@scalar/apis/galaxy/latest?format=json"; + public static final String SCALAR_DEFAULT_URL = "https://registry.scalar.com/@scalar/apis/galaxy?format=json"; /** * The constant DEFAULT_SCALAR_ACTUATOR_PATH. */ public static final String DEFAULT_SCALAR_ACTUATOR_PATH = "scalar"; + + /** + * The constant HTML_TEMPLATE_PATH. + */ + public static final String HTML_TEMPLATE_PATH = "/META-INF/resources/webjars/scalar/index.html"; + } diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java index 4f254dafe..c9e222b04 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarActuatorController.java @@ -31,6 +31,7 @@ import com.scalar.maven.webjar.ScalarProperties; import io.swagger.v3.oas.annotations.Operation; import org.springdoc.scalar.AbstractScalarController; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.endpoint.web.annotation.ControllerEndpoint; @@ -59,9 +60,10 @@ public class ScalarActuatorController extends AbstractScalarController { * * @param scalarProperties the scalar properties * @param webEndpointProperties the web endpoint properties + * @param objectMapper the object mapper */ - protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties) { - super(scalarProperties); + protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) { + super(scalarProperties, objectMapper); this.webEndpointProperties = webEndpointProperties; } diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java index 94e742abb..1dd9e3677 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarConfiguration.java @@ -30,6 +30,7 @@ import org.springdoc.core.configuration.SpringDocConfiguration; import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; @@ -69,14 +70,15 @@ public class ScalarConfiguration { * * @param scalarProperties the scalar properties * @param springDocConfigProperties the spring doc config properties + * @param objectMapper the object mapper * @return the scalar web mvc controller */ @Bean @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @ConditionalOnMissingBean @Lazy(false) - ScalarWebFluxController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { - return new ScalarWebFluxController(scalarProperties,springDocConfigProperties); + ScalarWebFluxController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) { + return new ScalarWebFluxController(scalarProperties,springDocConfigProperties, objectMapper); } /** @@ -118,13 +120,14 @@ static class SwaggerActuatorWelcomeConfiguration { * * @param properties the properties * @param webEndpointProperties the web endpoint properties + * @param objectMapper the object mapper * @return the scalar actuator controller */ @Bean @ConditionalOnMissingBean @Lazy(false) - ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { - return new ScalarActuatorController(properties,webEndpointProperties); + ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) { + return new ScalarActuatorController(properties,webEndpointProperties, objectMapper); } /** diff --git a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java index 85597fb82..64656179b 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java +++ b/springdoc-openapi-starter-webflux-scalar/src/main/java/org/springdoc/webflux/scalar/ScalarWebFluxController.java @@ -31,6 +31,7 @@ import com.scalar.maven.webjar.ScalarProperties; import org.springdoc.core.properties.SpringDocConfigProperties; import org.springdoc.scalar.AbstractScalarController; +import tools.jackson.databind.ObjectMapper; import org.springframework.http.ResponseEntity; import org.springframework.http.server.reactive.ServerHttpRequest; @@ -61,9 +62,10 @@ public class ScalarWebFluxController extends AbstractScalarController { * * @param scalarProperties the scalar properties * @param springDocConfigProperties the spring doc config properties + * @param objectMapper the object mapper */ - protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { - super(scalarProperties); + protected ScalarWebFluxController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) { + super(scalarProperties, objectMapper); this.springDocConfigProperties = springDocConfigProperties; } diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 index 19e300d37..e1509f923 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 deleted file mode 100644 index dfbe8d55c..000000000 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app10 +++ /dev/null @@ -1,25 +0,0 @@ - - - - Scalar API Reference - - - - - -
- - - - - - - - diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 index 6b9b9273d..e1509f923 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 index 9501a81ca..3c295c4ca 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 index b3de119ee..8eb5ffd17 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app11-2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 index 008c75abc..844a7e492 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app12 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 index 8a5017e08..f33e2d27e 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app13 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 index 57691e413..d20d37394 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 index bba87d100..8f6c4ae27 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app3 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 index dc17a8ec8..3b7276151 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app4 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 index 98d5fe303..706664496 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app5 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 index d2c196024..013e443c2 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app6 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 index fb40ef696..5cf457e6f 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app7 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 index 10573c433..346052d28 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app8 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 index 73c9ba06a..a2289eb03 100644 --- a/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 +++ b/springdoc-openapi-starter-webflux-scalar/src/test/resources/results/app9 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java index 23ae45d36..3540b515d 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarActuatorController.java @@ -28,6 +28,8 @@ import java.io.IOException; + +import tools.jackson.databind.ObjectMapper; import com.scalar.maven.webjar.ScalarProperties; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletRequest; @@ -59,9 +61,10 @@ public class ScalarActuatorController extends AbstractScalarController { * * @param scalarProperties the scalar properties * @param webEndpointProperties the web endpoint properties + * @param objectMapper the object mapper */ - protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties) { - super(scalarProperties); + protected ScalarActuatorController(ScalarProperties scalarProperties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) { + super(scalarProperties, objectMapper); this.webEndpointProperties = webEndpointProperties; } diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java index 6007bc42f..fdcb0da5d 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarConfiguration.java @@ -30,6 +30,7 @@ import org.springdoc.core.configuration.SpringDocConfiguration; import org.springdoc.core.events.SpringDocAppInitializer; import org.springdoc.core.properties.SpringDocConfigProperties; +import tools.jackson.databind.ObjectMapper; import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties; import org.springframework.boot.actuate.autoconfigure.web.server.ConditionalOnManagementPort; @@ -70,14 +71,15 @@ public class ScalarConfiguration { * * @param scalarProperties the scalar properties * @param springDocConfigProperties the spring doc config properties + * @param objectMapper the object mapper * @return the scalar web mvc controller */ @Bean @ConditionalOnProperty(name = SPRINGDOC_USE_MANAGEMENT_PORT, havingValue = "false", matchIfMissing = true) @ConditionalOnMissingBean @Lazy(false) - ScalarWebMvcController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { - return new ScalarWebMvcController(scalarProperties, springDocConfigProperties); + ScalarWebMvcController scalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) { + return new ScalarWebMvcController(scalarProperties, springDocConfigProperties, objectMapper); } /** @@ -119,13 +121,14 @@ static class SwaggerActuatorWelcomeConfiguration { * * @param properties the properties * @param webEndpointProperties the web endpoint properties + * @param objectMapper the object mapper * @return the scalar actuator controller */ @Bean @ConditionalOnMissingBean @Lazy(false) - ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties) { - return new ScalarActuatorController(properties, webEndpointProperties); + ScalarActuatorController scalarActuatorController(ScalarProperties properties, WebEndpointProperties webEndpointProperties, ObjectMapper objectMapper) { + return new ScalarActuatorController(properties, webEndpointProperties, objectMapper); } diff --git a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java index c41d6112c..9845230ff 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java +++ b/springdoc-openapi-starter-webmvc-scalar/src/main/java/org/springdoc/webmvc/scalar/ScalarWebMvcController.java @@ -28,6 +28,7 @@ import java.io.IOException; +import tools.jackson.databind.ObjectMapper; import com.scalar.maven.webjar.ScalarProperties; import jakarta.servlet.http.HttpServletRequest; import org.springdoc.core.properties.SpringDocConfigProperties; @@ -61,9 +62,10 @@ public class ScalarWebMvcController extends AbstractScalarController { * * @param scalarProperties the scalar properties * @param springDocConfigProperties the spring doc config properties + * @param objectMapper the object mapper */ - protected ScalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties) { - super(scalarProperties); + protected ScalarWebMvcController(ScalarProperties scalarProperties, SpringDocConfigProperties springDocConfigProperties, ObjectMapper objectMapper) { + super(scalarProperties, objectMapper); this.springDocConfigProperties = springDocConfigProperties; } diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 index 19e300d37..e1509f923 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 index f5c061728..cb070c3a7 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app10 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 index 8b67f74a0..87c9507a2 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app11 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 index 143bdbe0d..336fe7d7e 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app12 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 index 35f039756..2c3d611c4 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app13 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 index 4c16125c7..8c22dbac3 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app14 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 index 19e300d37..e1509f923 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app15 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 index 19e300d37..e1509f923 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 index 9501a81ca..3c295c4ca 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 index b3de119ee..8eb5ffd17 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app16-2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 index 283140e4d..570095a1a 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 index 54c4dbde7..f33ad7ed9 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 index f57db2773..b36e67947 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app17-2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 index 5a8152f2d..c0773c02f 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 index 58a9afb5c..f33e2d27e 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app18-1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 index 5d3ff1550..d07d20501 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app19 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 index 0b10a2dde..d2baa0b57 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 index fdc75a528..31f0abec7 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app3 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 index f62a9805b..c6b455298 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app4 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ - + \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 index ae093c742..564b88889 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app5 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 index de88d5e88..620aee4b2 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app6 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 index 4966e1084..cd12f1096 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-1 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 index 13dfec43b..e7b136282 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app7-2 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file diff --git a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 index b84405624..31f0abec7 100644 --- a/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 +++ b/springdoc-openapi-starter-webmvc-scalar/src/test/resources/results/app8 @@ -4,8 +4,8 @@ Scalar API Reference + content="width=device-width, initial-scale=1" + name="viewport" /> @@ -16,10 +16,7 @@ \ No newline at end of file From 44e2f70e605311a1b258d8e014127ed3f4c335dd Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 21 Nov 2025 01:31:57 +0100 Subject: [PATCH 41/45] Upgrade to spring-boot 4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index ddda92636..f2be8423b 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT pom Spring openapi documentation Spring openapi documentation @@ -11,7 +11,7 @@ org.springframework.boot spring-boot-starter-parent - 4.0.0-SNAPSHOT + 4.0.0 From aa333b3497ae75ebe5844b4fa3cc8106af32cdf1 Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 21 Nov 2025 01:55:01 +0100 Subject: [PATCH 42/45] moving to 3.0.0-SNAPSHOT --- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-scalar/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-scalar/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml | 2 +- springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml | 2 +- springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index c461127f5..44fda6b86 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index 7a5d3b021..e34488823 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index a0a9d1abc..6ab60fff1 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index c84da2a40..845a0837a 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webflux-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index 9fa3f63e9..b7ce33148 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index 5dd9f3577..c4661b16f 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index 29179ea84..1ba1ff209 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webmvc-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index ba4e17be6..756dded61 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index f3f036f50..8eda1e03b 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 441e8196f..798f573a7 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index be68398cc..586d110cd 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index 9b83f8eb8..53b439b94 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 0a3913753..6f0d0f165 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index 0679ec918..0342202ab 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index ecdda2f90..b61201b93 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index e7050de67..a09917f88 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 6dc226dec..6a5e7434d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 2e95577cb..c25c71ec0 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index a3e6e12be..2bd32d366 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index 51bf48cbc..9acd436f8 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-RC2-SNAPSHOT + 3.0.0-SNAPSHOT springdoc-openapi-security-tests ${project.artifactId} From 49409a9982c492664b505ea76920dd24369a71dc Mon Sep 17 00:00:00 2001 From: "Badr.NassLahsen" Date: Fri, 21 Nov 2025 02:27:25 +0100 Subject: [PATCH 43/45] Prepare for next release --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e71124f9c..0fde4af6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.0.0] - 2025-11-21 + +### Added +- #2975 - Spring Framework 7 - Initial API versioning support +- #3123 - Support static resources for webflux + +### Changed +- Upgrade to Spring Boot 4.0.0 +- Upgrade to Scalar 0.4.3 + +### Fixed + +- #3131 - Warning messages when docs are explicitly enabled +- #3121 - NPE in KotlinDeprecatedPropertyCustomizer - resolvedSchema is null + ## [3.0.0-RC1] - 2025-11-02 ### Added From 6526d7a6ad516dbf77ddac34cd055160c1a1dcf6 Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 21 Nov 2025 01:29:37 +0000 Subject: [PATCH 44/45] [maven-release-plugin] prepare release v3.0.0 --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-scalar/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-scalar/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 21 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index f2be8423b..46cbce477 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - HEAD + v3.0.0 diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 44fda6b86..61c3a1dfd 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index e34488823..eddb0ff99 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index 6ab60fff1..df34c8484 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index 845a0837a..c71b3ed09 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webflux-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index b7ce33148..d5abf58aa 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index c4661b16f..c3643b2e7 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index 1ba1ff209..c70ffcf50 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webmvc-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index 756dded61..bdca28e01 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 8eda1e03b..9c2bda6cd 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 798f573a7..2029f8b63 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index 586d110cd..c273606c3 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index 53b439b94..5890a5383 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index 6f0d0f165..f4fe304fb 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index 0342202ab..e44d785f4 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index b61201b93..38a9bbe5a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index a09917f88..2be8ef7ec 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 6a5e7434d..16cbdef54 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index c25c71ec0..669265037 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index 2bd32d366..bdb813e53 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0-SNAPSHOT + 3.0.0 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index 9acd436f8..674c053ba 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0-SNAPSHOT + 3.0.0 springdoc-openapi-security-tests ${project.artifactId} From c833910f9396fa04208a4ee707a7821827168f54 Mon Sep 17 00:00:00 2001 From: jenkins Date: Fri, 21 Nov 2025 01:29:40 +0000 Subject: [PATCH 45/45] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- springdoc-openapi-bom/pom.xml | 2 +- springdoc-openapi-starter-common/pom.xml | 2 +- springdoc-openapi-starter-webflux-api/pom.xml | 2 +- springdoc-openapi-starter-webflux-scalar/pom.xml | 2 +- springdoc-openapi-starter-webflux-ui/pom.xml | 2 +- springdoc-openapi-starter-webmvc-api/pom.xml | 2 +- springdoc-openapi-starter-webmvc-scalar/pom.xml | 2 +- springdoc-openapi-starter-webmvc-ui/pom.xml | 2 +- springdoc-openapi-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-actuator-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-data-rest-tests/pom.xml | 2 +- .../springdoc-openapi-function-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-function-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-groovy-tests/pom.xml | 2 +- .../springdoc-openapi-hateoas-tests/pom.xml | 2 +- .../springdoc-openapi-javadoc-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webflux-tests/pom.xml | 2 +- .../springdoc-openapi-kotlin-webmvc-tests/pom.xml | 2 +- .../springdoc-openapi-security-tests/pom.xml | 2 +- 21 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pom.xml b/pom.xml index 46cbce477..73b98cabb 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT pom Spring openapi documentation Spring openapi documentation @@ -35,7 +35,7 @@ scm:git:git@github.com:springdoc/springdoc-openapi.git scm:git:git@github.com:springdoc/springdoc-openapi.git - v3.0.0 + HEAD diff --git a/springdoc-openapi-bom/pom.xml b/springdoc-openapi-bom/pom.xml index 61c3a1dfd..9223da8ed 100644 --- a/springdoc-openapi-bom/pom.xml +++ b/springdoc-openapi-bom/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-bom ${project.artifactId} diff --git a/springdoc-openapi-starter-common/pom.xml b/springdoc-openapi-starter-common/pom.xml index eddb0ff99..d5978ecef 100644 --- a/springdoc-openapi-starter-common/pom.xml +++ b/springdoc-openapi-starter-common/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-common ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-api/pom.xml b/springdoc-openapi-starter-webflux-api/pom.xml index df34c8484..b9839e6c4 100644 --- a/springdoc-openapi-starter-webflux-api/pom.xml +++ b/springdoc-openapi-starter-webflux-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webflux-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-scalar/pom.xml b/springdoc-openapi-starter-webflux-scalar/pom.xml index c71b3ed09..ede055b9e 100644 --- a/springdoc-openapi-starter-webflux-scalar/pom.xml +++ b/springdoc-openapi-starter-webflux-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webflux-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webflux-ui/pom.xml b/springdoc-openapi-starter-webflux-ui/pom.xml index d5abf58aa..1667a8cae 100644 --- a/springdoc-openapi-starter-webflux-ui/pom.xml +++ b/springdoc-openapi-starter-webflux-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webflux-ui ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-api/pom.xml b/springdoc-openapi-starter-webmvc-api/pom.xml index c3643b2e7..af7fc5dc0 100644 --- a/springdoc-openapi-starter-webmvc-api/pom.xml +++ b/springdoc-openapi-starter-webmvc-api/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webmvc-api ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-scalar/pom.xml b/springdoc-openapi-starter-webmvc-scalar/pom.xml index c70ffcf50..544518649 100644 --- a/springdoc-openapi-starter-webmvc-scalar/pom.xml +++ b/springdoc-openapi-starter-webmvc-scalar/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webmvc-scalar ${project.artifactId} diff --git a/springdoc-openapi-starter-webmvc-ui/pom.xml b/springdoc-openapi-starter-webmvc-ui/pom.xml index bdca28e01..04780686e 100644 --- a/springdoc-openapi-starter-webmvc-ui/pom.xml +++ b/springdoc-openapi-starter-webmvc-ui/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-starter-webmvc-ui ${project.artifactId} diff --git a/springdoc-openapi-tests/pom.xml b/springdoc-openapi-tests/pom.xml index 9c2bda6cd..7549df430 100644 --- a/springdoc-openapi-tests/pom.xml +++ b/springdoc-openapi-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT pom 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml index 2029f8b63..d6b39965d 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml index c273606c3..31d087b0b 100644 --- a/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-actuator-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml index 5890a5383..42bc3717f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-data-rest-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 springdoc-openapi-data-rest-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml index f4fe304fb..538d92f7a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml index e44d785f4..1ca092b13 100644 --- a/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-function-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml index 38a9bbe5a..c0c347446 100644 --- a/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-groovy-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-groovy-tests ${project.artifactId} diff --git a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml index 2be8ef7ec..cba8b7096 100644 --- a/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-hateoas-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 springdoc-openapi-hateoas-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml index 16cbdef54..797df2c1e 100644 --- a/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-javadoc-tests/pom.xml @@ -2,7 +2,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml index 669265037..811b71d92 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webflux-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webflux-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml index bdb813e53..b5077c60f 100644 --- a/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-kotlin-webmvc-tests/pom.xml @@ -2,7 +2,7 @@ springdoc-openapi-tests org.springdoc - 3.0.0 + 3.0.1-SNAPSHOT 4.0.0 springdoc-openapi-kotlin-webmvc-tests diff --git a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml index 674c053ba..8a308778a 100644 --- a/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml +++ b/springdoc-openapi-tests/springdoc-openapi-security-tests/pom.xml @@ -3,7 +3,7 @@ org.springdoc springdoc-openapi-tests - 3.0.0 + 3.0.1-SNAPSHOT springdoc-openapi-security-tests ${project.artifactId}