From: Kai Moritz Date: Tue, 14 Jan 2020 23:58:26 +0000 (+0100) Subject: RestController throws 503 Service Unavailable, if the remote-server fails X-Git-Url: http://juplo.de/gitweb/?a=commitdiff_plain;h=d254e8fa52ab3897c7d7a95e36d9b93635d7d7c6;p=demos%2Ftesting RestController throws 503 Service Unavailable, if the remote-server fails * Added unit-test RestControllerTest.testResponseOtherErrors() * Fixed the behavior of the RestController accordingly --- diff --git a/src/main/java/de/juplo/demo/RestController.java b/src/main/java/de/juplo/demo/RestController.java index 288fd9e..f7f63a6 100644 --- a/src/main/java/de/juplo/demo/RestController.java +++ b/src/main/java/de/juplo/demo/RestController.java @@ -4,6 +4,8 @@ package de.juplo.demo; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.reactive.function.client.WebClientResponseException; +import org.springframework.web.reactive.function.client.WebClientResponseException.NotFound; import reactor.core.publisher.Mono; @@ -26,6 +28,22 @@ public class RestController @GetMapping(path = { "", "/" }, produces = MediaType.TEXT_PLAIN_VALUE) public Mono fetch(@RequestParam String path) { - return service.getRemoteText(path); + return + service + .getRemoteText(path) + .onErrorResume(t -> + { + if(t.getClass().equals(NotFound.class)) + return Mono.error(t); + + return + Mono.error( + WebClientResponseException.create( + 503, + "Service Unavailable - Cause: " + t.getMessage(), + null, + null, + null)); + }); } } diff --git a/src/test/java/de/juplo/demo/RestControllerTest.java b/src/test/java/de/juplo/demo/RestControllerTest.java index dae8929..4b4526a 100644 --- a/src/test/java/de/juplo/demo/RestControllerTest.java +++ b/src/test/java/de/juplo/demo/RestControllerTest.java @@ -1,13 +1,18 @@ package de.juplo.demo; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; import org.mockito.Mockito; import static org.mockito.Mockito.when; +import org.springframework.http.HttpStatus; import org.springframework.web.reactive.function.client.WebClientResponseException; import org.springframework.web.reactive.function.client.WebClientResponseException.NotFound; +import org.springframework.web.reactive.function.client.WebClientResponseException.ServiceUnavailable; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; @@ -59,6 +64,50 @@ public class RestControllerTest .verify(); } + /** + * Only the behavior on the common errors, as defined in {@link + * WebClientResponseException#create(int, String, org.springframework.http.HttpHeaders, byte[], java.nio.charset.Charset, org.springframework.http.HttpRequest) + * WebClientResponseException.create()} is tested. + */ + @DisplayName("Other error while fetching data from remote-server") + @ParameterizedTest(name = "{arguments} ==> HTTP-status={0}") + @EnumSource(value = HttpStatus.class, names = { + "BAD_REQUEST", + "UNAUTHORIZED", + "FORBIDDEN", + "METHOD_NOT_ALLOWED", + "NOT_ACCEPTABLE", + "CONFLICT", + "GONE", + "UNSUPPORTED_MEDIA_TYPE", + "TOO_MANY_REQUESTS", + "UNPROCESSABLE_ENTITY", + "INTERNAL_SERVER_ERROR", + "NOT_IMPLEMENTED", + "BAD_GATEWAY", + "SERVICE_UNAVAILABLE", + "GATEWAY_TIMEOUT" + }) + void testResponseOtherErrors(HttpStatus status) + { + Mono mono = Mono.error(exception(status.value())); + when(service.getRemoteText("foo")).thenReturn(mono); + + Mono result = controller.fetch("foo"); + + StepVerifier + .create(result) + .expectErrorSatisfies((t) -> + { + assertThat(t).isInstanceOf(ServiceUnavailable.class); + assertThat(t.getMessage()) + .startsWith( + "503 Service Unavailable - Cause: " + + Integer.toString(status.value())); + }) + .verify(); + } + WebClientResponseException exception(int status) {