diff --git a/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractJacksonSerializationTest.java b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractJacksonSerializationTest.java
index f2dc1015..7094f029 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractJacksonSerializationTest.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractJacksonSerializationTest.java
@@ -195,6 +195,24 @@ void legacyInvalidParamProblem() throws IOException {
assertThat(writeProblem(badRequestProblem)).isEqualToIgnoringWhitespace(json);
}
+ @Test
+ void titleAndStatusOverride() throws IOException {
+ String json = "{\n"
+ + " \"type\": \"urn:problem-type:belgif:badRequest\",\n"
+ + " \"href\": \"https://www.test.be\",\n"
+ + " \"title\": \"TEST\",\n"
+ + " \"status\": 401,\n"
+ + " \"detail\": \"Test\"\n"
+ + "}";
+ Problem problem = readProblem(json);
+ assertThat(problem).isInstanceOf(BadRequestProblem.class);
+ BadRequestProblem badRequestProblem = (BadRequestProblem) problem;
+ assertThat(badRequestProblem.getType()).isEqualTo(BadRequestProblem.TYPE_URI);
+ assertThat(badRequestProblem.getHref()).isEqualTo(URI.create("https://www.test.be"));
+ assertThat(badRequestProblem.getStatus()).isEqualTo(BadRequestProblem.STATUS);
+ assertThat(badRequestProblem.getTitle()).isEqualTo(BadRequestProblem.TITLE);
+ }
+
@Test
void unknownProblemWithMessage() throws IOException {
String json = "{\n"
diff --git a/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractRestProblemIT.java b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractRestProblemIT.java
index ff2d22a3..fc75ae53 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractRestProblemIT.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/AbstractRestProblemIT.java
@@ -133,6 +133,18 @@ public void jacksonMismatchedInputFromBackend(String client) {
.body("type", equalTo("urn:problem-type:belgif:internalServerError"));
}
+ @ParameterizedTest
+ @MethodSource("getClients")
+ public void inconsistentProblemStatusFromBackend(String client) {
+ getSpec().when().queryParam("client", client)
+ .get("/inconsistentProblemStatusFromBackend").then().assertThat()
+ .statusCode(400)
+ .body("type", equalTo("urn:problem-type:belgif:badRequest"))
+ .body("detail", equalTo("Bad Request with inconsistent problem status code"
+ + " (caught successfully by frontend)"))
+ .body("status", equalTo(400));
+ }
+
@Test
public void notFound() {
getSpec().when().get("/not/found").then().assertThat()
@@ -562,4 +574,13 @@ public void invalidJsonType() {
.body("issues[0].value", equalTo("twenty-two"));
}
+ @ParameterizedTest
+ @MethodSource("getClients")
+ public void healthDown(String client) {
+ getSpec().when().queryParam("client", client)
+ .get("/healthDown").then().assertThat()
+ .statusCode(503)
+ .body("status", equalTo("DOWN"));
+ }
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/ProblemPayloads.java b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/ProblemPayloads.java
new file mode 100644
index 00000000..8b32f718
--- /dev/null
+++ b/belgif-rest-problem-it/belgif-rest-problem-it-common/src/main/java/io/github/belgif/rest/problem/it/ProblemPayloads.java
@@ -0,0 +1,19 @@
+package io.github.belgif.rest.problem.it;
+
+/**
+ * Problem payload constants.
+ */
+public class ProblemPayloads {
+
+ public static final String INCONSISTENT_STATUS_CODE = "{\n"
+ + " \"type\": \"urn:problem-type:belgif:badRequest\",\n"
+ + " \"href\": \"https://www.belgif.be/specification/rest/api-guide/problems/badRequest.html\",\n"
+ + " \"title\": \"Bad Request\",\n"
+ + " \"status\": 401,\n" // <- 401 instead of 400
+ + " \"detail\": \"Bad Request with inconsistent problem status code\"\n"
+ + "}";
+
+ private ProblemPayloads() {
+ }
+
+}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/pom.xml
index 95b603f4..5437975d 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/pom.xml
+++ b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/pom.xml
@@ -62,6 +62,12 @@
provided
3.0.1.Final
+
+ org.slf4j
+ slf4j-api
+ 2.0.19
+ provided
+
org.junit.jupiter
junit-jupiter
diff --git a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
index 2694124f..d158a912 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
@@ -31,4 +31,12 @@ public interface Backend {
@Path("/jacksonMismatchedInput")
Response jacksonMismatchedInput();
+ @GET
+ @Path("/inconsistentProblemStatus")
+ Response inconsistentProblemStatus();
+
+ @GET
+ @Path("/healthDown")
+ Response healthDown();
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
index 8da77b71..4819a9ec 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
@@ -1,6 +1,8 @@
package io.github.belgif.rest.problem;
import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
import jakarta.enterprise.context.RequestScoped;
import jakarta.ws.rs.core.MediaType;
@@ -9,6 +11,7 @@
import com.acme.custom.CustomProblem;
import io.github.belgif.rest.problem.api.Problem;
+import io.github.belgif.rest.problem.it.ProblemPayloads;
import io.github.belgif.rest.problem.it.model.JacksonModel;
@RequestScoped
@@ -56,4 +59,22 @@ public Response jacksonMismatchedInput() {
return Response.ok(model, MediaType.APPLICATION_JSON_TYPE).build();
}
+ @Override
+ public Response inconsistentProblemStatus() {
+ return Response.status(402) // -> HTTP status code 402 instead of 400
+ .type("application/problem+json")
+ .entity(ProblemPayloads.INCONSISTENT_STATUS_CODE) // -> problem status code 401 instead of 400
+ .build();
+ }
+
+ @Override
+ public Response healthDown() {
+ Map response = new HashMap<>();
+ response.put("status", "DOWN");
+ return Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .entity(response)
+ .build();
+ }
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
index 1b0cba04..1341ece7 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
@@ -73,6 +73,10 @@ public interface Frontend {
@Path("/jacksonMismatchedInputFromBackend")
Response jacksonMismatchedInputFromBackend(@QueryParam("client") Client client);
+ @GET
+ @Path("/inconsistentProblemStatusFromBackend")
+ Response inconsistentProblemStatusFromBackend(@QueryParam("client") Client client);
+
@GET
@Path("/beanValidation/queryParameter")
Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive Integer p,
@@ -118,4 +122,8 @@ Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive In
@Path("/jackson/mismatchedInputException")
Response jacksonMismatchedInputException(@Valid JacksonModel body);
+ @GET
+ @Path("/healthDown")
+ Response healthDown(@QueryParam("client") Client client);
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
index 22fdc3ee..a316b5f0 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-jakarta-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
@@ -14,10 +14,13 @@
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.jboss.resteasy.client.jaxrs.internal.ResteasyClientBuilderImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.acme.custom.CustomProblem;
@@ -37,6 +40,8 @@
@Path("/frontend")
public class FrontendImpl implements Frontend {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FrontendImpl.class);
+
private static final URI BASE_URI =
URI.create("http://" + System.getProperty("jboss.bind.address") + ":8080/rest-problem");
@@ -266,6 +271,67 @@ public Response jacksonMismatchedInputFromBackend(Client client) {
throw new IllegalStateException("Unsupported client " + client);
}
+ @Override
+ public Response inconsistentProblemStatusFromBackend(Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.inconsistentProblemStatus();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ jaxRsClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().async().get()
+ .get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (client == Client.RESTEASY) {
+ return resteasyClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().get();
+ } else if (client == Client.RESTEASY_PROXY) {
+ return resteasyProxyClient.inconsistentProblemStatus();
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ } catch (BadRequestProblem e) {
+ e.setDetail(e.getDetail() + " (caught successfully by frontend)");
+ throw e;
+ }
+ }
+
+ @Override
+ public Response healthDown(@QueryParam("client") Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.healthDown();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(BASE_URI).path("backend/healthDown").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ return jaxRsClient.target(BASE_URI).path("backend/healthDown").request().async()
+ .get().get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (client == Client.RESTEASY) {
+ return resteasyClient.target(BASE_URI).path("backend/healthDown").request().get();
+ } else if (client == Client.RESTEASY_PROXY) {
+ return resteasyProxyClient.healthDown();
+ }
+ } catch (WebApplicationException e) {
+ if (e.getResponse().getStatus() == Response.Status.SERVICE_UNAVAILABLE.getStatusCode()) {
+ LOGGER.info("Caught WebApplicationException with status 503");
+ return e.getResponse();
+ }
+ throw e;
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ }
+
@Override
public Response beanValidationQueryParameter(Integer p, String o) {
return Response.ok("param: " + p + ", other: " + o).build();
diff --git a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/pom.xml b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/pom.xml
index 0482f1e9..545700dc 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/pom.xml
+++ b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/pom.xml
@@ -162,6 +162,12 @@
8.0.0
provided
+
+ org.slf4j
+ slf4j-api
+ 2.0.19
+ provided
+
org.jboss.resteasy
resteasy-client-microprofile
diff --git a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
index d18a564d..dc796584 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Backend.java
@@ -31,4 +31,12 @@ public interface Backend {
@Path("/jacksonMismatchedInput")
Response jacksonMismatchedInput();
+ @GET
+ @Path("/inconsistentProblemStatus")
+ Response inconsistentProblemStatus();
+
+ @GET
+ @Path("/healthDown")
+ Response healthDown();
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
index 85741b3e..ffac3286 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/BackendImpl.java
@@ -1,6 +1,8 @@
package io.github.belgif.rest.problem;
import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
import javax.enterprise.context.RequestScoped;
import javax.ws.rs.core.MediaType;
@@ -9,6 +11,7 @@
import com.acme.custom.CustomProblem;
import io.github.belgif.rest.problem.api.Problem;
+import io.github.belgif.rest.problem.it.ProblemPayloads;
import io.github.belgif.rest.problem.it.model.JacksonModel;
@RequestScoped
@@ -56,4 +59,22 @@ public Response jacksonMismatchedInput() {
return Response.ok(model, MediaType.APPLICATION_JSON_TYPE).build();
}
+ @Override
+ public Response inconsistentProblemStatus() {
+ return Response.status(402) // -> HTTP status code 402 instead of 400
+ .type("application/problem+json")
+ .entity(ProblemPayloads.INCONSISTENT_STATUS_CODE) // -> problem status code 401 instead of 400
+ .build();
+ }
+
+ @Override
+ public Response healthDown() {
+ Map response = new HashMap<>();
+ response.put("status", "DOWN");
+ return Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .entity(response)
+ .build();
+ }
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
index 9f0b23bb..3841d281 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/Frontend.java
@@ -73,6 +73,10 @@ public interface Frontend {
@Path("/jacksonMismatchedInputFromBackend")
Response jacksonMismatchedInputFromBackend(@QueryParam("client") Client client);
+ @GET
+ @Path("/inconsistentProblemStatusFromBackend")
+ Response inconsistentProblemStatusFromBackend(@QueryParam("client") Client client);
+
@GET
@Path("/beanValidation/queryParameter")
Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive Integer p,
@@ -118,4 +122,8 @@ Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive In
@Path("/jackson/mismatchedInputException")
Response jacksonMismatchedInputException(@Valid JacksonModel body);
+ @GET
+ @Path("/healthDown")
+ Response healthDown(@QueryParam("client") Client client);
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
index fb151b98..26ec6767 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-java-ee-it/src/main/java/io/github/belgif/rest/problem/FrontendImpl.java
@@ -14,10 +14,13 @@
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
+import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.acme.custom.CustomProblem;
@@ -37,6 +40,8 @@
@Path("/frontend")
public class FrontendImpl implements Frontend {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FrontendImpl.class);
+
private static final URI BASE_URI =
URI.create("http://" + System.getProperty("jboss.bind.address") + ":8080/rest-problem");
@@ -265,6 +270,67 @@ public Response jacksonMismatchedInputFromBackend(Client client) {
throw new IllegalStateException("Unsupported client " + client);
}
+ @Override
+ public Response inconsistentProblemStatusFromBackend(Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.inconsistentProblemStatus();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ jaxRsClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().async().get()
+ .get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (client == Client.RESTEASY) {
+ return resteasyClient.target(BASE_URI).path("backend/inconsistentProblemStatus").request().get();
+ } else if (client == Client.RESTEASY_PROXY) {
+ return resteasyProxyClient.inconsistentProblemStatus();
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ } catch (BadRequestProblem e) {
+ e.setDetail(e.getDetail() + " (caught successfully by frontend)");
+ throw e;
+ }
+ }
+
+ @Override
+ public Response healthDown(@QueryParam("client") Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.healthDown();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(BASE_URI).path("backend/healthDown").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ return jaxRsClient.target(BASE_URI).path("backend/healthDown").request().async()
+ .get().get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ } else if (client == Client.RESTEASY) {
+ return resteasyClient.target(BASE_URI).path("backend/healthDown").request().get();
+ } else if (client == Client.RESTEASY_PROXY) {
+ return resteasyProxyClient.healthDown();
+ }
+ } catch (WebApplicationException e) {
+ if (e.getResponse().getStatus() == Response.Status.SERVICE_UNAVAILABLE.getStatusCode()) {
+ LOGGER.info("Caught WebApplicationException with status 503");
+ return e.getResponse();
+ }
+ throw e;
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ }
+
@Override
public Response beanValidationQueryParameter(Integer p, String o) {
return Response.ok("param: " + p + ", other: " + o).build();
diff --git a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Backend.java b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Backend.java
index 5a9f2e6d..fc69b97b 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Backend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Backend.java
@@ -34,4 +34,12 @@ public interface Backend {
@Path("/jacksonMismatchedInput")
Response jacksonMismatchedInput();
+ @GET
+ @Path("/inconsistentProblemStatus")
+ Response inconsistentProblemStatus();
+
+ @GET
+ @Path("/healthDown")
+ Response healthDown();
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/BackendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/BackendImpl.java
index 8c27c6ce..b9c08e26 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/BackendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/BackendImpl.java
@@ -1,6 +1,8 @@
package io.github.belgif.rest.problem.quarkus.it;
import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
import jakarta.enterprise.context.RequestScoped;
import jakarta.ws.rs.core.MediaType;
@@ -10,6 +12,7 @@
import io.github.belgif.rest.problem.BadRequestProblem;
import io.github.belgif.rest.problem.api.Problem;
+import io.github.belgif.rest.problem.it.ProblemPayloads;
import io.github.belgif.rest.problem.it.model.JacksonModel;
@RequestScoped
@@ -57,4 +60,22 @@ public Response jacksonMismatchedInput() {
return Response.ok(model, MediaType.APPLICATION_JSON_TYPE).build();
}
+ @Override
+ public Response inconsistentProblemStatus() {
+ return Response.status(402) // -> HTTP status code 402 instead of 400
+ .type("application/problem+json")
+ .entity(ProblemPayloads.INCONSISTENT_STATUS_CODE) // -> problem status code 401 instead of 400
+ .build();
+ }
+
+ @Override
+ public Response healthDown() {
+ Map response = new HashMap<>();
+ response.put("status", "DOWN");
+ return Response.status(Response.Status.SERVICE_UNAVAILABLE)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .entity(response)
+ .build();
+ }
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Frontend.java b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Frontend.java
index 3036f341..e3bc0324 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Frontend.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/Frontend.java
@@ -69,6 +69,10 @@ public interface Frontend {
@Path("/jacksonMismatchedInputFromBackend")
Response jacksonMismatchedInputFromBackend(@QueryParam("client") Client client);
+ @GET
+ @Path("/inconsistentProblemStatusFromBackend")
+ Response inconsistentProblemStatusFromBackend(@QueryParam("client") Client client);
+
@GET
@Path("/beanValidation/queryParameter")
Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive Integer p,
@@ -114,4 +118,8 @@ Response beanValidationQueryParameter(@QueryParam("param") @NotNull @Positive In
@Path("/jackson/mismatchedInputException")
Response jacksonMismatchedInputException(@Valid JacksonModel body);
+ @GET
+ @Path("/healthDown")
+ Response healthDown(@QueryParam("client") Client client);
+
}
diff --git a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/FrontendImpl.java b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/FrontendImpl.java
index a6a37d6c..57208ccf 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/FrontendImpl.java
+++ b/belgif-rest-problem-it/belgif-rest-problem-quarkus-it/src/main/java/io/github/belgif/rest/problem/quarkus/it/FrontendImpl.java
@@ -15,11 +15,14 @@
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.Response;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.inject.RestClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.acme.custom.CustomProblem;
@@ -42,6 +45,8 @@
@Path("/frontend")
public class FrontendImpl implements Frontend {
+ private static final Logger LOGGER = LoggerFactory.getLogger(FrontendImpl.class);
+
@Context
private HttpServerRequest serverRequest;
@@ -272,6 +277,67 @@ public Response jacksonMismatchedInputFromBackend(Client client) {
throw new IllegalStateException("Unsupported client " + client);
}
+ @Override
+ public Response inconsistentProblemStatusFromBackend(Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.inconsistentProblemStatus();
+ } else if (client == Client.REGISTER_REST_CLIENT) {
+ return restClientBuilderClient.inconsistentProblemStatus();
+ } else if (client == Client.QUARKUS_REST_CLIENT_BUILDER) {
+ return quarkusRestClientBuilderClient.inconsistentProblemStatus();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(baseUri).path("backend/inconsistentProblemStatus").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ return jaxRsClient.target(baseUri).path("backend/inconsistentProblemStatus").request().async()
+ .get().get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ } catch (BadRequestProblem e) {
+ e.setDetail(e.getDetail() + " (caught successfully by frontend)");
+ throw e;
+ }
+ }
+
+ @Override
+ public Response healthDown(@QueryParam("client") Client client) {
+ try {
+ if (client == null || client == Client.MICROPROFILE) {
+ return microprofileClient.healthDown();
+ } else if (client == Client.REGISTER_REST_CLIENT) {
+ return restClientBuilderClient.healthDown();
+ } else if (client == Client.QUARKUS_REST_CLIENT_BUILDER) {
+ return quarkusRestClientBuilderClient.healthDown();
+ } else if (client == Client.JAXRS) {
+ return jaxRsClient.target(baseUri).path("backend/healthDown").request().get();
+ } else if (client == Client.JAXRS_ASYNC) {
+ try {
+ return jaxRsClient.target(baseUri).path("backend/healthDown").request().async()
+ .get().get();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new RuntimeException(e);
+ } catch (ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ } catch (WebApplicationException e) {
+ if (e.getResponse().getStatus() == Response.Status.SERVICE_UNAVAILABLE.getStatusCode()) {
+ LOGGER.info("Caught WebApplicationException with status 503");
+ return e.getResponse();
+ }
+ throw e;
+ }
+ throw new IllegalStateException("Unsupported client " + client);
+ }
+
@Override
public Response beanValidationQueryParameter(Integer p, String o) {
return Response.ok("param: " + p + ", other: " + o).build();
diff --git a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/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
index 8a627e80..cf60fee5 100644
--- a/belgif-rest-problem-it/belgif-rest-problem-spring-boot-3-it/src/main/java/io/github/belgif/rest/problem/it/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,7 +1,9 @@
package io.github.belgif.rest.problem.it;
import java.net.URI;
+import java.util.Map;
+import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,6 +14,7 @@
import io.github.belgif.rest.problem.BadRequestProblem;
import io.github.belgif.rest.problem.api.Problem;
import io.github.belgif.rest.problem.it.model.JacksonModel;
+import io.github.belgif.rest.problem.spring.ProblemMediaType;
@RestController
@RequestMapping("/backend")
@@ -56,4 +59,19 @@ public ResponseEntity mismatchedInput() {
return ResponseEntity.ok(model);
}
+ @GetMapping("/inconsistentProblemStatus")
+ public ResponseEntity inconsistentProblemStatus() {
+ return ResponseEntity.status(402) // -> HTTP status code 402 instead of 400
+ .contentType(ProblemMediaType.INSTANCE)
+ .body(ProblemPayloads.INCONSISTENT_STATUS_CODE); // -> problem status code 401 instead of 400
+ }
+
+ @GetMapping("/healthDown")
+ public ResponseEntity