Last active
March 8, 2022 22:23
-
-
Save edeandrea/3ce39125cd050c4419757179f15a4c5e to your computer and use it in GitHub Desktop.
Quarkus super heroes custom fault tolerance exception class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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