Merge pull request #12137 from hkhan/JAVA-8148-update-guide-webflux
Java 8148 update guide webflux
This commit is contained in:
		
						commit
						64999b737c
					
				| @ -12,6 +12,4 @@ public class Employee { | ||||
|     private String id; | ||||
|     private String name; | ||||
| 
 | ||||
|     // standard getters and setters | ||||
|      | ||||
| } | ||||
|  | ||||
| @ -10,46 +10,32 @@ import java.util.Map; | ||||
| @Repository | ||||
| public class EmployeeRepository { | ||||
| 
 | ||||
|     static Map<String, Employee> employeeData; | ||||
| 
 | ||||
|     static Map<String, String> employeeAccessData; | ||||
|     private static final Map<String, Employee> EMPLOYEE_DATA; | ||||
| 
 | ||||
|     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"); | ||||
|         EMPLOYEE_DATA = new HashMap<>(); | ||||
|         EMPLOYEE_DATA.put("1", new Employee("1", "Employee 1")); | ||||
|         EMPLOYEE_DATA.put("2", new Employee("2", "Employee 2")); | ||||
|         EMPLOYEE_DATA.put("3", new Employee("3", "Employee 3")); | ||||
|         EMPLOYEE_DATA.put("4", new Employee("4", "Employee 4")); | ||||
|         EMPLOYEE_DATA.put("5", new Employee("5", "Employee 5")); | ||||
|         EMPLOYEE_DATA.put("6", new Employee("6", "Employee 6")); | ||||
|         EMPLOYEE_DATA.put("7", new Employee("7", "Employee 7")); | ||||
|         EMPLOYEE_DATA.put("8", new Employee("8", "Employee 8")); | ||||
|         EMPLOYEE_DATA.put("9", new Employee("9", "Employee 9")); | ||||
|         EMPLOYEE_DATA.put("10", new Employee("10", "Employee 10")); | ||||
|     } | ||||
| 
 | ||||
|     public Mono<Employee> findEmployeeById(String id) { | ||||
|         return Mono.just(employeeData.get(id)); | ||||
|         return Mono.just(EMPLOYEE_DATA.get(id)); | ||||
|     } | ||||
| 
 | ||||
|     public Flux<Employee> findAllEmployees() { | ||||
|         return Flux.fromIterable(employeeData.values()); | ||||
|         return Flux.fromIterable(EMPLOYEE_DATA.values()); | ||||
|     } | ||||
| 
 | ||||
