diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java index c40db74003..50579d8721 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/ErrorHandlingApplication.java @@ -3,23 +3,16 @@ package com.baeldung.reactive.errorhandling; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.security.config.web.server.ServerHttpSecurity; -import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration; -@SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class) +@SpringBootApplication(exclude = { + MongoReactiveAutoConfiguration.class, + ReactiveSecurityAutoConfiguration.class, + ReactiveUserDetailsServiceAutoConfiguration.class }) public class ErrorHandlingApplication { public static void main(String[] args) { SpringApplication.run(ErrorHandlingApplication.class, args); } - - @Bean - public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) { - http.authorizeExchange() - .anyExchange() - .permitAll(); - http.csrf().disable(); - return http.build(); - } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java index 0a96a8593c..3458a175e4 100644 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/GlobalErrorAttributes.java @@ -9,44 +9,14 @@ import org.springframework.web.reactive.function.server.ServerRequest; import java.util.Map; @Component -public class GlobalErrorAttributes extends DefaultErrorAttributes{ - - private HttpStatus status = HttpStatus.BAD_REQUEST; - private String message = "please provide a name"; +public class GlobalErrorAttributes extends DefaultErrorAttributes { @Override public Map getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { Map map = super.getErrorAttributes(request, options); - map.put("status", getStatus()); - map.put("message", getMessage()); + map.put("status", HttpStatus.BAD_REQUEST); + map.put("message", "please provide a name"); return map; } - /** - * @return the status - */ - public HttpStatus getStatus() { - return status; - } - - /** - * @param status the status to set - */ - public void setStatus(HttpStatus status) { - this.status = status; - } - - /** - * @return the message - */ - public String getMessage() { - return message; - } - - /** - * @param message the message to set - */ - public void setMessage(String message) { - this.message = message; - } } diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java new file mode 100644 index 0000000000..d49d9b4be2 --- /dev/null +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Handler.java @@ -0,0 +1,67 @@ +package com.baeldung.reactive.errorhandling; + +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.ServerRequest; +import org.springframework.web.reactive.function.server.ServerResponse; +import reactor.core.publisher.Mono; + +@Component +public class Handler { + + public Mono handleWithErrorReturn(ServerRequest request) { + return sayHello(request) + .onErrorReturn("Hello, Stranger") + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)); + } + + public Mono handleWithErrorResumeAndDynamicFallback(ServerRequest request) { + return sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)) + .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + e.getMessage())) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s))); + } + + public Mono handleWithErrorResumeAndFallbackMethod(ServerRequest request) { + return sayHello(request) + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s)) + .onErrorResume(e -> sayHelloFallback() + .flatMap(s -> ServerResponse.ok() + .contentType(MediaType.TEXT_PLAIN) + .bodyValue(s))); + } + + public Mono handleWithErrorResumeAndCustomException(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request) + .onErrorResume(e -> Mono.error(new NameRequiredException( + HttpStatus.BAD_REQUEST, + "please provide a name", e))), String.class); + } + + public Mono handleWithGlobalErrorHandler(ServerRequest request) { + return ServerResponse.ok() + .body(sayHello(request), String.class); + } + + private Mono sayHello(ServerRequest request) { + try { + return Mono.just("Hello, " + request.queryParam("name").get()); + } catch (Exception e) { + return Mono.error(e); + } + } + + private Mono sayHelloFallback() { + return Mono.just("Hello, Stranger"); + } +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java new file mode 100644 index 0000000000..5f130ec035 --- /dev/null +++ b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/Router.java @@ -0,0 +1,26 @@ +package com.baeldung.reactive.errorhandling; + +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; + +import static org.springframework.http.MediaType.TEXT_PLAIN; +import static org.springframework.web.reactive.function.server.RequestPredicates.GET; +import static org.springframework.web.reactive.function.server.RequestPredicates.accept; + +@Component +public class Router { + + @Bean + public RouterFunction routes(Handler handler) { + return RouterFunctions + .route(GET("/api/endpoint1").and(accept(TEXT_PLAIN)), handler::handleWithErrorReturn) + .andRoute(GET("/api/endpoint2").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndFallbackMethod) + .andRoute(GET("/api/endpoint3").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndDynamicFallback) + .andRoute(GET("/api/endpoint4").and(accept(TEXT_PLAIN)), handler::handleWithErrorResumeAndCustomException) + .andRoute(GET("/api/endpoint5").and(accept(TEXT_PLAIN)), handler::handleWithGlobalErrorHandler); + } + +} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java deleted file mode 100644 index 32f2f1c3a2..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler1.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler1 { - - public Mono handleRequest1(ServerRequest request) { - return sayHello(request).onErrorReturn("Hello, Stranger") - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)); - } - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java deleted file mode 100644 index 093120c92b..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler2.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler2 { - -public Mono handleRequest2(ServerRequest request) { - return - sayHello(request) - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)) - .onErrorResume(e -> sayHelloFallback() - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s))); -} - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - - private Mono sayHelloFallback() { - return Mono.just("Hello, Stranger"); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java deleted file mode 100644 index 44842e0539..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler3.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler3 { - - public Mono handleRequest3(ServerRequest request) { - return - sayHello(request) - .flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s)) - .onErrorResume(e -> (Mono.just("Hi, I looked around for your name but found: " + - e.getMessage())).flatMap(s -> ServerResponse.ok() - .contentType(MediaType.TEXT_PLAIN) - .bodyValue(s))); - } - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name") - .get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java deleted file mode 100644 index 2d391a42a7..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler4.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import com.baeldung.reactive.errorhandling.NameRequiredException; -import org.springframework.http.HttpStatus; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler4 { - -public Mono handleRequest4(ServerRequest request) { - return ServerResponse.ok() - .body(sayHello(request) - .onErrorResume(e -> - Mono.error(new NameRequiredException( - HttpStatus.BAD_REQUEST, "please provide a name", e))), String.class); -} - - private Mono sayHello(ServerRequest request) { - try { - return Mono.just("Hello, " + request.queryParam("name").get()); - } catch (Exception e) { - return Mono.error(e); - } - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java deleted file mode 100644 index a466982865..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/handlers/Handler5.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.handlers; - -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.ServerRequest; -import org.springframework.web.reactive.function.server.ServerResponse; -import reactor.core.publisher.Mono; - -@Component -public class Handler5 { - - public Mono handleRequest5(ServerRequest request) { - return ServerResponse.ok() - .body(sayHello(request), String.class); - - } - - private Mono sayHello(ServerRequest request) { - return Mono.just("Hello, " + request.queryParam("name").get()); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java deleted file mode 100644 index caf779b456..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router1.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler1; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router1 { - - @Bean - public RouterFunction routeRequest1(Handler1 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint1") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest1); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java deleted file mode 100644 index b965257c30..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router2.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler2; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router2 { - - @Bean - public RouterFunction routeRequest2(Handler2 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint2") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest2); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java deleted file mode 100644 index b8f7f983cc..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router3.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler3; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router3 { - - @Bean - public RouterFunction routeRequest3(Handler3 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint3") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest3); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java deleted file mode 100644 index 03c65fec67..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router4.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler4; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router4 { - - @Bean - public RouterFunction routeRequest4(Handler4 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint4") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest4); - } - -} diff --git a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java b/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java deleted file mode 100644 index c68e04659f..0000000000 --- a/spring-reactive/src/main/java/com/baeldung/reactive/errorhandling/routers/Router5.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.baeldung.reactive.errorhandling.routers; - -import com.baeldung.reactive.errorhandling.handlers.Handler5; -import org.springframework.context.annotation.Bean; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Component; -import org.springframework.web.reactive.function.server.RequestPredicates; -import org.springframework.web.reactive.function.server.RouterFunction; -import org.springframework.web.reactive.function.server.RouterFunctions; -import org.springframework.web.reactive.function.server.ServerResponse; - -@Component -public class Router5 { - - @Bean - public RouterFunction routeRequest5(Handler5 handler) { - return RouterFunctions.route(RequestPredicates.GET("/api/endpoint5") - .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)), handler::handleRequest5); - } - -} diff --git a/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java b/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java index 1167792542..bbcab179eb 100644 --- a/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java +++ b/spring-reactive/src/test/java/com/baeldung/reactive/errorhandling/ErrorHandlingIntegrationTest.java @@ -7,19 +7,13 @@ import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWeb import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.http.MediaType; -import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.reactive.server.WebTestClient; -import java.io.IOException; - -import static org.junit.Assert.assertEquals; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @DirtiesContext -@WithMockUser @AutoConfigureWebTestClient(timeout = "10000") public class ErrorHandlingIntegrationTest { @@ -27,150 +21,107 @@ public class ErrorHandlingIntegrationTest { private WebTestClient webTestClient; @Test - public void givenErrorReturn_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint1?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - - } - - @Test - public void givenErrorReturn_whenNoUsername_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint1") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Stranger", s); - } - - @Test - public void givenResumeFallback_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint2?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeFallback_whenNoUsername_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint2") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Stranger", s); - - } - - @Test - public void givenResumeDynamicValue_whenUsernamePresent_thenOk() throws IOException { - - String s = webTestClient.get() - .uri("/api/endpoint3?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeDynamicValue_whenNoUsername_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint3") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hi, I looked around for your name but found: No value present", s); - } - - @Test - public void givenResumeRethrow_whenUsernamePresent_thenOk() throws IOException { - String s = webTestClient.get() - .uri("/api/endpoint4?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenResumeRethrow_whenNoUsername_thenOk() throws IOException { + public void givenErrorReturn_whenUsernamePresent_thenOk() { webTestClient.get() - .uri("/api/endpoint4") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isBadRequest() - .expectHeader() - .contentType(MediaType.APPLICATION_JSON) - .expectBody() - .jsonPath("$.message") - .isNotEmpty() - .jsonPath("$.message") - .isEqualTo("please provide a name"); + .uri("/api/endpoint1?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); } @Test - public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() throws IOException { + public void givenErrorReturn_whenNoUsername_thenOk() { - String s = webTestClient.get() - .uri("/api/endpoint5?name={username}", "Tony") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .returnResult(String.class) - .getResponseBody() - .blockFirst(); - - assertEquals("Hello, Tony", s); - } - - @Test - public void givenGlobalErrorHandling_whenNoUsername_thenOk() throws IOException { webTestClient.get() - .uri("/api/endpoint5") - .accept(MediaType.TEXT_PLAIN) - .exchange() - .expectStatus() - .isBadRequest() - .expectHeader() - .contentType(MediaType.APPLICATION_JSON) - .expectBody() - .jsonPath("$.message") - .isNotEmpty() - .jsonPath("$.message") - .isEqualTo("please provide a name"); + .uri("/api/endpoint1") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Stranger"); + } + @Test + public void givenResumeFallback_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint2?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeFallback_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint2") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Stranger"); + } + + @Test + public void givenResumeDynamicValue_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint3?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeDynamicValue_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint3") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hi, I looked around for your name but found: No value present"); + } + + @Test + public void givenResumeRethrow_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint4?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenResumeRethrow_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint4") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus().isBadRequest() + .expectHeader().contentType(MediaType.APPLICATION_JSON) + .expectBody().jsonPath("$.message").isEqualTo("please provide a name"); + } + + @Test + public void givenGlobalErrorHandling_whenUsernamePresent_thenOk() { + + webTestClient.get() + .uri("/api/endpoint5?name={username}", "Tony") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectBody(String.class).isEqualTo("Hello, Tony"); + } + + @Test + public void givenGlobalErrorHandling_whenNoUsername_thenOk() { + + webTestClient.get() + .uri("/api/endpoint5") + .accept(MediaType.TEXT_PLAIN) + .exchange() + .expectStatus().isBadRequest() + .expectHeader().contentType(MediaType.APPLICATION_JSON) + .expectBody().jsonPath("$.message").isEqualTo("please provide a name"); } } diff --git a/spring-state-machine/pom.xml b/spring-state-machine/pom.xml index 741361b3fa..0e930d6ff1 100644 --- a/spring-state-machine/pom.xml +++ b/spring-state-machine/pom.xml @@ -39,7 +39,7 @@ 3.2.0 5.3.19 - 4.3.7.RELEASE + 5.3.19 1.7.0 diff --git a/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java b/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java index 0c392c2c35..8c95e9d843 100644 --- a/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java +++ b/spring-state-machine/src/main/java/com/baeldung/spring/statemachine/config/SimpleStateMachineConfiguration.java @@ -38,7 +38,7 @@ public class SimpleStateMachineConfiguration extends StateMachineConfigurerAdapt .stateEntry("S3", entryAction()) .stateExit("S3", exitAction()) .state("S4", executeAction(), errorAction()) - .stateDo("S5", executeAction()); + .state("S5", executeAction(), errorAction()); } diff --git a/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java b/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java index 5909340a82..ac2d6a22c2 100644 --- a/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java +++ b/spring-state-machine/src/test/java/com/baeldung/spring/statemachine/StateMachineIntegrationTest.java @@ -1,32 +1,37 @@ package com.baeldung.spring.statemachine; -import com.baeldung.spring.statemachine.config.SimpleStateMachineConfiguration; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.statemachine.StateMachine; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.baeldung.spring.statemachine.config.SimpleStateMachineConfiguration; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -@RunWith(SpringJUnit4ClassRunner.class) +@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = SimpleStateMachineConfiguration.class) +@TestMethodOrder(OrderAnnotation.class) public class StateMachineIntegrationTest { @Autowired private StateMachine stateMachine; - @Before + @BeforeEach public void setUp() { stateMachine.start(); } @Test + @Order(1) public void whenSimpleStringStateMachineEvents_thenEndState() { assertEquals("SI", stateMachine.getState().getId()); @@ -37,8 +42,8 @@ public class StateMachineIntegrationTest { assertEquals("S2", stateMachine.getState().getId()); } - @Ignore("Fixing in JAVA-9808") @Test + @Order(2) public void whenSimpleStringMachineActionState_thenActionExecuted() { stateMachine.sendEvent("E3"); @@ -58,7 +63,7 @@ public class StateMachineIntegrationTest { assertEquals(2, stateMachine.getExtendedState().getVariables().get("approvalCount")); } - @After + @AfterEach public void tearDown() { stateMachine.stop(); }