Merge branch 'master' of https://github.com/eugenp/tutorials
This commit is contained in:
commit
96bb1a3bd3
|
@ -12,7 +12,7 @@ import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class CustomerRepositoryInitialMigrationTest {
|
public class CustomerRepositoryInitialMigrationIntegrationTest {
|
||||||
|
|
||||||
@Autowired CustomerRepository customerRepository;
|
@Autowired CustomerRepository customerRepository;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import static org.junit.Assert.*;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class CustomerRepositoryInsertDataMigrationTest {
|
public class CustomerRepositoryInsertDataIntegrationTest {
|
||||||
|
|
||||||
@Autowired CustomerRepository customerRepository;
|
@Autowired CustomerRepository customerRepository;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class CustomerRepositoryNotNullConstraintMigrationTest {
|
public class CustomerRepositoryNotNullConstraintMigrationIntegrationTest {
|
||||||
|
|
||||||
@Autowired CustomerRepository customerRepository;
|
@Autowired CustomerRepository customerRepository;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
@SpringBootTest(properties = {
|
@SpringBootTest(properties = {
|
||||||
"flyway.locations[0]=db/migration", "flyway.locations[1]=com/baeldung/springflyway/migration"
|
"flyway.locations[0]=db/migration", "flyway.locations[1]=com/baeldung/springflyway/migration"
|
||||||
})
|
})
|
||||||
public class CustomerRepositoryUniqueConstraintJavaMigrationTest {
|
public class CustomerRepositoryUniqueConstraintJavaMigrationIntegrationTest {
|
||||||
|
|
||||||
@Autowired CustomerRepository customerRepository;
|
@Autowired CustomerRepository customerRepository;
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class CustomerRepositoryUniqueConstraintMigrationTest {
|
public class CustomerRepositoryUniqueConstraintMigrationIntegrationTest {
|
||||||
|
|
||||||
@Autowired CustomerRepository customerRepository;
|
@Autowired CustomerRepository customerRepository;
|
||||||
|
|
|
@ -633,9 +633,26 @@
|
||||||
<version>${googleclient.version}</version>
|
<version>${googleclient.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.http-client</groupId>
|
<groupId>com.google.http-client</groupId>
|
||||||
<artifactId>google-http-client-gson</artifactId>
|
<artifactId>google-http-client-gson</artifactId>
|
||||||
<version>${googleclient.version}</version>
|
<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>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
|
@ -710,5 +727,7 @@
|
||||||
<cache.version>1.0.0</cache.version>
|
<cache.version>1.0.0</cache.version>
|
||||||
<hazelcast.version>3.8.4</hazelcast.version>
|
<hazelcast.version>3.8.4</hazelcast.version>
|
||||||
<caffeine.version>2.5.5</caffeine.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>
|
</properties>
|
||||||
</project>
|
</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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import org.neuroph.core.NeuralNetwork;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
public class XORTest {
|
public class XORIntegrationTest {
|
||||||
private NeuralNetwork ann = null;
|
private NeuralNetwork ann = null;
|
||||||
|
|
||||||
private void print(String input, double output, double actual) {
|
private void print(String input, double output, double actual) {
|
6
pom.xml
6
pom.xml
|
@ -49,8 +49,6 @@
|
||||||
<module>core-java-8</module>
|
<module>core-java-8</module>
|
||||||
<module>core-java-concurrency</module>
|
<module>core-java-concurrency</module>
|
||||||
<module>couchbase</module>
|
<module>couchbase</module>
|
||||||
<module>cas/cas-server</module>
|
|
||||||
<module>cas/cas-secured-app</module>
|
|
||||||
|
|
||||||
<module>deltaspike</module>
|
<module>deltaspike</module>
|
||||||
<module>dozer</module>
|
<module>dozer</module>
|
||||||
|
@ -141,8 +139,8 @@
|
||||||
<module>persistence-modules/solr</module>
|
<module>persistence-modules/solr</module>
|
||||||
<module>spark-java</module>
|
<module>spark-java</module>
|
||||||
<!-- <module>spring-5</module>-->
|
<!-- <module>spring-5</module>-->
|
||||||
|
<module>spring-5-reactive</module>
|
||||||
<module>spring-5-mvc</module>
|
<module>spring-5-mvc</module>
|
||||||
<module>spring-acl</module>
|
|
||||||
<module>spring-activiti</module>
|
<module>spring-activiti</module>
|
||||||
<module>spring-akka</module>
|
<module>spring-akka</module>
|
||||||
<module>spring-amqp</module>
|
<module>spring-amqp</module>
|
||||||
|
@ -152,7 +150,7 @@
|
||||||
<module>spring-batch</module>
|
<module>spring-batch</module>
|
||||||
<module>spring-bom</module>
|
<module>spring-bom</module>
|
||||||
<module>spring-boot</module>
|
<module>spring-boot</module>
|
||||||
<module>spring-boot-keycloak</module>
|
<module>spring-boot-keycloak</module>
|
||||||
<module>spring-boot-bootstrap</module>
|
<module>spring-boot-bootstrap</module>
|
||||||
<module>spring-cloud-data-flow</module>
|
<module>spring-cloud-data-flow</module>
|
||||||
<module>spring-cloud</module>
|
<module>spring-cloud</module>
|
||||||
|
|
|
@ -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>
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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>
|
|
@ -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</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>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package com.baeldung.reactive;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Spring5ReactiveApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Spring5ReactiveApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
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 {
|
||||||
|
|
||||||
|
@GetMapping("/foos/{id}")
|
||||||
|
public Mono<Foo> getFoo(@PathVariable("id") long id) {
|
||||||
|
return Mono.just(new Foo(id, randomAlphabetic(6)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(new Random().nextLong(), randomAlphabetic(6)));
|
||||||
|
}
|
||||||
|
}).sample(Duration.ofSeconds(1)).log();
|
||||||
|
|
||||||
|
return flux;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
logging.level.root=INFO
|
|
@ -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,30 @@
|
||||||
|
package com.baeldung.reactive;
|
||||||
|
|
||||||
|
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.model.Foo;
|
||||||
|
|
||||||
|
import reactor.core.publisher.Flux;
|
||||||
|
|
||||||
|
public class FluxUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenFluxIsConstructed_thenCorrect() {
|
||||||
|
final Flux<Foo> flux = Flux.<Foo> create(fluxSink -> {
|
||||||
|
while (true) {
|
||||||
|
fluxSink.next(new Foo(new Random().nextLong(), randomAlphabetic(6)));
|
||||||
|
}
|
||||||
|
}).sample(Duration.ofSeconds(1)).log();
|
||||||
|
|
||||||
|
flux.subscribe();
|
||||||
|
|
||||||
|
assertNotNull(flux);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package com.baeldung.web;
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
|
|
|
@ -1,66 +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</groupId>
|
|
||||||
<artifactId>spring-acl</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<name>spring-acl</name>
|
|
||||||
<description>Spring ACL</description>
|
|
||||||
|
|
||||||
<parent>
|
|
||||||
<artifactId>parent-boot-5</artifactId>
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<relativePath>../parent-boot-5</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.h2database</groupId>
|
|
||||||
<artifactId>h2</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-acl</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.security</groupId>
|
|
||||||
<artifactId>spring-security-config</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework</groupId>
|
|
||||||
<artifactId>spring-context-support</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.sf.ehcache</groupId>
|
|
||||||
<artifactId>ehcache-core</artifactId>
|
|
||||||
<version>2.6.11</version>
|
|
||||||
<type>jar</type>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,80 +0,0 @@
|
||||||
package org.baeldung.acl.config;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
|
||||||
import org.springframework.cache.ehcache.EhCacheFactoryBean;
|
|
||||||
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
|
||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
|
||||||
import org.springframework.security.acls.AclPermissionCacheOptimizer;
|
|
||||||
import org.springframework.security.acls.AclPermissionEvaluator;
|
|
||||||
import org.springframework.security.acls.domain.AclAuthorizationStrategy;
|
|
||||||
import org.springframework.security.acls.domain.AclAuthorizationStrategyImpl;
|
|
||||||
import org.springframework.security.acls.domain.ConsoleAuditLogger;
|
|
||||||
import org.springframework.security.acls.domain.DefaultPermissionGrantingStrategy;
|
|
||||||
import org.springframework.security.acls.domain.EhCacheBasedAclCache;
|
|
||||||
import org.springframework.security.acls.jdbc.BasicLookupStrategy;
|
|
||||||
import org.springframework.security.acls.jdbc.JdbcMutableAclService;
|
|
||||||
import org.springframework.security.acls.jdbc.LookupStrategy;
|
|
||||||
import org.springframework.security.acls.model.PermissionGrantingStrategy;
|
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableAutoConfiguration
|
|
||||||
public class ACLContext {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
DataSource dataSource;
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EhCacheBasedAclCache aclCache() {
|
|
||||||
return new EhCacheBasedAclCache(aclEhCacheFactoryBean().getObject(), permissionGrantingStrategy(), aclAuthorizationStrategy());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EhCacheFactoryBean aclEhCacheFactoryBean() {
|
|
||||||
EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
|
|
||||||
ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
|
|
||||||
ehCacheFactoryBean.setCacheName("aclCache");
|
|
||||||
return ehCacheFactoryBean;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public EhCacheManagerFactoryBean aclCacheManager() {
|
|
||||||
return new EhCacheManagerFactoryBean();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PermissionGrantingStrategy permissionGrantingStrategy() {
|
|
||||||
return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AclAuthorizationStrategy aclAuthorizationStrategy() {
|
|
||||||
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
|
|
||||||
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
|
||||||
AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
|
|
||||||
expressionHandler.setPermissionEvaluator(permissionEvaluator);
|
|
||||||
expressionHandler.setPermissionCacheOptimizer(new AclPermissionCacheOptimizer(aclService()));
|
|
||||||
return expressionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public LookupStrategy lookupStrategy() {
|
|
||||||
return new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), new ConsoleAuditLogger());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public JdbcMutableAclService aclService() {
|
|
||||||
return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package org.baeldung.acl.config;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
|
||||||
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
|
|
||||||
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected MethodSecurityExpressionHandler createExpressionHandler() {
|
|
||||||
return defaultMethodSecurityExpressionHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
package org.baeldung.acl.config;
|
|
||||||
|
|
||||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.PropertySource;
|
|
||||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableTransactionManagement
|
|
||||||
@EnableJpaRepositories(basePackages = "org.baeldung.acl.persistence.dao")
|
|
||||||
@PropertySource("classpath:org.baeldung.acl.datasource.properties")
|
|
||||||
@EntityScan(basePackages={ "org.baeldung.acl.persistence.entity" })
|
|
||||||
public class JPAPersistenceConfig {
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
package org.baeldung.acl.persistence.dao;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.baeldung.acl.persistence.entity.NoticeMessage;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
import org.springframework.data.repository.query.Param;
|
|
||||||
import org.springframework.security.access.prepost.PostAuthorize;
|
|
||||||
import org.springframework.security.access.prepost.PostFilter;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
|
|
||||||
public interface NoticeMessageRepository extends JpaRepository<NoticeMessage, Long>{
|
|
||||||
|
|
||||||
@PostFilter("hasPermission(filterObject, 'READ')")
|
|
||||||
List<NoticeMessage> findAll();
|
|
||||||
|
|
||||||
@PostAuthorize("hasPermission(returnObject, 'READ')")
|
|
||||||
NoticeMessage findById(Integer id);
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@PreAuthorize("hasPermission(#noticeMessage, 'WRITE')")
|
|
||||||
NoticeMessage save(@Param("noticeMessage")NoticeMessage noticeMessage);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package org.baeldung.acl.persistence.entity;
|
|
||||||
|
|
||||||
import javax.persistence.Column;
|
|
||||||
import javax.persistence.Entity;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
import javax.persistence.Table;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name="system_message")
|
|
||||||
public class NoticeMessage {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@Column
|
|
||||||
private Integer id;
|
|
||||||
@Column
|
|
||||||
private String content;
|
|
||||||
public Integer getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public void setId(Integer id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
public String getContent() {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
public void setContent(String content) {
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
INSERT INTO system_message(id,content) VALUES (1,'First Level Message');
|
|
||||||
INSERT INTO system_message(id,content) VALUES (2,'Second Level Message');
|
|
||||||
INSERT INTO system_message(id,content) VALUES (3,'Third Level Message');
|
|
||||||
|
|
||||||
INSERT INTO acl_class (id, class) VALUES
|
|
||||||
(1, 'org.baeldung.acl.persistence.entity.NoticeMessage');
|
|
||||||
|
|
||||||
INSERT INTO acl_sid (id, principal, sid) VALUES
|
|
||||||
(1, 1, 'manager'),
|
|
||||||
(2, 1, 'hr'),
|
|
||||||
(3, 1, 'admin'),
|
|
||||||
(4, 0, 'ROLE_EDITOR');
|
|
||||||
|
|
||||||
INSERT INTO acl_object_identity (id, object_id_class, object_id_identity, parent_object, owner_sid, entries_inheriting) VALUES
|
|
||||||
(1, 1, 1, NULL, 3, 0),
|
|
||||||
(2, 1, 2, NULL, 3, 0),
|
|
||||||
(3, 1, 3, NULL, 3, 0)
|
|
||||||
;
|
|
||||||
|
|
||||||
INSERT INTO acl_entry (id, acl_object_identity, ace_order, sid, mask, granting, audit_success, audit_failure) VALUES
|
|
||||||
(1, 1, 1, 1, 1, 1, 1, 1),
|
|
||||||
(2, 1, 2, 1, 2, 1, 1, 1),
|
|
||||||
(3, 1, 3, 4, 1, 1, 1, 1),
|
|
||||||
(4, 2, 1, 2, 1, 1, 1, 1),
|
|
||||||
(5, 2, 2, 4, 1, 1, 1, 1),
|
|
||||||
(6, 3, 1, 4, 1, 1, 1, 1),
|
|
||||||
(7, 3, 2, 4, 2, 1, 1, 1)
|
|
||||||
;
|
|
|
@ -1,58 +0,0 @@
|
||||||
create table system_message (id integer not null, content varchar(255), primary key (id));
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acl_sid (
|
|
||||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
principal tinyint(1) NOT NULL,
|
|
||||||
sid varchar(100) NOT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
UNIQUE KEY unique_uk_1 (sid,principal)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acl_class (
|
|
||||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
class varchar(255) NOT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
UNIQUE KEY unique_uk_2 (class)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acl_entry (
|
|
||||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
acl_object_identity bigint(20) NOT NULL,
|
|
||||||
ace_order int(11) NOT NULL,
|
|
||||||
sid bigint(20) NOT NULL,
|
|
||||||
mask int(11) NOT NULL,
|
|
||||||
granting tinyint(1) NOT NULL,
|
|
||||||
audit_success tinyint(1) NOT NULL,
|
|
||||||
audit_failure tinyint(1) NOT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS acl_object_identity (
|
|
||||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
|
||||||
object_id_class bigint(20) NOT NULL,
|
|
||||||
object_id_identity bigint(20) NOT NULL,
|
|
||||||
parent_object bigint(20) DEFAULT NULL,
|
|
||||||
owner_sid bigint(20) DEFAULT NULL,
|
|
||||||
entries_inheriting tinyint(1) NOT NULL,
|
|
||||||
PRIMARY KEY (id),
|
|
||||||
UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity)
|
|
||||||
);
|
|
||||||
|
|
||||||
ALTER TABLE acl_entry
|
|
||||||
ADD FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity(id);
|
|
||||||
|
|
||||||
ALTER TABLE acl_entry
|
|
||||||
ADD FOREIGN KEY (sid) REFERENCES acl_sid(id);
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Constraints for table acl_object_identity
|
|
||||||
--
|
|
||||||
ALTER TABLE acl_object_identity
|
|
||||||
ADD FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id);
|
|
||||||
|
|
||||||
ALTER TABLE acl_object_identity
|
|
||||||
ADD FOREIGN KEY (object_id_class) REFERENCES acl_class (id);
|
|
||||||
|
|
||||||
ALTER TABLE acl_object_identity
|
|
||||||
ADD FOREIGN KEY (owner_sid) REFERENCES acl_sid (id);
|
|
|
@ -1,12 +0,0 @@
|
||||||
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE
|
|
||||||
spring.datasource.username=sa
|
|
||||||
spring.datasource.password=
|
|
||||||
spring.datasource.driverClassName=org.h2.Driver
|
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
|
||||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
|
|
||||||
|
|
||||||
spring.h2.console.path=/myconsole
|
|
||||||
spring.h2.console.enabled=true
|
|
||||||
spring.datasource.initialize=true
|
|
||||||
spring.datasource.schema=classpath:acl-schema.sql
|
|
||||||
spring.datasource.data=classpath:acl-data.sql
|
|
|
@ -1,119 +0,0 @@
|
||||||
package org.baeldung.acl;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.baeldung.acl.persistence.dao.NoticeMessageRepository;
|
|
||||||
import org.baeldung.acl.persistence.entity.NoticeMessage;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
|
||||||
import org.springframework.security.test.context.support.WithMockUser;
|
|
||||||
import org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener;
|
|
||||||
import org.springframework.test.context.ContextConfiguration;
|
|
||||||
import org.springframework.test.context.TestExecutionListeners;
|
|
||||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
|
||||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
|
||||||
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
|
|
||||||
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
|
|
||||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
|
||||||
import org.springframework.test.context.web.ServletTestExecutionListener;
|
|
||||||
|
|
||||||
@RunWith(SpringJUnit4ClassRunner.class)
|
|
||||||
@ContextConfiguration
|
|
||||||
@TestExecutionListeners(listeners={ServletTestExecutionListener.class,
|
|
||||||
DependencyInjectionTestExecutionListener.class,
|
|
||||||
DirtiesContextTestExecutionListener.class,
|
|
||||||
TransactionalTestExecutionListener.class,
|
|
||||||
WithSecurityContextTestExecutionListener.class})
|
|
||||||
public class SpringAclTest extends AbstractJUnit4SpringContextTests{
|
|
||||||
|
|
||||||
private static Integer FIRST_MESSAGE_ID = 1;
|
|
||||||
private static Integer SECOND_MESSAGE_ID = 2;
|
|
||||||
private static Integer THIRD_MESSAGE_ID = 3;
|
|
||||||
private static String EDITTED_CONTENT = "EDITED";
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ComponentScan("org.baeldung.acl.*")
|
|
||||||
public static class SpringConfig {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
NoticeMessageRepository repo;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithMockUser(username="manager")
|
|
||||||
public void givenUsernameManager_whenFindAllMessage_thenReturnFirstMessage(){
|
|
||||||
List<NoticeMessage> details = repo.findAll();
|
|
||||||
assertNotNull(details);
|
|
||||||
assertEquals(1,details.size());
|
|
||||||
assertEquals(FIRST_MESSAGE_ID,details.get(0).getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithMockUser(username="manager")
|
|
||||||
public void givenUsernameManager_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenOK(){
|
|
||||||
NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID);
|
|
||||||
assertNotNull(firstMessage);
|
|
||||||
assertEquals(FIRST_MESSAGE_ID,firstMessage.getId());
|
|
||||||
|
|
||||||
firstMessage.setContent(EDITTED_CONTENT);
|
|
||||||
repo.save(firstMessage);
|
|
||||||
|
|
||||||
NoticeMessage editedFirstMessage = repo.findById(FIRST_MESSAGE_ID);
|
|
||||||
assertNotNull(editedFirstMessage);
|
|
||||||
assertEquals(FIRST_MESSAGE_ID,editedFirstMessage.getId());
|
|
||||||
assertEquals(EDITTED_CONTENT,editedFirstMessage.getContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithMockUser(username="hr")
|
|
||||||
public void givenUsernameHr_whenFindMessageById2_thenOK(){
|
|
||||||
NoticeMessage secondMessage = repo.findById(SECOND_MESSAGE_ID);
|
|
||||||
assertNotNull(secondMessage);
|
|
||||||
assertEquals(SECOND_MESSAGE_ID,secondMessage.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=AccessDeniedException.class)
|
|
||||||
@WithMockUser(username="hr")
|
|
||||||
public void givenUsernameHr_whenUpdateMessageWithId2_thenFail(){
|
|
||||||
NoticeMessage secondMessage = new NoticeMessage();
|
|
||||||
secondMessage.setId(SECOND_MESSAGE_ID);
|
|
||||||
secondMessage.setContent(EDITTED_CONTENT);
|
|
||||||
repo.save(secondMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithMockUser(roles={"EDITOR"})
|
|
||||||
public void givenRoleEditor_whenFindAllMessage_thenReturnThreeMessage(){
|
|
||||||
List<NoticeMessage> details = repo.findAll();
|
|
||||||
assertNotNull(details);
|
|
||||||
assertEquals(3,details.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@WithMockUser(roles={"EDITOR"})
|
|
||||||
public void givenRoleEditor_whenUpdateThirdMessage_thenOK(){
|
|
||||||
NoticeMessage thirdMessage = new NoticeMessage();
|
|
||||||
thirdMessage.setId(THIRD_MESSAGE_ID);
|
|
||||||
thirdMessage.setContent(EDITTED_CONTENT);
|
|
||||||
repo.save(thirdMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=AccessDeniedException.class)
|
|
||||||
@WithMockUser(roles={"EDITOR"})
|
|
||||||
public void givenRoleEditor_whenFindFirstMessageByIdAndUpdateFirstMessageContent_thenFail(){
|
|
||||||
NoticeMessage firstMessage = repo.findById(FIRST_MESSAGE_ID);
|
|
||||||
assertNotNull(firstMessage);
|
|
||||||
assertEquals(FIRST_MESSAGE_ID,firstMessage.getId());
|
|
||||||
firstMessage.setContent(EDITTED_CONTENT);
|
|
||||||
repo.save(firstMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>spring-security-acl</artifactId>
|
<artifactId>spring-security-acl</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package org.baeldung.acl;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class Application {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(Application.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,7 @@ import org.springframework.test.context.web.ServletTestExecutionListener;
|
||||||
DirtiesContextTestExecutionListener.class,
|
DirtiesContextTestExecutionListener.class,
|
||||||
TransactionalTestExecutionListener.class,
|
TransactionalTestExecutionListener.class,
|
||||||
WithSecurityContextTestExecutionListener.class})
|
WithSecurityContextTestExecutionListener.class})
|
||||||
public class SpringAclTest extends AbstractJUnit4SpringContextTests{
|
public class SpringACLIntegrationTest extends AbstractJUnit4SpringContextTests{
|
||||||
|
|
||||||
private static Integer FIRST_MESSAGE_ID = 1;
|
private static Integer FIRST_MESSAGE_ID = 1;
|
||||||
private static Integer SECOND_MESSAGE_ID = 2;
|
private static Integer SECOND_MESSAGE_ID = 2;
|
Loading…
Reference in New Issue