From 471ed5d99297d2acd627bf80f55948749309d29c Mon Sep 17 00:00:00 2001 From: Eugen Paraschiv Date: Wed, 13 Dec 2017 18:59:17 +0200 Subject: [PATCH] new client project, general cleanup, testing work --- spring-5-reactive-client/.gitignore | 12 ++ spring-5-reactive-client/README.md | 15 ++ spring-5-reactive-client/pom.xml | 201 ++++++++++++++++++ .../com/baeldung/reactive/model}/Foo.java | 2 +- .../src/main/resources/application.properties | 3 + .../src/main/resources/logback.xml | 16 ++ .../src/main/webapp/WEB-INF/web.xml | 21 ++ .../reactive/ReactiveIntegrationTest.java | 42 ++++ .../Spring5ReactiveTestApplication.java | 35 +++ .../src/test/resources/logback-test.xml | 16 ++ .../controller/FooReactiveController.java | 17 +- .../java/com/baeldung/reactive/model/Foo.java | 13 ++ .../src/main/resources/files/hello.txt | 1 - .../src/main/resources/files/test/test.txt | 1 - .../com/baeldung/reactive/FluxUnitTest.java | 5 +- 15 files changed, 393 insertions(+), 7 deletions(-) create mode 100644 spring-5-reactive-client/.gitignore create mode 100644 spring-5-reactive-client/README.md create mode 100644 spring-5-reactive-client/pom.xml rename {spring-5-reactive/src/main/java/com/baeldung/reactive/controller => spring-5-reactive-client/src/main/java/com/baeldung/reactive/model}/Foo.java (78%) create mode 100644 spring-5-reactive-client/src/main/resources/application.properties create mode 100644 spring-5-reactive-client/src/main/resources/logback.xml create mode 100644 spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml create mode 100644 spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java create mode 100644 spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java create mode 100644 spring-5-reactive-client/src/test/resources/logback-test.xml create mode 100644 spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java delete mode 100644 spring-5-reactive/src/main/resources/files/hello.txt delete mode 100644 spring-5-reactive/src/main/resources/files/test/test.txt diff --git a/spring-5-reactive-client/.gitignore b/spring-5-reactive-client/.gitignore new file mode 100644 index 0000000000..dec013dfa4 --- /dev/null +++ b/spring-5-reactive-client/.gitignore @@ -0,0 +1,12 @@ +#folders# +.idea +/target +/neoDb* +/data +/src/main/webapp/WEB-INF/classes +*/META-INF/* + +# Packaged files # +*.jar +*.war +*.ear \ No newline at end of file diff --git a/spring-5-reactive-client/README.md b/spring-5-reactive-client/README.md new file mode 100644 index 0000000000..400e343263 --- /dev/null +++ b/spring-5-reactive-client/README.md @@ -0,0 +1,15 @@ +## Spring REST Example Project + +### The Course +The "REST With Spring" Classes: http://bit.ly/restwithspring + +### Relevant Articles + +- [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests) +- [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web) +- [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching) +- [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient) +- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans) +- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config) +- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive) +- [Spring 5 Testing with @EnabledIf Annotation](https://github.com/eugenp/tutorials/tree/master/spring-5) diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml new file mode 100644 index 0000000000..8aa579b724 --- /dev/null +++ b/spring-5-reactive-client/pom.xml @@ -0,0 +1,201 @@ + + + 4.0.0 + + com.baeldung + spring-5-reactive-client + 0.0.1-SNAPSHOT + jar + + spring-5 + spring 5 sample project about new features + + + org.springframework.boot + spring-boot-starter-parent + 2.0.0.M7 + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-webflux + + + org.projectreactor + reactor-spring + ${reactor-spring.version} + + + javax.json.bind + javax.json.bind-api + + + + + + + + + + + + + + + + + org.apache.geronimo.specs + geronimo-json_1.1_spec + ${geronimo-json_1.1_spec.version} + + + org.apache.johnzon + johnzon-jsonb + + + + org.apache.commons + commons-lang3 + + + + + + org.springframework.boot + spring-boot-devtools + runtime + + + com.h2database + h2 + runtime + + + + org.springframework + spring-test + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.apache.commons + commons-collections4 + 4.1 + test + + + + org.junit.jupiter + junit-jupiter-api + + + org.junit.jupiter + junit-jupiter-engine + test + + + org.junit.platform + junit-platform-surefire-provider + ${junit.platform.version} + test + + + org.junit.platform + junit-platform-runner + ${junit.platform.version} + test + + + + org.projectlombok + lombok + + + org.apache.commons + commons-lang3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + com.baeldung.Spring5Application + JAR + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 3 + true + methods + true + + **/*IntegrationTest.java + **/*LiveTest.java + + + + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + false + + + + + + UTF-8 + UTF-8 + 1.8 + 1.0.0 + 5.0.0 + 2.20 + 5.0.1.RELEASE + 1.0.1.RELEASE + 1.1.3 + 1.0 + 1.0 + + + diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java similarity index 78% rename from spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java rename to spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java index 480782a551..2c49e6146a 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java +++ b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java @@ -1,4 +1,4 @@ -package com.baeldung.reactive.controller; +package com.baeldung.reactive.model; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/spring-5-reactive-client/src/main/resources/application.properties b/spring-5-reactive-client/src/main/resources/application.properties new file mode 100644 index 0000000000..2d93456aeb --- /dev/null +++ b/spring-5-reactive-client/src/main/resources/application.properties @@ -0,0 +1,3 @@ +logging.level.root=INFO + +server.port=8081 \ No newline at end of file diff --git a/spring-5-reactive-client/src/main/resources/logback.xml b/spring-5-reactive-client/src/main/resources/logback.xml new file mode 100644 index 0000000000..8bbe8c1d67 --- /dev/null +++ b/spring-5-reactive-client/src/main/resources/logback.xml @@ -0,0 +1,16 @@ + + + + + # Pattern of log message for console appender + %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n + + + + + + + + + + \ No newline at end of file diff --git a/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml b/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000000..bfcf43dad2 --- /dev/null +++ b/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,21 @@ + + + + Spring Functional Application + + + functional + com.baeldung.functional.RootServlet + 1 + true + + + functional + / + + + + \ No newline at end of file diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java new file mode 100644 index 0000000000..394ff42e5f --- /dev/null +++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java @@ -0,0 +1,42 @@ +package com.baeldung.reactive; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; + +import com.baeldung.reactive.model.Foo; + +import reactor.core.publisher.Mono; + +@SpringBootTest +public class ReactiveIntegrationTest { + + private WebClient client; + + @BeforeEach + public void before() { + client = WebClient.create("http://localhost:8080"); + } + + // + + @Test + public void whenMonoReactiveEndpointIsConsumed_thenCorrectOutput() { + final Mono fooMono = client.get().uri("/foos/123").exchange().log(); + + System.out.println(fooMono.subscribe()); + } + + @Test + public void whenFluxReactiveEndpointIsConsumed_thenCorrectOutput() throws InterruptedException { + client.get().uri("/foos") + .retrieve() + .bodyToFlux(Foo.class).log() + .subscribe(System.out::println); + + System.out.println(); + } + +} diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java new file mode 100644 index 0000000000..c884ace323 --- /dev/null +++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java @@ -0,0 +1,35 @@ +package com.baeldung.reactive; + +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.web.reactive.function.client.WebClient; + +import com.baeldung.reactive.model.Foo; + +@SpringBootApplication +public class Spring5ReactiveTestApplication { + + @Bean + public WebClient client() { + return WebClient.create("http://localhost:8080"); + } + + @Bean + CommandLineRunner cmd(WebClient client) { + return args -> { + client.get().uri("/foos2") + .retrieve() + .bodyToFlux(Foo.class).log() + .subscribe(System.out::println); + }; + } + + // + + public static void main(String[] args) { + SpringApplication.run(Spring5ReactiveTestApplication.class, args); + } + +} diff --git a/spring-5-reactive-client/src/test/resources/logback-test.xml b/spring-5-reactive-client/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..8bbe8c1d67 --- /dev/null +++ b/spring-5-reactive-client/src/test/resources/logback-test.xml @@ -0,0 +1,16 @@ + + + + + # Pattern of log message for console appender + %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n + + + + + + + + + + \ No newline at end of file diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java index 1115036ad3..933d469f65 100644 --- a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java @@ -3,13 +3,19 @@ package com.baeldung.reactive.controller; import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import java.time.Duration; +import java.util.Random; +import java.util.stream.Stream; +import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; +import com.baeldung.reactive.model.Foo; + import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; +import reactor.util.function.Tuple2; @RestController public class FooReactiveController { @@ -19,11 +25,18 @@ public class FooReactiveController { return Mono.just(new Foo(id, randomAlphabetic(6))); } - @GetMapping("/foos") + @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/foos") + public Flux getAllFoos2() { + final Flux foosFlux = Flux.fromStream(Stream.generate(() -> new Foo(new Random().nextLong(), randomAlphabetic(6)))); + final Flux emmitFlux = Flux.interval(Duration.ofSeconds(1)); + return Flux.zip(foosFlux, emmitFlux).map(Tuple2::getT1); + } + + @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/foos2") public Flux getAllFoos() { final Flux flux = Flux. create(fluxSink -> { while (true) { - fluxSink.next(new Foo(System.currentTimeMillis(), randomAlphabetic(6))); + fluxSink.next(new Foo(new Random().nextLong(), randomAlphabetic(6))); } }).sample(Duration.ofSeconds(1)).log(); diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java new file mode 100644 index 0000000000..2c49e6146a --- /dev/null +++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java @@ -0,0 +1,13 @@ +package com.baeldung.reactive.model; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@AllArgsConstructor +@Data +public class Foo { + + private long id; + private String name; + +} diff --git a/spring-5-reactive/src/main/resources/files/hello.txt b/spring-5-reactive/src/main/resources/files/hello.txt deleted file mode 100644 index b6fc4c620b..0000000000 --- a/spring-5-reactive/src/main/resources/files/hello.txt +++ /dev/null @@ -1 +0,0 @@ -hello \ No newline at end of file diff --git a/spring-5-reactive/src/main/resources/files/test/test.txt b/spring-5-reactive/src/main/resources/files/test/test.txt deleted file mode 100644 index 30d74d2584..0000000000 --- a/spring-5-reactive/src/main/resources/files/test/test.txt +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java index 5499e72877..bad5fc5f22 100644 --- a/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java +++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java @@ -4,10 +4,11 @@ import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic; import static org.junit.Assert.assertNotNull; import java.time.Duration; +import java.util.Random; import org.junit.jupiter.api.Test; -import com.baeldung.reactive.controller.Foo; +import com.baeldung.reactive.model.Foo; import reactor.core.publisher.Flux; @@ -17,7 +18,7 @@ public class FluxUnitTest { public void whenFluxIsConstructed_thenCorrect() { final Flux flux = Flux. create(fluxSink -> { while (true) { - fluxSink.next(new Foo(System.currentTimeMillis(), randomAlphabetic(6))); + fluxSink.next(new Foo(new Random().nextLong(), randomAlphabetic(6))); } }).sample(Duration.ofSeconds(1)).log();