|     public Mono<Employee> updateEmployee(Employee employee) { | ||||
|         Employee existingEmployee = employeeData.get(employee.getId()); | ||||
|         Employee existingEmployee = EMPLOYEE_DATA.get(employee.getId()); | ||||
|         if (existingEmployee != null) { | ||||
|             existingEmployee.setName(employee.getName()); | ||||
|         } | ||||
|  | ||||
| @ -1,12 +1,19 @@ | ||||
| package com.baeldung.reactive.webflux.annotation; | ||||
| 
 | ||||
| import com.baeldung.reactive.webflux.EmployeeRepository; | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| 
 | ||||
| @SpringBootApplication(exclude = MongoReactiveAutoConfiguration.class) | ||||
| public class EmployeeSpringApplication { | ||||
| 
 | ||||
|     @Bean | ||||
|     EmployeeRepository employeeRepository() { | ||||
|         return new EmployeeRepository(); | ||||
|     } | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(EmployeeSpringApplication.class, args); | ||||
| 
 | ||||
|  | ||||
| @ -16,17 +16,17 @@ public class EmployeeWebClient { | ||||
|     public void consume() { | ||||
| 
 | ||||
|         Mono<Employee> employeeMono = client.get() | ||||
|             .uri("/employees/{id}", "1") | ||||
|             .retrieve() | ||||
|             .bodyToMono(Employee.class); | ||||
|           .uri("/employees/{id}", "1") | ||||
|           .retrieve() | ||||
|           .bodyToMono(Employee.class); | ||||
| 
 | ||||
|         employeeMono.subscribe(employee -> LOGGER.debug("Employee: {}", employee)); | ||||
|         employeeMono.subscribe(employee -> LOGGER.info("Employee: {}", employee)); | ||||
| 
 | ||||
|         Flux<Employee> employeeFlux = client.get() | ||||
|             .uri("/employees") | ||||
|             .retrieve() | ||||
|             .bodyToFlux(Employee.class); | ||||
|           .uri("/employees") | ||||
|           .retrieve() | ||||
|           .bodyToFlux(Employee.class); | ||||
| 
 | ||||
|         employeeFlux.subscribe(employee -> LOGGER.debug("Employee: {}", employee)); | ||||
|         employeeFlux.subscribe(employee -> LOGGER.info("Employee: {}", employee)); | ||||
|     } | ||||
| } | ||||
| @ -17,29 +17,27 @@ public class EmployeeWebSecurityConfig { | ||||
|     @Bean | ||||
|     public MapReactiveUserDetailsService userDetailsService() { | ||||
|         UserDetails user = User | ||||
|             .withUsername("admin") | ||||
|             .password(passwordEncoder().encode("password")) | ||||
|             .roles("ADMIN") | ||||
|             .build(); | ||||
|           .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(); | ||||
|         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(); | ||||
|         return new BCryptPasswordEncoder(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -25,50 +25,49 @@ public class EmployeeFunctionalConfig { | ||||
| 
 | ||||
|     @Bean | ||||
|     RouterFunction<ServerResponse> getAllEmployeesRoute() { | ||||
|       return route(GET("/employees"),  | ||||
|         req -> ok().body( | ||||
|           employeeRepository().findAllEmployees(), Employee.class)); | ||||
|         return route(GET("/employees"), | ||||
|           req -> ok().body( | ||||
|             employeeRepository().findAllEmployees(), Employee.class)); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     RouterFunction<ServerResponse> getEmployeeByIdRoute() { | ||||
|       return route(GET("/employees/{id}"),  | ||||
|         req -> ok().body( | ||||
|           employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); | ||||
|         return route(GET("/employees/{id}"), | ||||
|           req -> ok().body( | ||||
|             employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class)); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     RouterFunction<ServerResponse> updateEmployeeRoute() { | ||||
|       return route(POST("/employees/update"),  | ||||
|         req -> req.body(toMono(Employee.class)) | ||||
|                   .doOnNext(employeeRepository()::updateEmployee) | ||||
|                   .then(ok().build())); | ||||
|         return route(POST("/employees/update"), | ||||
|           req -> req.body(toMono(Employee.class)) | ||||
|             .doOnNext(employeeRepository()::updateEmployee) | ||||
|             .then(ok().build())); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     RouterFunction<ServerResponse> composedRoutes() { | ||||
|       return  | ||||
|         return | ||||
|           route(GET("/employees"), | ||||
|             req -> ok().body( | ||||
|               employeeRepository().findAllEmployees(), Employee.class)) | ||||
| 
 | ||||
|           .and(route(GET("/employees/{id}"),  | ||||
|             req -> ok().body( | ||||
|               employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class))) | ||||
|             .and(route(GET("/employees/{id}"), | ||||
|               req -> ok().body( | ||||
|                 employeeRepository().findEmployeeById(req.pathVariable("id")), Employee.class))) | ||||
| 
 | ||||
|           .and(route(POST("/employees/update"),  | ||||
|             req -> req.body(toMono(Employee.class)) | ||||
|                       .doOnNext(employeeRepository()::updateEmployee) | ||||
|                       .then(ok().build()))); | ||||
|             .and(route(POST("/employees/update"), | ||||
|               req -> req.body(toMono(Employee.class)) | ||||
|                 .doOnNext(employeeRepository()::updateEmployee) | ||||
|                 .then(ok().build()))); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) { | ||||
|         http.csrf() | ||||
|             .disable() | ||||
|             .authorizeExchange() | ||||
|             .anyExchange() | ||||
|             .permitAll(); | ||||
|         http | ||||
|           .csrf().disable() | ||||
|           .authorizeExchange() | ||||
|             .anyExchange().permitAll(); | ||||
|         return http.build(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,27 +2,27 @@ 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; | ||||
| import org.junit.runners.MethodSorters; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.boot.test.mock.mockito.MockBean; | ||||
| import org.springframework.security.test.context.support.WithMockUser; | ||||
| import org.springframework.test.context.junit4.SpringRunner; | ||||
| import org.springframework.test.web.reactive.server.WebTestClient; | ||||
| import reactor.core.publisher.Flux; | ||||
| import reactor.core.publisher.Mono; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import static org.mockito.BDDMockito.given; | ||||
| import static org.mockito.Mockito.verify; | ||||
| import static org.mockito.Mockito.verifyNoInteractions; | ||||
| import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes= EmployeeSpringApplication.class) | ||||
| @FixMethodOrder(MethodSorters.NAME_ASCENDING) | ||||
| @SpringBootTest(webEnvironment = RANDOM_PORT, classes = EmployeeSpringApplication.class) | ||||
| public class EmployeeControllerIntegrationTest { | ||||
| 
 | ||||
|     @Autowired | ||||
| @ -37,38 +37,60 @@ public class EmployeeControllerIntegrationTest { | ||||
|         Employee employee = new Employee("1", "Employee 1 Name"); | ||||
| 
 | ||||
|         given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); | ||||
| 
 | ||||
|         testClient.get() | ||||
|             .uri("/employees/1") | ||||
|             .exchange() | ||||
|             .expectStatus() | ||||
|             .isOk() | ||||
|             .expectBody(Employee.class) | ||||
|             .isEqualTo(employee); | ||||
|           .uri("/employees/1") | ||||
|           .exchange() | ||||
|           .expectStatus().isOk() | ||||
|           .expectBody(Employee.class).isEqualTo(employee); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenGetAllEmployees_thenCorrectEmployees() { | ||||
| 
 | ||||
|         List<Employee> employeeList = new ArrayList<>(); | ||||
| 
 | ||||
|         Employee employee1 = new Employee("1", "Employee 1 Name"); | ||||
|         Employee employee2 = new Employee("2", "Employee 2 Name"); | ||||
|         Employee employee3 = new Employee("3", "Employee 3 Name"); | ||||
| 
 | ||||
|         employeeList.add(employee1); | ||||
|         employeeList.add(employee2); | ||||
|         employeeList.add(employee3); | ||||
| 
 | ||||
|         List<Employee> employeeList = Arrays.asList( | ||||
|           new Employee("1", "Employee 1 Name"), | ||||
|           new Employee("2", "Employee 2 Name"), | ||||
|           new Employee("3", "Employee 3 Name") | ||||
|         ); | ||||
|         Flux<Employee> employeeFlux = Flux.fromIterable(employeeList); | ||||
| 
 | ||||
|         given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); | ||||
| 
 | ||||
|         testClient.get() | ||||
|             .uri("/employees") | ||||
|             .exchange() | ||||
|             .expectStatus() | ||||
|             .isOk() | ||||
|             .expectBodyList(Employee.class) | ||||
|             .hasSize(3) | ||||
|             .isEqualTo(employeeList); | ||||
|           .uri("/employees") | ||||
|           .exchange() | ||||
|           .expectStatus().isOk() | ||||
|           .expectBodyList(Employee.class).isEqualTo(employeeList); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @WithMockUser(username = "admin", roles = { "ADMIN" }) | ||||
|     public void givenValidUser_whenUpdateEmployee_thenEmployeeUpdated() { | ||||
|         Employee employee = new Employee("10", "Employee 10 Updated"); | ||||
| 
 | ||||
|         given(employeeRepository.updateEmployee(employee)).willReturn(Mono.just(employee)); | ||||
| 
 | ||||
|         testClient.post() | ||||
|           .uri("/employees/update") | ||||
|           .body(Mono.just(employee), Employee.class) | ||||
|           .exchange() | ||||
|           .expectStatus().isOk() | ||||
|           .expectBody(Employee.class).isEqualTo(employee); | ||||
| 
 | ||||
|         verify(employeeRepository).updateEmployee(employee); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     @WithMockUser | ||||
|     public void givenInvalidUser_whenUpdateEmployee_thenForbidden() { | ||||
|         Employee employee = new Employee("10", "Employee 10 Updated"); | ||||
| 
 | ||||
|         testClient.post() | ||||
|           .uri("/employees/update") | ||||
|           .body(Mono.just(employee), Employee.class) | ||||
|           .exchange() | ||||
|           .expectStatus().isForbidden(); | ||||
| 
 | ||||
|         verifyNoInteractions(employeeRepository); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,10 +2,8 @@ package com.baeldung.reactive.webflux.functional; | ||||
| 
 | ||||
| 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; | ||||
| import org.junit.runners.MethodSorters; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.test.context.SpringBootTest; | ||||
| import org.springframework.boot.test.mock.mockito.MockBean; | ||||
| @ -19,10 +17,10 @@ import java.util.List; | ||||
| 
 | ||||
| import static org.mockito.BDDMockito.given; | ||||
| import static org.mockito.Mockito.verify; | ||||
| import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; | ||||
| 
 | ||||
| @RunWith(SpringRunner.class) | ||||
| @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = EmployeeSpringFunctionalApplication.class) | ||||
| @FixMethodOrder(MethodSorters.NAME_ASCENDING) | ||||
| @SpringBootTest(webEnvironment = RANDOM_PORT, classes = EmployeeSpringFunctionalApplication.class) | ||||
| public class EmployeeSpringFunctionalIntegrationTest { | ||||
| 
 | ||||
|     @Autowired | ||||
| @ -34,58 +32,54 @@ public class EmployeeSpringFunctionalIntegrationTest { | ||||
|     @Test | ||||
|     public void givenEmployeeId_whenGetEmployeeById_thenCorrectEmployee() { | ||||
|         WebTestClient client = WebTestClient | ||||
|             .bindToRouterFunction(config.getEmployeeByIdRoute()) | ||||
|             .build(); | ||||
|           .bindToRouterFunction(config.getEmployeeByIdRoute()) | ||||
|           .build(); | ||||
| 
 | ||||
|         Employee employee = new Employee("1", "Employee 1"); | ||||
| 
 | ||||
|         given(employeeRepository.findEmployeeById("1")).willReturn(Mono.just(employee)); | ||||
| 
 | ||||
|         client.get() | ||||
|             .uri("/employees/1") | ||||
|             .exchange() | ||||
|             .expectStatus() | ||||
|             .isOk() | ||||
|             .expectBody(Employee.class) | ||||
|             .isEqualTo(employee); | ||||
|           .uri("/employees/1") | ||||
|           .exchange() | ||||
|           .expectStatus().isOk() | ||||
|           .expectBody(Employee.class).isEqualTo(employee); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenGetAllEmployees_thenCorrectEmployees() { | ||||
|         WebTestClient client = WebTestClient | ||||
|             .bindToRouterFunction(config.getAllEmployeesRoute()) | ||||
|             .build(); | ||||
|           .bindToRouterFunction(config.getAllEmployeesRoute()) | ||||
|           .build(); | ||||
| 
 | ||||
|         List<Employee> employees = Arrays.asList( | ||||
|             new Employee("1", "Employee 1"), | ||||
|             new Employee("2", "Employee 2")); | ||||
|           new Employee("1", "Employee 1"), | ||||
|           new Employee("2", "Employee 2") | ||||
|         ); | ||||
| 
 | ||||
|         Flux<Employee> employeeFlux = Flux.fromIterable(employees); | ||||
|         given(employeeRepository.findAllEmployees()).willReturn(employeeFlux); | ||||
| 
 | ||||
|         client.get() | ||||
|             .uri("/employees") | ||||
|             .exchange() | ||||
|             .expectStatus() | ||||
|             .isOk() | ||||
|             .expectBodyList(Employee.class) | ||||
|             .isEqualTo(employees); | ||||
|           .uri("/employees") | ||||
|           .exchange() | ||||
|           .expectStatus().isOk() | ||||
|           .expectBodyList(Employee.class).isEqualTo(employees); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenUpdateEmployee_thenEmployeeUpdated() { | ||||
|         WebTestClient client = WebTestClient | ||||
|             .bindToRouterFunction(config.updateEmployeeRoute()) | ||||
|             .build(); | ||||
|           .bindToRouterFunction(config.updateEmployeeRoute()) | ||||
|           .build(); | ||||
| 
 | ||||
|         Employee employee = new Employee("1", "Employee 1 Updated"); | ||||
| 
 | ||||
|         client.post() | ||||
|             .uri("/employees/update") | ||||
|             .body(Mono.just(employee), Employee.class) | ||||
|             .exchange() | ||||
|             .expectStatus() | ||||
|             .isOk(); | ||||
|           .uri("/employees/update") | ||||
|           .body(Mono.just(employee), Employee.class) | ||||
|           .exchange() | ||||
|           .expectStatus().isOk(); | ||||
| 
 | ||||
|         verify(employeeRepository).updateEmployee(employee); | ||||
|     } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user