Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save edeandrea/3ce39125cd050c4419757179f15a4c5e to your computer and use it in GitHub Desktop.
Save edeandrea/3ce39125cd050c4419757179f15a4c5e to your computer and use it in GitHub Desktop.
Quarkus super heroes custom fault tolerance exception class
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Is404Exception.java
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Is404Exception.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Is404Exception.java
deleted file mode 100644
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Is404Exception.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ /dev/null (revision 5979c59422db6696207d720f96aebc6c79480bb8)
@@ -1,28 +0,0 @@
-package io.quarkus.sample.superheroes.fight.client;
-
-import java.util.Optional;
-import java.util.function.Predicate;
-
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.Response.Status;
-
-/**
- * {@link Predicate} for determining if a {@link Throwable} received from a rest client represents an HTTP {@code 404}.
- */
-class Is404Exception implements Predicate<Throwable> {
- static final Is404Exception IS_404 = new Is404Exception();
-
- private Is404Exception() {
-
- }
-
- @Override
- public boolean test(Throwable throwable) {
- return Optional.ofNullable(throwable)
- .filter(t -> t instanceof WebApplicationException)
- .map(WebApplicationException.class::cast)
- .map(WebApplicationException::getResponse)
- .filter(response -> response.getStatus() == Status.NOT_FOUND.getStatusCode())
- .isPresent();
- }
-}
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Hero.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Hero.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/Hero.java
rename from rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Hero.java
rename to rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/Hero.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Hero.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/Hero.java (date 1646778086781)
@@ -1,4 +1,4 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.hero;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/service/FightService.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/service/FightService.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/service/FightService.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/service/FightService.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/service/FightService.java (date 1646778087352)
@@ -18,10 +18,10 @@
import io.quarkus.logging.Log;
import io.quarkus.sample.superheroes.fight.Fight;
import io.quarkus.sample.superheroes.fight.Fighters;
-import io.quarkus.sample.superheroes.fight.client.Hero;
-import io.quarkus.sample.superheroes.fight.client.HeroClient;
-import io.quarkus.sample.superheroes.fight.client.Villain;
-import io.quarkus.sample.superheroes.fight.client.VillainClient;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
+import io.quarkus.sample.superheroes.fight.client.hero.HeroClient;
+import io.quarkus.sample.superheroes.fight.client.villain.Villain;
+import io.quarkus.sample.superheroes.fight.client.villain.VillainClient;
import io.quarkus.sample.superheroes.fight.config.FightConfig;
import io.quarkus.sample.superheroes.fight.mapping.FightMapper;
Index: rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceIT.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceIT.java b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceIT.java
--- a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceIT.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceIT.java (date 1646778087558)
@@ -37,8 +37,8 @@
import io.quarkus.sample.superheroes.fight.InjectKafkaConsumer;
import io.quarkus.sample.superheroes.fight.InjectWireMock;
import io.quarkus.sample.superheroes.fight.KafkaConsumerResource;
-import io.quarkus.sample.superheroes.fight.client.Hero;
-import io.quarkus.sample.superheroes.fight.client.Villain;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
+import io.quarkus.sample.superheroes.fight.client.villain.Villain;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusIntegrationTest;
Index: rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceTests.java b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceTests.java
--- a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceTests.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/rest/FightResourceTests.java (date 1646778087574)
@@ -20,8 +20,8 @@
import io.quarkus.sample.superheroes.fight.Fight;
import io.quarkus.sample.superheroes.fight.Fighters;
-import io.quarkus.sample.superheroes.fight.client.Hero;
-import io.quarkus.sample.superheroes.fight.client.Villain;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
+import io.quarkus.sample.superheroes.fight.client.villain.Villain;
import io.quarkus.sample.superheroes.fight.service.FightService;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.junit.mockito.InjectMock;
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Villain.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Villain.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/Villain.java
rename from rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Villain.java
rename to rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/Villain.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/Villain.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/Villain.java (date 1646778087051)
@@ -1,4 +1,4 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.villain;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/VillainClient.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/VillainClient.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClient.java
rename from rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/VillainClient.java
rename to rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClient.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/VillainClient.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClient.java (date 1646778087101)
@@ -1,17 +1,26 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.villain;
-import java.time.Duration;
+import java.io.IOException;
import java.time.temporal.ChronoUnit;
+import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import javax.enterprise.context.ApplicationScoped;
import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.ClientRequestContext;
+import javax.ws.rs.client.ClientResponseContext;
+import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
+import org.eclipse.microprofile.faulttolerance.Fallback;
+import org.eclipse.microprofile.faulttolerance.Retry;
import org.jboss.resteasy.reactive.client.impl.UniInvoker;
+import org.jboss.resteasy.reactive.common.core.UnwrappableException;
+import io.quarkus.sample.superheroes.fight.client.NotFoundException;
import io.quarkus.sample.superheroes.fight.config.FightConfig;
import io.smallrye.faulttolerance.api.CircuitBreakerName;
@@ -29,6 +38,7 @@
public VillainClient(FightConfig fightConfig) {
this.villainClient = ClientBuilder.newClient()
+ .register(NotFoundExceptionFilter.class)
.target(fightConfig.villain().clientBaseUrl())
.path("api/villains/random");
}
@@ -37,8 +47,19 @@
* Gets a Villain from the Villain service wrapped with a recovery on a {@code 404} error. Also wrapped in a {@link CircuitBreaker}.
* @return The Villain
*/
- @CircuitBreaker(requestVolumeThreshold = 8, failureRatio = 0.5, delay = 2, delayUnit = ChronoUnit.SECONDS)
+ @CircuitBreaker(
+ requestVolumeThreshold = 8,
+ delay = 2,
+ delayUnit = ChronoUnit.SECONDS,
+ skipOn = NotFoundException.class
+ )
@CircuitBreakerName("findRandomVillain")
+ @Fallback(fallbackMethod = "getRandomVillainFallback", applyOn = NotFoundException.class)
+ @Retry(
+ maxRetries = 3,
+ maxDuration = 200,
+ abortOn = NotFoundException.class
+ )
CompletionStage<Villain> getRandomVillain() {
// Want the 404 handling to be part of the circuit breaker
// This means that the 404 responses aren't considered errors by the circuit breaker
@@ -46,10 +67,14 @@
.request(MediaType.APPLICATION_JSON_TYPE)
.rx(UniInvoker.class)
.get(Villain.class)
- .onFailure(Is404Exception.IS_404).recoverWithNull()
.subscribeAsCompletionStage();
}
+ CompletionStage<Villain> getRandomVillainFallback() {
+ System.out.println("Invoking VillainClient.getRandomVillainFallback");
+ return CompletableFuture.completedStage(null);
+ }
+
/**
* Finds a random {@link Villain}. The retry logic is applied to the result of the {@link CircuitBreaker}, meaning that retries that return failures could trigger the breaker to open.
* @return A random {@link Villain}
@@ -57,7 +82,15 @@
public Uni<Villain> findRandomVillain() {
// The CompletionState is important so that on retry the Uni re-subscribes to a new
// CompletionStage rather than the original one (which has already completed)
- return Uni.createFrom().completionStage(this::getRandomVillain)
- .onFailure().retry().withBackOff(Duration.ofMillis(200)).atMost(3);
+ return Uni.createFrom().completionStage(this::getRandomVillain);
}
+
+ public static class NotFoundExceptionFilter implements ClientResponseFilter {
+ @Override
+ public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+ if (responseContext.getStatus() == Status.NOT_FOUND.getStatusCode()) {
+ throw new UnwrappableException(new NotFoundException(Status.fromStatusCode(responseContext.getStatus())));
+ }
+ }
+ }
}
Index: rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/HeroClientTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/HeroClientTests.java b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClientTests.java
rename from rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/HeroClientTests.java
rename to rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClientTests.java
--- a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/HeroClientTests.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClientTests.java (date 1646778087378)
@@ -1,4 +1,4 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.hero;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static javax.ws.rs.core.HttpHeaders.ACCEPT;
@@ -29,7 +29,7 @@
import io.smallrye.mutiny.helpers.test.UniAssertSubscriber;
/**
- * Tests for the {@link HeroClient}. Uses wiremock to stub responses and verify interactions.
+ * Tests for the {@link io.quarkus.sample.superheroes.fight.client.hero.HeroClient}. Uses wiremock to stub responses and verify interactions.
* @see HeroesVillainsWiremockServerResource
*/
@QuarkusTest
@@ -52,7 +52,7 @@
WireMockServer wireMockServer;
@Inject
- HeroClient heroClient;
+ HeroClient heroClient;
@Inject
ObjectMapper objectMapper;
@@ -73,6 +73,9 @@
@Test
public void findsRandom() {
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomHero"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.stubFor(
get(urlEqualTo(HERO_URI))
.willReturn(okForContentType(APPLICATION_JSON, getDefaultHeroJson()))
@@ -102,6 +105,9 @@
);
});
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomHero"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.verify(5,
getRequestedFor(urlEqualTo(HERO_URI))
.withHeader(ACCEPT, equalTo(APPLICATION_JSON))
@@ -110,6 +116,9 @@
@Test
public void recoversFrom404() {
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomHero"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.stubFor(
get(urlEqualTo(HERO_URI))
.willReturn(notFound())
@@ -124,6 +133,9 @@
.assertItem(null)
);
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomHero"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.verify(5,
getRequestedFor(urlEqualTo(HERO_URI))
.withHeader(ACCEPT, equalTo(APPLICATION_JSON))
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroClient.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroClient.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClient.java
rename from rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroClient.java
rename to rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClient.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroClient.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroClient.java (date 1646778152523)
@@ -1,12 +1,12 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.hero;
-import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.CompletionStage;
import javax.enterprise.context.ApplicationScoped;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
+import org.eclipse.microprofile.faulttolerance.Retry;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import io.smallrye.faulttolerance.api.CircuitBreakerName;
@@ -29,11 +29,11 @@
*/
@CircuitBreaker(requestVolumeThreshold = 8, failureRatio = 0.5, delay = 2, delayUnit = ChronoUnit.SECONDS)
@CircuitBreakerName("findRandomHero")
- CompletionStage<Hero> getRandomHero() {
+ @Retry(maxRetries = 3, maxDuration = 200)
+ CompletionStage<Hero> getRandomHero() {
// Want the 404 handling to be part of the circuit breaker
// This means that the 404 responses aren't considered errors by the circuit breaker
return this.heroClient.findRandomHero()
- .onFailure(Is404Exception.IS_404).recoverWithNull()
.subscribeAsCompletionStage();
}
@@ -44,7 +44,6 @@
public Uni<Hero> findRandomHero() {
// The CompletionState is important so that on retry the Uni re-subscribes to a new
// CompletionStage rather than the original one (which has already completed)
- return Uni.createFrom().completionStage(this::getRandomHero)
- .onFailure().retry().withBackOff(Duration.ofMillis(200)).atMost(3);
+ return Uni.createFrom().completionStage(this::getRandomHero);
}
}
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroRestClient.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroRestClient.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroRestClient.java
rename from rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroRestClient.java
rename to rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroRestClient.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/HeroRestClient.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/HeroRestClient.java (date 1646778086976)
@@ -1,12 +1,16 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.hero;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
+import org.eclipse.microprofile.faulttolerance.Fallback;
+import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
+import io.quarkus.sample.superheroes.fight.client.NotFoundException;
+
import io.smallrye.mutiny.Uni;
/**
@@ -18,6 +22,7 @@
@Path("/api/heroes")
@Produces(MediaType.APPLICATION_JSON)
@RegisterRestClient(configKey = "hero-client")
+@RegisterProvider(NotFoundExceptionMapper.class)
interface HeroRestClient {
/**
* HTTP <code>GET</code> call to {@code /api/heroes/random} on the Heros service
@@ -26,5 +31,11 @@
*/
@GET
@Path("/random")
- Uni<Hero> findRandomHero();
+ @Fallback(fallbackMethod = "findRandomHeroFallback", applyOn = NotFoundException.class)
+ Uni<Hero> findRandomHero();
+
+ default Uni<Hero> findRandomHeroFallback() {
+ return Uni.createFrom().<Hero>nullItem()
+ .invoke(() -> System.out.println("Invoking HeroRestClient.findRandomHeroFallback"));
+ }
}
Index: rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/VillainClientTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/VillainClientTests.java b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClientTests.java
rename from rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/VillainClientTests.java
rename to rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClientTests.java
--- a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/VillainClientTests.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/client/villain/VillainClientTests.java (date 1646778087463)
@@ -1,4 +1,4 @@
-package io.quarkus.sample.superheroes.fight.client;
+package io.quarkus.sample.superheroes.fight.client.villain;
import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static javax.ws.rs.core.HttpHeaders.ACCEPT;
@@ -29,7 +29,7 @@
import io.smallrye.mutiny.helpers.test.UniAssertSubscriber;
/**
- * Tests for the {@link VillainClient}. Uses wiremock to stub responses and verify interactions.
+ * Tests for the {@link io.quarkus.sample.superheroes.fight.client.villain.VillainClient}. Uses wiremock to stub responses and verify interactions.
* @see HeroesVillainsWiremockServerResource
*/
@QuarkusTest
@@ -52,7 +52,7 @@
WireMockServer wireMockServer;
@Inject
- VillainClient villainClient;
+ VillainClient villainClient;
@Inject
ObjectMapper objectMapper;
@@ -73,6 +73,9 @@
@Test
public void findsRandom() {
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomVillain"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.stubFor(
get(urlEqualTo(VILLAIN_API))
.willReturn(okForContentType(APPLICATION_JSON, getDefaultVillainJson()))
@@ -102,6 +105,9 @@
);
});
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomVillain"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.verify(5,
getRequestedFor(urlEqualTo(VILLAIN_API))
.withHeader(ACCEPT, equalTo(APPLICATION_JSON))
@@ -110,6 +116,9 @@
@Test
public void recoversFrom404() {
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomVillain"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.stubFor(
get(urlEqualTo(VILLAIN_API))
.willReturn(notFound())
@@ -124,6 +133,9 @@
.assertItem(null)
);
+ assertThat(this.circuitBreakerMaintenance.currentState("findRandomVillain"))
+ .isEqualTo(CircuitBreakerState.CLOSED);
+
this.wireMockServer.verify(5,
getRequestedFor(urlEqualTo(VILLAIN_API))
.withHeader(ACCEPT, equalTo(APPLICATION_JSON))
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/rest/FightResource.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/rest/FightResource.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/rest/FightResource.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/rest/FightResource.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/rest/FightResource.java (date 1646778087339)
@@ -26,7 +26,7 @@
import io.quarkus.logging.Log;
import io.quarkus.sample.superheroes.fight.Fight;
import io.quarkus.sample.superheroes.fight.Fighters;
-import io.quarkus.sample.superheroes.fight.client.Hero;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
import io.quarkus.sample.superheroes.fight.service.FightService;
import io.smallrye.common.annotation.NonBlocking;
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/Fighters.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/Fighters.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/Fighters.java
--- a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/Fighters.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/Fighters.java (date 1646778087363)
@@ -5,8 +5,8 @@
import org.eclipse.microprofile.openapi.annotations.media.Schema;
-import io.quarkus.sample.superheroes.fight.client.Hero;
-import io.quarkus.sample.superheroes.fight.client.Villain;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
+import io.quarkus.sample.superheroes.fight.client.villain.Villain;
/**
* Entity class representing Fighters
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/NotFoundException.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/NotFoundException.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/NotFoundException.java
new file mode 100644
--- /dev/null (date 1646778087323)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/NotFoundException.java (date 1646778087323)
@@ -0,0 +1,32 @@
+package io.quarkus.sample.superheroes.fight.client;
+
+import java.util.Optional;
+
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.core.Response.StatusType;
+
+public class NotFoundException extends RuntimeException {
+ public NotFoundException(Response response) {
+ super(computeExceptionMessage(response));
+ }
+
+ public NotFoundException(StatusType statusInfo) {
+ super(computeExceptionMessage(statusInfo));
+ }
+
+ private static String computeExceptionMessage(Response response) {
+ var statusInfo = Optional.ofNullable(response)
+ .map(Response::getStatusInfo)
+ .orElse(Status.NOT_FOUND);
+
+ return computeExceptionMessage(statusInfo);
+ }
+
+ private static String computeExceptionMessage(StatusType status) {
+ var statusInfo = Optional.ofNullable(status)
+ .orElse(Status.NOT_FOUND);
+
+ return String.format("HTTP %s %s", statusInfo.getStatusCode(), statusInfo.getReasonPhrase());
+ }
+}
Index: rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/NotFoundExceptionMapper.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/NotFoundExceptionMapper.java b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/NotFoundExceptionMapper.java
new file mode 100644
--- /dev/null (date 1646778087032)
+++ b/rest-fights/src/main/java/io/quarkus/sample/superheroes/fight/client/hero/NotFoundExceptionMapper.java (date 1646778087032)
@@ -0,0 +1,21 @@
+package io.quarkus.sample.superheroes.fight.client.hero;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper;
+
+import io.quarkus.sample.superheroes.fight.client.NotFoundException;
+
+public class NotFoundExceptionMapper implements ResponseExceptionMapper<NotFoundException> {
+ @Override
+ public NotFoundException toThrowable(Response response) {
+ return new NotFoundException(response);
+ }
+
+ @Override
+ public boolean handles(int status, MultivaluedMap<String, Object> headers) {
+ return status == Status.NOT_FOUND.getStatusCode();
+ }
+}
Index: rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/service/FightServiceTests.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/service/FightServiceTests.java b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/service/FightServiceTests.java
--- a/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/service/FightServiceTests.java (revision 5979c59422db6696207d720f96aebc6c79480bb8)
+++ b/rest-fights/src/test/java/io/quarkus/sample/superheroes/fight/service/FightServiceTests.java (date 1646778087592)
@@ -23,10 +23,10 @@
import io.quarkus.panache.mock.PanacheMock;
import io.quarkus.sample.superheroes.fight.Fight;
import io.quarkus.sample.superheroes.fight.Fighters;
-import io.quarkus.sample.superheroes.fight.client.Hero;
-import io.quarkus.sample.superheroes.fight.client.HeroClient;
-import io.quarkus.sample.superheroes.fight.client.Villain;
-import io.quarkus.sample.superheroes.fight.client.VillainClient;
+import io.quarkus.sample.superheroes.fight.client.hero.Hero;
+import io.quarkus.sample.superheroes.fight.client.hero.HeroClient;
+import io.quarkus.sample.superheroes.fight.client.villain.Villain;
+import io.quarkus.sample.superheroes.fight.client.villain.VillainClient;
import io.quarkus.sample.superheroes.fight.config.FightConfig;
import io.quarkus.sample.superheroes.fight.mapping.FightMapper;
import io.quarkus.test.junit.QuarkusTest;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment