Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-1433
This commit is contained in:
commit
4e6650ca4d
|
@ -633,9 +633,26 @@
|
|||
<version>${googleclient.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client-gson</artifactId>
|
||||
<version>${googleclient.version}</version>
|
||||
<groupId>com.google.http-client</groupId>
|
||||
<artifactId>google-http-client-gson</artifactId>
|
||||
<version>${googleclient.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- google api -->
|
||||
<dependency>
|
||||
<groupId>com.google.api-client</groupId>
|
||||
<artifactId>google-api-client</artifactId>
|
||||
<version>${google-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.oauth-client</groupId>
|
||||
<artifactId>google-oauth-client-jetty</artifactId>
|
||||
<version>${google-api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.apis</groupId>
|
||||
<artifactId>google-api-services-sheets</artifactId>
|
||||
<version>${google-sheets.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
|
@ -710,5 +727,7 @@
|
|||
<cache.version>1.0.0</cache.version>
|
||||
<hazelcast.version>3.8.4</hazelcast.version>
|
||||
<caffeine.version>2.5.5</caffeine.version>
|
||||
<google-api.version>1.23.0</google-api.version>
|
||||
<google-sheets.version>v4-rev493-1.21.0</google-sheets.version>
|
||||
</properties>
|
||||
</project>
|
|
@ -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<String> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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"]}}
|
|
@ -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<ValueRange> 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<String> 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<Request> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#folders#
|
||||
.idea
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
|
@ -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)
|
|
@ -0,0 +1,201 @@
|
|||
<?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</groupId>
|
||||
<artifactId>spring-5-reactive-client</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>spring-5</name>
|
||||
<description>spring 5 sample project about new features</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.M7</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</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-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectreactor</groupId>
|
||||
<artifactId>reactor-spring</artifactId>
|
||||
<version>${reactor-spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.json.bind</groupId>
|
||||
<artifactId>javax.json.bind-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Dependencies for Yasson -->
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.eclipse</groupId> -->
|
||||
<!-- <artifactId>yasson</artifactId> -->
|
||||
<!-- <version>1.0</version> -->
|
||||
<!-- </dependency> -->
|
||||
<!-- <dependency> -->
|
||||
<!-- <groupId>org.glassfish</groupId> -->
|
||||
<!-- <artifactId>javax.json</artifactId> -->
|
||||
<!-- <version>1.1.2</version> -->
|
||||
<!-- </dependency> -->
|
||||
<!-- Dependencies for Johnzon -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.geronimo.specs</groupId>
|
||||
<artifactId>geronimo-json_1.1_spec</artifactId>
|
||||
<version>${geronimo-json_1.1_spec.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.johnzon</groupId>
|
||||
<artifactId>johnzon-jsonb</artifactId>
|
||||
</dependency>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- runtime and test scoped -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>4.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-surefire-provider</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.platform</groupId>
|
||||
<artifactId>junit-platform-runner</artifactId>
|
||||
<version>${junit.platform.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<mainClass>com.baeldung.Spring5Application</mainClass>
|
||||
<layout>JAR</layout>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<forkCount>3</forkCount>
|
||||
<reuseForks>true</reuseForks>
|
||||
<parallel>methods</parallel>
|
||||
<useUnlimitedThreads>true</useUnlimitedThreads>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<junit.platform.version>1.0.0</junit.platform.version>
|
||||
<junit.jupiter.version>5.0.0</junit.jupiter.version>
|
||||
<maven-surefire-plugin.version>2.20</maven-surefire-plugin.version>
|
||||
<spring.version>5.0.1.RELEASE</spring.version>
|
||||
<reactor-spring.version>1.0.1.RELEASE</reactor-spring.version>
|
||||
<johnzon.version>1.1.3</johnzon.version>
|
||||
<jsonb-api.version>1.0</jsonb-api.version>
|
||||
<geronimo-json_1.1_spec.version>1.0</geronimo-json_1.1_spec.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -1,4 +1,4 @@
|
|||
package com.baeldung.reactive.controller;
|
||||
package com.baeldung.reactive.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
|
@ -0,0 +1,3 @@
|
|||
logging.level.root=INFO
|
||||
|
||||
server.port=8081
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
# Pattern of log message for console appender
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="INFO" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
|
||||
version="3.1">
|
||||
|
||||
<display-name>Spring Functional Application</display-name>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>functional</servlet-name>
|
||||
<servlet-class>com.baeldung.functional.RootServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
<async-supported>true</async-supported>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>functional</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
|
||||
</web-app>
|
|
@ -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<ClientResponse> 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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
# Pattern of log message for console appender
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="INFO" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="stdout" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -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<Foo> getAllFoos2() {
|
||||
final Flux<Foo> foosFlux = Flux.fromStream(Stream.generate(() -> new Foo(new Random().nextLong(), randomAlphabetic(6))));
|
||||
final Flux<Long> 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<Foo> getAllFoos() {
|
||||
final Flux<Foo> flux = Flux.<Foo> 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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
hello
|
|
@ -1 +0,0 @@
|
|||
test
|
|
@ -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<Foo> flux = Flux.<Foo> 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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue