Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
ee6fcb2079
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant articles:
|
||||||
|
- [CAS SSO With Spring Security](http://www.baeldung.com/spring-security-cas-sso)
|
|
@ -32,3 +32,4 @@
|
||||||
- [“Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception)
|
- [“Stream has already been operated upon or closed” Exception in Java](http://www.baeldung.com/java-stream-operated-upon-or-closed-exception)
|
||||||
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
- [Display All Time Zones With GMT And UTC in Java](http://www.baeldung.com/java-time-zones)
|
||||||
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
||||||
|
- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers)
|
||||||
|
|
|
@ -18,3 +18,4 @@
|
||||||
- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates)
|
- [How to Get All Dates Between Two Dates?](http://www.baeldung.com/java-between-dates)
|
||||||
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
- [Java 9 java.util.Objects Additions](http://www.baeldung.com/java-9-objects-new)
|
||||||
- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
|
- [Compact Strings in Java 9](http://www.baeldung.com/java-9-compact-string)
|
||||||
|
- [Convert Date to LocalDate or LocalDateTime and Back](http://www.baeldung.com/java-date-to-localdate-and-localdatetime)
|
||||||
|
|
|
@ -31,3 +31,5 @@
|
||||||
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
|
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
|
||||||
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
|
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
|
||||||
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
|
- [Daemon Threads in Java](http://www.baeldung.com/java-daemon-thread)
|
||||||
|
- [Implementing a Runnable vs Extending a Thread](http://www.baeldung.com/java-runnable-vs-extending-thread)
|
||||||
|
- [How to Kill a Java Thread](http://www.baeldung.com/java-thread-stop)
|
||||||
|
|
|
@ -121,4 +121,8 @@
|
||||||
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
|
||||||
- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns)
|
- [Introduction to Creational Design Patterns](http://www.baeldung.com/creational-design-patterns)
|
||||||
- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable)
|
- [Quick Example - Comparator vs Comparable in Java](http://www.baeldung.com/java-comparator-comparable)
|
||||||
|
- [Quick Guide to Java Stack](http://www.baeldung.com/java-stack)
|
||||||
|
- [The Java continue and break Keywords](http://www.baeldung.com/java-continue-and-break)
|
||||||
|
- [Java – Append Data to a File](http://www.baeldung.com/java-append-to-file)
|
||||||
|
- [Introduction to the Java ArrayDeque](http://www.baeldung.com/java-array-deque)
|
||||||
|
- [Guide to java.util.Formatter](http://www.baeldung.com/java-string-formatter)
|
||||||
|
|
|
@ -5,12 +5,12 @@ import org.openjdk.jmh.annotations.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@Warmup(iterations = 5)
|
||||||
|
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
||||||
public class SearchArrayTest {
|
public class SearchArrayTest {
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayLoop() {
|
public void searchArrayLoop() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
@ -21,9 +21,6 @@ public class SearchArrayTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayAllocNewList() {
|
public void searchArrayAllocNewList() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
@ -35,9 +32,6 @@ public class SearchArrayTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayAllocNewSet() {
|
public void searchArrayAllocNewSet() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
@ -49,9 +43,6 @@ public class SearchArrayTest {
|
||||||
|
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayReuseList() {
|
public void searchArrayReuseList() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
@ -66,9 +57,6 @@ public class SearchArrayTest {
|
||||||
|
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayReuseSet() {
|
public void searchArrayReuseSet() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
@ -81,9 +69,6 @@ public class SearchArrayTest {
|
||||||
|
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
@BenchmarkMode(Mode.AverageTime)
|
|
||||||
@Warmup(iterations = 5)
|
|
||||||
@OutputTimeUnit(TimeUnit.MICROSECONDS)
|
|
||||||
public void searchArrayBinarySearch() {
|
public void searchArrayBinarySearch() {
|
||||||
|
|
||||||
int count = 1000;
|
int count = 1000;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Introduction to Drools](http://www.baeldung.com/drools)
|
- [Introduction to Drools](http://www.baeldung.com/drools)
|
||||||
- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel)
|
- [Drools Using Rules from Excel Files](http://www.baeldung.com/drools-excel)
|
||||||
|
- [An Example of Backward Chaining in Drools](http://www.baeldung.com/drools-backward-chaining)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
## Relevant articles:
|
## Relevant articles:
|
||||||
|
- [Introduction to Gradle](http://www.baeldung.com/gradle)
|
||||||
|
|
|
@ -2,3 +2,5 @@
|
||||||
|
|
||||||
- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
|
- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
|
||||||
- [An Overview of Identifiers in Hibernate](http://www.baeldung.com/hibernate-identifiers)
|
- [An Overview of Identifiers in Hibernate](http://www.baeldung.com/hibernate-identifiers)
|
||||||
|
- [Hibernate – Mapping Date and Time](http://www.baeldung.com/hibernate-date-time)
|
||||||
|
- [Hibernate Inheritance Mapping](http://www.baeldung.com/hibernate-inheritance)
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
## JSON B
|
## JSON B
|
||||||
|
|
||||||
|
## Relevant articles:
|
||||||
|
- [Introduction to the JSON Binding API (JSR 367) in Java](http://www.baeldung.com/java-json-binding-api)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant articles:
|
||||||
|
- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order)
|
|
@ -630,13 +630,13 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.http-client</groupId>
|
<groupId>com.google.http-client</groupId>
|
||||||
<artifactId>google-http-client-jackson2</artifactId>
|
<artifactId>google-http-client-jackson2</artifactId>
|
||||||
<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>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
|
|
|
@ -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) {
|
|
@ -86,6 +86,9 @@ org.eclipse.osgi_3.12.1.v20170821-1548.jar
|
||||||
|
|
||||||
= = NOT GOOD = =
|
= = NOT GOOD = =
|
||||||
|
|
||||||
|
## Relevant articles:
|
||||||
|
- [Introduction to OSGi](http://www.baeldung.com/osgi)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
###Relevant Articles:
|
###Relevant Articles:
|
||||||
- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern)
|
- [A Guide to the Front Controller Pattern in Java](http://www.baeldung.com/java-front-controller-pattern)
|
||||||
- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java)
|
- [Introduction to Intercepting Filter Pattern in Java](http://www.baeldung.com/intercepting-filter-pattern-in-java)
|
||||||
- [Implementing the Template Method Pattern in Java](http://www.baeldung.com/template-method-pattern-in-java)
|
- [Implementing the Template Method Pattern in Java](http://www.baeldung.com/java-template-method-pattern)
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
- [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate)
|
- [Deleting Objects with Hibernate](http://www.baeldung.com/delete-with-hibernate)
|
||||||
- [Self-Contained Testing Using an In-Memory Database](http://www.baeldung.com/spring-jpa-test-in-memory-database)
|
- [Self-Contained Testing Using an In-Memory Database](http://www.baeldung.com/spring-jpa-test-in-memory-database)
|
||||||
- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
- [Spring Data JPA – Adding a Method in All Repositories](http://www.baeldung.com/spring-data-jpa-method-in-all-repositories)
|
||||||
|
- [A Guide to Spring AbstractRoutingDatasource](http://www.baeldung.com/spring-abstract-routing-data-source)
|
||||||
|
|
||||||
### Eclipse Config
|
### Eclipse Config
|
||||||
After importing the project into Eclipse, you may see the following error:
|
After importing the project into Eclipse, you may see the following error:
|
||||||
|
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,3 +11,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
- [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient)
|
- [Spring 5 WebClient](http://www.baeldung.com/spring-5-webclient)
|
||||||
- [Spring 5 Functional Bean Registration](http://www.baeldung.com/spring-5-functional-beans)
|
- [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)
|
- [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)
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,4 +2,5 @@
|
||||||
|
|
||||||
- [Implementing a Custom Spring AOP Annotation](http://www.baeldung.com/spring-aop-annotation)
|
- [Implementing a Custom Spring AOP Annotation](http://www.baeldung.com/spring-aop-annotation)
|
||||||
- [Intro to AspectJ](http://www.baeldung.com/aspectj)
|
- [Intro to AspectJ](http://www.baeldung.com/aspectj)
|
||||||
- [Spring Performance Logging](http://www.baeldung.com/spring-performance-logging)
|
- [Spring Performance Logging](http://www.baeldung.com/spring-performance-logging)
|
||||||
|
- [Introduction to Spring AOP](http://www.baeldung.com/spring-aop)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant articles:
|
||||||
|
- [A Quick Guide to Using Keycloak with Spring Boot](http://www.baeldung.com/spring-boot-keycloak)
|
|
@ -28,4 +28,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
|
||||||
- [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz)
|
- [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz)
|
||||||
- [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql)
|
- [Getting Started with GraphQL and Spring Boot](http://www.baeldung.com/spring-graphql)
|
||||||
- [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions)
|
- [Guide to Spring Type Conversions](http://www.baeldung.com/spring-type-conversions)
|
||||||
|
- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql)
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
## Spring Cloud CLI
|
## Spring Cloud CLI
|
||||||
|
|
||||||
### Relevant Articles:
|
### Relevant Articles:
|
||||||
- [Introduction to Spring Cloud CLI](http://www.baeldung.com/introduction-to-spring-cloud-cli/)
|
- [Introduction to Spring Cloud CLI](http://www.baeldung.com/spring-cloud-cli)
|
||||||
|
|
|
@ -8,3 +8,5 @@
|
||||||
- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml)
|
- [Spring YAML Configuration](http://www.baeldung.com/spring-yaml)
|
||||||
- [Introduction to Spring’s StreamUtils](http://www.baeldung.com/spring-stream-utils)
|
- [Introduction to Spring’s StreamUtils](http://www.baeldung.com/spring-stream-utils)
|
||||||
- [Using Spring @Value with Defaults](http://www.baeldung.com/spring-value-defaults)
|
- [Using Spring @Value with Defaults](http://www.baeldung.com/spring-value-defaults)
|
||||||
|
- [Groovy Bean Definitions](http://www.baeldung.com/spring-groovy-beans)
|
||||||
|
- [XML-Based Injection in Spring](http://www.baeldung.com/spring-xml-injection)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
## Relevant articles:
|
||||||
|
- [HibernateException: No Hibernate Session Bound to Thread in Hibernate 3](http://www.baeldung.com/no-hibernate-session-bound-to-thread-exception)
|
|
@ -346,7 +346,7 @@
|
||||||
</profiles>
|
</profiles>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<commons-fileupload.version>1.3.2</commons-fileupload.version>
|
<commons-fileupload.version>1.3.3</commons-fileupload.version>
|
||||||
<kryo.version>4.0.0</kryo.version>
|
<kryo.version>4.0.0</kryo.version>
|
||||||
<protobuf-java-format.version>1.4</protobuf-java-format.version>
|
<protobuf-java-format.version>1.4</protobuf-java-format.version>
|
||||||
<protobuf-java.version>3.1.0</protobuf-java.version>
|
<protobuf-java.version>3.1.0</protobuf-java.version>
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package com.baeldung.apachefileupload;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import org.apache.commons.fileupload.FileItem;
|
||||||
|
import org.apache.commons.fileupload.FileItemIterator;
|
||||||
|
import org.apache.commons.fileupload.FileItemStream;
|
||||||
|
import org.apache.commons.fileupload.FileUploadException;
|
||||||
|
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||||
|
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||||
|
import org.apache.commons.fileupload.util.Streams;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class UploadController {
|
||||||
|
|
||||||
|
@RequestMapping(value = "/upload", method = RequestMethod.POST)
|
||||||
|
public String handleUpload(HttpServletRequest request) {
|
||||||
|
System.out.println(System.getProperty("java.io.tmpdir"));
|
||||||
|
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
|
||||||
|
// Create a factory for disk-based file items
|
||||||
|
DiskFileItemFactory factory = new DiskFileItemFactory();
|
||||||
|
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
|
||||||
|
factory.setSizeThreshold(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD);
|
||||||
|
factory.setFileCleaningTracker(null);
|
||||||
|
// Configure a repository (to ensure a secure temp location is used)
|
||||||
|
ServletFileUpload upload = new ServletFileUpload(factory);
|
||||||
|
try {
|
||||||
|
// Parse the request
|
||||||
|
List<FileItem> items = upload.parseRequest(request);
|
||||||
|
// Process the uploaded items
|
||||||
|
Iterator<FileItem> iter = items.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
FileItem item = iter.next();
|
||||||
|
|
||||||
|
if (!item.isFormField()) {
|
||||||
|
try (InputStream uploadedStream = item.getInputStream();
|
||||||
|
OutputStream out = new FileOutputStream("file.mov");) {
|
||||||
|
IOUtils.copy(uploadedStream, out);
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Parse the request with Streaming API
|
||||||
|
upload = new ServletFileUpload();
|
||||||
|
FileItemIterator iterStream = upload.getItemIterator(request);
|
||||||
|
while (iterStream.hasNext()) {
|
||||||
|
FileItemStream item = iterStream.next();
|
||||||
|
String name = item.getFieldName();
|
||||||
|
InputStream stream = item.openStream();
|
||||||
|
if (!item.isFormField()) {
|
||||||
|
//Process the InputStream
|
||||||
|
} else {
|
||||||
|
//process form fields
|
||||||
|
String formFieldValue = Streams.asString(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "success!";
|
||||||
|
} catch (IOException | FileUploadException ex) {
|
||||||
|
return "failed: " + ex.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
|
@ -1,6 +1,7 @@
|
||||||
### Relevant articles
|
### Relevant articles
|
||||||
|
|
||||||
- [Mockito’s Java 8 Features](http://www.baeldung.com/mockito-2-java-8)
|
- [Mockito’s Java 8 Features](http://www.baeldung.com/mockito-2-java-8)
|
||||||
|
- [Lazy Verification with Mockito 2](http://www.baeldung.com/mockito-2-lazy-verification)
|
||||||
|
|
||||||
## Mockito 2 and Java 8 Tips
|
## Mockito 2 and Java 8 Tips
|
||||||
|
|
||||||
|
|
|
@ -12,3 +12,5 @@
|
||||||
- [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock)
|
- [Introduction to PowerMock](http://www.baeldung.com/intro-to-powermock)
|
||||||
- [Mocking Exception Throwing using Mockito](http://www.baeldung.com/mockito-exceptions)
|
- [Mocking Exception Throwing using Mockito](http://www.baeldung.com/mockito-exceptions)
|
||||||
- [Mocking Void Methods with Mockito](http://www.baeldung.com/mockito-void-methods)
|
- [Mocking Void Methods with Mockito](http://www.baeldung.com/mockito-void-methods)
|
||||||
|
- [Mocking of Private Methods Using PowerMock](http://www.baeldung.com/powermock-private-method)
|
||||||
|
- [Mock Final Classes and Methods with Mockito](http://www.baeldung.com/mockito-final)
|
||||||
|
|
|
@ -94,6 +94,11 @@
|
||||||
<version>1.5</version>
|
<version>1.5</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.javalite</groupId>
|
||||||
|
<artifactId>javalite-common</artifactId>
|
||||||
|
<version>${javalite.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
|
@ -162,5 +167,6 @@
|
||||||
<truth.version>0.32</truth.version>
|
<truth.version>0.32</truth.version>
|
||||||
<jUnitParams.version>1.1.0</jUnitParams.version>
|
<jUnitParams.version>1.1.0</jUnitParams.version>
|
||||||
<jgotesting.version>0.12</jgotesting.version>
|
<jgotesting.version>0.12</jgotesting.version>
|
||||||
|
<javalite.version>1.4.13</javalite.version>
|
||||||
</properties>
|
</properties>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
public abstract class Animal {
|
||||||
|
|
||||||
|
protected String name;
|
||||||
|
|
||||||
|
public Animal(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((name == null) ? 0 : name.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
Animal other = (Animal) obj;
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null)
|
||||||
|
return false;
|
||||||
|
} else if (!name.equals(other.name))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Cage {
|
||||||
|
|
||||||
|
private Set<Animal> animals = new HashSet<>();
|
||||||
|
|
||||||
|
public void put(Animal animal) {
|
||||||
|
animals.add(animal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(Animal... animals) {
|
||||||
|
this.animals.addAll(Arrays.asList(animals));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Animal release(Animal animal) {
|
||||||
|
return animals.remove(animal) ? animal : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() {
|
||||||
|
animals.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasAnimals() {
|
||||||
|
return animals.size() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return animals.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Animal> getAnimals() {
|
||||||
|
return this.animals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return animals.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Cage [animals=" + animals + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
public class Cat extends Animal {
|
||||||
|
|
||||||
|
public Cat(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Cat [name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
public class Dog extends Animal {
|
||||||
|
|
||||||
|
public Dog(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Dog [name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
import static org.javalite.test.jspec.JSpec.$;
|
||||||
|
import static org.javalite.test.jspec.JSpec.expect;
|
||||||
|
import static org.javalite.test.jspec.JSpec.the;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.javalite.test.jspec.DifferenceExpectation;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class CageUnitTest {
|
||||||
|
|
||||||
|
Cat tomCat = new Cat("Tom");
|
||||||
|
Cat felixCat = new Cat("Felix");
|
||||||
|
Dog boltDog = new Dog("Bolt");
|
||||||
|
Cage cage = new Cage();
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void puttingAnimals_shouldIncreaseCageSize() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, boltDog);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(cage.size()).shouldEqual(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void releasingAnimals_shouldDecreaseCageSize() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, boltDog);
|
||||||
|
cage.release(tomCat);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(cage.size()).shouldEqual(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void puttingAnimals_shouldLeaveThemInsideTheCage() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, boltDog);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(cage).shouldHave("animals");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void openingTheCage_shouldReleaseAllAnimals() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, boltDog);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(cage).shouldNotBe("empty");
|
||||||
|
|
||||||
|
// When
|
||||||
|
cage.open();
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(cage).shouldBe("empty");
|
||||||
|
the(cage.isEmpty()).shouldBeTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void comparingTwoDogs() {
|
||||||
|
// When
|
||||||
|
Dog firstDog = new Dog("Rex");
|
||||||
|
Dog secondDog = new Dog("Rex");
|
||||||
|
|
||||||
|
// Then
|
||||||
|
$(firstDog).shouldEqual(secondDog);
|
||||||
|
$(firstDog).shouldNotBeTheSameAs(secondDog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void puttingCatsOnly_shouldLetCageAnimalsToContainCats() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, felixCat);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
Set<Animal> animals = cage.getAnimals();
|
||||||
|
the(animals).shouldContain(tomCat);
|
||||||
|
the(animals).shouldContain(felixCat);
|
||||||
|
the(animals).shouldNotContain(boltDog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void puttingCatsOnly_shouldLetCageToContainCats() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, felixCat);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
// Check with toString of the tested objects
|
||||||
|
the(cage).shouldContain(tomCat);
|
||||||
|
the(cage).shouldContain(felixCat);
|
||||||
|
the(cage).shouldNotContain(boltDog);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void puttingMoreAnimals_shouldChangeSize() {
|
||||||
|
// When
|
||||||
|
cage.put(tomCat, boltDog);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
expect( new DifferenceExpectation<Integer>(cage.size()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer exec() {
|
||||||
|
cage.release(tomCat);
|
||||||
|
return cage.size();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void releasingTheDog_shouldReleaseAnAnimalOfDogType() {
|
||||||
|
// When
|
||||||
|
cage.put(boltDog);
|
||||||
|
Animal releasedAnimal = cage.release(boltDog);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
the(releasedAnimal).shouldNotBeNull();
|
||||||
|
the(releasedAnimal).shouldBeA(Dog.class);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.baeldung.jspec;
|
||||||
|
|
||||||
|
import static org.javalite.test.jspec.JSpec.$;
|
||||||
|
import static org.javalite.test.jspec.JSpec.a;
|
||||||
|
import static org.javalite.test.jspec.JSpec.expect;
|
||||||
|
import static org.javalite.test.jspec.JSpec.it;
|
||||||
|
import static org.javalite.test.jspec.JSpec.the;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.javalite.test.jspec.ExceptionExpectation;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class JSpecUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onePlusTwo_shouldEqualThree() {
|
||||||
|
$(1 + 2).shouldEqual(3);
|
||||||
|
a(1 + 2).shouldEqual(3);
|
||||||
|
the(1 + 2).shouldEqual(3);
|
||||||
|
it(1 + 2).shouldEqual(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void messageShouldContainJSpec() {
|
||||||
|
String message = "Welcome to JSpec demo";
|
||||||
|
// The message should not be empty
|
||||||
|
the(message).shouldNotBe("empty");
|
||||||
|
// The message should contain JSpec
|
||||||
|
the(message).shouldContain("JSpec");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void colorsListShouldContainRed() {
|
||||||
|
List<String> colorsList = Arrays.asList("red", "green", "blue");
|
||||||
|
$(colorsList).shouldContain("red");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void guessedNumberShouldEqualHiddenNumber() {
|
||||||
|
Integer guessedNumber = 11;
|
||||||
|
Integer hiddenNumber = 11;
|
||||||
|
|
||||||
|
$(guessedNumber).shouldEqual(hiddenNumber);
|
||||||
|
$(guessedNumber).shouldNotBeTheSameAs(hiddenNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dividingByThero_shouldThrowArithmeticException() {
|
||||||
|
expect(new ExceptionExpectation<ArithmeticException>(ArithmeticException.class) {
|
||||||
|
@Override
|
||||||
|
public void exec() throws ArithmeticException {
|
||||||
|
System.out.println(1 / 0);
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue