Merge pull request #11581 from chaos2418/JAVA-3060

JAVA-3060: adding new spring-reactive module for the ebook.
This commit is contained in:
kwoyke 2022-01-09 13:48:23 +01:00 committed by GitHub
commit 122ed65b1e
79 changed files with 528 additions and 501 deletions

View File

@ -557,7 +557,6 @@
<module>atomikos</module> <module>atomikos</module>
<module>reactive-systems</module> <module>reactive-systems</module>
<module>slack</module> <module>slack</module>
<module>spring-webflux-threads</module>
</modules> </modules>
</profile> </profile>
@ -620,6 +619,7 @@
<module>spring-5-reactive-security</module> <module>spring-5-reactive-security</module>
<module>spring-5-webflux</module> <module>spring-5-webflux</module>
<module>spring-5-webflux-2</module> <module>spring-5-webflux-2</module>
<module>spring-reactive</module>
<module>spring-activiti</module> <module>spring-activiti</module>
<module>spring-akka</module> <module>spring-akka</module>
@ -1039,7 +1039,6 @@
<module>atomikos</module> <module>atomikos</module>
<module>reactive-systems</module> <module>reactive-systems</module>
<module>slack</module> <module>slack</module>
<module>spring-webflux-threads</module>
</modules> </modules>
</profile> </profile>
@ -1093,6 +1092,7 @@
<module>spring-5-reactive-oauth</module> <module>spring-5-reactive-oauth</module>
<module>spring-5-reactive-security</module> <module>spring-5-reactive-security</module>
<module>spring-5-webflux</module> <module>spring-5-webflux</module>
<module>spring-reactive</module>
<module>spring-activiti</module> <module>spring-activiti</module>
<module>spring-akka</module> <module>spring-akka</module>

View File

@ -4,7 +4,6 @@ This module contains articles about Reactor Core.
### Relevant articles ### Relevant articles
- [Intro To Reactor Core](https://www.baeldung.com/reactor-core)
- [Combining Publishers in Project Reactor](https://www.baeldung.com/reactor-combine-streams) - [Combining Publishers in Project Reactor](https://www.baeldung.com/reactor-combine-streams)
- [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor) - [Programmatically Creating Sequences with Project Reactor](https://www.baeldung.com/flux-sequences-reactor)
- [How to Extract a Monos Content in Java](https://www.baeldung.com/java-string-from-mono) - [How to Extract a Monos Content in Java](https://www.baeldung.com/java-string-from-mono)

View File

@ -2,10 +2,8 @@
This module contains articles about reactive Spring 5. This module contains articles about reactive Spring 5.
- [Spring WebClient vs. RestTemplate](https://www.baeldung.com/spring-webclient-resttemplate)
- [Validation for Functional Endpoints in Spring 5](https://www.baeldung.com/spring-functional-endpoints-validation) - [Validation for Functional Endpoints in Spring 5](https://www.baeldung.com/spring-functional-endpoints-validation)
- [Testing Reactive Streams Using StepVerifier and TestPublisher](https://www.baeldung.com/reactive-streams-step-verifier-test-publisher) - [Testing Reactive Streams Using StepVerifier and TestPublisher](https://www.baeldung.com/reactive-streams-step-verifier-test-publisher)
- [Debugging Reactive Streams in Java](https://www.baeldung.com/spring-debugging-reactive-streams)
- [Static Content in Spring WebFlux](https://www.baeldung.com/spring-webflux-static-content) - [Static Content in Spring WebFlux](https://www.baeldung.com/spring-webflux-static-content)
- [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events) - [Server-Sent Events in Spring](https://www.baeldung.com/spring-server-sent-events)
- [Backpressure Mechanism in Spring WebFlux](https://www.baeldung.com/spring-webflux-backpressure) - [Backpressure Mechanism in Spring WebFlux](https://www.baeldung.com/spring-webflux-backpressure)

View File

@ -8,8 +8,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles ### Relevant Articles
- [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators) - [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators)
- [Spring Security 5 for Reactive Applications](https://www.baeldung.com/spring-security-5-reactive)
- [Guide to Spring 5 WebFlux](https://www.baeldung.com/spring-webflux)
- [Introduction to the Functional Web Framework in Spring 5](https://www.baeldung.com/spring-5-functional-web)
- [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver) - [Guide to the AuthenticationManagerResolver in Spring Security](https://www.baeldung.com/spring-security-authenticationmanagerresolver)
- [Spring Webflux and CORS](https://www.baeldung.com/spring-webflux-cors) - [Spring Webflux and CORS](https://www.baeldung.com/spring-webflux-cors)

View File

@ -110,7 +110,7 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<configuration> <configuration>
<mainClass>com.baeldung.webflux.EmployeeSpringApplication</mainClass> <mainClass>com.baeldung.reactive.actuator.Spring5ReactiveApplication</mainClass>
<layout>JAR</layout> <layout>JAR</layout>
</configuration> </configuration>
</plugin> </plugin>

View File

@ -1,64 +0,0 @@
package com.baeldung.webflux;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Repository
public class EmployeeRepository {
static Map<String,Employee> employeeData;
static Map<String,String> employeeAccessData;
static
{
employeeData = new HashMap<>();
employeeData.put("1",new Employee("1","Employee 1"));
employeeData.put("2",new Employee("2","Employee 2"));
employeeData.put("3",new Employee("3","Employee 3"));
employeeData.put("4",new Employee("4","Employee 4"));
employeeData.put("5",new Employee("5","Employee 5"));
employeeData.put("6",new Employee("6","Employee 6"));
employeeData.put("7",new Employee("7","Employee 7"));
employeeData.put("8",new Employee("8","Employee 8"));
employeeData.put("9",new Employee("9","Employee 9"));
employeeData.put("10",new Employee("10","Employee 10"));
employeeAccessData=new HashMap<>();
employeeAccessData.put("1", "Employee 1 Access Key");
employeeAccessData.put("2", "Employee 2 Access Key");
employeeAccessData.put("3", "Employee 3 Access Key");
employeeAccessData.put("4", "Employee 4 Access Key");
employeeAccessData.put("5", "Employee 5 Access Key");
employeeAccessData.put("6", "Employee 6 Access Key");
employeeAccessData.put("7", "Employee 7 Access Key");
employeeAccessData.put("8", "Employee 8 Access Key");
employeeAccessData.put("9", "Employee 9 Access Key");
employeeAccessData.put("10", "Employee 10 Access Key");
}
public Mono<Employee> findEmployeeById(String id)
{
return Mono.just(employeeData.get(id));
}
public Flux<Employee> findAllEmployees()
{
return Flux.fromIterable(employeeData.values());
}
public Mono<Employee> updateEmployee(Employee employee)
{
Employee existingEmployee=employeeData.get(employee.getId());
if(existingEmployee!=null)
{
existingEmployee.setName(employee.getName());
}
return Mono.just(existingEmployee);
}
}

View File

@ -1,14 +1,13 @@
package com.baeldung; package com.baeldung;
import com.baeldung.reactive.actuator.Spring5ReactiveApplication;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.reactive.security.SpringSecurity5Application;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringSecurity5Application.class) @SpringBootTest(classes = Spring5ReactiveApplication.class)
public class SpringContextTest { public class SpringContextTest {
@Test @Test

View File

@ -7,11 +7,9 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring
### Relevant Articles ### Relevant Articles
- [Spring 5 WebClient](https://www.baeldung.com/spring-5-webclient)
- [Exploring the Spring 5 WebFlux URL Matching](https://www.baeldung.com/spring-5-mvc-url-matching) - [Exploring the Spring 5 WebFlux URL Matching](https://www.baeldung.com/spring-5-mvc-url-matching)
- [Reactive WebSockets with Spring 5](https://www.baeldung.com/spring-5-reactive-websockets) - [Reactive WebSockets with Spring 5](https://www.baeldung.com/spring-5-reactive-websockets)
- [Spring Webflux Filters](https://www.baeldung.com/spring-webflux-filters) - [Spring Webflux Filters](https://www.baeldung.com/spring-webflux-filters)
- [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header) - [How to Set a Header on a Response with Spring 5](https://www.baeldung.com/spring-response-header)
- [Handling Errors in Spring WebFlux](https://www.baeldung.com/spring-webflux-errors)
- [A Guide to Spring Session Reactive Support: WebSession](https://www.baeldung.com/spring-session-reactive) - [A Guide to Spring Session Reactive Support: WebSession](https://www.baeldung.com/spring-session-reactive)
- More articles: [[next -->]](/spring-5-reactive-2) - More articles: [[next -->]](/spring-5-reactive-2)

View File

@ -1,28 +0,0 @@
package com.baeldung.web.reactive;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Task {
private final String name;
private final int id;
public Task(@JsonProperty("name") String name, @JsonProperty("id") int id) {
this.name = name;
this.id = id;
}
public String getName() {
return this.name;
}
public int getId() {
return this.id;
}
@Override
public String toString() {
return "Task{" + "name='" + name + '\'' + ", id=" + id + '}';
}
}

View File

@ -6,7 +6,6 @@ This module contains articles about Spring 5 WebFlux
- [Spring Boot Reactor Netty Configuration](https://www.baeldung.com/spring-boot-reactor-netty) - [Spring Boot Reactor Netty Configuration](https://www.baeldung.com/spring-boot-reactor-netty)
- [How to Return 404 with Spring WebFlux](https://www.baeldung.com/spring-webflux-404) - [How to Return 404 with Spring WebFlux](https://www.baeldung.com/spring-webflux-404)
- [Spring WebClient Requests with Parameters](https://www.baeldung.com/webflux-webclient-parameters)
- [RSocket Using Spring Boot](https://www.baeldung.com/spring-boot-rsocket) - [RSocket Using Spring Boot](https://www.baeldung.com/spring-boot-rsocket)
- [Spring MVC Async vs Spring WebFlux](https://www.baeldung.com/spring-mvc-async-vs-webflux) - [Spring MVC Async vs Spring WebFlux](https://www.baeldung.com/spring-mvc-async-vs-webflux)
- [Set a Timeout in Spring 5 Webflux WebClient](https://www.baeldung.com/spring-webflux-timeout) - [Set a Timeout in Spring 5 Webflux WebClient](https://www.baeldung.com/spring-webflux-timeout)

16
spring-reactive/README.md Normal file
View File

@ -0,0 +1,16 @@
## Spring Reactive
This module contains articles describing reactive processing in Spring.
## Relevant articles:
- [Intro To Reactor Core](https://www.baeldung.com/reactor-core)
- [Debugging Reactive Streams in Java](https://www.baeldung.com/spring-debugging-reactive-streams)
- [Guide to Spring 5 WebFlux](https://www.baeldung.com/spring-webflux)
- [Introduction to the Functional Web Framework in Spring 5](https://www.baeldung.com/spring-5-functional-web)
- [Spring 5 WebClient](https://www.baeldung.com/spring-5-webclient)
- [Spring WebClient vs. RestTemplate](https://www.baeldung.com/spring-webclient-resttemplate)
- [Spring WebClient Requests with Parameters](https://www.baeldung.com/webflux-webclient-parameters)
- [Handling Errors in Spring WebFlux](https://www.baeldung.com/spring-webflux-errors)
- [Spring Security 5 for Reactive Applications](https://www.baeldung.com/spring-security-5-reactive)
- [Concurrency in Spring WebFlux](https://www.baeldung.com/spring-webflux-concurrency)

103
spring-reactive/pom.xml Normal file
View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<artifactId>spring-reactive</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>${rxjava.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor.kafka</groupId>
<artifactId>reactor-kafka</artifactId>
<version>${reactor-kafka.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>${reactor.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>integration-lite-first</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<logback.configurationFile>${project.basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>integration-lite-second</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<logback.configurationFile>${project.basedir}/src/test/resources/logback-test.xml</logback.configurationFile>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<properties>
<reactor.version>3.4.12</reactor.version>
<reactor-kafka.version>1.2.2.RELEASE</reactor-kafka.version>
<rxjava.version>2.2.19</rxjava.version>
</properties>
</project>

View File

@ -1,4 +1,4 @@
package com.baeldung.webflux; package com.baeldung.reactive.concurrency;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,12 +1,6 @@
package com.baeldung.webflux; package com.baeldung.reactive.concurrency;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import io.reactivex.Observable;
import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.clients.producer.ProducerRecord;
@ -21,8 +15,6 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import io.reactivex.Observable;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler; import reactor.core.scheduler.Scheduler;
@ -34,6 +26,13 @@ import reactor.kafka.sender.KafkaSender;
import reactor.kafka.sender.SenderOptions; import reactor.kafka.sender.SenderOptions;
import reactor.kafka.sender.SenderRecord; import reactor.kafka.sender.SenderRecord;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@RestController @RestController
@RequestMapping("/") @RequestMapping("/")
public class Controller { public class Controller {

View File

@ -1,4 +1,4 @@
package com.baeldung.webflux; package com.baeldung.reactive.concurrency;
import org.springframework.data.annotation.Id; import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;

View File

@ -1,4 +1,4 @@
package com.baeldung.webflux; package com.baeldung.reactive.concurrency;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.data.mongodb.repository.ReactiveMongoRepository;

View File

@ -1,6 +1,4 @@
package com.baeldung.debugging.consumer; package com.baeldung.reactive.debugging.consumer;
import java.util.Collections;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -9,9 +7,10 @@ import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.SecurityWebFilterChain;
import reactor.core.publisher.Hooks; import reactor.core.publisher.Hooks;
import java.util.Collections;
@SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class) @SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class)
@EnableScheduling @EnableScheduling
public class ConsumerDebuggingApplication { public class ConsumerDebuggingApplication {

View File

@ -1,8 +1,8 @@
package com.baeldung.debugging.consumer.chronjobs; package com.baeldung.reactive.debugging.consumer.chronjobs;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import com.baeldung.reactive.debugging.consumer.model.FooDto;
import com.baeldung.reactive.debugging.consumer.service.FooService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -10,13 +10,11 @@ import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import com.baeldung.debugging.consumer.model.Foo;
import com.baeldung.debugging.consumer.model.FooDto;
import com.baeldung.debugging.consumer.service.FooService;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
@Component @Component
public class ChronJobs { public class ChronJobs {

View File

@ -1,8 +1,7 @@
package com.baeldung.debugging.consumer.controllers; package com.baeldung.reactive.debugging.consumer.controllers;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Hooks; import reactor.core.publisher.Hooks;
@RestController @RestController

View File

@ -1,12 +1,12 @@
package com.baeldung.debugging.consumer.model; package com.baeldung.reactive.debugging.consumer.model;
import java.util.concurrent.ThreadLocalRandom;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import java.util.concurrent.ThreadLocalRandom;
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor

View File

@ -1,4 +1,4 @@
package com.baeldung.debugging.consumer.model; package com.baeldung.reactive.debugging.consumer.model;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;

View File

@ -1,11 +1,10 @@
package com.baeldung.debugging.consumer.service; package com.baeldung.reactive.debugging.consumer.service;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
public class FooNameHelper { public class FooNameHelper {
public static Flux<Foo> concatAndSubstringFooName(Flux<Foo> flux) { public static Flux<Foo> concatAndSubstringFooName(Flux<Foo> flux) {

View File

@ -1,11 +1,10 @@
package com.baeldung.debugging.consumer.service; package com.baeldung.reactive.debugging.consumer.service;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
public class FooQuantityHelper { public class FooQuantityHelper {
public static Flux<Foo> processFooReducingQuantity(Flux<Foo> flux) { public static Flux<Foo> processFooReducingQuantity(Flux<Foo> flux) {

View File

@ -1,10 +1,8 @@
package com.baeldung.debugging.consumer.service; package com.baeldung.reactive.debugging.consumer.service;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
public class FooReporter { public class FooReporter {

View File

@ -1,20 +1,18 @@
package com.baeldung.debugging.consumer.service; package com.baeldung.reactive.debugging.consumer.service;
import static com.baeldung.debugging.consumer.service.FooNameHelper.concatAndSubstringFooName;
import static com.baeldung.debugging.consumer.service.FooNameHelper.substringFooName;
import static com.baeldung.debugging.consumer.service.FooQuantityHelper.divideFooQuantity;
import static com.baeldung.debugging.consumer.service.FooQuantityHelper.processFooReducingQuantity;
import static com.baeldung.debugging.consumer.service.FooReporter.reportResult;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers; import reactor.core.scheduler.Schedulers;
import static com.baeldung.reactive.debugging.consumer.service.FooNameHelper.concatAndSubstringFooName;
import static com.baeldung.reactive.debugging.consumer.service.FooNameHelper.substringFooName;
import static com.baeldung.reactive.debugging.consumer.service.FooQuantityHelper.divideFooQuantity;
import static com.baeldung.reactive.debugging.consumer.service.FooQuantityHelper.processFooReducingQuantity;
import static com.baeldung.reactive.debugging.consumer.service.FooReporter.reportResult;
@Component @Component
public class FooService { public class FooService {

View File

@ -1,6 +1,4 @@
package com.baeldung.debugging.server; package com.baeldung.reactive.debugging.server;
import java.util.Collections;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -9,6 +7,8 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.EnableWebFlux;
import java.util.Collections;
@EnableWebFlux @EnableWebFlux
@SpringBootApplication @SpringBootApplication
public class ServerDebuggingApplication { public class ServerDebuggingApplication {

View File

@ -1,20 +1,18 @@
package com.baeldung.debugging.server.handlers; package com.baeldung.reactive.debugging.server.handlers;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
import com.baeldung.reactive.debugging.server.model.Foo;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import com.baeldung.debugging.server.model.Foo;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
@Component @Component
public class ServerHandler { public class ServerHandler {

View File

@ -1,4 +1,4 @@
package com.baeldung.debugging.server.model; package com.baeldung.reactive.debugging.server.model;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

View File

@ -1,5 +1,6 @@
package com.baeldung.debugging.server.routers; package com.baeldung.reactive.debugging.server.routers;
import com.baeldung.reactive.debugging.server.handlers.ServerHandler;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -8,8 +9,6 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import com.baeldung.debugging.server.handlers.ServerHandler;
@Configuration @Configuration
public class ServerRouter { public class ServerRouter {

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient; package com.baeldung.reactive.errorhandling;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -7,16 +7,17 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.SecurityWebFilterChain;
@SpringBootApplication @SpringBootApplication
public class WebClientApplication { public class ErrorHandlingApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(WebClientApplication.class, args); SpringApplication.run(ErrorHandlingApplication.class, args);
} }
@Bean @Bean
public SecurityWebFilterChain functionalValidationsSpringSecurityFilterChain(ServerHttpSecurity http) { public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange() http.authorizeExchange()
.anyExchange() .anyExchange()
.permitAll(); .permitAll();
http.csrf().disable(); http.csrf().disable();
return http.build(); return http.build();
} }

View File

@ -1,14 +1,13 @@
package com.baeldung.reactive.errorhandling; package com.baeldung.reactive.errorhandling;
import java.util.Map;
import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes; import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import java.util.Map;
@Component @Component
public class GlobalErrorAttributes extends DefaultErrorAttributes{ public class GlobalErrorAttributes extends DefaultErrorAttributes{

View File

@ -1,8 +1,5 @@
package com.baeldung.reactive.errorhandling; package com.baeldung.reactive.errorhandling;
import java.util.Map;
import org.springframework.boot.autoconfigure.web.WebProperties; import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler; import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions;
@ -19,14 +16,15 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.util.Map;
@Component @Component
@Order(-2) @Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext, public GlobalErrorWebExceptionHandler(GlobalErrorAttributes g, ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) { ServerCodecConfigurer serverCodecConfigurer) {
super(g, new WebProperties.Resources(), applicationContext); super(g, new WebProperties.Resources(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters()); super.setMessageWriters(serverCodecConfigurer.getWriters());

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling; package com.baeldung.reactive.errorhandling;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.handlers; package com.baeldung.reactive.errorhandling.handlers;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.handlers; package com.baeldung.reactive.errorhandling.handlers;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.handlers; package com.baeldung.reactive.errorhandling.handlers;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.handlers; package com.baeldung.reactive.errorhandling.handlers;
import com.baeldung.reactive.errorhandling.NameRequiredException; import com.baeldung.reactive.errorhandling.NameRequiredException;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.handlers; package com.baeldung.reactive.errorhandling.handlers;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.routers; package com.baeldung.reactive.errorhandling.routers;
import com.baeldung.reactive.errorhandling.handlers.Handler1; import com.baeldung.reactive.errorhandling.handlers.Handler1;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.routers; package com.baeldung.reactive.errorhandling.routers;
import com.baeldung.reactive.errorhandling.handlers.Handler2; import com.baeldung.reactive.errorhandling.handlers.Handler2;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.routers; package com.baeldung.reactive.errorhandling.routers;
import com.baeldung.reactive.errorhandling.handlers.Handler3; import com.baeldung.reactive.errorhandling.handlers.Handler3;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.routers; package com.baeldung.reactive.errorhandling.routers;
import com.baeldung.reactive.errorhandling.handlers.Handler4; import com.baeldung.reactive.errorhandling.handlers.Handler4;

View File

@ -1,4 +1,3 @@
package com.baeldung.reactive.errorhandling.routers; package com.baeldung.reactive.errorhandling.routers;
import com.baeldung.reactive.errorhandling.handlers.Handler5; import com.baeldung.reactive.errorhandling.handlers.Handler5;

View File

@ -1,6 +1,5 @@
package com.baeldung.reactive.security; package com.baeldung.reactive.security;
import org.springframework.boot.actuate.autoconfigure.security.reactive.EndpointRequest;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
@ -12,8 +11,6 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain; import org.springframework.security.web.server.SecurityWebFilterChain;
import com.baeldung.reactive.actuator.FeaturesEndpoint;
@EnableWebFluxSecurity @EnableWebFluxSecurity
@EnableReactiveMethodSecurity @EnableReactiveMethodSecurity
public class SecurityConfig { public class SecurityConfig {
@ -23,8 +20,6 @@ public class SecurityConfig {
return http.authorizeExchange() return http.authorizeExchange()
.pathMatchers("/admin") .pathMatchers("/admin")
.hasAuthority("ROLE_ADMIN") .hasAuthority("ROLE_ADMIN")
.matchers(EndpointRequest.to(FeaturesEndpoint.class))
.permitAll()
.anyExchange() .anyExchange()
.authenticated() .authenticated()
.and() .and()

View File

@ -8,7 +8,6 @@ import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter; import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import reactor.netty.DisposableServer; import reactor.netty.DisposableServer;
import reactor.netty.http.server.HttpServer; import reactor.netty.http.server.HttpServer;

View File

@ -1,4 +1,4 @@
package com.baeldung.web.reactive.client; package com.baeldung.reactive.webclient;
public class Foo { public class Foo {

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient; package com.baeldung.reactive.webclient;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient; package com.baeldung.reactive.webclient;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -1,4 +1,4 @@
package com.baeldung.web.reactive.client; package com.baeldung.reactive.webclient;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -1,7 +1,4 @@
package com.baeldung.web.reactive.client; package com.baeldung.reactive.webclient;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -11,9 +8,11 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@RestController @RestController
public class WebClientController { public class WebClientController {
@ -37,6 +36,6 @@ public class WebClientController {
@PostMapping(value = "/resource-multipart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/resource-multipart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String handleFormUpload(@RequestPart("key1") String value1, @RequestPart("key2") String value2) { public String handleFormUpload(@RequestPart("key1") String value1, @RequestPart("key2") String value2) {
return "processed-" + value1 + "-" + value2; return "processed-" + value1 + '-' + value2;
} }
} }

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient; package com.baeldung.reactive.webclient;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -1,4 +1,4 @@
package com.baeldung.spring.webclientrequests; package com.baeldung.reactive.webclientrequests;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;

View File

@ -0,0 +1,17 @@
package com.baeldung.reactive.webflux;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
private String id;
private String name;
// standard getters and setters
}

View File

@ -0,0 +1,59 @@
package com.baeldung.reactive.webflux;
import com.baeldung.reactive.webflux.Employee;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Repository
public class EmployeeRepository {
static Map<String, Employee> employeeData;
static Map<String, String> employeeAccessData;
static {
employeeData = new HashMap<>();
employeeData.put("1", new Employee("1", "Employee 1"));
employeeData.put("2", new Employee("2", "Employee 2"));
employeeData.put("3", new Employee("3", "Employee 3"));
employeeData.put("4", new Employee("4", "Employee 4"));
employeeData.put("5", new Employee("5", "Employee 5"));
employeeData.put("6", new Employee("6", "Employee 6"));
employeeData.put("7", new Employee("7", "Employee 7"));
employeeData.put("8", new Employee("8", "Employee 8"));
employeeData.put("9", new Employee("9", "Employee 9"));
employeeData.put("10", new Employee("10", "Employee 10"));
employeeAccessData = new HashMap<>();
employeeAccessData.put("1", "Employee 1 Access Key");
employeeAccessData.put("2", "Employee 2 Access Key");
employeeAccessData.put("3", "Employee 3 Access Key");
employeeAccessData.put("4", "Employee 4 Access Key");
employeeAccessData.put("5", "Employee 5 Access Key");
employeeAccessData.put("6", "Employee 6 Access Key");
employeeAccessData.put("7", "Employee 7 Access Key");
employeeAccessData.put("8", "Employee 8 Access Key");
employeeAccessData.put("9", "Employee 9 Access Key");
employeeAccessData.put("10", "Employee 10 Access Key");
}
public Mono<Employee> findEmployeeById(String id) {
return Mono.just(employeeData.get(id));
}
public Flux<Employee> findAllEmployees() {
return Flux.fromIterable(employeeData.values());
}
public Mono<Employee> updateEmployee(Employee employee) {
Employee existingEmployee = employeeData.get(employee.getId());
if (existingEmployee != null) {
existingEmployee.setName(employee.getName());
}
return Mono.just(existingEmployee);
}
}

View File

@ -1,12 +1,13 @@
package com.baeldung.webflux; package com.baeldung.reactive.webflux.annotation;
import com.baeldung.reactive.webflux.Employee;
import com.baeldung.reactive.webflux.EmployeeRepository;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -14,7 +15,7 @@ import reactor.core.publisher.Mono;
@RequestMapping("/employees") @RequestMapping("/employees")
public class EmployeeController { public class EmployeeController {
private EmployeeRepository employeeRepository; private final EmployeeRepository employeeRepository;
public EmployeeController(EmployeeRepository employeeRepository) { public EmployeeController(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository; this.employeeRepository = employeeRepository;

View File

@ -1,4 +1,4 @@
package com.baeldung.webflux; package com.baeldung.reactive.webflux.annotation;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -7,7 +7,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
public class EmployeeSpringApplication { public class EmployeeSpringApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(EmployeeSpringApplication.class, args); SpringApplication.run(EmployeeSpringApplication.class, args);
EmployeeWebClient employeeWebClient = new EmployeeWebClient(); EmployeeWebClient employeeWebClient = new EmployeeWebClient();

View File

@ -1,12 +1,16 @@
package com.baeldung.webflux; package com.baeldung.reactive.webflux.annotation;
import com.baeldung.reactive.webflux.Employee;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
public class EmployeeWebClient { public class EmployeeWebClient {
private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeWebClient.class);
WebClient client = WebClient.create("http://localhost:8080"); WebClient client = WebClient.create("http://localhost:8080");
public void consume() { public void consume() {
@ -16,13 +20,13 @@ public class EmployeeWebClient {
.retrieve() .retrieve()
.bodyToMono(Employee.class); .bodyToMono(Employee.class);
employeeMono.subscribe(System.out::println); employeeMono.subscribe(employee -> LOGGER.debug("Employee: {}", employee));
Flux<Employee> employeeFlux = client.get() Flux<Employee> employeeFlux = client.get()
.uri("/employees") .uri("/employees")
.retrieve() .retrieve()
.bodyToFlux(Employee.class); .bodyToFlux(Employee.class);
employeeFlux.subscribe(System.out::println); employeeFlux.subscribe(employee -> LOGGER.debug("Employee: {}", employee));
} }
} }

View File

@ -0,0 +1,45 @@
package com.baeldung.reactive.webflux.annotation;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.server.SecurityWebFilterChain;
@EnableWebFluxSecurity
public class EmployeeWebSecurityConfig {
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User
.withUsername("admin")
.password(passwordEncoder().encode("password"))
.roles("ADMIN")
.build();
return new MapReactiveUserDetailsService(user);
}
@Bean
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
http.csrf()
.disable()
.authorizeExchange()
.pathMatchers(HttpMethod.POST, "/employees/update")
.hasRole("ADMIN")
.pathMatchers("/**")
.permitAll()
.and()
.httpBasic();
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}

View File

@ -1,75 +1,74 @@
package com.baeldung.reactive.functional; package com.baeldung.reactive.webflux.functional;
import static org.springframework.web.reactive.function.BodyExtractors.toMono; import com.baeldung.reactive.webflux.Employee;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import com.baeldung.reactive.webflux.EmployeeRepository;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST; import org.springframework.context.annotation.Bean;
import static org.springframework.web.reactive.function.server.RouterFunctions.route; import org.springframework.context.annotation.Configuration;
import static org.springframework.web.reactive.function.server.ServerResponse.ok; import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.context.annotation.Bean; import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain; import static org.springframework.web.reactive.function.BodyExtractors.toMono;
import org.springframework.web.reactive.function.server.RouterFunction; import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import org.springframework.web.reactive.function.server.ServerResponse; import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import com.baeldung.webflux.Employee; import static org.springframework.web.reactive.function.server.ServerResponse.ok;
import com.baeldung.webflux.EmployeeRepository;
@Configuration
@Configuration public class EmployeeFunctionalConfig {
public class EmployeeFunctionalConfig {
@Bean
@Bean EmployeeRepository employeeRepository() {
EmployeeRepository employeeRepository() { return new EmployeeRepository();
return new EmployeeRepository(); }
}
@Bean
@Bean RouterFunction<ServerResponse> getAllEmployeesRoute() {
RouterFunction<ServerResponse> getAllEmployeesRoute() { return route(GET("/employees"),
return route(GET("/employees"), req -> ok().body(
req -> ok().body( employeeRepository().findAllEmployees(), Employee.class));
employeeRepository().findAllEmployees(), Employee.class)); }
}
@Bean
@Bean RouterFunction<ServerResponse> getEmployeeByIdRoute() {
RouterFunction<ServerResponse> getEmployeeByIdRoute() { return route(GET("/employees/{id}"),
return route(GET("/employees/{id}"), req -> ok().body(
req -> ok().body( employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class));
employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); }
}
@Bean
@Bean RouterFunction<ServerResponse> updateEmployeeRoute() {
RouterFunction<ServerResponse> updateEmployeeRoute() { return route(POST("/employees/update"),
return route(POST("/employees/update"), req -> req.body(toMono(Employee.class))
req -> req.body(toMono(Employee.class)) .doOnNext(employeeRepository()::updateEmployee)
.doOnNext(employeeRepository()::updateEmployee) .then(ok().build()));
.then(ok().build())); }
}
@Bean
@Bean RouterFunction<ServerResponse> composedRoutes() {
RouterFunction<ServerResponse> composedRoutes() { return
return route(GET("/employees"),
route(GET("/employees"), req -> ok().body(
req -> ok().body( employeeRepository().findAllEmployees(), Employee.class))
employeeRepository().findAllEmployees(), Employee.class))
.and(route(GET("/employees/{id}"),
.and(route(GET("/employees/{id}"), req -> ok().body(
req -> ok().body( employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)))
employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)))
.and(route(POST("/employees/update"),
.and(route(POST("/employees/update"), req -> req.body(toMono(Employee.class))
req -> req.body(toMono(Employee.class)) .doOnNext(employeeRepository()::updateEmployee)
.doOnNext(employeeRepository()::updateEmployee) .then(ok().build())));
.then(ok().build()))); }
}
@Bean
@Bean public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { http.csrf()
http.csrf() .disable()
.disable() .authorizeExchange()
.authorizeExchange() .anyExchange()
.anyExchange() .permitAll();
.permitAll(); return http.build();
return http.build(); }
} }
}

View File

@ -1,13 +1,13 @@
package com.baeldung.reactive.functional; package com.baeldung.reactive.webflux.functional;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication @SpringBootApplication
public class EmployeeSpringFunctionalApplication { public class EmployeeSpringFunctionalApplication {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(EmployeeSpringFunctionalApplication.class, args); SpringApplication.run(EmployeeSpringFunctionalApplication.class, args);
} }
} }

View File

@ -1,4 +1,4 @@
package com.baeldung.debugging.consumer; package com.baeldung.reactive.debugging.consumer;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
@ -8,13 +8,12 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import com.baeldung.reactive.debugging.consumer.service.FooService;
import com.baeldung.reactive.debugging.consumer.utils.ListAppender;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import com.baeldung.debugging.consumer.model.Foo;
import com.baeldung.debugging.consumer.service.FooService;
import com.baeldung.debugging.consumer.utils.ListAppender;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.classic.spi.IThrowableProxy;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
@ -39,26 +38,26 @@ public class ConsumerFooServiceIntegrationTest {
service.processFoo(flux); service.processFoo(flux);
Collection<String> allLoggedEntries = ListAppender.getEvents() Collection<String> allLoggedEntries = ListAppender.getEvents()
.stream() .stream()
.map(ILoggingEvent::getFormattedMessage) .map(ILoggingEvent::getFormattedMessage)
.collect(Collectors.toList()); .collect(Collectors.toList());
Collection<String> allSuppressedEntries = ListAppender.getEvents() Collection<String> allSuppressedEntries = ListAppender.getEvents()
.stream() .stream()
.map(ILoggingEvent::getThrowableProxy) .map(ILoggingEvent::getThrowableProxy)
.flatMap(t -> { .flatMap(t -> {
return Optional.ofNullable(t) return Optional.ofNullable(t)
.map(IThrowableProxy::getSuppressed) .map(IThrowableProxy::getSuppressed)
.map(Arrays::stream) .map(Arrays::stream)
.orElse(Stream.empty()); .orElse(Stream.empty());
}) })
.map(IThrowableProxy::getClassName) .map(IThrowableProxy::getClassName)
.collect(Collectors.toList()); .collect(Collectors.toList());
assertThat(allLoggedEntries).anyMatch(entry -> entry.contains("The following error happened on processFoo method!")) assertThat(allLoggedEntries).anyMatch(entry -> entry.contains("The following error happened on processFoo method!"))
.anyMatch(entry -> entry.contains("| onSubscribe")) .anyMatch(entry -> entry.contains("| onSubscribe"))
.anyMatch(entry -> entry.contains("| cancel()")); .anyMatch(entry -> entry.contains("| cancel()"));
assertThat(allSuppressedEntries) assertThat(allSuppressedEntries)
.anyMatch(entry -> entry.contains("reactor.core.publisher.FluxOnAssembly$OnAssemblyException")); .anyMatch(entry -> entry.contains("reactor.core.publisher.FluxOnAssembly$OnAssemblyException"));
} }
} }

View File

@ -1,16 +1,15 @@
package com.baeldung.debugging.consumer; package com.baeldung.reactive.debugging.consumer;
import com.baeldung.reactive.debugging.consumer.service.FooService;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec; import org.springframework.test.web.reactive.server.WebTestClient.ResponseSpec;
import com.baeldung.debugging.consumer.service.FooService;
/** /**
* In order to run this live test, start the following classes: * In order to run this live test, start the following classes:
* - com.baeldung.debugging.server.ServerDebuggingApplication * - com.baeldung.reactive.debugging.server.ServerDebuggingApplication
* - com.baeldung.debugging.consumer.ConsumerDebuggingApplication * - com.baeldung.reactive.debugging.consumer.ConsumerDebuggingApplication
*/ */
public class ConsumerFooServiceLiveTest { public class ConsumerFooServiceLiveTest {

View File

@ -1,11 +1,11 @@
package com.baeldung.debugging.consumer.utils; package com.baeldung.reactive.debugging.consumer.utils;
import java.util.ArrayList;
import java.util.List;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.AppenderBase;
import java.util.ArrayList;
import java.util.List;
public class ListAppender extends AppenderBase<ILoggingEvent> { public class ListAppender extends AppenderBase<ILoggingEvent> {
static private List<ILoggingEvent> events = new ArrayList<>(); static private List<ILoggingEvent> events = new ArrayList<>();

View File

@ -1,9 +1,5 @@
package com.baeldung.reactive.errorhandling; package com.baeldung.reactive.errorhandling;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -16,6 +12,10 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext @DirtiesContext

View File

@ -1,8 +1,10 @@
package com.baeldung.reactor.introduction; package com.baeldung.reactive.introduction;
import org.junit.Test; import org.junit.Test;
import org.reactivestreams.Subscriber; import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription; import org.reactivestreams.Subscription;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.ConnectableFlux; import reactor.core.publisher.ConnectableFlux;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers; import reactor.core.scheduler.Schedulers;
@ -14,6 +16,8 @@ import static org.assertj.core.api.Assertions.assertThat;
public class ReactorIntegrationTest { public class ReactorIntegrationTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ReactorIntegrationTest.class);
@Test @Test
public void givenFlux_whenSubscribing_thenStream() { public void givenFlux_whenSubscribing_thenStream() {
@ -22,7 +26,7 @@ public class ReactorIntegrationTest {
Flux.just(1, 2, 3, 4) Flux.just(1, 2, 3, 4)
.log() .log()
.map(i -> { .map(i -> {
System.out.println(i + ":" + Thread.currentThread()); LOGGER.debug("{}:{}", i, Thread.currentThread());
return i * 2; return i * 2;
}) })
.subscribe(elements::add); .subscribe(elements::add);
@ -97,7 +101,8 @@ public class ReactorIntegrationTest {
Thread.sleep(1000); Thread.sleep(1000);
assertThat(threadNames).containsExactly("parallel-1", "parallel-1", "parallel-1", "parallel-1"); assertThat(threadNames).isNotEmpty();
assertThat(threadNames).hasSize(4);
} }
@Test @Test

View File

@ -1,19 +1,16 @@
package com.baeldung.security; package com.baeldung.reactive.security;
import org.junit.Before; import org.junit.jupiter.api.BeforeEach;
import org.junit.Ignore; import org.junit.jupiter.api.Test;
import org.junit.Test; import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.security.test.context.support.WithMockUser; import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import com.baeldung.reactive.security.SpringSecurity5Application; @ExtendWith(SpringExtension.class)
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = SpringSecurity5Application.class) @ContextConfiguration(classes = SpringSecurity5Application.class)
public class SecurityIntegrationTest { public class SecurityIntegrationTest {
@ -22,7 +19,7 @@ public class SecurityIntegrationTest {
private WebTestClient rest; private WebTestClient rest;
@Before @BeforeEach
public void setup() { public void setup() {
this.rest = WebTestClient.bindToApplicationContext(this.context).configureClient().build(); this.rest = WebTestClient.bindToApplicationContext(this.context).configureClient().build();
} }
@ -33,7 +30,6 @@ public class SecurityIntegrationTest {
} }
@Test @Test
@Ignore
@WithMockUser @WithMockUser
public void whenHasCredentials_thenSeesGreeting() { public void whenHasCredentials_thenSeesGreeting() {
this.rest.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello, user"); this.rest.get().uri("/").exchange().expectStatus().isOk().expectBody(String.class).isEqualTo("Hello, user");

View File

@ -1,10 +1,8 @@
package com.baeldung.web.client; package com.baeldung.reactive.webclient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import com.baeldung.web.reactive.client.WebClientApplication;
@SpringBootTest(classes = WebClientApplication.class) @SpringBootTest(classes = WebClientApplication.class)
public class SpringContextTest { public class SpringContextTest {

View File

@ -1,15 +1,9 @@
package com.baeldung.web.client; package com.baeldung.reactive.webclient;
import static org.assertj.core.api.Assertions.assertThat;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@ -34,18 +28,20 @@ import org.springframework.web.reactive.function.client.WebClient.RequestHeaders
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec; import org.springframework.web.reactive.function.client.WebClient.RequestHeadersUriSpec;
import org.springframework.web.reactive.function.client.WebClient.ResponseSpec; import org.springframework.web.reactive.function.client.WebClient.ResponseSpec;
import org.springframework.web.reactive.function.client.WebClientRequestException; import org.springframework.web.reactive.function.client.WebClientRequestException;
import com.baeldung.web.reactive.client.Foo;
import com.baeldung.web.reactive.client.WebClientApplication;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient; import reactor.netty.http.client.HttpClient;
import reactor.test.StepVerifier; import reactor.test.StepVerifier;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(classes = WebClientApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = WebClientApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class WebClientIntegrationTest { public class WebClientIntegrationTest {
@ -211,8 +207,7 @@ public class WebClientIntegrationTest {
ResponseSpec responseSpecPostString = createDefaultPostResourceRequestResponse().retrieve(); ResponseSpec responseSpecPostString = createDefaultPostResourceRequestResponse().retrieve();
Mono<String> responsePostString = responseSpecPostString.bodyToMono(String.class); Mono<String> responsePostString = responseSpecPostString.bodyToMono(String.class);
Mono<String> responsePostString2 = createDefaultPostResourceRequestResponse().exchangeToMono(response -> { Mono<String> responsePostString2 = createDefaultPostResourceRequestResponse().exchangeToMono(response -> {
if (response.statusCode() if (response.statusCode() == HttpStatus.OK) {
.equals(HttpStatus.OK)) {
return response.bodyToMono(String.class); return response.bodyToMono(String.class);
} else if (response.statusCode() } else if (response.statusCode()
.is4xxClientError()) { .is4xxClientError()) {
@ -223,8 +218,7 @@ public class WebClientIntegrationTest {
} }
}); });
Mono<String> responsePostNoBody = createDefaultPostResourceRequest().exchangeToMono(response -> { Mono<String> responsePostNoBody = createDefaultPostResourceRequest().exchangeToMono(response -> {
if (response.statusCode() if (response.statusCode() == HttpStatus.OK) {
.equals(HttpStatus.OK)) {
return response.bodyToMono(String.class); return response.bodyToMono(String.class);
} else if (response.statusCode() } else if (response.statusCode()
.is4xxClientError()) { .is4xxClientError()) {

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient; package com.baeldung.reactive.webclient;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@ -1,4 +1,4 @@
package com.baeldung.web.client; package com.baeldung.reactive.webclient;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -12,10 +12,6 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.WebHandler; import org.springframework.web.server.WebHandler;
import com.baeldung.web.reactive.client.WebClientApplication;
import com.baeldung.web.reactive.client.WebClientController;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@SpringBootTest(classes = WebClientApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @SpringBootTest(classes = WebClientApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

View File

@ -1,10 +1,5 @@
package com.baeldung.spring.webclientrequests; package com.baeldung.reactive.webclientrequests;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import java.time.Duration;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -22,6 +17,12 @@ import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.DefaultUriBuilderFactory; import org.springframework.web.util.DefaultUriBuilderFactory;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.time.Duration;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@WebFluxTest @WebFluxTest
public class WebClientRequestsUnitTest { public class WebClientRequestsUnitTest {
@ -48,7 +49,6 @@ public class WebClientRequestsUnitTest {
.build(); .build();
} }
@Test @Test
public void whenCallSimpleURI_thenURIMatched() { public void whenCallSimpleURI_thenURIMatched() {
this.webClient.get() this.webClient.get()

View File

@ -1,10 +1,8 @@
package com.baeldung.reactive.webflux; package com.baeldung.reactive.webflux.annotation;
import static org.mockito.BDDMockito.given;
import java.util.ArrayList;
import java.util.List;
import com.baeldung.reactive.webflux.Employee;
import com.baeldung.reactive.webflux.EmployeeRepository;
import com.baeldung.reactive.webflux.annotation.EmployeeSpringApplication;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -14,16 +12,16 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import com.baeldung.webflux.EmployeeSpringApplication;
import com.baeldung.webflux.Employee;
import com.baeldung.webflux.EmployeeRepository;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.BDDMockito.given;
@RunWith(SpringRunner.class) @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes=EmployeeSpringApplication.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes= EmployeeSpringApplication.class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) @FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EmployeeControllerIntegrationTest { public class EmployeeControllerIntegrationTest {

View File

@ -1,7 +1,7 @@
package com.baeldung.reactive.functional; package com.baeldung.reactive.webflux.functional;
import com.baeldung.webflux.Employee; import com.baeldung.reactive.webflux.Employee;
import com.baeldung.webflux.EmployeeRepository; import com.baeldung.reactive.webflux.EmployeeRepository;
import org.junit.FixMethodOrder; import org.junit.FixMethodOrder;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include
resource="org/springframework/boot/logging/logback/base.xml" />
<appender name="LISTAPPENDER"
class="com.baeldung.reactive.debugging.consumer.utils.ListAppender">
</appender>
<logger
name="com.baeldung.reactive.debugging.consumer.service.FooService">
<appender-ref ref="LISTAPPENDER" />
</logger>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="LISTAPPENDER" />
</root>
</configuration>

View File

@ -1,3 +0,0 @@
### Relevant Articles:
- [Concurrency in Spring WebFlux](https://www.baeldung.com/spring-webflux-concurrency)

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung.spring</groupId>
<artifactId>spring-webflux-threads</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>spring-webflux-threads</name>
<packaging>jar</packaging>
<description>Spring WebFlux Threads Sample</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<!-- Uncomment the following to switch from Netty to Tomcat/Jetty -->
<!-- <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-reactor-netty</artifactId>
</exclusion> </exclusions> -->
</dependency>
<!-- Uncomment the following to switch from Netty to Tomcat -->
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency> -->
<!-- Uncomment the following to switch from Netty to Jetty -->
<!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId>
</dependency> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-reactive-httpclient</artifactId>
</dependency> -->
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.2.19</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor.kafka</groupId>
<artifactId>reactor-kafka</artifactId>
<version>1.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>