diff --git a/libraries/pom.xml b/libraries/pom.xml
index eaa2d9d38f..3627e74472 100644
--- a/libraries/pom.xml
+++ b/libraries/pom.xml
@@ -633,9 +633,26 @@
${googleclient.version}
- com.google.http-client
- google-http-client-gson
- ${googleclient.version}
+ com.google.http-client
+ google-http-client-gson
+ ${googleclient.version}
+
+
+
+
+ com.google.api-client
+ google-api-client
+ ${google-api.version}
+
+
+ com.google.oauth-client
+ google-oauth-client-jetty
+ ${google-api.version}
+
+
+ com.google.apis
+ google-api-services-sheets
+ ${google-sheets.version}
@@ -710,5 +727,7 @@
1.0.0
3.8.4
2.5.5
+ 1.23.0
+ v4-rev493-1.21.0
\ No newline at end of file
diff --git a/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java b/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java
new file mode 100644
index 0000000000..650a1d084c
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/google/sheets/GoogleAuthorizeUtil.java
@@ -0,0 +1,42 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+import java.util.List;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
+import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
+import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
+import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.client.util.store.MemoryDataStoreFactory;
+import com.google.api.services.sheets.v4.SheetsScopes;
+
+public class GoogleAuthorizeUtil {
+ public static Credential authorize() throws IOException, GeneralSecurityException {
+ InputStream in = GoogleAuthorizeUtil.class.getResourceAsStream("/google-sheets-client-secret.json");
+ GoogleClientSecrets clientSecrets = GoogleClientSecrets
+ .load(JacksonFactory.getDefaultInstance(), new InputStreamReader(in));
+
+ List scopes = Arrays.asList(SheetsScopes.SPREADSHEETS);
+
+ GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow
+ .Builder(GoogleNetHttpTransport.newTrustedTransport(),
+ JacksonFactory.getDefaultInstance(),
+ clientSecrets,
+ scopes)
+ .setDataStoreFactory(new MemoryDataStoreFactory())
+ .setAccessType("offline")
+ .build();
+ Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver())
+ .authorize("user");
+
+ return credential;
+ }
+
+}
diff --git a/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java b/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java
new file mode 100644
index 0000000000..bbce96f389
--- /dev/null
+++ b/libraries/src/main/java/com/baeldung/google/sheets/SheetsServiceUtil.java
@@ -0,0 +1,23 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.api.services.sheets.v4.Sheets;
+
+public class SheetsServiceUtil {
+
+ private static final String APPLICATION_NAME = "Google Sheets Example";
+
+ public static Sheets getSheetsService() throws IOException, GeneralSecurityException {
+ Credential credential = GoogleAuthorizeUtil.authorize();
+ return new Sheets.Builder(GoogleNetHttpTransport.newTrustedTransport(),
+ JacksonFactory.getDefaultInstance(), credential)
+ .setApplicationName(APPLICATION_NAME)
+ .build();
+ }
+
+}
diff --git a/libraries/src/main/resources/google-sheets-client-secret.json b/libraries/src/main/resources/google-sheets-client-secret.json
new file mode 100644
index 0000000000..c92ccd6b9b
--- /dev/null
+++ b/libraries/src/main/resources/google-sheets-client-secret.json
@@ -0,0 +1 @@
+{"installed":{"client_id":"394827218507-2ev02b2ha8plt7g2lh5nqse02ee737cf.apps.googleusercontent.com","project_id":"decisive-octane-187810","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"2MnN1DfenoCGWMay3v8Bf7eI","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
\ No newline at end of file
diff --git a/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java b/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java
new file mode 100644
index 0000000000..5280073be2
--- /dev/null
+++ b/libraries/src/test/java/com/baeldung/google/sheets/GoogleSheetsIntegrationTest.java
@@ -0,0 +1,140 @@
+package com.baeldung.google.sheets;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.api.services.sheets.v4.Sheets;
+import com.google.api.services.sheets.v4.model.AppendValuesResponse;
+import com.google.api.services.sheets.v4.model.BatchGetValuesResponse;
+import com.google.api.services.sheets.v4.model.BatchUpdateSpreadsheetRequest;
+import com.google.api.services.sheets.v4.model.BatchUpdateValuesRequest;
+import com.google.api.services.sheets.v4.model.BatchUpdateValuesResponse;
+import com.google.api.services.sheets.v4.model.CopyPasteRequest;
+import com.google.api.services.sheets.v4.model.GridRange;
+import com.google.api.services.sheets.v4.model.Request;
+import com.google.api.services.sheets.v4.model.Spreadsheet;
+import com.google.api.services.sheets.v4.model.SpreadsheetProperties;
+import com.google.api.services.sheets.v4.model.UpdateSpreadsheetPropertiesRequest;
+import com.google.api.services.sheets.v4.model.UpdateValuesResponse;
+import com.google.api.services.sheets.v4.model.ValueRange;
+
+import static org.assertj.core.api.Assertions.*;
+
+public class GoogleSheetsIntegrationTest {
+
+ private static Sheets sheetsService;
+
+ // this id can be replaced with your spreadsheet id
+ // otherwise be advised that multiple people may run this test and update the public spreadsheet
+ private static final String SPREADSHEET_ID = "1sILuxZUnyl_7-MlNThjt765oWshN3Xs-PPLfqYe4DhI";
+
+ @BeforeClass
+ public static void setup() throws GeneralSecurityException, IOException {
+ sheetsService = SheetsServiceUtil.getSheetsService();
+ }
+
+ @Test
+ public void whenWriteSheet_thenReadSheetOk() throws IOException {
+ ValueRange body = new ValueRange()
+ .setValues(Arrays.asList(
+ Arrays.asList("Expenses January"),
+ Arrays.asList("books", "30"),
+ Arrays.asList("pens", "10"),
+ Arrays.asList("Expenses February"),
+ Arrays.asList("clothes", "20"),
+ Arrays.asList("shoes", "5")));
+ UpdateValuesResponse result = sheetsService.spreadsheets().values()
+ .update(SPREADSHEET_ID, "A1", body)
+ .setValueInputOption("RAW")
+ .execute();
+
+ List data = new ArrayList<>();
+ data.add(new ValueRange()
+ .setRange("D1")
+ .setValues(Arrays.asList(
+ Arrays.asList("January Total", "=B2+B3"))));
+ data.add(new ValueRange()
+ .setRange("D4")
+ .setValues(Arrays.asList(
+ Arrays.asList("February Total", "=B5+B6"))));
+
+ BatchUpdateValuesRequest batchBody = new BatchUpdateValuesRequest()
+ .setValueInputOption("USER_ENTERED")
+ .setData(data);
+ BatchUpdateValuesResponse batchResult =
+ sheetsService.spreadsheets().values()
+ .batchUpdate(SPREADSHEET_ID, batchBody)
+ .execute();
+
+ List ranges = Arrays.asList("E1","E4");
+ BatchGetValuesResponse readResult =
+ sheetsService.spreadsheets().values()
+ .batchGet(SPREADSHEET_ID)
+ .setRanges(ranges)
+ .execute();
+
+ ValueRange januaryTotal = readResult.getValueRanges().get(0);
+ assertThat(januaryTotal.getValues().get(0).get(0)).isEqualTo("40");
+
+ ValueRange febTotal = readResult.getValueRanges().get(1);
+ assertThat(febTotal.getValues().get(0).get(0)).isEqualTo("25");
+
+ ValueRange appendBody = new ValueRange()
+ .setValues(Arrays.asList(
+ Arrays.asList("Total", "=E1+E4")));
+ AppendValuesResponse appendResult =
+ sheetsService.spreadsheets().values()
+ .append(SPREADSHEET_ID, "A1", appendBody)
+ .setValueInputOption("USER_ENTERED")
+ .setInsertDataOption("INSERT_ROWS")
+ .setIncludeValuesInResponse(true)
+ .execute();
+
+ ValueRange total = appendResult.getUpdates().getUpdatedData();
+ assertThat(total.getValues().get(0).get(1)).isEqualTo("65");
+ }
+
+
+ @Test
+ public void whenUpdateSpreadSheetTitle_thenOk() throws IOException {
+
+ UpdateSpreadsheetPropertiesRequest updateRequest = new UpdateSpreadsheetPropertiesRequest()
+ .setFields("*")
+ .setProperties(new SpreadsheetProperties().setTitle("Expenses"));
+
+ CopyPasteRequest copyRequest = new CopyPasteRequest()
+ .setSource(new GridRange().setSheetId(0)
+ .setStartColumnIndex(0).setEndColumnIndex(2)
+ .setStartRowIndex(0).setEndRowIndex(1))
+ .setDestination(new GridRange().setSheetId(1)
+ .setStartColumnIndex(0).setEndColumnIndex(2)
+ .setStartRowIndex(0).setEndRowIndex(1))
+ .setPasteType("PASTE_VALUES");
+
+ List requests = new ArrayList<>();
+
+ requests.add(new Request().setCopyPaste(copyRequest));
+ requests.add(new Request().setUpdateSpreadsheetProperties(updateRequest));
+
+ BatchUpdateSpreadsheetRequest body =
+ new BatchUpdateSpreadsheetRequest().setRequests(requests);
+
+ sheetsService.spreadsheets().batchUpdate(SPREADSHEET_ID, body).execute();
+ }
+
+ @Test
+ public void whenCreateSpreadSheet_thenIdOk() throws IOException {
+ Spreadsheet spreadSheet = new Spreadsheet()
+ .setProperties(new SpreadsheetProperties().setTitle("My Spreadsheet"));
+ Spreadsheet result = sheetsService.spreadsheets().create(spreadSheet).execute();
+
+ assertThat(result.getSpreadsheetId()).isNotNull();
+ }
+
+}
diff --git a/spring-5-reactive-client/.gitignore b/spring-5-reactive-client/.gitignore
new file mode 100644
index 0000000000..dec013dfa4
--- /dev/null
+++ b/spring-5-reactive-client/.gitignore
@@ -0,0 +1,12 @@
+#folders#
+.idea
+/target
+/neoDb*
+/data
+/src/main/webapp/WEB-INF/classes
+*/META-INF/*
+
+# Packaged files #
+*.jar
+*.war
+*.ear
\ No newline at end of file
diff --git a/spring-5-reactive-client/README.md b/spring-5-reactive-client/README.md
new file mode 100644
index 0000000000..400e343263
--- /dev/null
+++ b/spring-5-reactive-client/README.md
@@ -0,0 +1,15 @@
+## Spring REST Example Project
+
+### The Course
+The "REST With Spring" Classes: http://bit.ly/restwithspring
+
+### Relevant Articles
+
+- [Concurrent Test Execution in Spring 5](http://www.baeldung.com/spring-5-concurrent-tests)
+- [Introduction to the Functional Web Framework in Spring 5](http://www.baeldung.com/spring-5-functional-web)
+- [Exploring the Spring 5 MVC URL Matching Improvements](http://www.baeldung.com/spring-5-mvc-url-matching)
+- [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient)
+- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans)
+- [The SpringJUnitConfig and SpringJUnitWebConfig Annotations in Spring 5](http://www.baeldung.com/spring-5-junit-config)
+- [Spring Security 5 for Reactive Applications](http://www.baeldung.com/spring-security-5-reactive)
+- [Spring 5 Testing with @EnabledIf Annotation](https://github.com/eugenp/tutorials/tree/master/spring-5)
diff --git a/spring-5-reactive-client/pom.xml b/spring-5-reactive-client/pom.xml
new file mode 100644
index 0000000000..8aa579b724
--- /dev/null
+++ b/spring-5-reactive-client/pom.xml
@@ -0,0 +1,201 @@
+
+
+ 4.0.0
+
+ com.baeldung
+ spring-5-reactive-client
+ 0.0.1-SNAPSHOT
+ jar
+
+ spring-5
+ spring 5 sample project about new features
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.0.0.M7
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.projectreactor
+ reactor-spring
+ ${reactor-spring.version}
+
+
+ javax.json.bind
+ javax.json.bind-api
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.geronimo.specs
+ geronimo-json_1.1_spec
+ ${geronimo-json_1.1_spec.version}
+
+
+ org.apache.johnzon
+ johnzon-jsonb
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework
+ spring-test
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+ org.apache.commons
+ commons-collections4
+ 4.1
+ test
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ test
+
+
+ org.junit.platform
+ junit-platform-surefire-provider
+ ${junit.platform.version}
+ test
+
+
+ org.junit.platform
+ junit-platform-runner
+ ${junit.platform.version}
+ test
+
+
+
+ org.projectlombok
+ lombok
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ com.baeldung.Spring5Application
+ JAR
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ 3
+ true
+ methods
+ true
+
+ **/*IntegrationTest.java
+ **/*LiveTest.java
+
+
+
+
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ spring-milestones
+ Spring Milestones
+ https://repo.spring.io/milestone
+
+ false
+
+
+
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.0.0
+ 5.0.0
+ 2.20
+ 5.0.1.RELEASE
+ 1.0.1.RELEASE
+ 1.1.3
+ 1.0
+ 1.0
+
+
+
diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java
similarity index 78%
rename from spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java
rename to spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java
index 480782a551..2c49e6146a 100644
--- a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/Foo.java
+++ b/spring-5-reactive-client/src/main/java/com/baeldung/reactive/model/Foo.java
@@ -1,4 +1,4 @@
-package com.baeldung.reactive.controller;
+package com.baeldung.reactive.model;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/spring-5-reactive-client/src/main/resources/application.properties b/spring-5-reactive-client/src/main/resources/application.properties
new file mode 100644
index 0000000000..2d93456aeb
--- /dev/null
+++ b/spring-5-reactive-client/src/main/resources/application.properties
@@ -0,0 +1,3 @@
+logging.level.root=INFO
+
+server.port=8081
\ No newline at end of file
diff --git a/spring-5-reactive-client/src/main/resources/logback.xml b/spring-5-reactive-client/src/main/resources/logback.xml
new file mode 100644
index 0000000000..8bbe8c1d67
--- /dev/null
+++ b/spring-5-reactive-client/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ # Pattern of log message for console appender
+ %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml b/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000..bfcf43dad2
--- /dev/null
+++ b/spring-5-reactive-client/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+
+
+
+ Spring Functional Application
+
+
+ functional
+ com.baeldung.functional.RootServlet
+ 1
+ true
+
+
+ functional
+ /
+
+
+
+
\ No newline at end of file
diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java
new file mode 100644
index 0000000000..394ff42e5f
--- /dev/null
+++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/ReactiveIntegrationTest.java
@@ -0,0 +1,42 @@
+package com.baeldung.reactive;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.web.reactive.function.client.ClientResponse;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import com.baeldung.reactive.model.Foo;
+
+import reactor.core.publisher.Mono;
+
+@SpringBootTest
+public class ReactiveIntegrationTest {
+
+ private WebClient client;
+
+ @BeforeEach
+ public void before() {
+ client = WebClient.create("http://localhost:8080");
+ }
+
+ //
+
+ @Test
+ public void whenMonoReactiveEndpointIsConsumed_thenCorrectOutput() {
+ final Mono fooMono = client.get().uri("/foos/123").exchange().log();
+
+ System.out.println(fooMono.subscribe());
+ }
+
+ @Test
+ public void whenFluxReactiveEndpointIsConsumed_thenCorrectOutput() throws InterruptedException {
+ client.get().uri("/foos")
+ .retrieve()
+ .bodyToFlux(Foo.class).log()
+ .subscribe(System.out::println);
+
+ System.out.println();
+ }
+
+}
diff --git a/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java
new file mode 100644
index 0000000000..c884ace323
--- /dev/null
+++ b/spring-5-reactive-client/src/test/java/com/baeldung/reactive/Spring5ReactiveTestApplication.java
@@ -0,0 +1,35 @@
+package com.baeldung.reactive;
+
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.reactive.function.client.WebClient;
+
+import com.baeldung.reactive.model.Foo;
+
+@SpringBootApplication
+public class Spring5ReactiveTestApplication {
+
+ @Bean
+ public WebClient client() {
+ return WebClient.create("http://localhost:8080");
+ }
+
+ @Bean
+ CommandLineRunner cmd(WebClient client) {
+ return args -> {
+ client.get().uri("/foos2")
+ .retrieve()
+ .bodyToFlux(Foo.class).log()
+ .subscribe(System.out::println);
+ };
+ }
+
+ //
+
+ public static void main(String[] args) {
+ SpringApplication.run(Spring5ReactiveTestApplication.class, args);
+ }
+
+}
diff --git a/spring-5-reactive-client/src/test/resources/logback-test.xml b/spring-5-reactive-client/src/test/resources/logback-test.xml
new file mode 100644
index 0000000000..8bbe8c1d67
--- /dev/null
+++ b/spring-5-reactive-client/src/test/resources/logback-test.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ # Pattern of log message for console appender
+ %d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java
index 1115036ad3..933d469f65 100644
--- a/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/controller/FooReactiveController.java
@@ -3,13 +3,19 @@ package com.baeldung.reactive.controller;
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import java.time.Duration;
+import java.util.Random;
+import java.util.stream.Stream;
+import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
+import com.baeldung.reactive.model.Foo;
+
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import reactor.util.function.Tuple2;
@RestController
public class FooReactiveController {
@@ -19,11 +25,18 @@ public class FooReactiveController {
return Mono.just(new Foo(id, randomAlphabetic(6)));
}
- @GetMapping("/foos")
+ @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/foos")
+ public Flux getAllFoos2() {
+ final Flux foosFlux = Flux.fromStream(Stream.generate(() -> new Foo(new Random().nextLong(), randomAlphabetic(6))));
+ final Flux emmitFlux = Flux.interval(Duration.ofSeconds(1));
+ return Flux.zip(foosFlux, emmitFlux).map(Tuple2::getT1);
+ }
+
+ @GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE, value = "/foos2")
public Flux getAllFoos() {
final Flux flux = Flux. create(fluxSink -> {
while (true) {
- fluxSink.next(new Foo(System.currentTimeMillis(), randomAlphabetic(6)));
+ fluxSink.next(new Foo(new Random().nextLong(), randomAlphabetic(6)));
}
}).sample(Duration.ofSeconds(1)).log();
diff --git a/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java b/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java
new file mode 100644
index 0000000000..2c49e6146a
--- /dev/null
+++ b/spring-5-reactive/src/main/java/com/baeldung/reactive/model/Foo.java
@@ -0,0 +1,13 @@
+package com.baeldung.reactive.model;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@AllArgsConstructor
+@Data
+public class Foo {
+
+ private long id;
+ private String name;
+
+}
diff --git a/spring-5-reactive/src/main/resources/files/hello.txt b/spring-5-reactive/src/main/resources/files/hello.txt
deleted file mode 100644
index b6fc4c620b..0000000000
--- a/spring-5-reactive/src/main/resources/files/hello.txt
+++ /dev/null
@@ -1 +0,0 @@
-hello
\ No newline at end of file
diff --git a/spring-5-reactive/src/main/resources/files/test/test.txt b/spring-5-reactive/src/main/resources/files/test/test.txt
deleted file mode 100644
index 30d74d2584..0000000000
--- a/spring-5-reactive/src/main/resources/files/test/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-test
\ No newline at end of file
diff --git a/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java b/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java
index 5499e72877..bad5fc5f22 100644
--- a/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java
+++ b/spring-5-reactive/src/test/java/com/baeldung/reactive/FluxUnitTest.java
@@ -4,10 +4,11 @@ import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
import static org.junit.Assert.assertNotNull;
import java.time.Duration;
+import java.util.Random;
import org.junit.jupiter.api.Test;
-import com.baeldung.reactive.controller.Foo;
+import com.baeldung.reactive.model.Foo;
import reactor.core.publisher.Flux;
@@ -17,7 +18,7 @@ public class FluxUnitTest {
public void whenFluxIsConstructed_thenCorrect() {
final Flux flux = Flux. create(fluxSink -> {
while (true) {
- fluxSink.next(new Foo(System.currentTimeMillis(), randomAlphabetic(6)));
+ fluxSink.next(new Foo(new Random().nextLong(), randomAlphabetic(6)));
}
}).sample(Duration.ofSeconds(1)).log();