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

View File

@ -4,7 +4,6 @@ This module contains articles about Reactor Core.
### Relevant articles
- [Intro To Reactor Core](https://www.baeldung.com/reactor-core)
- [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)
- [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.
- [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)
- [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)
- [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)

View File

@ -8,8 +8,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
### Relevant Articles
- [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)
- [Spring Webflux and CORS](https://www.baeldung.com/spring-webflux-cors)

View File

@ -110,7 +110,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.baeldung.webflux.EmployeeSpringApplication</mainClass>
<mainClass>com.baeldung.reactive.actuator.Spring5ReactiveApplication</mainClass>
<layout>JAR</layout>
</configuration>
</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;
import com.baeldung.reactive.actuator.Spring5ReactiveApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.baeldung.reactive.security.SpringSecurity5Application;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringSecurity5Application.class)
@SpringBootTest(classes = Spring5ReactiveApplication.class)
public class SpringContextTest {
@Test

View File

@ -7,11 +7,9 @@ The "REST With Spring" Classes: https://bit.ly/restwithspring
### 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)
- [Reactive WebSockets with Spring 5](https://www.baeldung.com/spring-5-reactive-websockets)
- [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)
- [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)
- 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)
- [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)
- [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)

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.autoconfigure.SpringBootApplication;

View File

@ -1,12 +1,6 @@
package com.baeldung.webflux;
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;
package com.baeldung.reactive.concurrency;
import io.reactivex.Observable;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
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.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import io.reactivex.Observable;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
@ -34,6 +26,13 @@ import reactor.kafka.sender.KafkaSender;
import reactor.kafka.sender.SenderOptions;
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
@RequestMapping("/")
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.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;

View File

@ -1,6 +1,4 @@
package com.baeldung.debugging.consumer;
import java.util.Collections;
package com.baeldung.reactive.debugging.consumer;
import org.springframework.boot.SpringApplication;
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.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import reactor.core.publisher.Hooks;
import java.util.Collections;
@SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class)
@EnableScheduling
public class ConsumerDebuggingApplication {

View File

@ -1,8 +1,8 @@
package com.baeldung.debugging.consumer.chronjobs;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
package com.baeldung.reactive.debugging.consumer.chronjobs;
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.LoggerFactory;
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.stereotype.Component;
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 java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
@Component
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.RestController;
import reactor.core.publisher.Hooks;
@RestController

View File

@ -1,12 +1,12 @@
package com.baeldung.debugging.consumer.model;
import java.util.concurrent.ThreadLocalRandom;
package com.baeldung.reactive.debugging.consumer.model;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.concurrent.ThreadLocalRandom;
@Getter
@Setter
@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.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 com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
public class FooNameHelper {
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 com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
public class FooQuantityHelper {
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.LoggerFactory;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
public class FooReporter {

View File

@ -1,20 +1,18 @@
package com.baeldung.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;
package com.baeldung.reactive.debugging.consumer.service;
import com.baeldung.reactive.debugging.consumer.model.Foo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.baeldung.debugging.consumer.model.Foo;
import reactor.core.publisher.Flux;
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
public class FooService {

View File

@ -1,6 +1,4 @@
package com.baeldung.debugging.server;
import java.util.Collections;
package com.baeldung.reactive.debugging.server;
import org.springframework.boot.SpringApplication;
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.web.reactive.config.EnableWebFlux;
import java.util.Collections;
@EnableWebFlux
@SpringBootApplication
public class ServerDebuggingApplication {

View File

@ -1,20 +1,18 @@
package com.baeldung.debugging.server.handlers;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
package com.baeldung.reactive.debugging.server.handlers;
import com.baeldung.reactive.debugging.server.model.Foo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 com.baeldung.debugging.server.model.Foo;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
import java.util.concurrent.ThreadLocalRandom;
@Component
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.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.context.annotation.Bean;
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.ServerResponse;
import com.baeldung.debugging.server.handlers.ServerHandler;
@Configuration
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.autoconfigure.SpringBootApplication;
@ -7,16 +7,17 @@ import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@SpringBootApplication
public class WebClientApplication {
public class ErrorHandlingApplication {
public static void main(String[] args) {
SpringApplication.run(WebClientApplication.class, args);
SpringApplication.run(ErrorHandlingApplication.class, args);
}
@Bean
public SecurityWebFilterChain functionalValidationsSpringSecurityFilterChain(ServerHttpSecurity http) {
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
http.authorizeExchange()
.anyExchange()
.permitAll();
.anyExchange()
.permitAll();
http.csrf().disable();
return http.build();
}

View File

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

View File

@ -1,8 +1,5 @@
package com.baeldung.reactive.errorhandling;
import java.util.Map;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.autoconfigure.web.reactive.error.AbstractErrorWebExceptionHandler;
import org.springframework.boot.web.error.ErrorAttributeOptions;
@ -19,9 +16,10 @@ import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import java.util.Map;
@Component
@Order(-2)
public class GlobalErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -8,7 +8,6 @@ import org.springframework.http.server.reactive.HttpHandler;
import org.springframework.http.server.reactive.ReactorHttpHandlerAdapter;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
import reactor.netty.DisposableServer;
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 {

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient;
package com.baeldung.reactive.webclient;
import lombok.AllArgsConstructor;
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.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.autoconfigure.SpringBootApplication;

View File

@ -1,7 +1,4 @@
package com.baeldung.web.reactive.client;
import java.util.HashMap;
import java.util.Map;
package com.baeldung.reactive.webclient;
import org.springframework.http.HttpStatus;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@RestController
public class WebClientController {
@ -37,6 +36,6 @@ public class WebClientController {
@PostMapping(value = "/resource-multipart", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
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.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.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.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@ -14,7 +15,7 @@ import reactor.core.publisher.Mono;
@RequestMapping("/employees")
public class EmployeeController {
private EmployeeRepository employeeRepository;
private final EmployeeRepository employeeRepository;
public EmployeeController(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.autoconfigure.SpringBootApplication;
@ -7,7 +7,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
public class EmployeeSpringApplication {
public static void main(String[] args) {
SpringApplication.run(EmployeeSpringApplication.class, args);
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 reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class EmployeeWebClient {
private static final Logger LOGGER = LoggerFactory.getLogger(EmployeeWebClient.class);
WebClient client = WebClient.create("http://localhost:8080");
public void consume() {
@ -16,13 +20,13 @@ public class EmployeeWebClient {
.retrieve()
.bodyToMono(Employee.class);
employeeMono.subscribe(System.out::println);
employeeMono.subscribe(employee -> LOGGER.debug("Employee: {}", employee));
Flux<Employee> employeeFlux = client.get()
.uri("/employees")
.retrieve()
.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,11 +1,7 @@
package com.baeldung.reactive.functional;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
package com.baeldung.reactive.webflux.functional;
import com.baeldung.reactive.webflux.Employee;
import com.baeldung.reactive.webflux.EmployeeRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.web.server.ServerHttpSecurity;
@ -13,8 +9,11 @@ import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import com.baeldung.webflux.Employee;
import com.baeldung.webflux.EmployeeRepository;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
@Configuration
public class EmployeeFunctionalConfig {

View File

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

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;
@ -8,13 +8,12 @@ import java.util.Optional;
import java.util.stream.Collectors;
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.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.IThrowableProxy;
import reactor.core.publisher.Flux;
@ -39,26 +38,26 @@ public class ConsumerFooServiceIntegrationTest {
service.processFoo(flux);
Collection<String> allLoggedEntries = ListAppender.getEvents()
.stream()
.map(ILoggingEvent::getFormattedMessage)
.collect(Collectors.toList());
.stream()
.map(ILoggingEvent::getFormattedMessage)
.collect(Collectors.toList());
Collection<String> allSuppressedEntries = ListAppender.getEvents()
.stream()
.map(ILoggingEvent::getThrowableProxy)
.flatMap(t -> {
return Optional.ofNullable(t)
.map(IThrowableProxy::getSuppressed)
.map(Arrays::stream)
.orElse(Stream.empty());
})
.map(IThrowableProxy::getClassName)
.collect(Collectors.toList());
.stream()
.map(ILoggingEvent::getThrowableProxy)
.flatMap(t -> {
return Optional.ofNullable(t)
.map(IThrowableProxy::getSuppressed)
.map(Arrays::stream)
.orElse(Stream.empty());
})
.map(IThrowableProxy::getClassName)
.collect(Collectors.toList());
assertThat(allLoggedEntries).anyMatch(entry -> entry.contains("The following error happened on processFoo method!"))
.anyMatch(entry -> entry.contains("| onSubscribe"))
.anyMatch(entry -> entry.contains("| cancel()"));
.anyMatch(entry -> entry.contains("| onSubscribe"))
.anyMatch(entry -> entry.contains("| cancel()"));
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.Test;
import org.springframework.test.web.reactive.server.WebTestClient;
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:
* - com.baeldung.debugging.server.ServerDebuggingApplication
* - com.baeldung.debugging.consumer.ConsumerDebuggingApplication
* - com.baeldung.reactive.debugging.server.ServerDebuggingApplication
* - com.baeldung.reactive.debugging.consumer.ConsumerDebuggingApplication
*/
public class ConsumerFooServiceLiveTest {

View File

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

View File

@ -1,9 +1,5 @@
package com.baeldung.reactive.errorhandling;
import static org.junit.Assert.assertEquals;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
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.web.reactive.server.WebTestClient;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext

View File

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

View File

@ -1,19 +1,16 @@
package com.baeldung.security;
package com.baeldung.reactive.security;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.test.context.support.WithMockUser;
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 com.baeldung.reactive.security.SpringSecurity5Application;
@RunWith(SpringRunner.class)
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = SpringSecurity5Application.class)
public class SecurityIntegrationTest {
@ -22,7 +19,7 @@ public class SecurityIntegrationTest {
private WebTestClient rest;
@Before
@BeforeEach
public void setup() {
this.rest = WebTestClient.bindToApplicationContext(this.context).configureClient().build();
}
@ -33,7 +30,6 @@ public class SecurityIntegrationTest {
}
@Test
@Ignore
@WithMockUser
public void whenHasCredentials_thenSeesGreeting() {
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.springframework.boot.test.context.SpringBootTest;
import com.baeldung.web.reactive.client.WebClientApplication;
@SpringBootTest(classes = WebClientApplication.class)
public class SpringContextTest {

View File

@ -1,15 +1,9 @@
package com.baeldung.web.client;
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;
package com.baeldung.reactive.webclient;
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.springframework.boot.test.context.SpringBootTest;
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.ResponseSpec;
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.netty.http.client.HttpClient;
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)
public class WebClientIntegrationTest {
@ -211,8 +207,7 @@ public class WebClientIntegrationTest {
ResponseSpec responseSpecPostString = createDefaultPostResourceRequestResponse().retrieve();
Mono<String> responsePostString = responseSpecPostString.bodyToMono(String.class);
Mono<String> responsePostString2 = createDefaultPostResourceRequestResponse().exchangeToMono(response -> {
if (response.statusCode()
.equals(HttpStatus.OK)) {
if (response.statusCode() == HttpStatus.OK) {
return response.bodyToMono(String.class);
} else if (response.statusCode()
.is4xxClientError()) {
@ -223,8 +218,7 @@ public class WebClientIntegrationTest {
}
});
Mono<String> responsePostNoBody = createDefaultPostResourceRequest().exchangeToMono(response -> {
if (response.statusCode()
.equals(HttpStatus.OK)) {
if (response.statusCode() == HttpStatus.OK) {
return response.bodyToMono(String.class);
} else if (response.statusCode()
.is4xxClientError()) {

View File

@ -1,4 +1,4 @@
package com.baeldung.webclient;
package com.baeldung.reactive.webclient;
import org.junit.Before;
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.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.ServerResponse;
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;
@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.Before;
import org.junit.Test;
@ -22,6 +17,12 @@ import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.util.DefaultUriBuilderFactory;
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)
@WebFluxTest
public class WebClientRequestsUnitTest {
@ -48,7 +49,6 @@ public class WebClientRequestsUnitTest {
.build();
}
@Test
public void whenCallSimpleURI_thenURIMatched() {
this.webClient.get()

View File

@ -1,10 +1,8 @@
package com.baeldung.reactive.webflux;
import static org.mockito.BDDMockito.given;
import java.util.ArrayList;
import java.util.List;
package com.baeldung.reactive.webflux.annotation;
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.Test;
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.test.context.junit4.SpringRunner;
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.Mono;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.BDDMockito.given;
@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)
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.webflux.EmployeeRepository;
import com.baeldung.reactive.webflux.Employee;
import com.baeldung.reactive.webflux.EmployeeRepository;
import org.junit.FixMethodOrder;
import org.junit.Test;
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>