From 4ce1835f939ad7c0e5e4c130bb7c34c3fbd8c5a9 Mon Sep 17 00:00:00 2001 From: uzma Date: Wed, 12 Jul 2023 01:23:19 +0100 Subject: [PATCH 1/3] [BAEL-6689] code for zipwhen --- .../baeldung/webflux/zipwhen/model/User.java | 22 ++++++++++ .../zipwhen/service/DatabaseService.java | 37 ++++++++++++++++ .../webflux/zipwhen/service/EmailService.java | 29 ++++++++++++ .../webflux/zipwhen/service/UserService.java | 15 +++++++ .../webflux/zipwhen/web/UserController.java | 44 +++++++++++++++++++ .../webflux/zipwhen/UserControllerTest.java | 42 ++++++++++++++++++ 6 files changed, 189 insertions(+) create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/model/User.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java create mode 100644 spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java create mode 100644 spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/model/User.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/model/User.java new file mode 100644 index 0000000000..37008bb061 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/model/User.java @@ -0,0 +1,22 @@ +package com.baeldung.webflux.zipwhen.model; + +public class User { + + private final String id; + private final String email; + + public User(String id, String email) { + this.id = id; + this.email = email; + + } + + public String getId() { + return id; + } + + public String getEmail() { + return email; + } + +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java new file mode 100644 index 0000000000..b7e7a1aa50 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java @@ -0,0 +1,37 @@ +package com.baeldung.webflux.zipwhen.service; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +public class DatabaseService { + private Map dataStore = new ConcurrentHashMap<>(); + + // public Mono saveUserData(User user) { + // + // + // return Mono.fromRunnable(() -> { + // // Simulate saving the user data to a database or data store + // dataStore.put(user.getId(), user); + // + // + // }); + // } + //} + + public Mono saveUserData(User user) { + return Mono.create(sink -> { + // Simulate saving the user data to a database or data store + try { + dataStore.put(user.getId(), user); + sink.success(true); // Database save operation successful + } catch (Exception e) { + sink.success(false); // Database save operation failed + } + }); + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java new file mode 100644 index 0000000000..7c33466f24 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -0,0 +1,29 @@ +package com.baeldung.webflux.zipwhen.service; + +import reactor.core.publisher.Mono; + +//public class EmailService { +// public Mono sendEmail(String userId) { +// //code to send the email +// return Mono.just(true); +// } +//} + + +public class EmailService { + private final UserService userService; + + public EmailService(UserService userService) { + this.userService = userService; + } + + public Mono sendEmail(String userId) { + return userService.getUser(userId) + .flatMap(user -> { + // Code to send the email using the user's information + System.out.println("Sending email to: " + user.getEmail()); + return Mono.just(true); + }) + .defaultIfEmpty(false); + } +} diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java new file mode 100644 index 0000000000..4d5a6448d5 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java @@ -0,0 +1,15 @@ +package com.baeldung.webflux.zipwhen.service; + +import com.baeldung.webflux.zipwhen.model.User; + +import reactor.core.publisher.Mono; + +public class UserService { + public Mono getUser(String userId) { + // Replace with your implementation to validate the user + // and return a Mono with the validated user data + // For example: + return Mono.just(new User(userId, "John Doe")); + } +} + diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java new file mode 100644 index 0000000000..a08f364d90 --- /dev/null +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -0,0 +1,44 @@ +package com.baeldung.webflux.zipwhen.web; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; + +import com.baeldung.webflux.zipwhen.model.User; +import com.baeldung.webflux.zipwhen.service.DatabaseService; +import com.baeldung.webflux.zipwhen.service.EmailService; +import com.baeldung.webflux.zipwhen.service.UserService; + +import reactor.core.publisher.Mono; +import reactor.core.scheduler.Schedulers; +import reactor.util.function.Tuples; + +public class UserController { + private final UserService userService; + private final EmailService emailService; + private final DatabaseService databaseService; + public UserController(UserService userService, + EmailService emailService, + DatabaseService databaseService) { + this.userService = userService; + this.emailService = emailService; + this.databaseService = databaseService; + } + + @GetMapping("/example/{userId}") + public Mono> combineAllDataFor(@PathVariable String userId) { + Mono userMono = userService.getUser(userId); + Mono emailSentMono = emailService.sendEmail(userId) + .subscribeOn(Schedulers.parallel()); + Mono databaseResultMono = userMono.flatMap(user -> databaseService.saveUserData(user) + .map(Object::toString)); + + return userMono.zipWhen(user -> emailSentMono, Tuples::of) + .zipWhen(tuple -> databaseResultMono, (tuple, databaseResult) -> { + User user = tuple.getT1(); + Boolean emailSent = tuple.getT2(); + return ResponseEntity.ok() + .body("Response: " + user + ", Email Sent: " + emailSent + ", Database Result: " + databaseResult); + }); + } +} diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java new file mode 100644 index 0000000000..69b14f3172 --- /dev/null +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java @@ -0,0 +1,42 @@ +package com.baeldung.webflux.zipwhen; + +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.baeldung.webflux.zipwhen.model.User; +import com.baeldung.webflux.zipwhen.service.DatabaseService; +import com.baeldung.webflux.zipwhen.service.EmailService; +import com.baeldung.webflux.zipwhen.service.UserService; +import com.baeldung.webflux.zipwhen.web.UserController; + +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + +public class UserControllerTest { + @Test + public void givenUserId_whenCombineAllData_thenReturnsMonoWithCombinedData() { + UserService userService = Mockito.mock(UserService.class); + EmailService emailService = Mockito.mock(EmailService.class); + DatabaseService databaseService = Mockito.mock(DatabaseService.class); + + String userId = "123"; + User user = new User(userId, "John Doe"); + + Mockito.when(userService.getUser(userId)).thenReturn(Mono.just(user)); + Mockito.when(emailService.sendEmail(userId)).thenReturn(Mono.just(true)); + Mockito.when(databaseService.saveUserData(user)).thenReturn(Mono.just(true)); + + UserController userController = new UserController(userService, emailService, databaseService); + + Mono> responseMono = userController.combineAllDataFor(userId); + + StepVerifier.create(responseMono) + .expectNextMatches(responseEntity -> + responseEntity.getStatusCode() == HttpStatus.OK && + responseEntity.getBody().equals("Response: " + user + ", Email Sent: true, Database Result: " + true) + ) + .verifyComplete(); + } +} From d04a16784016c76eb7c48ec971f8373a4dcae01c Mon Sep 17 00:00:00 2001 From: uzma Date: Wed, 12 Jul 2023 01:26:57 +0100 Subject: [PATCH 2/3] [BAEL-6689] code for zipwhen --- .../zipwhen/service/DatabaseService.java | 17 ++--------------- .../webflux/zipwhen/service/EmailService.java | 9 --------- .../webflux/zipwhen/service/UserService.java | 5 +---- .../webflux/zipwhen/web/UserController.java | 19 +++++++++---------- .../webflux/zipwhen/UserControllerTest.java | 15 ++++++++------- 5 files changed, 20 insertions(+), 45 deletions(-) diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java index b7e7a1aa50..d420646871 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/DatabaseService.java @@ -10,26 +10,13 @@ import reactor.core.publisher.Mono; public class DatabaseService { private Map dataStore = new ConcurrentHashMap<>(); - // public Mono saveUserData(User user) { - // - // - // return Mono.fromRunnable(() -> { - // // Simulate saving the user data to a database or data store - // dataStore.put(user.getId(), user); - // - // - // }); - // } - //} - public Mono saveUserData(User user) { return Mono.create(sink -> { - // Simulate saving the user data to a database or data store try { dataStore.put(user.getId(), user); - sink.success(true); // Database save operation successful + sink.success(true); } catch (Exception e) { - sink.success(false); // Database save operation failed + sink.success(false); } }); } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java index 7c33466f24..9c0340b7ee 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/EmailService.java @@ -2,14 +2,6 @@ package com.baeldung.webflux.zipwhen.service; import reactor.core.publisher.Mono; -//public class EmailService { -// public Mono sendEmail(String userId) { -// //code to send the email -// return Mono.just(true); -// } -//} - - public class EmailService { private final UserService userService; @@ -20,7 +12,6 @@ public class EmailService { public Mono sendEmail(String userId) { return userService.getUser(userId) .flatMap(user -> { - // Code to send the email using the user's information System.out.println("Sending email to: " + user.getEmail()); return Mono.just(true); }) diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java index 4d5a6448d5..fe602fbc33 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/service/UserService.java @@ -6,10 +6,7 @@ import reactor.core.publisher.Mono; public class UserService { public Mono getUser(String userId) { - // Replace with your implementation to validate the user - // and return a Mono with the validated user data - // For example: - return Mono.just(new User(userId, "John Doe")); + return Mono.just(new User(userId, "john Major")); } } diff --git a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java index a08f364d90..dbd89c45d3 100644 --- a/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java +++ b/spring-5-webflux-2/src/main/java/com/baeldung/webflux/zipwhen/web/UserController.java @@ -14,16 +14,15 @@ import reactor.core.scheduler.Schedulers; import reactor.util.function.Tuples; public class UserController { - private final UserService userService; - private final EmailService emailService; - private final DatabaseService databaseService; - public UserController(UserService userService, - EmailService emailService, - DatabaseService databaseService) { - this.userService = userService; - this.emailService = emailService; - this.databaseService = databaseService; - } + private final UserService userService; + private final EmailService emailService; + private final DatabaseService databaseService; + + public UserController(UserService userService, EmailService emailService, DatabaseService databaseService) { + this.userService = userService; + this.emailService = emailService; + this.databaseService = databaseService; + } @GetMapping("/example/{userId}") public Mono> combineAllDataFor(@PathVariable String userId) { diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java index 69b14f3172..1d86d5ce99 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java @@ -24,19 +24,20 @@ public class UserControllerTest { String userId = "123"; User user = new User(userId, "John Doe"); - Mockito.when(userService.getUser(userId)).thenReturn(Mono.just(user)); - Mockito.when(emailService.sendEmail(userId)).thenReturn(Mono.just(true)); - Mockito.when(databaseService.saveUserData(user)).thenReturn(Mono.just(true)); + Mockito.when(userService.getUser(userId)) + .thenReturn(Mono.just(user)); + Mockito.when(emailService.sendEmail(userId)) + .thenReturn(Mono.just(true)); + Mockito.when(databaseService.saveUserData(user)) + .thenReturn(Mono.just(true)); UserController userController = new UserController(userService, emailService, databaseService); Mono> responseMono = userController.combineAllDataFor(userId); StepVerifier.create(responseMono) - .expectNextMatches(responseEntity -> - responseEntity.getStatusCode() == HttpStatus.OK && - responseEntity.getBody().equals("Response: " + user + ", Email Sent: true, Database Result: " + true) - ) + .expectNextMatches(responseEntity -> responseEntity.getStatusCode() == HttpStatus.OK && responseEntity.getBody() + .equals("Response: " + user + ", Email Sent: true, Database Result: " + true)) .verifyComplete(); } } From af8b296223ea9e151190ba92eb84d9ed344afbe4 Mon Sep 17 00:00:00 2001 From: uzma Date: Wed, 12 Jul 2023 07:41:33 +0100 Subject: [PATCH 3/3] [BAEL-6689] update test name --- .../{UserControllerTest.java => UserControllerUnitTest.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/{UserControllerTest.java => UserControllerUnitTest.java} (97%) diff --git a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java similarity index 97% rename from spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java rename to spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java index 1d86d5ce99..8ed4cfb6c6 100644 --- a/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerTest.java +++ b/spring-5-webflux-2/src/test/java/com/baeldung/webflux/zipwhen/UserControllerUnitTest.java @@ -14,7 +14,7 @@ import com.baeldung.webflux.zipwhen.web.UserController; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -public class UserControllerTest { +public class UserControllerUnitTest { @Test public void givenUserId_whenCombineAllData_thenReturnsMonoWithCombinedData() { UserService userService = Mockito.mock(UserService.class);