diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 272c07a5..6fed9055 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,6 +20,7 @@ updates: - dependency-name: "org.jboss.weld:weld-junit5" - dependency-name: "org.hibernate.validator:hibernate-validator" - dependency-name: "com.fasterxml.jackson.core:jackson-databind" + - dependency-name: "tools.jackson.core:jackson-databind" groups: maven: patterns: diff --git a/belgif-rest-problem-bom/pom.xml b/belgif-rest-problem-bom/pom.xml index 1605625d..f4ac8e8b 100644 --- a/belgif-rest-problem-bom/pom.xml +++ b/belgif-rest-problem-bom/pom.xml @@ -63,17 +63,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-client - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring ${project.version} @@ -83,37 +73,27 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-core - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-client - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-server + belgif-rest-problem-spring-boot-3-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4 + belgif-rest-problem-spring-boot-3-server-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-core + belgif-rest-problem-spring-boot-4-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-client + belgif-rest-problem-spring-boot-4-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-4-server-starter ${project.version} diff --git a/belgif-rest-problem-it/belgif-rest-problem-it-common-jakarta/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-it-common-jakarta/pom.xml index 40749991..7212f334 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-it-common-jakarta/pom.xml +++ b/belgif-rest-problem-it/belgif-rest-problem-it-common-jakarta/pom.xml @@ -12,26 +12,151 @@ belgif-rest-problem-it-common-jakarta ${project.groupId}:${project.artifactId} + + + io.github.belgif.rest.problem + belgif-rest-problem + ${project.version} + + + io.github.belgif.rest.problem + belgif-rest-problem-apt + ${project.version} + true + + + jakarta.platform + jakarta.jakartaee-api + 9.0.0 + provided + + + com.fasterxml.jackson.core + jackson-databind + ${version.jackson.minimal} + provided + + + tools.jackson.core + jackson-databind + ${version.jackson3.minimal} + provided + + + org.junit.jupiter + junit-jupiter + provided + + + org.assertj + assertj-core + provided + + + io.rest-assured + rest-assured + provided + + - org.eclipse.transformer - transformer-maven-plugin + org.apache.maven.plugins + maven-dependency-plugin - package + unpack-core-sources + generate-sources - jar + unpack - - io.github.belgif.rest.problem - belgif-rest-problem-it-common - ${project.version} - - - true - + + + io.github.belgif.rest.problem + belgif-rest-problem-it-common + ${project.version} + sources + + ${project.build.directory}/sources-to-transform + + + + + + + + + org.codehaus.mojo + exec-maven-plugin + + + transform-to-jakarta + generate-sources + + java + + + true + false + true + + org.eclipse.transformer.cli.JakartaTransformerCLI + + + + ${project.build.directory}/sources-to-transform + + + ${project.build.directory}/generated-sources/jakarta + + + + + + + + org.eclipse.transformer + org.eclipse.transformer.cli + 1.0.0 + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + add-transformed-sources + generate-sources + + add-source + + + + + ${project.build.directory}/generated-sources/jakarta + + + + + + add-resource + generate-resources + + add-resource + + + + + ${project.build.directory}/generated-sources/jakarta + + **/*.java + META-INF/MANIFEST.MF + META-INF/io.github.belgif.rest.problem/** + + + diff --git a/belgif-rest-problem-it/belgif-rest-problem-it-common/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-it-common/pom.xml index be20e755..405f6c12 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-it-common/pom.xml +++ b/belgif-rest-problem-it/belgif-rest-problem-it-common/pom.xml @@ -12,6 +12,23 @@ belgif-rest-problem-it-common ${project.groupId}:${project.artifactId} + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + + io.github.belgif.rest.problem diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/pom.xml index e19b6479..bfd3afee 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/pom.xml +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/pom.xml @@ -87,8 +87,8 @@ ${project.basedir}/../belgif-rest-problem-it-common/src/main/resources/openapi.yaml spring - io.github.belgif.rest.problem.openapi.validation.sb3.api - io.github.belgif.rest.problem.openapi.validation.sb3.model + io.github.belgif.rest.problem.it.openapi.validation.sb3.api + io.github.belgif.rest.problem.it.openapi.validation.sb3.model REF_AS_PARENT_IN_ALLOF=true false diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Application.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Application.java similarity index 87% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Application.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Application.java index 39f16429..72206306 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Application.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Application.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/BackendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java similarity index 94% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/BackendController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java index b3d6af05..8a627e80 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/BackendController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.net.URI; @@ -9,6 +9,7 @@ import com.acme.custom.CustomProblem; +import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.api.Problem; import io.github.belgif.rest.problem.it.model.JacksonModel; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Client.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Client.java similarity index 62% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Client.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Client.java index 0a4f64af..bbc54c9d 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Client.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/Client.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; public enum Client { diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java similarity index 95% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java index 3d39fd72..60516423 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java similarity index 98% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java index 1a4ca8e3..69e08e6e 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.net.URI; @@ -26,6 +26,9 @@ import com.acme.custom.CustomProblem; +import io.github.belgif.rest.problem.BadRequestProblem; +import io.github.belgif.rest.problem.DefaultProblem; +import io.github.belgif.rest.problem.ServiceUnavailableProblem; import io.github.belgif.rest.problem.api.Input; import io.github.belgif.rest.problem.api.Problem; import io.github.belgif.rest.problem.i18n.I18N; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java similarity index 97% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java index b6ecd1fd..b40769d3 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.util.Collections; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java similarity index 71% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java index 1d3f6a2a..8c5cfc6a 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java @@ -1,15 +1,15 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import io.github.belgif.rest.problem.openapi.validation.sb4.api.MyFirstPathApi; -import io.github.belgif.rest.problem.openapi.validation.sb4.api.MyHeaderPathApi; -import io.github.belgif.rest.problem.openapi.validation.sb4.api.MyQueryPathApi; -import io.github.belgif.rest.problem.openapi.validation.sb4.model.MyRequestBodySchema; -import io.github.belgif.rest.problem.openapi.validation.sb4.model.PostOperationWithAllOfSchemaRequest; -import io.github.belgif.rest.problem.openapi.validation.sb4.model.PostOperationWithOneOfSchemaRequest; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.api.MyFirstPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.api.MyHeaderPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.api.MyQueryPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.model.MyRequestBodySchema; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.model.PostOperationWithAllOfSchemaRequest; +import io.github.belgif.rest.problem.it.openapi.validation.sb3.model.PostOperationWithOneOfSchemaRequest; @RestController @RequestMapping("/openapi-validation") diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot3IT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot3IT.java similarity index 85% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot3IT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot3IT.java index fcf01eef..4310f8ee 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot3IT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot3IT.java @@ -1,10 +1,9 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; -import io.github.belgif.rest.problem.it.AbstractOpenApiValidationSpringBootIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3ExtIT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3ExtIT.java similarity index 87% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3ExtIT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3ExtIT.java index 565266ad..75c8f388 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3ExtIT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3ExtIT.java @@ -1,11 +1,10 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import io.github.belgif.rest.problem.it.AbstractRestProblemExtIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3IT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3IT.java similarity index 88% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3IT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3IT.java index 6675d0f0..7cb4174f 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot3IT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot3IT.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.util.Arrays; import java.util.stream.Stream; @@ -7,7 +7,6 @@ import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; -import io.github.belgif.rest.problem.it.AbstractRestProblemSpringBootIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/pom.xml index 86ec535a..24876100 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/pom.xml +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/pom.xml @@ -32,7 +32,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4 + belgif-rest-problem-spring-boot-4-starter ${project.version} @@ -104,12 +104,13 @@ ${project.basedir}/../belgif-rest-problem-it-common/src/main/resources/openapi.yaml spring - io.github.belgif.rest.problem.openapi.validation.sb4.api - io.github.belgif.rest.problem.openapi.validation.sb4.model + io.github.belgif.rest.problem.it.openapi.validation.sb4.api + io.github.belgif.rest.problem.it.openapi.validation.sb4.model REF_AS_PARENT_IN_ALLOF=true false - true + true + true true true false diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Application.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Application.java similarity index 87% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Application.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Application.java index 39f16429..72206306 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/Application.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Application.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/BackendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java similarity index 94% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/BackendController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java index b3d6af05..8a627e80 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/BackendController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.net.URI; @@ -9,6 +9,7 @@ import com.acme.custom.CustomProblem; +import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.api.Problem; import io.github.belgif.rest.problem.it.model.JacksonModel; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Client.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Client.java similarity index 62% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Client.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Client.java index 0a4f64af..bbc54c9d 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/Client.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/Client.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; public enum Client { diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java similarity index 95% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java index 3d39fd72..60516423 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/ControllerInterface.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Positive; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java similarity index 98% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java index 8821242d..1494824e 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/FrontendController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.net.URI; @@ -26,6 +26,9 @@ import com.acme.custom.CustomProblem; +import io.github.belgif.rest.problem.BadRequestProblem; +import io.github.belgif.rest.problem.DefaultProblem; +import io.github.belgif.rest.problem.ServiceUnavailableProblem; import io.github.belgif.rest.problem.api.Input; import io.github.belgif.rest.problem.api.Problem; import io.github.belgif.rest.problem.i18n.I18N; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java similarity index 97% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java index 97506597..2ef7ca3c 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationConfig.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.util.Collections; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java similarity index 71% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java index 5d61539b..cf0fc1e9 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/OpenApiValidationController.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java @@ -1,13 +1,15 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import io.github.belgif.rest.problem.openapi.validation.sb3.api.*; -import io.github.belgif.rest.problem.openapi.validation.sb3.model.MyRequestBodySchema; -import io.github.belgif.rest.problem.openapi.validation.sb3.model.PostOperationWithAllOfSchemaRequest; -import io.github.belgif.rest.problem.openapi.validation.sb3.model.PostOperationWithOneOfSchemaRequest; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyFirstPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyHeaderPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyQueryPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.MyRequestBodySchema; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.PostOperationWithAllOfSchemaRequest; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.PostOperationWithOneOfSchemaRequest; @RestController @RequestMapping("/openapi-validation") diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot4IT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot4IT.java similarity index 85% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot4IT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot4IT.java index 863d2502..d20c375d 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemOpenApiValidationSpringBoot4IT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemOpenApiValidationSpringBoot4IT.java @@ -1,10 +1,9 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; -import io.github.belgif.rest.problem.it.AbstractOpenApiValidationSpringBootIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4ExtIT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4ExtIT.java similarity index 87% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4ExtIT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4ExtIT.java index 8e7b2551..638e3455 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4ExtIT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4ExtIT.java @@ -1,11 +1,10 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ActiveProfiles; -import io.github.belgif.rest.problem.it.AbstractRestProblemExtIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4IT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4IT.java similarity index 88% rename from belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4IT.java rename to belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4IT.java index b2928c16..6c9b01df 100644 --- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/RestProblemSpringBoot4IT.java +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringBoot4IT.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem; +package io.github.belgif.rest.problem.it; import java.util.Arrays; import java.util.stream.Stream; @@ -7,7 +7,6 @@ import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.annotation.DirtiesContext; -import io.github.belgif.rest.problem.it.AbstractRestProblemSpringBootIT; import io.restassured.RestAssured; import io.restassured.specification.RequestSpecification; diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-spring-it/pom.xml new file mode 100644 index 00000000..6f96b5a9 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/pom.xml @@ -0,0 +1,146 @@ + + + 4.0.0 + + + io.github.belgif.rest.problem + belgif-rest-problem-it + ${revision} + + + belgif-rest-problem-spring-it + ${project.groupId}:${project.artifactId} + jar + + + 17 + + + + + + org.springframework.boot + spring-boot-dependencies + ${version.spring.boot.4} + pom + import + + + + + + + io.github.belgif.rest.problem + belgif-rest-problem-spring + ${project.version} + + + tools.jackson.core + jackson-databind + + + io.github.belgif.rest.problem + belgif-rest-problem-validator + ${project.version} + + + org.springframework + spring-webmvc + + + io.github.belgif.rest.problem + belgif-rest-problem-it-common-jakarta + ${project.version} + + + org.hibernate.validator + hibernate-validator + + + jakarta.validation + jakarta.validation-api + + + jakarta.annotation + jakarta.annotation-api + + + jakarta.servlet + jakarta.servlet-api + + + com.atlassian.oai + swagger-request-validator-spring-webmvc + 2.46.0 + + + org.springframework.boot + spring-boot-starter-webmvc + test + + + org.springframework.boot + spring-boot-starter-validation + test + + + org.springframework.boot + spring-boot-test + + + org.junit.jupiter + junit-jupiter + test + + + org.springframework + spring-webflux + + + org.springframework + spring-test + test + + + io.rest-assured + rest-assured + 6.0.0 + test + + + + + + + org.openapitools + openapi-generator-maven-plugin + + + + generate + + + ${project.basedir}/../belgif-rest-problem-it-common/src/main/resources/openapi.yaml + spring + io.github.belgif.rest.problem.it.openapi.validation.sb4.api + io.github.belgif.rest.problem.it.openapi.validation.sb4.model + REF_AS_PARENT_IN_ALLOF=true + false + + true + true + true + false + none + none + false + + + + + + + + + diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java new file mode 100644 index 00000000..8a627e80 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/BackendController.java @@ -0,0 +1,59 @@ +package io.github.belgif.rest.problem.it; + +import java.net.URI; + +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 com.acme.custom.CustomProblem; + +import io.github.belgif.rest.problem.BadRequestProblem; +import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.it.model.JacksonModel; + +@RestController +@RequestMapping("/backend") +public class BackendController { + + @GetMapping("/ok") + public ResponseEntity ok() { + return ResponseEntity.ok("OK"); + } + + @GetMapping("/badRequest") + public void badRequest() { + BadRequestProblem problem = new BadRequestProblem(); + problem.setDetail("Bad Request from backend"); + throw problem; + } + + @GetMapping("/custom") + public void custom() { + throw new CustomProblem("value from backend"); + } + + @GetMapping("/unmapped") + public void unmapped() { + Problem unmapped = new Problem(URI.create("urn:problem-type:belgif:test:unmapped"), "Unmapped problem", 400) { + }; + unmapped.setDetail("Unmapped problem from backend"); + throw unmapped; + } + + @GetMapping("/applicationJsonProblem") + public ResponseEntity applicationJsonProblem() { + BadRequestProblem problem = new BadRequestProblem(); + problem.setDetail("Bad Request with application/json media type from backend"); + return ResponseEntity.badRequest().body(problem); + } + + @GetMapping("/jacksonMismatchedInput") + public ResponseEntity mismatchedInput() { + JacksonModel model = new JacksonModel(null); + model.setDescription("description"); + return ResponseEntity.ok(model); + } + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/Client.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/Client.java new file mode 100644 index 00000000..bbc54c9d --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/Client.java @@ -0,0 +1,7 @@ +package io.github.belgif.rest.problem.it; + +public enum Client { + + REST_TEMPLATE, WEB_CLIENT, REST_CLIENT + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java new file mode 100644 index 00000000..60516423 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/ControllerInterface.java @@ -0,0 +1,24 @@ +package io.github.belgif.rest.problem.it; + +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; + +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +@Validated +@Controller +public interface ControllerInterface { + + @GetMapping("/beanValidation/pathParameter/inherited/{param}") + ResponseEntity beanValidationPathParameterInherited( + @PathVariable("param") @Positive @NotNull Integer p); + + @GetMapping("/beanValidation/pathParameter/overridden/{param}") + ResponseEntity beanValidationPathParameterOverridden( + @PathVariable("param") @Positive @NotNull Integer p); + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java new file mode 100644 index 00000000..b9f93410 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/FrontendController.java @@ -0,0 +1,267 @@ +package io.github.belgif.rest.problem.it; + +import java.net.URI; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import jakarta.validation.constraints.Size; + +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.WebClient; + +import com.acme.custom.CustomProblem; + +import io.github.belgif.rest.problem.BadRequestProblem; +import io.github.belgif.rest.problem.DefaultProblem; +import io.github.belgif.rest.problem.ServiceUnavailableProblem; +import io.github.belgif.rest.problem.api.Input; +import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.i18n.I18N; +import io.github.belgif.rest.problem.it.model.ChildModel; +import io.github.belgif.rest.problem.it.model.JacksonModel; +import io.github.belgif.rest.problem.it.model.Model; +import io.github.belgif.rest.problem.it.model.NestedModel; +import io.github.belgif.rest.problem.validation.RequestValidator; + +@RestController +@RequestMapping("/frontend") +@Validated +public class FrontendController implements ControllerInterface { + + private static final String DETAIL_MESSAGE_SUFFIX = " (caught successfully by frontend)"; + private static final String ILLEGAL_STATE_MESSAGE_PREFIX = "Unsupported client "; + + private WebClient.Builder webClientBuilder; + + private RestClient.Builder restClientBuilder; + + private RestTemplate restTemplate; + + private WebClient webClient; + + private RestClient restClient; + + public FrontendController(WebClient.Builder webClientBuilder, RestClient.Builder restClientBuilder) { + this.webClientBuilder = webClientBuilder; + this.restClientBuilder = restClientBuilder; + } + + public void initClients(int port) { + String apiBaseUrl = "http://localhost:" + port + "/spring/backend"; + this.webClient = this.webClientBuilder + .baseUrl(apiBaseUrl) + .build(); + this.restClient = this.restClientBuilder + .baseUrl(apiBaseUrl) + .build(); + // we're not testing RestTemplate for now + // there's no builder or baseUrl support for RestTemplate without Spring Boot, so would require more refactoring + } + + @GetMapping("/ping") + public String ping() { + return "pong"; + } + + @GetMapping("/badRequest") + public void badRequest() { + BadRequestProblem problem = new BadRequestProblem(); + problem.setDetail("Bad Request from frontend"); + throw problem; + } + + @GetMapping("/custom") + public void custom() { + throw new CustomProblem("value from frontend"); + } + + @GetMapping("/runtime") + public void runtime() { + throw new RuntimeException("oops"); + } + + @GetMapping("/unmapped") + public void unmapped() { + Problem unmapped = new Problem(URI.create("urn:problem-type:belgif:test:unmapped"), "Unmapped problem", 400) { + }; + unmapped.setDetail("Unmapped problem from frontend"); + throw unmapped; + } + + @GetMapping("/retryAfter") + public void retryAfter() { + ServiceUnavailableProblem problem = new ServiceUnavailableProblem(); + problem.setRetryAfterSec(10000L); + throw problem; + } + + @GetMapping(value = "/okFromBackend", produces = "application/json") + public ResponseEntity okFromBackend(@RequestParam("client") Client client) { + String result = null; + if (client == Client.REST_TEMPLATE) { + result = restTemplate.getForObject("/ok", String.class); + } else if (client == Client.WEB_CLIENT) { + result = webClient.get().uri("/ok").retrieve().toEntity(String.class).block().getBody(); + } else if (client == Client.REST_CLIENT) { + result = restClient.get().uri("/ok").retrieve().toEntity(String.class).getBody(); + } + return ResponseEntity.ok(result); + } + + @GetMapping("/badRequestFromBackend") + public void badRequestFromBackend(@RequestParam("client") Client client) { + try { + if (client == Client.REST_TEMPLATE) { + restTemplate.getForObject("/badRequest", String.class); + } else if (client == Client.WEB_CLIENT) { + webClient.get().uri("/badRequest").retrieve().toEntity(String.class).block(); + } else if (client == Client.REST_CLIENT) { + restClient.get().uri("/badRequest").retrieve().toEntity(String.class); + } + throw new IllegalStateException(ILLEGAL_STATE_MESSAGE_PREFIX + client); + } catch (BadRequestProblem e) { + e.setDetail(e.getDetail() + DETAIL_MESSAGE_SUFFIX); + throw e; + } + } + + @GetMapping("/customFromBackend") + public void customFromBackend(@RequestParam("client") Client client) { + try { + if (client == Client.REST_TEMPLATE) { + restTemplate.getForObject("/custom", String.class); + } else if (client == Client.WEB_CLIENT) { + webClient.get().uri("/custom").retrieve().toEntity(String.class).block(); + } else if (client == Client.REST_CLIENT) { + restClient.get().uri("/custom").retrieve().toEntity(String.class); + } + throw new IllegalStateException(ILLEGAL_STATE_MESSAGE_PREFIX + client); + } catch (CustomProblem e) { + e.setCustomField(e.getCustomField() + DETAIL_MESSAGE_SUFFIX); + throw e; + } + } + + @GetMapping("/unmappedFromBackend") + public void unmappedFromBackend(@RequestParam("client") Client client) { + try { + if (client == Client.REST_TEMPLATE) { + restTemplate.getForObject("/unmapped", String.class); + } else if (client == Client.WEB_CLIENT) { + webClient.get().uri("/unmapped").retrieve().toEntity(String.class).block(); + } else if (client == Client.REST_CLIENT) { + restClient.get().uri("/unmapped").retrieve().toEntity(String.class); + } + throw new IllegalStateException(ILLEGAL_STATE_MESSAGE_PREFIX + client); + } catch (DefaultProblem e) { + e.setDetail(e.getDetail() + DETAIL_MESSAGE_SUFFIX); + throw e; + } + } + + @GetMapping("/applicationJsonProblemFromBackend") + public void applicationJsonProblemFromBackend(@RequestParam("client") Client client) { + try { + if (client == Client.REST_TEMPLATE) { + restTemplate.getForObject("/applicationJsonProblem", String.class); + } else if (client == Client.WEB_CLIENT) { + webClient.get().uri("/applicationJsonProblem").retrieve().toEntity(String.class).block(); + } else if (client == Client.REST_CLIENT) { + restClient.get().uri("/applicationJsonProblem").retrieve().toEntity(String.class); + } + throw new IllegalStateException(ILLEGAL_STATE_MESSAGE_PREFIX + client); + } catch (BadRequestProblem e) { + e.setDetail(e.getDetail() + DETAIL_MESSAGE_SUFFIX); + throw e; + } + } + + @GetMapping("/jacksonMismatchedInputFromBackend") + public void jacksonMismatchedInputFromBackend(@RequestParam("client") Client client) { + if (client == Client.REST_TEMPLATE) { + restTemplate.getForObject("/jacksonMismatchedInput", JacksonModel.class); + } else if (client == Client.WEB_CLIENT) { + webClient.get().uri("/jacksonMismatchedInput").retrieve().toEntity(JacksonModel.class).block(); + } else if (client == Client.REST_CLIENT) { + restClient.get().uri("/jacksonMismatchedInput").retrieve().toEntity(JacksonModel.class); + } + throw new IllegalStateException(ILLEGAL_STATE_MESSAGE_PREFIX + client); + } + + @GetMapping("/beanValidation/queryParameter") + public ResponseEntity beanValidationQueryParameter( + @RequestParam("param") @Positive @NotNull Integer p, + @RequestParam @Size(max = 5) String other) { + return ResponseEntity.ok("param: " + p + ", other: " + other); + } + + @GetMapping("/beanValidation/headerParameter") + public ResponseEntity beanValidationHeaderParameter( + @RequestHeader("param") @Positive @NotNull Integer p) { + return ResponseEntity.ok("param: " + p); + } + + @GetMapping("/beanValidation/pathParameter/class/{param}") + public ResponseEntity beanValidationPathParameter( + @PathVariable("param") @Positive @NotNull Integer p) { + return ResponseEntity.ok("param: " + p); + } + + @Override + public ResponseEntity beanValidationPathParameterInherited(Integer p) { + return ResponseEntity.ok("param: " + p); + } + + @Override + @GetMapping("/beanValidation/pathParameter/overridden") + public ResponseEntity beanValidationPathParameterOverridden(@RequestParam("param") Integer p) { + return ResponseEntity.ok("param: " + p); + } + + @PostMapping("/beanValidation/body") + public ResponseEntity beanValidationBody(@Valid @RequestBody Model body) { + return ResponseEntity.ok("body: " + body); + } + + @PostMapping("/beanValidation/body/nested") + public ResponseEntity beanValidationBodyNested(@Valid @RequestBody NestedModel body) { + return ResponseEntity.ok("body: " + body); + } + + @PostMapping("/beanValidation/body/inheritance") + public ResponseEntity beanValidationBodyInheritance(@Valid @RequestBody ChildModel body) { + return ResponseEntity.ok("body: " + body); + } + + @PostMapping("/beanValidation/queryParameter/nested") + public ResponseEntity beanValidationQueryParameterNested(@Valid Model p) { + return ResponseEntity.ok("param: " + p); + } + + @PostMapping("/jackson/mismatchedInputException") + public ResponseEntity jacksonMismatchedInputException(@Valid @RequestBody JacksonModel p) { + return ResponseEntity.ok("param: " + p); + } + + @PostMapping("/i18n") + public ResponseEntity i18n(@RequestParam("enabled") boolean enabled) { + I18N.setEnabled(enabled); + return ResponseEntity.ok().build(); + } + + @GetMapping("/requestValidator") + public ResponseEntity requestValidator(@RequestParam("ssin") String ssin, + @RequestParam(name = "a", required = false) String a, + @RequestParam(name = "b", required = false) String b) { + new RequestValidator().ssin(Input.query("ssin", ssin)) + .zeroOrAllOf(Input.query("a", a), Input.query("b", b)) + .validate(); + return ResponseEntity.ok().build(); + } + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java new file mode 100644 index 00000000..e965740b --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationConfig.java @@ -0,0 +1,45 @@ +package io.github.belgif.rest.problem.it; + +import jakarta.servlet.Filter; +import jakarta.servlet.http.HttpServletRequest; + +import org.jspecify.annotations.NonNull; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import com.atlassian.oai.validator.OpenApiInteractionValidator; +import com.atlassian.oai.validator.report.LevelResolver; +import com.atlassian.oai.validator.report.ValidationReport; +import com.atlassian.oai.validator.springmvc.OpenApiValidationFilter; +import com.atlassian.oai.validator.springmvc.OpenApiValidationInterceptor; + +@Configuration +public class OpenApiValidationConfig implements WebMvcConfigurer { + + @Bean + public Filter validationFilter() { + return new OpenApiValidationFilter(true, false) { + @Override + protected boolean shouldNotFilter(HttpServletRequest request) { + String path = request.getServletPath(); + return !path.startsWith("/openapi-validation"); // replaces FilterRegistrationBean in Spring Boot + } + }; + } + + @Override + public void addInterceptors(@NonNull InterceptorRegistry registry) { + OpenApiInteractionValidator validator = OpenApiInteractionValidator + .createForSpecificationUrl("/openapi.yaml") + .withLevelResolver(LevelResolver.create() + // Accept additionalProperties even if they're not defined in the schema + .withLevel("validation.schema.additionalProperties", ValidationReport.Level.IGNORE) + .build()) + .withBasePathOverride("/openapi-validation") + .build(); + registry.addInterceptor(new OpenApiValidationInterceptor(validator)); + } + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java new file mode 100644 index 00000000..cf0fc1e9 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/OpenApiValidationController.java @@ -0,0 +1,60 @@ +package io.github.belgif.rest.problem.it; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyFirstPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyHeaderPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.api.MyQueryPathApi; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.MyRequestBodySchema; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.PostOperationWithAllOfSchemaRequest; +import io.github.belgif.rest.problem.it.openapi.validation.sb4.model.PostOperationWithOneOfSchemaRequest; + +@RestController +@RequestMapping("/openapi-validation") +public class OpenApiValidationController + implements MyFirstPathApi, MyHeaderPathApi, MyQueryPathApi { + + @Override + public ResponseEntity myFirstGetOperation(String myParam) { + return buildResponse(); + } + + @Override + public ResponseEntity myFirstPostOperation(MyRequestBodySchema myRequestBodySchema) { + return buildResponse(); + } + + @Override + public ResponseEntity mySecondGetOperation(String pathParam) { + return buildResponse(); + } + + @Override + public ResponseEntity myHeaderGetOperation(String myHeader) { + return buildResponse(); + } + + @Override + public ResponseEntity myQueryParamOperation(String myParam) { + return buildResponse(); + } + + @Override + public ResponseEntity + postOperationWithAllOfSchema(PostOperationWithAllOfSchemaRequest postOperationWithAllOfSchemaRequest) { + return buildResponse(); + } + + @Override + public ResponseEntity + postOperationWithOneOfSchema(PostOperationWithOneOfSchemaRequest postOperationWithOneOfSchemaRequest) { + return buildResponse(); + } + + private ResponseEntity buildResponse() { + return ResponseEntity.ok("All good!"); + } + +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/WebConfig.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/WebConfig.java new file mode 100644 index 00000000..39589f04 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/main/java/io/github/belgif/rest/problem/it/WebConfig.java @@ -0,0 +1,53 @@ +package io.github.belgif.rest.problem.it; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.codec.json.JacksonJsonDecoder; +import org.springframework.http.codec.json.JacksonJsonEncoder; +import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; +import org.springframework.web.client.RestClient; +import org.springframework.web.reactive.function.client.ExchangeStrategies; +import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import io.github.belgif.rest.problem.spring.EnableProblemModule; +import io.github.belgif.rest.problem.spring.SpringProblemModuleJackson3; +import io.github.belgif.rest.problem.spring.client.ProblemResponseErrorHandler; +import io.github.belgif.rest.problem.spring.client.WebClientFilter; +import tools.jackson.databind.json.JsonMapper; + +@Configuration +@EnableProblemModule(beanValidation = true) +public class WebConfig { + + @Bean + public JsonMapper objectMapper(SpringProblemModuleJackson3 springProblemModule) { + return JsonMapper.builder() + // application-specific JsonMapper customizations can be added here + .changeDefaultPropertyInclusion((incl) -> incl.withContentInclusion(JsonInclude.Include.NON_NULL) + .withValueInclusion(JsonInclude.Include.NON_NULL)) + .addModule(springProblemModule) // add springProblem module to the mapper. + .build(); + } + + @Bean + public RestClient.Builder restClientBuilder(ProblemResponseErrorHandler problemResponseErrorHandler, + JsonMapper mapper) { + return RestClient.builder() + .defaultStatusHandler(problemResponseErrorHandler) + .configureMessageConverters(converter -> converter.registerDefaults() + .withJsonConverter(new JacksonJsonHttpMessageConverter(mapper))); // change converter with + // custom json mapper + } + + @Bean + public WebClient.Builder webClientBuilder(ProblemResponseErrorHandler problemResponseErrorHandler, + JsonMapper mapper) { + ExchangeStrategies strategies = ExchangeStrategies.builder().codecs(configurer -> { + configurer.defaultCodecs().jacksonJsonEncoder(new JacksonJsonEncoder(mapper)); + configurer.defaultCodecs().jacksonJsonDecoder(new JacksonJsonDecoder(mapper)); + }).build(); + return WebClient.builder().exchangeStrategies(strategies).filter(WebClientFilter.PROBLEM_FILTER); + } +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/Application.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/Application.java new file mode 100644 index 00000000..72206306 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/Application.java @@ -0,0 +1,12 @@ +package io.github.belgif.rest.problem.it; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringIT.java b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringIT.java new file mode 100644 index 00000000..894c87b9 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/java/io/github/belgif/rest/problem/it/RestProblemSpringIT.java @@ -0,0 +1,40 @@ +package io.github.belgif.rest.problem.it; + +import java.util.List; +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.server.LocalServerPort; +import org.springframework.test.annotation.DirtiesContext; + +import io.restassured.RestAssured; +import io.restassured.specification.RequestSpecification; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@DirtiesContext +// uses spring boot to start the server-side, but doesn't rely on starter integration with rest-problem +class RestProblemSpringIT extends AbstractRestProblemSpringBootIT { + + @LocalServerPort + private int port; + + @Autowired + private FrontendController frontendController; + + @BeforeEach + public void init() { + frontendController.initClients(port); + } + + @Override + protected RequestSpecification getSpec() { + return RestAssured.with().baseUri("http://localhost").port(port).basePath("/spring/frontend"); + } + + @Override + protected Stream getClients() { + return List.of(Client.REST_CLIENT.name(), Client.WEB_CLIENT.name()).stream(); + } +} diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application-ext.properties b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application-ext.properties new file mode 100644 index 00000000..15345d91 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application-ext.properties @@ -0,0 +1,2 @@ +io.github.belgif.rest.problem.ext.issue-types-enabled=true +io.github.belgif.rest.problem.ext.inputs-array-enabled=true diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application.properties b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application.properties new file mode 100644 index 00000000..c7602404 --- /dev/null +++ b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/application.properties @@ -0,0 +1,7 @@ +server.servlet.context-path=/spring +io.github.belgif.rest.problem.scan-additional-problem-packages=com.acme.custom + +#If this property is not set the client will receive an InvalidRequestException or InvalidResponseException +#without knowing what is wrong with the request / response as the message field will be missing. +# https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-spring-webmvc/README.md#Configuration +spring.web.error.include-message=always \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-3-client/src/test/resources/logback-test.xml b/belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-3-client/src/test/resources/logback-test.xml rename to belgif-rest-problem-it/belgif-rest-problem-spring-it/src/test/resources/logback-test.xml diff --git a/belgif-rest-problem-it/pom.xml b/belgif-rest-problem-it/pom.xml index 56562119..1ce7ff5e 100644 --- a/belgif-rest-problem-it/pom.xml +++ b/belgif-rest-problem-it/pom.xml @@ -35,6 +35,7 @@ belgif-rest-problem-apt belgif-rest-problem-it-common belgif-rest-problem-it-common-jakarta + belgif-rest-problem-spring-it belgif-rest-problem-spring-boot-3-it belgif-rest-problem-spring-boot-4-it belgif-rest-problem-java-ee-it diff --git a/belgif-rest-problem-spring-boot-common-client/pom.xml b/belgif-rest-problem-spring-boot-3-client-starter/pom.xml similarity index 90% rename from belgif-rest-problem-spring-boot-common-client/pom.xml rename to belgif-rest-problem-spring-boot-3-client-starter/pom.xml index 5ebfcea6..45277ce8 100644 --- a/belgif-rest-problem-spring-boot-common-client/pom.xml +++ b/belgif-rest-problem-spring-boot-3-client-starter/pom.xml @@ -9,9 +9,8 @@ ${revision} - belgif-rest-problem-spring-boot-common-client + belgif-rest-problem-spring-boot-3-client-starter ${project.groupId}:${project.artifactId} - Contains shared client components that are common between Spring Boot versions jar @@ -33,7 +32,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common + belgif-rest-problem-spring ${project.version} diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java new file mode 100644 index 00000000..ec5c39a0 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java @@ -0,0 +1,50 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.WebClient; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import io.github.belgif.rest.problem.spring.ProblemJackson2Configuration; + +/** + * Spring Boot AutoConfiguration for rest-problem-spring. + */ +@AutoConfiguration +@Import({ ProblemJackson2Configuration.class, JacksonAutoConfiguration.class }) +public class ClientProblemAutoConfiguration { + + @Bean + public ProblemResponseErrorHandler problemResponseErrorHandler(ObjectMapper objectMapper) { + return new ProblemResponseJackson2ErrorHandler(objectMapper); + } + + @ConditionalOnClass({ RestClient.class, RestClientCustomizer.class }) + @Bean + public ProblemRestClientCustomizer + problemRestClientCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + return new ProblemRestClientCustomizer(problemResponseErrorHandler); + } + + @ConditionalOnClass({ RestTemplate.class, RestTemplateCustomizer.class }) + @Bean + public ProblemRestTemplateCustomizer + problemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + return new ProblemRestTemplateCustomizer(problemResponseErrorHandler); + } + + @ConditionalOnClass({ WebClient.class, WebClientCustomizer.class }) + @Bean + public ProblemWebClientCustomizer problemWebClientCustomizer() { + return new ProblemWebClientCustomizer(); + } +} diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java new file mode 100644 index 00000000..582349aa --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java @@ -0,0 +1,22 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.web.client.RestClient; + +/** + * RestClientCustomizer that registers the {@link ProblemResponseErrorHandler}. + * + * @see ProblemResponseErrorHandler + */ +public class ProblemRestClientCustomizer implements RestClientCustomizer { + + private final ProblemResponseErrorHandler errorHandler; + + protected ProblemRestClientCustomizer(ProblemResponseErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + public void customize(RestClient.Builder restClientBuilder) { + restClientBuilder.defaultStatusHandler(errorHandler); + } +} diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java new file mode 100644 index 00000000..3a5d6abe --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java @@ -0,0 +1,24 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.web.client.RestTemplateCustomizer; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplateCustomizer that registers the {@link ProblemResponseErrorHandler}. + * + * @see ProblemResponseErrorHandler + */ +public class ProblemRestTemplateCustomizer implements RestTemplateCustomizer { + + private final ProblemResponseErrorHandler problemResponseErrorHandler; + + public ProblemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + this.problemResponseErrorHandler = problemResponseErrorHandler; + + } + + public void customize(RestTemplate restTemplate) { + restTemplate.setErrorHandler(problemResponseErrorHandler); + } + +} diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java new file mode 100644 index 00000000..c69915f7 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java @@ -0,0 +1,14 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. + */ +public class ProblemWebClientCustomizer implements WebClientCustomizer { + + public void customize(WebClient.Builder webClientBuilder) { + webClientBuilder.filter(WebClientFilter.PROBLEM_FILTER); + } +} diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/belgif-rest-problem-spring-boot-3-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..94df1c39 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +io.github.belgif.rest.problem.spring.client.ClientProblemAutoConfiguration \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-3-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java b/belgif-rest-problem-spring-boot-3-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java new file mode 100644 index 00000000..bc1e4f2a --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java @@ -0,0 +1,22 @@ +package io.github.belgif.rest.problem.spring.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import io.github.belgif.rest.problem.spring.ProblemJackson2Configuration; + +class ClientProblemAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ClientProblemAutoConfiguration.class)); + + @Test + void autoConfiguration() { + contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ProblemJackson2Configuration.class); + }); + } +} diff --git a/belgif-rest-problem-spring-boot-3-core/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-3-client-starter/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-3-core/src/test/resources/logback-test.xml rename to belgif-rest-problem-spring-boot-3-client-starter/src/test/resources/logback-test.xml diff --git a/belgif-rest-problem-spring-boot-3-client/pom.xml b/belgif-rest-problem-spring-boot-3-client/pom.xml deleted file mode 100644 index fbd0af4a..00000000 --- a/belgif-rest-problem-spring-boot-3-client/pom.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - 4.0.0 - - - io.github.belgif.rest.problem - belgif-rest-problem-parent - ${revision} - - - belgif-rest-problem-spring-boot-3-client - ${project.groupId}:${project.artifactId} - jar - - - 17 - - - - - - org.springframework.boot - spring-boot-dependencies - ${version.spring.boot.3} - pom - import - - - - - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-core - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-client - ${project.version} - - - org.springframework.boot - spring-boot-autoconfigure - provided - - - org.springframework - spring-web - provided - - - org.springframework - spring-webflux - provided - true - - - org.slf4j - slf4j-api - provided - - - com.fasterxml.jackson.core - jackson-databind - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - test - - - - diff --git a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java b/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java deleted file mode 100644 index 65672822..00000000 --- a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.client.RestClientCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestClient; - -/** - * RestClientCustomizer that registers the {@link ProblemResponseErrorHandler}. - * - * @see ProblemResponseErrorHandler - */ -@Component -@ConditionalOnClass({ RestClient.class, RestClientCustomizer.class }) -public class ProblemRestClientCustomizer extends AbstractProblemRestClientCustomizer implements RestClientCustomizer { - - public ProblemRestClientCustomizer(ProblemResponseErrorHandler errorHandler) { - super(errorHandler); - } -} diff --git a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java b/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java deleted file mode 100644 index ad83b432..00000000 --- a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.client.RestTemplateCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -/** - * RestTemplateCustomizer that registers the {@link ProblemResponseErrorHandler}. - * - * @see ProblemResponseErrorHandler - */ -@Component -@ConditionalOnClass({ RestTemplate.class, RestTemplateCustomizer.class }) -public class ProblemRestTemplateCustomizer extends AbstractProblemRestTemplateCustomizer - implements RestTemplateCustomizer { - - public ProblemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { - super(problemResponseErrorHandler); - } - -} diff --git a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java b/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java deleted file mode 100644 index c3b4ecff..00000000 --- a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.web.reactive.function.client.WebClientCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. - */ -@Component -@ConditionalOnClass({ WebClient.class, WebClientCustomizer.class }) -public class ProblemWebClientCustomizer extends AbstractProblemWebClientCustomizer implements WebClientCustomizer { - -} diff --git a/belgif-rest-problem-spring-boot-3-core/pom.xml b/belgif-rest-problem-spring-boot-3-core/pom.xml deleted file mode 100644 index 791c8e52..00000000 --- a/belgif-rest-problem-spring-boot-3-core/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - - io.github.belgif.rest.problem - belgif-rest-problem-parent - ${revision} - - - belgif-rest-problem-spring-boot-3-core - ${project.groupId}:${project.artifactId} - jar - - - 17 - - - - - - org.springframework.boot - spring-boot-dependencies - ${version.spring.boot.3} - pom - import - - - - - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common - ${project.version} - - - org.springframework.boot - spring-boot-autoconfigure - provided - - - org.slf4j - slf4j-api - provided - - - com.fasterxml.jackson.core - jackson-databind - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - test - - - - diff --git a/belgif-rest-problem-spring-boot-common-server/pom.xml b/belgif-rest-problem-spring-boot-3-server-starter/pom.xml similarity index 92% rename from belgif-rest-problem-spring-boot-common-server/pom.xml rename to belgif-rest-problem-spring-boot-3-server-starter/pom.xml index 27b4fcff..7b2b2890 100644 --- a/belgif-rest-problem-spring-boot-common-server/pom.xml +++ b/belgif-rest-problem-spring-boot-3-server-starter/pom.xml @@ -9,9 +9,8 @@ ${revision} - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring-boot-3-server-starter ${project.groupId}:${project.artifactId} - Contains shared server components that are common between Spring Boot versions jar @@ -33,7 +32,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common + belgif-rest-problem-spring ${project.version} diff --git a/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java b/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java new file mode 100644 index 00000000..d9e612af --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java @@ -0,0 +1,15 @@ +package io.github.belgif.rest.problem.spring.server; + +import jakarta.validation.Configuration; + +import org.springframework.boot.autoconfigure.validation.ValidationConfigurationCustomizer; + +/** + * ValidationConfigurationCustomizer that registers the AnnotationParameterNameProvider. + */ +public class ProblemValidationConfigurationCustomizer implements ValidationConfigurationCustomizer { + + public void customize(Configuration configuration) { + configuration.parameterNameProvider(new AnnotationParameterNameProvider()); + } +} diff --git a/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java b/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java new file mode 100644 index 00000000..f0913492 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java @@ -0,0 +1,61 @@ +package io.github.belgif.rest.problem.spring.server; + +import jakarta.validation.Configuration; +import jakarta.validation.ConstraintViolationException; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.boot.autoconfigure.validation.ValidationConfigurationCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +import com.atlassian.oai.validator.springmvc.InvalidRequestException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Spring Boot AutoConfiguration for rest-problem-spring. + */ +@AutoConfiguration +@Import({ io.github.belgif.rest.problem.spring.ProblemJackson2Configuration.class, JacksonAutoConfiguration.class }) +public class ServerProblemAutoConfiguration { + + private ObjectMapper objectMapper; + + public ServerProblemAutoConfiguration(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @ConditionalOnClass(ConstraintViolationException.class) + @ConditionalOnWebApplication + @Bean + public BeanValidationExceptionsHandler beanValidationExceptionsHandler() { + return new BeanValidationExceptionsHandler(); + } + + @ConditionalOnWebApplication + @Bean + public ProblemExceptionHandler problemExceptionHandler() { + return new ProblemExceptionHandler(); + } + + @ConditionalOnWebApplication + @Bean + public RoutingExceptionsJackson2Handler routingExceptionsHandler() { + return new RoutingExceptionsJackson2Handler(); + } + + @ConditionalOnClass({ Configuration.class, ValidationConfigurationCustomizer.class }) + @Bean + public ProblemValidationConfigurationCustomizer problemValidationConfigurationCustomizer() { + return new ProblemValidationConfigurationCustomizer(); + } + + @ConditionalOnWebApplication + @ConditionalOnClass(InvalidRequestException.class) + @Bean + public InvalidRequestExceptionJackson2Handler invalidRequestExceptionHandler() { + return new InvalidRequestExceptionJackson2Handler(objectMapper); + } +} diff --git a/belgif-rest-problem-spring-boot-3-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/belgif-rest-problem-spring-boot-3-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..379d1750 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +io.github.belgif.rest.problem.spring.server.ServerProblemAutoConfiguration \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-3-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java b/belgif-rest-problem-spring-boot-3-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java new file mode 100644 index 00000000..44245f70 --- /dev/null +++ b/belgif-rest-problem-spring-boot-3-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java @@ -0,0 +1,23 @@ +package io.github.belgif.rest.problem.spring.server; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import io.github.belgif.rest.problem.spring.ProblemJackson2Configuration; + +class ServerProblemAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ServerProblemAutoConfiguration.class)); + + @Test + void autoConfiguration() { + contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ProblemJackson2Configuration.class); + }); + } + +} diff --git a/belgif-rest-problem-spring-boot-3-server/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-3-server-starter/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-3-server/src/test/resources/logback-test.xml rename to belgif-rest-problem-spring-boot-3-server-starter/src/test/resources/logback-test.xml diff --git a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java b/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java deleted file mode 100644 index c7ef15f5..00000000 --- a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import jakarta.validation.Configuration; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.validation.ValidationConfigurationCustomizer; -import org.springframework.stereotype.Component; - -/** - * ValidationConfigurationCustomizer that registers the AnnotationParameterNameProvider. - */ -@Component -@ConditionalOnClass({ Configuration.class, ValidationConfigurationCustomizer.class }) -public class ProblemValidationConfigurationCustomizer extends AbstractProblemValidationConfigurationCustomizer - implements ValidationConfigurationCustomizer { - -} diff --git a/belgif-rest-problem-spring-boot-3/pom.xml b/belgif-rest-problem-spring-boot-3/pom.xml index af707bb5..d0fcfe73 100644 --- a/belgif-rest-problem-spring-boot-3/pom.xml +++ b/belgif-rest-problem-spring-boot-3/pom.xml @@ -16,12 +16,12 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-client + belgif-rest-problem-spring-boot-3-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-server + belgif-rest-problem-spring-boot-3-server-starter ${project.version} diff --git a/belgif-rest-problem-spring-boot-4-client/pom.xml b/belgif-rest-problem-spring-boot-4-client-starter/pom.xml similarity index 89% rename from belgif-rest-problem-spring-boot-4-client/pom.xml rename to belgif-rest-problem-spring-boot-4-client-starter/pom.xml index 56d9c6a6..238ec2ee 100644 --- a/belgif-rest-problem-spring-boot-4-client/pom.xml +++ b/belgif-rest-problem-spring-boot-4-client-starter/pom.xml @@ -9,7 +9,7 @@ ${revision} - belgif-rest-problem-spring-boot-4-client + belgif-rest-problem-spring-boot-4-client-starter ${project.groupId}:${project.artifactId} jar @@ -32,12 +32,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-core - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-client + belgif-rest-problem-spring ${project.version} diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java new file mode 100644 index 00000000..b9f321bd --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfiguration.java @@ -0,0 +1,48 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.restclient.RestClientCustomizer; +import org.springframework.boot.restclient.RestTemplateCustomizer; +import org.springframework.boot.webclient.WebClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; +import org.springframework.web.client.RestClient; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.WebClient; + +import tools.jackson.databind.ObjectMapper; + +/** + * Spring Boot AutoConfiguration for rest-problem-spring. + */ +@AutoConfiguration +@Import({ io.github.belgif.rest.problem.spring.ProblemJackson3Configuration.class, JacksonAutoConfiguration.class }) +public class ClientProblemAutoConfiguration { + + @Bean + public ProblemResponseErrorHandler problemResponseErrorHandler(ObjectMapper objectMapper) { + return new ProblemResponseJackson3ErrorHandler(objectMapper); + } + + @ConditionalOnClass({ RestClient.class, RestClientCustomizer.class }) + @Bean + public ProblemRestClientCustomizer + problemRestClientCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + return new ProblemRestClientCustomizer(problemResponseErrorHandler); + } + + @ConditionalOnClass({ RestTemplate.class, RestTemplateCustomizer.class }) + @Bean + public ProblemRestTemplateCustomizer + problemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + return new ProblemRestTemplateCustomizer(problemResponseErrorHandler); + } + + @ConditionalOnClass({ WebClient.class, WebClientCustomizer.class }) + @Bean + public ProblemWebClientCustomizer problemWebClientCustomizer() { + return new ProblemWebClientCustomizer(); + } +} diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java new file mode 100644 index 00000000..9621df39 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizer.java @@ -0,0 +1,23 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.restclient.RestClientCustomizer; +import org.springframework.web.client.RestClient; + +/** + * RestClientCustomizer that registers the {@link ProblemResponseErrorHandler}. + * + * @see ProblemResponseErrorHandler + */ +public class ProblemRestClientCustomizer implements RestClientCustomizer { + + private final ProblemResponseErrorHandler errorHandler; + + protected ProblemRestClientCustomizer(ProblemResponseErrorHandler errorHandler) { + this.errorHandler = errorHandler; + } + + public void customize(RestClient.Builder restClientBuilder) { + restClientBuilder.defaultStatusHandler(errorHandler); + } + +} diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java new file mode 100644 index 00000000..c4bb7ec8 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizer.java @@ -0,0 +1,24 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.restclient.RestTemplateCustomizer; +import org.springframework.web.client.RestTemplate; + +/** + * RestTemplateCustomizer that registers the {@link ProblemResponseErrorHandler}. + * + * @see ProblemResponseErrorHandler + */ +public class ProblemRestTemplateCustomizer implements RestTemplateCustomizer { + + private final ProblemResponseErrorHandler problemResponseErrorHandler; + + public ProblemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { + this.problemResponseErrorHandler = problemResponseErrorHandler; + + } + + public void customize(RestTemplate restTemplate) { + restTemplate.setErrorHandler(problemResponseErrorHandler); + } + +} diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java new file mode 100644 index 00000000..797ef3d0 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizer.java @@ -0,0 +1,15 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.boot.webclient.WebClientCustomizer; +import org.springframework.web.reactive.function.client.WebClient; + +/** + * WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. + */ +public class ProblemWebClientCustomizer implements WebClientCustomizer { + + public void customize(WebClient.Builder webClientBuilder) { + webClientBuilder.filter(WebClientFilter.PROBLEM_FILTER); + } + +} diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/belgif-rest-problem-spring-boot-4-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..94df1c39 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +io.github.belgif.rest.problem.spring.client.ClientProblemAutoConfiguration \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java new file mode 100644 index 00000000..175e9ecd --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ClientProblemAutoConfigurationTest.java @@ -0,0 +1,22 @@ +package io.github.belgif.rest.problem.spring.client; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import io.github.belgif.rest.problem.spring.ProblemJackson3Configuration; + +class ClientProblemAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ClientProblemAutoConfiguration.class)); + + @Test + void autoConfiguration() { + contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ProblemJackson3Configuration.class); + }); + } +} diff --git a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizerTest.java b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizerTest.java similarity index 64% rename from belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizerTest.java rename to belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizerTest.java index 21325ed7..ef51f745 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizerTest.java +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestClientCustomizerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -9,12 +9,12 @@ import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.client.RestClient; -class AbstractProblemRestClientCustomizerTest { +class ProblemRestClientCustomizerTest { @Test void customize() { - AbstractProblemResponseErrorHandler handler = mock(AbstractProblemResponseErrorHandler.class); - AbstractProblemRestClientCustomizer customizer = new AbstractProblemRestClientCustomizer(handler) { + ProblemResponseErrorHandler handler = mock(ProblemResponseErrorHandler.class); + ProblemRestClientCustomizer customizer = new ProblemRestClientCustomizer(handler) { }; RestClient.Builder builder = RestClient.builder(); customizer.customize(builder); diff --git a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizerTest.java b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizerTest.java similarity index 56% rename from belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizerTest.java rename to belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizerTest.java index 8f46d473..46c9a121 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizerTest.java +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemRestTemplateCustomizerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -6,12 +6,12 @@ import org.junit.jupiter.api.Test; import org.springframework.web.client.RestTemplate; -class AbstractProblemRestTemplateCustomizerTest { +class ProblemRestTemplateCustomizerTest { @Test void customize() { - AbstractProblemResponseErrorHandler handler = mock(AbstractProblemResponseErrorHandler.class); - AbstractProblemRestTemplateCustomizer customizer = new AbstractProblemRestTemplateCustomizer(handler) { + ProblemResponseErrorHandler handler = mock(ProblemResponseErrorHandler.class); + ProblemRestTemplateCustomizer customizer = new ProblemRestTemplateCustomizer(handler) { }; RestTemplate restTemplate = new RestTemplate(); customizer.customize(restTemplate); diff --git a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizerTest.java b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizerTest.java similarity index 94% rename from belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizerTest.java rename to belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizerTest.java index f1460e2a..1d72d27d 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizerTest.java +++ b/belgif-rest-problem-spring-boot-4-client-starter/src/test/java/io/github/belgif/rest/problem/spring/client/ProblemWebClientCustomizerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -20,9 +20,9 @@ import reactor.core.publisher.Mono; @ExtendWith(MockitoExtension.class) -class AbstractProblemWebClientCustomizerTest { +class ProblemWebClientCustomizerTest { - private final AbstractProblemWebClientCustomizer customizer = new AbstractProblemWebClientCustomizer() { + private final ProblemWebClientCustomizer customizer = new ProblemWebClientCustomizer() { }; @Mock diff --git a/belgif-rest-problem-spring-boot-4-client/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-4-client-starter/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-4-client/src/test/resources/logback-test.xml rename to belgif-rest-problem-spring-boot-4-client-starter/src/test/resources/logback-test.xml diff --git a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java b/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java deleted file mode 100644 index 7c9f4188..00000000 --- a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.restclient.RestClientCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestClient; - -/** - * RestClientCustomizer that registers the {@link ProblemResponseErrorHandler}. - * - * @see ProblemResponseErrorHandler - */ -@Component -@ConditionalOnClass({ RestClient.class, RestClientCustomizer.class }) -public class ProblemRestClientCustomizer extends AbstractProblemRestClientCustomizer implements RestClientCustomizer { - - public ProblemRestClientCustomizer(ProblemResponseErrorHandler errorHandler) { - super(errorHandler); - } - -} diff --git a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java b/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java deleted file mode 100644 index 02c7b37c..00000000 --- a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemRestTemplateCustomizer.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.restclient.RestTemplateCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; - -/** - * RestTemplateCustomizer that registers the {@link ProblemResponseErrorHandler}. - * - * @see ProblemResponseErrorHandler - */ -@Component -@ConditionalOnClass({ RestTemplate.class, RestTemplateCustomizer.class }) -public class ProblemRestTemplateCustomizer extends AbstractProblemRestTemplateCustomizer - implements RestTemplateCustomizer { - - public ProblemRestTemplateCustomizer(ProblemResponseErrorHandler problemResponseErrorHandler) { - super(problemResponseErrorHandler); - } - -} diff --git a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java b/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java deleted file mode 100644 index f7ad2295..00000000 --- a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemWebClientCustomizer.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.webclient.WebClientCustomizer; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. - */ -@Component -@ConditionalOnClass({ WebClient.class, WebClientCustomizer.class }) -public class ProblemWebClientCustomizer extends AbstractProblemWebClientCustomizer implements WebClientCustomizer { - -} diff --git a/belgif-rest-problem-spring-boot-4-core/pom.xml b/belgif-rest-problem-spring-boot-4-core/pom.xml deleted file mode 100644 index 612ac9e6..00000000 --- a/belgif-rest-problem-spring-boot-4-core/pom.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - 4.0.0 - - - io.github.belgif.rest.problem - belgif-rest-problem-parent - ${revision} - - - belgif-rest-problem-spring-boot-4-core - ${project.groupId}:${project.artifactId} - jar - - - 17 - - - - - - org.springframework.boot - spring-boot-dependencies - ${version.spring.boot.4} - pom - import - - - - - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common - ${project.version} - - - org.springframework.boot - spring-boot-autoconfigure - provided - - - org.springframework.boot - spring-boot-starter-jackson - provided - - - org.slf4j - slf4j-api - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - test - - - - diff --git a/belgif-rest-problem-spring-boot-4-server/pom.xml b/belgif-rest-problem-spring-boot-4-server-starter/pom.xml similarity index 89% rename from belgif-rest-problem-spring-boot-4-server/pom.xml rename to belgif-rest-problem-spring-boot-4-server-starter/pom.xml index 825b1920..75b0d368 100644 --- a/belgif-rest-problem-spring-boot-4-server/pom.xml +++ b/belgif-rest-problem-spring-boot-4-server-starter/pom.xml @@ -9,7 +9,7 @@ ${revision} - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-4-server-starter ${project.groupId}:${project.artifactId} jar @@ -32,12 +32,7 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-core - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring ${project.version} diff --git a/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java b/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java new file mode 100644 index 00000000..d779d3bc --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizer.java @@ -0,0 +1,15 @@ +package io.github.belgif.rest.problem.spring.server; + +import jakarta.validation.Configuration; + +import org.springframework.boot.validation.autoconfigure.ValidationConfigurationCustomizer; + +/** + * ValidationConfigurationCustomizer that registers the AnnotationParameterNameProvider. + */ +public class ProblemValidationConfigurationCustomizer implements ValidationConfigurationCustomizer { + + public void customize(Configuration configuration) { + configuration.parameterNameProvider(new AnnotationParameterNameProvider()); + } +} diff --git a/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java b/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java new file mode 100644 index 00000000..c3adfa5c --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-server-starter/src/main/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfiguration.java @@ -0,0 +1,62 @@ +package io.github.belgif.rest.problem.spring.server; + +import jakarta.validation.Configuration; +import jakarta.validation.ConstraintViolationException; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration; +import org.springframework.boot.validation.autoconfigure.ValidationConfigurationCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; + +import com.atlassian.oai.validator.springmvc.InvalidRequestException; + +import tools.jackson.databind.ObjectMapper; + +/** + * Spring Boot AutoConfiguration for rest-problem-spring. + */ +@AutoConfiguration +@Import({ io.github.belgif.rest.problem.spring.ProblemJackson3Configuration.class, JacksonAutoConfiguration.class }) +public class ServerProblemAutoConfiguration { + + private ObjectMapper objectMapper; + + public ServerProblemAutoConfiguration(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + @ConditionalOnClass(ConstraintViolationException.class) + @ConditionalOnWebApplication + @Bean + public BeanValidationExceptionsHandler beanValidationExceptionsHandler() { + return new BeanValidationExceptionsHandler(); + } + + @ConditionalOnWebApplication + @Bean + public ProblemExceptionHandler problemExceptionHandler() { + return new ProblemExceptionHandler(); + } + + @ConditionalOnWebApplication + @Bean + public RoutingExceptionsJackson3Handler routingExceptionsHandler() { + return new RoutingExceptionsJackson3Handler(); + } + + @ConditionalOnClass({ Configuration.class, ValidationConfigurationCustomizer.class }) + @Bean + public ProblemValidationConfigurationCustomizer problemValidationConfigurationCustomizer() { + return new ProblemValidationConfigurationCustomizer(); + } + + @ConditionalOnWebApplication + @ConditionalOnClass(InvalidRequestException.class) + @Bean + public InvalidRequestExceptionJackson3Handler invalidRequestExceptionHandler() { + return new InvalidRequestExceptionJackson3Handler(objectMapper); + } +} diff --git a/belgif-rest-problem-spring-boot-4-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/belgif-rest-problem-spring-boot-4-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 00000000..379d1750 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-server-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +io.github.belgif.rest.problem.spring.server.ServerProblemAutoConfiguration \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizerTest.java b/belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizerTest.java similarity index 76% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizerTest.java rename to belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizerTest.java index 4a4cf774..72d543d9 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizerTest.java +++ b/belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemValidationConfigurationCustomizerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -14,11 +14,10 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) -class AbstractProblemValidationConfigurationCustomizerTest { +class ProblemValidationConfigurationCustomizerTest { - private final AbstractProblemValidationConfigurationCustomizer customizer = - new AbstractProblemValidationConfigurationCustomizer() { - }; + private final ProblemValidationConfigurationCustomizer customizer = + new ProblemValidationConfigurationCustomizer(); @Mock private Configuration configuration; diff --git a/belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java b/belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java new file mode 100644 index 00000000..795d8059 --- /dev/null +++ b/belgif-rest-problem-spring-boot-4-server-starter/src/test/java/io/github/belgif/rest/problem/spring/server/ServerProblemAutoConfigurationTest.java @@ -0,0 +1,23 @@ +package io.github.belgif.rest.problem.spring.server; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import io.github.belgif.rest.problem.spring.ProblemJackson3Configuration; + +class ServerProblemAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(ServerProblemAutoConfiguration.class)); + + @Test + void autoConfiguration() { + contextRunner.run((context) -> { + assertThat(context).hasSingleBean(ProblemJackson3Configuration.class); + }); + } + +} diff --git a/belgif-rest-problem-spring-boot-4-core/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-4-server-starter/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-4-core/src/test/resources/logback-test.xml rename to belgif-rest-problem-spring-boot-4-server-starter/src/test/resources/logback-test.xml diff --git a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java b/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java deleted file mode 100644 index 8e7fbbfb..00000000 --- a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemValidationConfigurationCustomizer.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import jakarta.validation.Configuration; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.validation.autoconfigure.ValidationConfigurationCustomizer; -import org.springframework.stereotype.Component; - -/** - * ValidationConfigurationCustomizer that registers the AnnotationParameterNameProvider. - */ -@Component -@ConditionalOnClass({ Configuration.class, ValidationConfigurationCustomizer.class }) -public class ProblemValidationConfigurationCustomizer extends AbstractProblemValidationConfigurationCustomizer - implements ValidationConfigurationCustomizer { - -} diff --git a/belgif-rest-problem-spring-boot-4/pom.xml b/belgif-rest-problem-spring-boot-4-starter/pom.xml similarity index 78% rename from belgif-rest-problem-spring-boot-4/pom.xml rename to belgif-rest-problem-spring-boot-4-starter/pom.xml index 4ff85f26..dcc2589e 100644 --- a/belgif-rest-problem-spring-boot-4/pom.xml +++ b/belgif-rest-problem-spring-boot-4-starter/pom.xml @@ -9,19 +9,19 @@ ${revision} - belgif-rest-problem-spring-boot-4 + belgif-rest-problem-spring-boot-4-starter ${project.groupId}:${project.artifactId} jar io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-client + belgif-rest-problem-spring-boot-4-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-4-server-starter ${project.version} diff --git a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizer.java b/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizer.java deleted file mode 100644 index a5b70bd5..00000000 --- a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestClientCustomizer.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.web.client.RestClient; - -/** - * RestClientCustomizer that registers the {@link AbstractProblemResponseErrorHandler}. - * - * @see AbstractProblemResponseErrorHandler - */ -public abstract class AbstractProblemRestClientCustomizer { - - private final AbstractProblemResponseErrorHandler errorHandler; - - protected AbstractProblemRestClientCustomizer(AbstractProblemResponseErrorHandler errorHandler) { - this.errorHandler = errorHandler; - } - - public void customize(RestClient.Builder restClientBuilder) { - restClientBuilder.defaultStatusHandler(errorHandler); - } - -} diff --git a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizer.java b/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizer.java deleted file mode 100644 index 6e85fe78..00000000 --- a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemRestTemplateCustomizer.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.web.client.RestTemplate; - -/** - * RestTemplateCustomizer that registers the {@link AbstractProblemResponseErrorHandler}. - * - * @see AbstractProblemResponseErrorHandler - */ -public abstract class AbstractProblemRestTemplateCustomizer { - - private final AbstractProblemResponseErrorHandler problemResponseErrorHandler; - - protected AbstractProblemRestTemplateCustomizer(AbstractProblemResponseErrorHandler problemResponseErrorHandler) { - this.problemResponseErrorHandler = problemResponseErrorHandler; - } - - public void customize(RestTemplate restTemplate) { - restTemplate.setErrorHandler(problemResponseErrorHandler); - } - -} diff --git a/belgif-rest-problem-spring-boot-common-client/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-common-client/src/test/resources/logback-test.xml deleted file mode 100644 index fe45af16..00000000 --- a/belgif-rest-problem-spring-boot-common-client/src/test/resources/logback-test.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - DENY - ACCEPT - - System.out - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - ACCEPT - DENY - - System.err - - - - - - - - diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandler.java b/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandler.java deleted file mode 100644 index ad2e4d68..00000000 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandler.java +++ /dev/null @@ -1,28 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.core.annotation.Order; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; -import org.springframework.web.servlet.resource.NoResourceFoundException; - -import io.github.belgif.rest.problem.ResourceNotFoundProblem; -import io.github.belgif.rest.problem.api.Problem; - -@RestControllerAdvice -@Order(1) -@ConditionalOnWebApplication -public class NoResourceFoundExceptionHandler { - - @ExceptionHandler(NoResourceFoundException.class) - public ResponseEntity handleNoResourceFoundException( - NoResourceFoundException exception) { - ResourceNotFoundProblem problem = new ResourceNotFoundProblem(); - problem.setDetail("No resource %s found".formatted( - exception.getResourcePath().startsWith("/") ? exception.getResourcePath() - : "/" + exception.getResourcePath())); - return ProblemMediaType.INSTANCE.toResponse(problem); - } - -} diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver b/belgif-rest-problem-spring-boot-common-server/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver deleted file mode 100644 index 8ac9f41a..00000000 --- a/belgif-rest-problem-spring-boot-common-server/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver +++ /dev/null @@ -1 +0,0 @@ -io.github.belgif.rest.problem.spring.i18n.LocaleContextHolderLocaleResolver \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandlerTest.java b/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandlerTest.java deleted file mode 100644 index 5de8f636..00000000 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/NoResourceFoundExceptionHandlerTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.web.servlet.resource.NoResourceFoundException; - -import io.github.belgif.rest.problem.ResourceNotFoundProblem; -import io.github.belgif.rest.problem.api.Problem; - -class NoResourceFoundExceptionHandlerTest { - - private final NoResourceFoundExceptionHandler handler = new NoResourceFoundExceptionHandler(); - - @Test - void handleNoResourceFoundException() { - ResponseEntity entity = handler.handleNoResourceFoundException( - new NoResourceFoundException(HttpMethod.GET, "/test")); - assertThat(entity.getStatusCode().value()).isEqualTo(404); - assertThat(entity.getHeaders().getContentType()).isEqualTo(ProblemMediaType.INSTANCE); - ResourceNotFoundProblem problem = (ResourceNotFoundProblem) entity.getBody(); - assertThat(problem.getDetail()).isEqualTo("No resource /test found"); - } - - @Test - void handleNoResourceFoundExceptionAddsLeadingSlash() { - ResponseEntity entity = handler.handleNoResourceFoundException( - new NoResourceFoundException(HttpMethod.GET, "test")); - assertThat(entity.getStatusCode().value()).isEqualTo(404); - assertThat(entity.getHeaders().getContentType()).isEqualTo(ProblemMediaType.INSTANCE); - ResourceNotFoundProblem problem = (ResourceNotFoundProblem) entity.getBody(); - assertThat(problem.getDetail()).isEqualTo("No resource /test found"); - } - -} diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-common-server/src/test/resources/logback-test.xml deleted file mode 100644 index fe45af16..00000000 --- a/belgif-rest-problem-spring-boot-common-server/src/test/resources/logback-test.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - DENY - ACCEPT - - System.out - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - ACCEPT - DENY - - System.err - - - - - - - - diff --git a/belgif-rest-problem-spring-boot-common/pom.xml b/belgif-rest-problem-spring-boot-common/pom.xml deleted file mode 100644 index cd7feac7..00000000 --- a/belgif-rest-problem-spring-boot-common/pom.xml +++ /dev/null @@ -1,76 +0,0 @@ - - - 4.0.0 - - - io.github.belgif.rest.problem - belgif-rest-problem-parent - ${revision} - - - belgif-rest-problem-spring-boot-common - ${project.groupId}:${project.artifactId} - Contains shared components that are common between Spring Boot versions - jar - - - 17 - - - - - - org.springframework.boot - spring-boot-dependencies - ${version.spring.boot.3} - pom - import - - - - - - - io.github.belgif.rest.problem - belgif-rest-problem - ${project.version} - - - org.springframework.boot - spring-boot-autoconfigure - provided - - - org.springframework - spring-web - provided - - - org.slf4j - slf4j-api - provided - - - com.fasterxml.jackson.core - jackson-databind - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - test - - - - diff --git a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemAutoConfiguration.java b/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemAutoConfiguration.java deleted file mode 100644 index e3fe9a52..00000000 --- a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemAutoConfiguration.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import org.springframework.boot.autoconfigure.AutoConfiguration; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.ComponentScan; - -/** - * Spring Boot AutoConfiguration for rest-problem-spring. - */ -@AutoConfiguration -@ComponentScan("io.github.belgif.rest.problem") -@EnableConfigurationProperties({ ProblemConfigurationProperties.class, ProblemExtConfigurationProperties.class }) -public class ProblemAutoConfiguration { - -} diff --git a/belgif-rest-problem-spring-boot-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/belgif-rest-problem-spring-boot-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index f115dc5b..00000000 --- a/belgif-rest-problem-spring-boot-common/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -io.github.belgif.rest.problem.spring.ProblemAutoConfiguration \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemAutoConfigurationTest.java b/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemAutoConfigurationTest.java deleted file mode 100644 index c5a5c66b..00000000 --- a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemAutoConfigurationTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.github.belgif.rest.problem.spring; - -import static org.assertj.core.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -class ProblemAutoConfigurationTest { - - @Test - void autoConfiguration() { - assertThatNoException().isThrownBy(ProblemAutoConfiguration::new); - } - -} diff --git a/belgif-rest-problem-spring-boot-common/src/test/resources/logback-test.xml b/belgif-rest-problem-spring-boot-common/src/test/resources/logback-test.xml deleted file mode 100644 index fe45af16..00000000 --- a/belgif-rest-problem-spring-boot-common/src/test/resources/logback-test.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - DENY - ACCEPT - - System.out - - - - - %d [%thread] %.-1level %logger{36} %M - %msg%n - - - ERROR - ACCEPT - DENY - - System.err - - - - - - - - diff --git a/belgif-rest-problem-spring-boot-3-server/pom.xml b/belgif-rest-problem-spring/pom.xml similarity index 74% rename from belgif-rest-problem-spring-boot-3-server/pom.xml rename to belgif-rest-problem-spring/pom.xml index 80f1419b..7581ffe6 100644 --- a/belgif-rest-problem-spring-boot-3-server/pom.xml +++ b/belgif-rest-problem-spring/pom.xml @@ -9,8 +9,9 @@ ${revision} - belgif-rest-problem-spring-boot-3-server + belgif-rest-problem-spring ${project.groupId}:${project.artifactId} + Contains shared components that are common between Spring Boot versions jar @@ -32,28 +33,31 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-core + belgif-rest-problem ${project.version} - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-server - ${project.version} - - - org.springframework.boot - spring-boot-autoconfigure + org.springframework + spring-web provided org.springframework - spring-web + spring-webflux provided + true org.springframework spring-webmvc provided + true + + + com.atlassian.oai + swagger-request-validator-springmvc + 2.46.0 + true org.slf4j @@ -66,39 +70,49 @@ provided - jakarta.validation - jakarta.validation-api + tools.jackson.core + jackson-databind + ${version.jackson3.minimal} provided + jakarta.servlet jakarta.servlet-api provided + + + org.hibernate.validator + hibernate-validator + provided + true + - com.atlassian.oai - swagger-request-validator-springmvc - 2.46.0 + jakarta.validation + jakarta.validation-api + provided true + - org.springframework.boot - spring-boot-starter-test + org.junit.jupiter + junit-jupiter test - org.springframework.boot - spring-boot-starter-validation + org.assertj + assertj-core test - org.junit.jupiter - junit-jupiter + org.mockito + mockito-junit-jupiter test - org.assertj - assertj-core + org.springframework + spring-test test diff --git a/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/EnableProblemModule.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/EnableProblemModule.java new file mode 100644 index 00000000..f8ce0e35 --- /dev/null +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/EnableProblemModule.java @@ -0,0 +1,127 @@ +package io.github.belgif.rest.problem.spring; + +import java.lang.annotation.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; + +import io.github.belgif.rest.problem.spring.client.ProblemResponseJackson2ErrorHandler; +import io.github.belgif.rest.problem.spring.client.ProblemResponseJackson3ErrorHandler; +import io.github.belgif.rest.problem.spring.server.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Import(EnableProblemModule.ProblemModuleImportSelector.class) +/** + * Activate support of the belgif-rest-problem integration for spring. + * + * When running in a Spring Boot environment, use of the 'starter' modules is recommended, which require less + * configuration. + * + * Attributes select which optional integrations are activated. + * An application using this module, should provide an ObjectMapper bean on which the {@link SpringProblemModule} + * or {@link SpringProblemModuleJackson3} support bean is registered. + */ +public @interface EnableProblemModule { + + /** + * Activate RestControllerAdvice for rest-problem support on any RestController + */ + boolean server() default true; + + /** + * Creates support beans for REST clients. + * Requires: + * - setting ProblemResponseErrorHandler as defaultStatusHandler on the client + * - or for {@link org.springframework.web.reactive.function.client.WebClient}, setting PROBLEM_FILTER from + * {@link io.github.belgif.rest.problem.spring.client.WebClientFilter} + */ + boolean client() default true; + + /** + * Jackson version being used + */ + JacksonVersion jacksonVersion() default JacksonVersion.JACKSON_3; + + enum JacksonVersion { + JACKSON_2, JACKSON_3 + } + + /** + * Convert Jakarta Bean Validation exceptions to badRequestProblem + * + * Only supported server-side. + * For proper problem messages, requires using the {@link AnnotationParameterNameProvider} on the used + * {@link jakarta.validation.Configuration} + */ + boolean beanValidation() default false; + + /** + * Convert input validation exceptions from the swagger-request-validator library to badRequestProblem + * + * Only supported server-side + */ + boolean swaggerRequestValidator() default false; + + class ProblemModuleImportSelector implements ImportSelector { + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + Map attributes = importingClassMetadata + .getAnnotationAttributes(EnableProblemModule.class.getName()); + boolean includeServer = (boolean) attributes.get("server"); + boolean includeClient = (boolean) attributes.get("client"); + boolean useJackson3 = (attributes.get("jacksonVersion") == JacksonVersion.JACKSON_3); + boolean includeBeanValidation = (boolean) attributes.get("beanValidation"); + boolean includeSwaggerRequestValidator = (boolean) attributes.get("swaggerRequestValidator"); + + List imports = new ArrayList<>(); + + Class commonConfig = useJackson3 ? ProblemJackson3Configuration.class : ProblemJackson2Configuration.class; + imports.add(commonConfig.getName()); + + if (includeServer) { + imports.add(ProblemExceptionHandler.class.getName()); + Class routingExceptionsHandler = + useJackson3 ? RoutingExceptionsJackson3Handler.class : RoutingExceptionsJackson2Handler.class; + imports.add(routingExceptionsHandler.getName()); + + if (includeBeanValidation) { + imports.add(BeanValidationConfiguration.class.getName()); + } + if (includeSwaggerRequestValidator) { + Class invalidRequestExceptionHandler = useJackson3 ? InvalidRequestExceptionJackson3Handler.class + : InvalidRequestExceptionJackson2Handler.class; + imports.add(invalidRequestExceptionHandler.getName()); + } + } + if (includeClient) { + Class clientConfig = + useJackson3 ? ProblemResponseJackson3ErrorHandler.class + : ProblemResponseJackson2ErrorHandler.class; + imports.add(clientConfig.getName()); + } + return imports.toArray(new String[imports.size()]); + } + } + + @Configuration + @Import(BeanValidationExceptionsHandler.class) + class BeanValidationConfiguration { + @Bean + public LocalValidatorFactoryBean validator() { + LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); + validator.setConfigurationInitializer( + configuration -> configuration.parameterNameProvider(new AnnotationParameterNameProvider())); + return validator; + } + } +} diff --git a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java similarity index 73% rename from belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java index 52585db1..c104f59f 100644 --- a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemConfigurationProperties.java @@ -4,14 +4,15 @@ import java.util.List; import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import io.github.belgif.rest.problem.config.ProblemConfig; /** * Lists all supported application.properties configurations for the belgif-rest-problem-spring library. */ -@ConfigurationProperties(prefix = "io.github.belgif.rest.problem") +@Component // not using @ConfigurationProperties to avoid Spring Boot dependency public class ProblemConfigurationProperties implements InitializingBean { private List scanAdditionalProblemPackages = new ArrayList<>(); @@ -20,6 +21,7 @@ public class ProblemConfigurationProperties implements InitializingBean { private Boolean stackTraceEnabled = null; + @Value("${io.github.belgif.rest.problem.scan-additional-problem-packages:#{{}}}") public void setScanAdditionalProblemPackages(List scanAdditionalProblemPackages) { this.scanAdditionalProblemPackages = scanAdditionalProblemPackages; } @@ -28,10 +30,12 @@ public List getScanAdditionalProblemPackages() { return scanAdditionalProblemPackages; } - public void setI18nEnabled(boolean i18nEnabled) { + @Value("${io.github.belgif.rest.problem.i18n-enabled:#{null}}") + public void setI18nEnabled(Boolean i18nEnabled) { this.i18nEnabled = i18nEnabled; } + @Value("${io.github.belgif.rest.problem.stack-trace-enabled:#{null}}") public void setStackTraceEnabled(Boolean stackTraceEnabled) { this.stackTraceEnabled = stackTraceEnabled; } diff --git a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java similarity index 65% rename from belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java index 3d947fc9..05570665 100644 --- a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationProperties.java @@ -1,25 +1,28 @@ package io.github.belgif.rest.problem.spring; import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; import io.github.belgif.rest.problem.config.ProblemConfig; /** * Lists all supported application.properties extension configurations for the belgif-rest-problem-spring library. */ -@ConfigurationProperties(prefix = "io.github.belgif.rest.problem.ext") +@Component // not using @ConfigurationProperties to avoid Spring Boot dependency public class ProblemExtConfigurationProperties implements InitializingBean { private Boolean issueTypesEnabled = null; private Boolean inputsArrayEnabled = null; - public void setIssueTypesEnabled(boolean issueTypesEnabled) { + @Value("${io.github.belgif.rest.problem.ext.issue-types-enabled:#{null}}") + public void setIssueTypesEnabled(Boolean issueTypesEnabled) { this.issueTypesEnabled = issueTypesEnabled; } - public void setInputsArrayEnabled(boolean inputsArrayEnabled) { + @Value("${io.github.belgif.rest.problem.ext.inputs-array-enabled:#{null}}") + public void setInputsArrayEnabled(Boolean inputsArrayEnabled) { this.inputsArrayEnabled = inputsArrayEnabled; } diff --git a/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson2Configuration.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson2Configuration.java new file mode 100644 index 00000000..98263e7d --- /dev/null +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson2Configuration.java @@ -0,0 +1,29 @@ +package io.github.belgif.rest.problem.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ProblemJackson2Configuration { + + @Bean + ProblemConfigurationProperties problemConfigurationProperties() { + return new ProblemConfigurationProperties(); + } + + @Bean + public ProblemExtConfigurationProperties problemExtConfigurationProperties() { + return new ProblemExtConfigurationProperties(); + } + + @Bean + public SpringProblemTypeRegistry + springProblemTypeRegistry(ProblemConfigurationProperties problemConfigurationProperties) { + return new SpringProblemTypeRegistry(problemConfigurationProperties); + } + + @Bean + public SpringProblemModule springProblemModule(SpringProblemTypeRegistry springProblemTypeRegistry) { + return new SpringProblemModule(springProblemTypeRegistry); + } +} diff --git a/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson3Configuration.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson3Configuration.java new file mode 100644 index 00000000..23522461 --- /dev/null +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemJackson3Configuration.java @@ -0,0 +1,29 @@ +package io.github.belgif.rest.problem.spring; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ProblemJackson3Configuration { + + @Bean + ProblemConfigurationProperties problemConfigurationProperties() { + return new ProblemConfigurationProperties(); + } + + @Bean + public ProblemExtConfigurationProperties problemExtConfigurationProperties() { + return new ProblemExtConfigurationProperties(); + } + + @Bean + public SpringProblemTypeRegistry + springProblemTypeRegistry(ProblemConfigurationProperties problemConfigurationProperties) { + return new SpringProblemTypeRegistry(problemConfigurationProperties); + } + + @Bean + public SpringProblemModuleJackson3 springProblemModule(SpringProblemTypeRegistry springProblemTypeRegistry) { + return new SpringProblemModuleJackson3(springProblemTypeRegistry); + } +} diff --git a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemMediaType.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemMediaType.java similarity index 100% rename from belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/ProblemMediaType.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/ProblemMediaType.java diff --git a/belgif-rest-problem-spring-boot-3-core/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java similarity index 100% rename from belgif-rest-problem-spring-boot-3-core/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java diff --git a/belgif-rest-problem-spring-boot-4-core/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3.java similarity index 66% rename from belgif-rest-problem-spring-boot-4-core/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3.java index 708a3a9e..d45158d2 100644 --- a/belgif-rest-problem-spring-boot-4-core/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModule.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3.java @@ -10,9 +10,9 @@ * @see SpringProblemTypeRegistry */ @Component -public class SpringProblemModule extends ProblemModuleJackson3 { +public class SpringProblemModuleJackson3 extends ProblemModuleJackson3 { - public SpringProblemModule(SpringProblemTypeRegistry springProblemTypeRegistry) { + public SpringProblemModuleJackson3(SpringProblemTypeRegistry springProblemTypeRegistry) { super(springProblemTypeRegistry); } diff --git a/belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistry.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistry.java similarity index 100% rename from belgif-rest-problem-spring-boot-common/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistry.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistry.java diff --git a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandler.java similarity index 89% rename from belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandler.java index e1248fd2..e7987027 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import java.io.IOException; import java.io.InputStream; @@ -13,11 +13,10 @@ import io.github.belgif.rest.problem.DefaultProblem; import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.spring.ProblemMediaType; -/** - * RestTemplate/RestClient error handler that converts problem responses to Problem exceptions. - */ -public abstract class AbstractProblemResponseErrorHandler extends DefaultResponseErrorHandler { +public abstract class AbstractProblemResponseErrorHandler extends DefaultResponseErrorHandler + implements ProblemResponseErrorHandler { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractProblemResponseErrorHandler.class); diff --git a/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseErrorHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseErrorHandler.java new file mode 100644 index 00000000..f37478fd --- /dev/null +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseErrorHandler.java @@ -0,0 +1,9 @@ +package io.github.belgif.rest.problem.spring.client; + +import org.springframework.web.client.ResponseErrorHandler; + +/** + * RestTemplate/RestClient error handler that converts problem responses to Problem exceptions. + */ +public interface ProblemResponseErrorHandler extends ResponseErrorHandler { +} diff --git a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson2ErrorHandler.java similarity index 60% rename from belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson2ErrorHandler.java index fa92ed58..7b1ef42e 100644 --- a/belgif-rest-problem-spring-boot-3-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson2ErrorHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import org.springframework.stereotype.Component; @@ -10,9 +10,9 @@ * RestTemplate/RestClient error handler that converts problem responses to Problem exceptions. */ @Component -public class ProblemResponseErrorHandler extends AbstractProblemResponseErrorHandler { +public class ProblemResponseJackson2ErrorHandler extends AbstractProblemResponseErrorHandler { - public ProblemResponseErrorHandler(ObjectMapper objectMapper) { + public ProblemResponseJackson2ErrorHandler(ObjectMapper objectMapper) { super(input -> objectMapper.readValue(input, Problem.class)); } diff --git a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson3ErrorHandler.java similarity index 60% rename from belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson3ErrorHandler.java index e92cf6bb..9a72d778 100644 --- a/belgif-rest-problem-spring-boot-4-client/src/main/java/io/github/belgif/rest/problem/spring/ProblemResponseErrorHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/ProblemResponseJackson3ErrorHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import org.springframework.stereotype.Component; @@ -9,9 +9,9 @@ * RestTemplate/RestClient error handler that converts problem responses to Problem exceptions. */ @Component -public class ProblemResponseErrorHandler extends AbstractProblemResponseErrorHandler { +public class ProblemResponseJackson3ErrorHandler extends AbstractProblemResponseErrorHandler { - public ProblemResponseErrorHandler(ObjectMapper objectMapper) { + public ProblemResponseJackson3ErrorHandler(ObjectMapper objectMapper) { super(input -> objectMapper.readValue(input, Problem.class)); } diff --git a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizer.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/WebClientFilter.java similarity index 61% rename from belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizer.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/WebClientFilter.java index 9636e384..9dd9bf81 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemWebClientCustomizer.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/client/WebClientFilter.java @@ -1,18 +1,14 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.WebClient; import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.spring.ProblemMediaType; import reactor.core.publisher.Mono; -/** - * WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. - */ -public abstract class AbstractProblemWebClientCustomizer { - - private static final ExchangeFilterFunction PROBLEM_FILTER = +public class WebClientFilter { + public static final ExchangeFilterFunction PROBLEM_FILTER = ExchangeFilterFunction.ofResponseProcessor(response -> { MediaType mediaType = response.headers().contentType().orElse(null); if (ProblemMediaType.INSTANCE.isCompatibleWith(mediaType) @@ -22,9 +18,4 @@ public abstract class AbstractProblemWebClientCustomizer { return Mono.just(response); } }); - - public void customize(WebClient.Builder webClientBuilder) { - webClientBuilder.filter(PROBLEM_FILTER); - } - } diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandler.java similarity index 96% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandler.java index 78bdc976..8fdde018 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.util.ArrayList; import java.util.LinkedHashSet; @@ -22,7 +22,8 @@ import io.github.belgif.rest.problem.api.InputValidationIssue; import io.github.belgif.rest.problem.api.InputValidationIssues; import io.github.belgif.rest.problem.api.Problem; -import io.github.belgif.rest.problem.spring.internal.InvalidRequestExceptionUtil; +import io.github.belgif.rest.problem.spring.ProblemMediaType; +import io.github.belgif.rest.problem.spring.server.internal.InvalidRequestExceptionUtil; /** * RestController exception handler for InvalidRequestException thrown by Atlassian swagger-request-validator library. diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizer.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractProblemValidationConfigurationCustomizer.java similarity index 87% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizer.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractProblemValidationConfigurationCustomizer.java index 4401ab74..277264df 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractProblemValidationConfigurationCustomizer.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractProblemValidationConfigurationCustomizer.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import jakarta.validation.Configuration; diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandler.java similarity index 87% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandler.java index cb0566f4..dbf13746 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.util.Arrays; @@ -14,11 +14,14 @@ import org.springframework.web.bind.MissingRequestHeaderException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.resource.NoResourceFoundException; import io.github.belgif.rest.problem.BadRequestProblem; +import io.github.belgif.rest.problem.ResourceNotFoundProblem; import io.github.belgif.rest.problem.api.InEnum; import io.github.belgif.rest.problem.api.InputValidationIssues; import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.spring.ProblemMediaType; /** * RestController exception handler for routing-related exceptions. @@ -113,4 +116,14 @@ public ResponseEntity handleHttpMediaTypeNotSupported(HttpMediaTypeNotSupp return ResponseEntity.status(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value()).build(); } + @ExceptionHandler(NoResourceFoundException.class) + public ResponseEntity handleNoResourceFoundException( + NoResourceFoundException exception) { + ResourceNotFoundProblem problem = new ResourceNotFoundProblem(); + problem.setDetail("No resource %s found".formatted( + exception.getResourcePath().startsWith("/") ? exception.getResourcePath() + : "/" + exception.getResourcePath())); + return ProblemMediaType.INSTANCE.toResponse(problem); + } + } diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProvider.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProvider.java similarity index 78% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProvider.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProvider.java index 29ca1c54..251616fa 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProvider.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProvider.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.util.List; import java.util.stream.Collectors; @@ -6,7 +6,7 @@ import jakarta.validation.ParameterNameProvider; -import io.github.belgif.rest.problem.spring.internal.CachedAnnotationParameterNameSupport; +import io.github.belgif.rest.problem.spring.server.internal.CachedAnnotationParameterNameSupport; /** * ParameterNameProvider that retrieves the parameter name from Spring MVC annotations (if present). diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandler.java similarity index 89% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandler.java index 9e7e3046..45bea08b 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.util.Comparator; import java.util.List; @@ -6,8 +6,6 @@ import jakarta.validation.ConstraintViolationException; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.core.annotation.Order; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; @@ -22,15 +20,14 @@ import io.github.belgif.rest.problem.api.InputValidationIssue; import io.github.belgif.rest.problem.api.InputValidationIssues; import io.github.belgif.rest.problem.api.Problem; -import io.github.belgif.rest.problem.spring.internal.BeanValidationExceptionUtil; -import io.github.belgif.rest.problem.spring.internal.DetermineSourceUtil; +import io.github.belgif.rest.problem.spring.ProblemMediaType; +import io.github.belgif.rest.problem.spring.server.internal.BeanValidationExceptionUtil; +import io.github.belgif.rest.problem.spring.server.internal.DetermineSourceUtil; /** * RestController exception handler for exceptions related to bean validation. */ @RestControllerAdvice -@ConditionalOnClass(ConstraintViolationException.class) -@ConditionalOnWebApplication @Order(1) // @Order(1) to take precedence over io.github.belgif.rest.problem.spring.ProblemExceptionHandler public class BeanValidationExceptionsHandler { diff --git a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2Handler.java similarity index 78% rename from belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2Handler.java index 9db7da99..51e6d110 100644 --- a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2Handler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.io.IOException; import java.io.InputStream; @@ -8,12 +8,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.atlassian.oai.validator.springmvc.InvalidRequestException; import com.fasterxml.jackson.core.JsonPointer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; @@ -22,17 +19,15 @@ * RestController exception handler for InvalidRequestException thrown by Atlassian swagger-request-validator library. */ @RestControllerAdvice -@ConditionalOnWebApplication -@ConditionalOnClass(InvalidRequestException.class) @Order(1) // @Order(1) to take precedence over io.github.belgif.rest.problem.spring.ProblemExceptionHandler -public class InvalidRequestExceptionHandler extends AbstractInvalidRequestExceptionHandler { +public class InvalidRequestExceptionJackson2Handler extends AbstractInvalidRequestExceptionHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(InvalidRequestExceptionHandler.class); + private static final Logger LOGGER = LoggerFactory.getLogger(InvalidRequestExceptionJackson2Handler.class); private final ObjectMapper mapper; - public InvalidRequestExceptionHandler(ObjectMapper mapper) { + public InvalidRequestExceptionJackson2Handler(ObjectMapper mapper) { this.mapper = mapper; } diff --git a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3Handler.java similarity index 80% rename from belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3Handler.java index 8e7725af..6fe9f74f 100644 --- a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3Handler.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import java.io.IOException; import java.io.InputStream; @@ -8,13 +8,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.atlassian.oai.validator.springmvc.InvalidRequestException; - import tools.jackson.core.JsonPointer; import tools.jackson.databind.JsonNode; import tools.jackson.databind.ObjectMapper; @@ -23,17 +19,15 @@ * RestController exception handler for InvalidRequestException thrown by Atlassian swagger-request-validator library. */ @RestControllerAdvice -@ConditionalOnWebApplication -@ConditionalOnClass(InvalidRequestException.class) @Order(1) // @Order(1) to take precedence over io.github.belgif.rest.problem.spring.ProblemExceptionHandler -public class InvalidRequestExceptionHandler extends AbstractInvalidRequestExceptionHandler { +public class InvalidRequestExceptionJackson3Handler extends AbstractInvalidRequestExceptionHandler { - private static final Logger LOGGER = LoggerFactory.getLogger(InvalidRequestExceptionHandler.class); + private static final Logger LOGGER = LoggerFactory.getLogger(InvalidRequestExceptionJackson3Handler.class); private final ObjectMapper mapper; - public InvalidRequestExceptionHandler(ObjectMapper mapper) { + public InvalidRequestExceptionJackson3Handler(ObjectMapper mapper) { this.mapper = mapper; } diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandler.java similarity index 87% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandler.java index 4ebeb48a..3b3086b8 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandler.java @@ -1,14 +1,14 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import io.github.belgif.rest.problem.InternalServerErrorProblem; import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.spring.ProblemMediaType; /** * Exception handler for RestControllers. @@ -19,7 +19,6 @@ *

*/ @RestControllerAdvice -@ConditionalOnWebApplication public class ProblemExceptionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ProblemExceptionHandler.class); diff --git a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson2Handler.java similarity index 80% rename from belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson2Handler.java index 0019577f..436ff91d 100644 --- a/belgif-rest-problem-spring-boot-3-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson2Handler.java @@ -1,6 +1,5 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -15,13 +14,12 @@ * RestController exception handler for routing-related exceptions. */ @RestControllerAdvice -@ConditionalOnWebApplication @Order(1) // @Order(1) to take precedence over org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver // and io.github.belgif.rest.problem.spring.ProblemExceptionHandler -public class RoutingExceptionsHandler extends AbstractRoutingExceptionsHandler { +public class RoutingExceptionsJackson2Handler extends AbstractRoutingExceptionsHandler { - public RoutingExceptionsHandler() { + public RoutingExceptionsJackson2Handler() { super(JacksonException.class); } diff --git a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson3Handler.java similarity index 80% rename from belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson3Handler.java index 4c3a4956..88853076 100644 --- a/belgif-rest-problem-spring-boot-4-server/src/main/java/io/github/belgif/rest/problem/spring/RoutingExceptionsHandler.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/RoutingExceptionsJackson3Handler.java @@ -1,6 +1,5 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -14,13 +13,12 @@ * RestController exception handler for routing-related exceptions. */ @RestControllerAdvice -@ConditionalOnWebApplication @Order(1) // @Order(1) to take precedence over org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver // and io.github.belgif.rest.problem.spring.ProblemExceptionHandler -public class RoutingExceptionsHandler extends AbstractRoutingExceptionsHandler { +public class RoutingExceptionsJackson3Handler extends AbstractRoutingExceptionsHandler { - public RoutingExceptionsHandler() { + public RoutingExceptionsJackson3Handler() { super(JacksonException.class); } diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolver.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolver.java similarity index 88% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolver.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolver.java index 0f45a044..b3f8e3b4 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolver.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolver.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.i18n; +package io.github.belgif.rest.problem.spring.server.i18n; import java.util.Locale; diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtil.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtil.java similarity index 97% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtil.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtil.java index 38d82eef..a76fee7c 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtil.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtil.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import java.util.Iterator; import java.util.LinkedList; diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupport.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupport.java similarity index 97% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupport.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupport.java index 68ac4b1b..fd26d46d 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupport.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupport.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtil.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtil.java similarity index 98% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtil.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtil.java index 3c7c5e65..069a25d8 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtil.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtil.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import java.lang.annotation.Annotation; import java.lang.reflect.Method; diff --git a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtil.java b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtil.java similarity index 97% rename from belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtil.java rename to belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtil.java index 0461bcb8..e7142299 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/main/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtil.java +++ b/belgif-rest-problem-spring/src/main/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtil.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/belgif-rest-problem-spring/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver b/belgif-rest-problem-spring/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver new file mode 100644 index 00000000..7b3287f1 --- /dev/null +++ b/belgif-rest-problem-spring/src/main/resources/META-INF/services/io.github.belgif.rest.problem.i18n.LocaleResolver @@ -0,0 +1 @@ +io.github.belgif.rest.problem.spring.server.i18n.LocaleContextHolderLocaleResolver \ No newline at end of file diff --git a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemConfigurationPropertiesTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemConfigurationPropertiesTest.java similarity index 100% rename from belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemConfigurationPropertiesTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemConfigurationPropertiesTest.java diff --git a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationPropertiesTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationPropertiesTest.java similarity index 100% rename from belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationPropertiesTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemExtConfigurationPropertiesTest.java diff --git a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemMediaTypeTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemMediaTypeTest.java similarity index 100% rename from belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/ProblemMediaTypeTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/ProblemMediaTypeTest.java diff --git a/belgif-rest-problem-spring-boot-4-core/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3Test.java similarity index 86% rename from belgif-rest-problem-spring-boot-4-core/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3Test.java index 82430cee..914c6111 100644 --- a/belgif-rest-problem-spring-boot-4-core/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleJackson3Test.java @@ -11,7 +11,7 @@ import tools.jackson.databind.jsontype.NamedType; @ExtendWith(MockitoExtension.class) -class SpringProblemModuleTest { +class SpringProblemModuleJackson3Test { @Mock private SetupContext setupContext; @@ -20,7 +20,7 @@ class SpringProblemModuleTest { void module() { SpringProblemTypeRegistry problemTypeRegistry = new SpringProblemTypeRegistry(new ProblemConfigurationProperties()); - SpringProblemModule module = new SpringProblemModule(problemTypeRegistry); + SpringProblemModuleJackson3 module = new SpringProblemModuleJackson3(problemTypeRegistry); module.setupModule(setupContext); verify(setupContext).registerSubtypes(problemTypeRegistry.getProblemTypes().entrySet().stream() .map(entry -> new NamedType(entry.getValue(), entry.getKey())) diff --git a/belgif-rest-problem-spring-boot-3-core/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java similarity index 100% rename from belgif-rest-problem-spring-boot-3-core/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemModuleTest.java diff --git a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java similarity index 84% rename from belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java index 1418a167..c2fddc18 100644 --- a/belgif-rest-problem-spring-boot-common/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/SpringProblemTypeRegistryTest.java @@ -7,22 +7,29 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; +import org.springframework.context.annotation.Bean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import com.fasterxml.jackson.databind.ObjectMapper; + import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.api.ClientProblem; import io.github.belgif.rest.problem.api.ProblemType; import io.github.belgif.rest.problem.registry.ProblemTypeRegistry; @ExtendWith(SpringExtension.class) -@ContextConfiguration(classes = { ProblemAutoConfiguration.class, JacksonAutoConfiguration.class }) +@ContextConfiguration(classes = { ProblemJackson2Configuration.class }) class SpringProblemTypeRegistryTest { @Autowired private ProblemTypeRegistry problemTypeRegistry; + @Bean + public ObjectMapper objectMapper() { + return new ObjectMapper(); + } + @Test void getProblemTypes() { assertThat(problemTypeRegistry.getProblemTypes()).isNotEmpty(); diff --git a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandlerTest.java similarity index 95% rename from belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandlerTest.java index 8434df6f..538d2a31 100644 --- a/belgif-rest-problem-spring-boot-common-client/src/test/java/io/github/belgif/rest/problem/spring/AbstractProblemResponseErrorHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/client/AbstractProblemResponseErrorHandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.client; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -22,7 +22,8 @@ import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.DefaultProblem; import io.github.belgif.rest.problem.api.Problem; -import io.github.belgif.rest.problem.spring.AbstractProblemResponseErrorHandler.ProblemReader; +import io.github.belgif.rest.problem.spring.ProblemMediaType; +import io.github.belgif.rest.problem.spring.client.AbstractProblemResponseErrorHandler.ProblemReader; @ExtendWith(MockitoExtension.class) class AbstractProblemResponseErrorHandlerTest { diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandlerTest.java similarity index 96% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandlerTest.java index b7a77a60..e2aff911 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractInvalidRequestExceptionHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractInvalidRequestExceptionHandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; @@ -30,12 +30,14 @@ class AbstractInvalidRequestExceptionHandlerTest { - AbstractInvalidRequestExceptionHandler handler = new AbstractInvalidRequestExceptionHandler<>() { - @Override - protected String getBodyValue(String name, AtomicReference requestBody, HttpServletRequest request) { - return "myDummyValue"; - } - }; + AbstractInvalidRequestExceptionHandler handler = + new AbstractInvalidRequestExceptionHandler<>() { + @Override + protected String getBodyValue(String name, AtomicReference requestBody, + HttpServletRequest request) { + return "myDummyValue"; + } + }; @Test void inBodyTest() { diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandlerTest.java similarity index 89% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandlerTest.java index e763a3a4..e3f39da2 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AbstractRoutingExceptionsHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AbstractRoutingExceptionsHandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static io.github.belgif.rest.problem.api.InputValidationIssues.*; import static org.assertj.core.api.Assertions.*; @@ -21,6 +21,7 @@ import org.springframework.web.bind.MissingRequestHeaderException; import org.springframework.web.bind.MissingServletRequestParameterException; import org.springframework.web.client.RestTemplate; +import org.springframework.web.servlet.resource.NoResourceFoundException; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParseException; @@ -29,9 +30,11 @@ import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.InternalServerErrorProblem; +import io.github.belgif.rest.problem.ResourceNotFoundProblem; import io.github.belgif.rest.problem.api.InEnum; import io.github.belgif.rest.problem.api.Problem; import io.github.belgif.rest.problem.internal.Jackson2Util; +import io.github.belgif.rest.problem.spring.ProblemMediaType; class AbstractRoutingExceptionsHandlerTest { @@ -191,4 +194,24 @@ void handleHttpMediaTypeNotSupported() { assertThat(response.getStatusCode().value()).isEqualTo(415); } + @Test + void handleNoResourceFoundException() { + ResponseEntity entity = handler.handleNoResourceFoundException( + new NoResourceFoundException(HttpMethod.GET, "/test")); + assertThat(entity.getStatusCode().value()).isEqualTo(404); + assertThat(entity.getHeaders().getContentType()).isEqualTo(ProblemMediaType.INSTANCE); + ResourceNotFoundProblem problem = (ResourceNotFoundProblem) entity.getBody(); + assertThat(problem.getDetail()).isEqualTo("No resource /test found"); + } + + @Test + void handleNoResourceFoundExceptionAddsLeadingSlash() { + ResponseEntity entity = handler.handleNoResourceFoundException( + new NoResourceFoundException(HttpMethod.GET, "test")); + assertThat(entity.getStatusCode().value()).isEqualTo(404); + assertThat(entity.getHeaders().getContentType()).isEqualTo(ProblemMediaType.INSTANCE); + ResourceNotFoundProblem problem = (ResourceNotFoundProblem) entity.getBody(); + assertThat(problem.getDetail()).isEqualTo("No resource /test found"); + } + } diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProviderTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProviderTest.java similarity index 88% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProviderTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProviderTest.java index 5781c398..573c52d8 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/AnnotationParameterNameProviderTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/AnnotationParameterNameProviderTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandlerTest.java similarity index 98% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandlerTest.java index 4e818c31..20017d1c 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/BeanValidationExceptionsHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/BeanValidationExceptionsHandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; @@ -25,6 +25,7 @@ import io.github.belgif.rest.problem.BadRequestProblem; import io.github.belgif.rest.problem.api.InEnum; import io.github.belgif.rest.problem.api.Problem; +import io.github.belgif.rest.problem.spring.ProblemMediaType; class BeanValidationExceptionsHandlerTest { diff --git a/belgif-rest-problem-spring-boot-3-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2HandlerTest.java similarity index 89% rename from belgif-rest-problem-spring-boot-3-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2HandlerTest.java index c49ef943..834fc17a 100644 --- a/belgif-rest-problem-spring-boot-3-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson2HandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; @@ -15,11 +15,11 @@ import io.github.belgif.rest.problem.api.InEnum; import io.github.belgif.rest.problem.api.Problem; -class InvalidRequestExceptionHandlerTest { +class InvalidRequestExceptionJackson2HandlerTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - InvalidRequestExceptionHandler handler = new InvalidRequestExceptionHandler(OBJECT_MAPPER); + InvalidRequestExceptionJackson2Handler handler = new InvalidRequestExceptionJackson2Handler(OBJECT_MAPPER); @Test void inBodyTest() { diff --git a/belgif-rest-problem-spring-boot-4-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3HandlerTest.java similarity index 89% rename from belgif-rest-problem-spring-boot-4-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3HandlerTest.java index 103831e2..5c5bb642 100644 --- a/belgif-rest-problem-spring-boot-4-server/src/test/java/io/github/belgif/rest/problem/spring/InvalidRequestExceptionHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/InvalidRequestExceptionJackson3HandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; @@ -15,11 +15,11 @@ import io.github.belgif.rest.problem.api.Problem; import tools.jackson.databind.ObjectMapper; -class InvalidRequestExceptionHandlerTest { +class InvalidRequestExceptionJackson3HandlerTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - InvalidRequestExceptionHandler handler = new InvalidRequestExceptionHandler(OBJECT_MAPPER); + InvalidRequestExceptionJackson3Handler handler = new InvalidRequestExceptionJackson3Handler(OBJECT_MAPPER); @Test void inBodyTest() { diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandlerTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandlerTest.java similarity index 96% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandlerTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandlerTest.java index 02019f67..f9207acc 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/ProblemExceptionHandlerTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/ProblemExceptionHandlerTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring; +package io.github.belgif.rest.problem.spring.server; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolverTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolverTest.java similarity index 91% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolverTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolverTest.java index 2d5c48ea..6263636f 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/i18n/LocaleContextHolderLocaleResolverTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/i18n/LocaleContextHolderLocaleResolverTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.i18n; +package io.github.belgif.rest.problem.spring.server.i18n; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtilTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtilTest.java similarity index 99% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtilTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtilTest.java index 8bdf5eeb..7ec42ec8 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/BeanValidationExceptionUtilTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/BeanValidationExceptionUtilTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupportTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupportTest.java similarity index 97% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupportTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupportTest.java index 900a2d17..cabb7625 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/CachedAnnotationParameterNameSupportTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/CachedAnnotationParameterNameSupportTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtilTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtilTest.java similarity index 98% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtilTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtilTest.java index 47e8a8d6..c0f5acd8 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/DetermineSourceUtilTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/DetermineSourceUtilTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; diff --git a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtilTest.java b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtilTest.java similarity index 99% rename from belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtilTest.java rename to belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtilTest.java index 10f6197f..31c49cce 100644 --- a/belgif-rest-problem-spring-boot-common-server/src/test/java/io/github/belgif/rest/problem/spring/internal/InvalidRequestExceptionUtilTest.java +++ b/belgif-rest-problem-spring/src/test/java/io/github/belgif/rest/problem/spring/server/internal/InvalidRequestExceptionUtilTest.java @@ -1,4 +1,4 @@ -package io.github.belgif.rest.problem.spring.internal; +package io.github.belgif.rest.problem.spring.server.internal; import static org.assertj.core.api.Assertions.*; diff --git a/belgif-rest-problem-spring-boot-4-server/src/test/resources/logback-test.xml b/belgif-rest-problem-spring/src/test/resources/logback-test.xml similarity index 100% rename from belgif-rest-problem-spring-boot-4-server/src/test/resources/logback-test.xml rename to belgif-rest-problem-spring/src/test/resources/logback-test.xml diff --git a/jacoco-aggregator/pom.xml b/jacoco-aggregator/pom.xml index 82b30420..8b5145e3 100644 --- a/jacoco-aggregator/pom.xml +++ b/jacoco-aggregator/pom.xml @@ -61,17 +61,7 @@
io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-client - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring ${project.version} @@ -81,37 +71,27 @@ io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-core - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-client + belgif-rest-problem-spring-boot-3-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-3-server + belgif-rest-problem-spring-boot-3-server-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4 + belgif-rest-problem-spring-boot-4-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-core + belgif-rest-problem-spring-boot-4-client-starter ${project.version} io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-client - ${project.version} - - - io.github.belgif.rest.problem - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-4-server-starter ${project.version} @@ -171,6 +151,16 @@ belgif-rest-problem-spring-boot-3-it ${project.version} + + io.github.belgif.rest.problem + belgif-rest-problem-spring-boot-4-it + ${project.version} + + + io.github.belgif.rest.problem + belgif-rest-problem-spring-it + ${project.version} + io.github.belgif.rest.problem belgif-rest-problem-quarkus-it diff --git a/pom.xml b/pom.xml index 682e93e6..b2646c99 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,8 @@ UTF-8 2.12.7 - 3.1.0 + + 3.0.4 3.5.11 4.0.3 3.32.2 @@ -233,11 +234,10 @@ belgif-rest-problem-it, jacoco-aggregator, - + belgif-rest-problem-spring-boot-3, - belgif-rest-problem-spring-boot-3-core, - belgif-rest-problem-spring-boot-3-client, - belgif-rest-problem-spring-boot-3-server + belgif-rest-problem-spring-boot-3-client-starter, + belgif-rest-problem-spring-boot-3-server-starter all,-missing true @@ -379,17 +379,13 @@ belgif-rest-problem-jakarta-ee-core belgif-rest-problem-jakarta-ee-client belgif-rest-problem-jakarta-ee-server - belgif-rest-problem-spring-boot-common - belgif-rest-problem-spring-boot-common-client - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring belgif-rest-problem-spring-boot-3 - belgif-rest-problem-spring-boot-3-core - belgif-rest-problem-spring-boot-3-client - belgif-rest-problem-spring-boot-3-server - belgif-rest-problem-spring-boot-4 - belgif-rest-problem-spring-boot-4-core - belgif-rest-problem-spring-boot-4-client - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-3-client-starter + belgif-rest-problem-spring-boot-3-server-starter + belgif-rest-problem-spring-boot-4-starter + belgif-rest-problem-spring-boot-4-client-starter + belgif-rest-problem-spring-boot-4-server-starter belgif-rest-problem-quarkus belgif-rest-problem-quarkus-core belgif-rest-problem-quarkus-core-deployment @@ -471,6 +467,7 @@ belgif-rest-problem-jakarta-ee-it belgif-rest-problem-java-ee-it belgif-rest-problem-quarkus-it + belgif-rest-problem-spring-it belgif-rest-problem-spring-boot-3-it belgif-rest-problem-spring-boot-4-it @@ -503,17 +500,13 @@ belgif-rest-problem-jakarta-ee-core belgif-rest-problem-jakarta-ee-client belgif-rest-problem-jakarta-ee-server - belgif-rest-problem-spring-boot-common - belgif-rest-problem-spring-boot-common-client - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring belgif-rest-problem-spring-boot-3 - belgif-rest-problem-spring-boot-3-core - belgif-rest-problem-spring-boot-3-client - belgif-rest-problem-spring-boot-3-server - belgif-rest-problem-spring-boot-4 - belgif-rest-problem-spring-boot-4-core - belgif-rest-problem-spring-boot-4-client - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-3-client-starter + belgif-rest-problem-spring-boot-3-server-starter + belgif-rest-problem-spring-boot-4-starter + belgif-rest-problem-spring-boot-4-client-starter + belgif-rest-problem-spring-boot-4-server-starter belgif-rest-problem-quarkus belgif-rest-problem-quarkus-core belgif-rest-problem-quarkus-core-deployment @@ -562,17 +555,13 @@ spring-only belgif-rest-problem - belgif-rest-problem-spring-boot-common - belgif-rest-problem-spring-boot-common-client - belgif-rest-problem-spring-boot-common-server + belgif-rest-problem-spring belgif-rest-problem-spring-boot-3 - belgif-rest-problem-spring-boot-3-core - belgif-rest-problem-spring-boot-3-client - belgif-rest-problem-spring-boot-3-server - belgif-rest-problem-spring-boot-4 - belgif-rest-problem-spring-boot-4-core - belgif-rest-problem-spring-boot-4-client - belgif-rest-problem-spring-boot-4-server + belgif-rest-problem-spring-boot-3-client-starter + belgif-rest-problem-spring-boot-3-server-starter + belgif-rest-problem-spring-boot-4-starter + belgif-rest-problem-spring-boot-4-client-starter + belgif-rest-problem-spring-boot-4-server-starter belgif-rest-problem-it/belgif-rest-problem-apt belgif-rest-problem-it/belgif-rest-problem-codegen-it @@ -581,6 +570,7 @@ belgif-rest-problem-it/belgif-rest-problem-jackson2-latest-it belgif-rest-problem-it/belgif-rest-problem-jackson2-minimal-it belgif-rest-problem-it/belgif-rest-problem-jackson3-it + belgif-rest-problem-it/belgif-rest-problem-spring-it belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it belgif-rest-problem-it/belgif-rest-problem-spring-boot-4-it belgif-rest-problem-bom diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc index 56ecbfcd..d2b94312 100644 --- a/src/main/asciidoc/index.adoc +++ b/src/main/asciidoc/index.adoc @@ -237,7 +237,7 @@ Otherwise, you will see parameter names like `arg0`. InvalidRequestExceptions thrown by the https://bitbucket.org/atlassian/swagger-request-validator[Atlassian swagger-request-validator] are automatically converted to a proper RFC 9457 `application/problem+json` response. -For Spring Boot 3, use https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-spring-webmvc[swagger-request-validator-spring-webmvc]. +When using Spring, use https://bitbucket.org/atlassian/swagger-request-validator/src/master/swagger-request-validator-spring-webmvc[swagger-request-validator-spring-webmvc]. ==== RestTemplate @@ -257,6 +257,11 @@ Problem support is automatically enabled when constructing your RestClient throu When manually constructing a RestClient instance, you'll need to apply the link:apidocs/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.html[ProblemRestClientCustomizer] yourself. +==== Without Spring Boot + +If your application uses Spring without Spring Boot, use the link:apidocs/io/github/belgif/rest/problem/spring/ProblemRestClientCustomizer.html[`@EnableProblemModule`] annotation to activate problem support. Your application needs to provide a configured `ObjectMapper` (Jackson 2) or `JsonMapper` (Jackson3) bean. +REST clients have to be configured during their creation using beans provided by the problem module. See the `WebConfig` class in the integration test `belgif-rest-problem-spring-it` for an example. + [[getting-started-jakarta-ee]] === Jakarta EE @@ -880,10 +885,10 @@ public void setClient(Client client) { * *Jakarta EE 9+*: the main belgif-rest-problem-java-ee artifact targets Java EE (javax package namespace). A secondary artifact that targets Jakarta EE 9+ (jakarta package namespace) is available with `jakarta`. -[[belgif-rest-problem-spring-boot-3]] -=== belgif-rest-problem-spring-boot-3 +[[belgif-rest-problem-spring]] +=== belgif-rest-problem-spring -This module provides auto-configuration for components that handle Spring Boot 3 integration with the belgif-rest-problem library: +This module provides base components for Spring integration with the belgif-rest-problem library, without Spring Boot dependencies: * *SpringProblemTypeRegistry:* ProblemTypeRegistry implementation that uses classpath scanning to detect @ProblemType annotations. By default, only package `io.github.belgif.rest.problem` is scanned for @ProblemType annotations. @@ -898,20 +903,27 @@ io.github.belgif.rest.problem.scan-additional-problem-packages=com.acme.custom * *ProblemExceptionHandler:* an exception handler for RestControllers that handles the response serialization for Problem exceptions, and converts all other uncaught exceptions to an InternalServerErrorProblem. * *BeanValidationExceptionsHandler:* an exception handler for RestControllers that converts bean validation related exceptions to HTTP 400 BadRequestProblem. * *InvalidRequestExceptionHandler:* an exception handler for the link:https://bitbucket.org/atlassian/swagger-request-validator/src/master/[Atlassian swagger-request-validator] that converts InvalidRequestException to the correct Problem type. -* *RoutingExceptionsHandler:* an exception handler for RestControllers that converts routing related validation exceptions to HTTP 400 BadRequestProblem. +* *RoutingExceptionsHandler:* an exception handler for RestControllers that converts request handling exceptions to HTTP 4XX problems. +* *ProblemResponseErrorHandler:* a RestTemplate and RestClient error handler that converts problem responses to Problem exceptions. +* *AnnotationParameterNameProvider:* a bean validation ParameterNameProvider that retrieves parameter names from Spring MVC annotations + +In general, these components make it possible to use standard java exception handling (throw and try-catch) for dealing with problems in Spring Boot REST APIs. + +[[belgif-rest-problem-spring-boot-3]] +=== belgif-rest-problem-spring-boot-3 + +This module provides auto-configuration for the `belgif-rest-problem-spring` components that handle Spring Boot 3 integration with the belgif-rest-problem library: + * *ProblemWebClientCustomizer:* a WebClientCustomizer that registers a filter that converts problem responses to Problem exceptions. This handles integration with the https://docs.spring.io/spring-framework/reference/web/webflux-webclient.html[Reactive WebClient]. -* *ProblemResponseErrorHandler:* a RestTemplate and RestClient error handler that converts problem responses to Problem exceptions. * *ProblemRestTemplateCustomizer:* a RestTemplateCustomizer that registers the ProblemResponseErrorHandler. -* *NoResourceFoundExceptionHandler:* an exception handler for RestControllers that converts NoResourceFoundException to HTTP 404 ResourceNotFoundProblem. * *ProblemRestClientCustomizer:* a RestClientCustomizer that registers the ProblemResponseErrorHandler. -* *AnnotationParameterNameProvider:* a bean validation ParameterNameProvider that retrieves parameter names from Spring MVC annotations * *ProblemValidationConfigurationCustomizer:* a ValidationConfigurationCustomizer that registers the AnnotationParameterNameProvider In general, these components make it possible to use standard java exception handling (throw and try-catch) for dealing with problems in Spring Boot REST APIs. -[[belgif-rest-problem-spring-boot-4]] -=== belgif-rest-problem-spring-boot-4 +[[belgif-rest-problem-spring-boot-4-starter]] +=== belgif-rest-problem-spring-boot-4-starter This module provides auto-configuration for components that handle Spring Boot 4 integration with the belgif-rest-problem library. In general, this is very similar to the Spring Boot 3 module. diff --git a/src/main/asciidoc/release-notes.adoc b/src/main/asciidoc/release-notes.adoc index c2ef2ca0..c1afdc00 100644 --- a/src/main/asciidoc/release-notes.adoc +++ b/src/main/asciidoc/release-notes.adoc @@ -20,21 +20,41 @@ *belgif-rest-problem-spring-boot-3:* +[WARNING] +==== +*Breaking change:* Some classes were moved to `client`- and `server`-specific packages +==== + Provide separate modules in case you specifically only want to use problems either client-side or server-side. -* belgif-rest-problem-spring-boot-3-client -* belgif-rest-problem-spring-boot-3-server +* belgif-rest-problem-spring-boot-3-client-starter +* belgif-rest-problem-spring-boot-3-server-starter Note that you can keep using `belgif-rest-problem-spring-boot-3` as before if you want both client-side and server-side integration. -*belgif-rest-problem-spring-boot-4:* +*belgif-rest-problem-spring-boot-4-starter:* + +[WARNING] +==== +*Breaking changes:* + +* Users of `belgif-rest-problem-spring-boot-4` from version should now depend on the `belgif-rest-problem-spring-boot-4-starter` module. +* Some classes were moved to `client`- and `server`-specific packages +==== Provide separate modules in case you specifically only want to use problems either client-side or server-side. -* belgif-rest-problem-spring-boot-4-client -* belgif-rest-problem-spring-boot-4-server +* belgif-rest-problem-spring-boot-4-client-starter +* belgif-rest-problem-spring-boot-4-server-starter + +Note that you can use `belgif-rest-problem-spring-boot-4-starter` when you want both client-side and server-side integration. + +*belgif-rest-problem-spring:* + +Depend on this module to integrate with Spring without depending on Spring Boot. +When using one of the spring boot modules, it is added as transitive dependency. -Note that you can keep using `belgif-rest-problem-spring-boot-4` as before when you want both client-side and server-side integration. +It provides support for both Jackson 2 and 3. *belgif-rest-problem-java-ee:*