Merge remote-tracking branch 'upstream/master' into tutorials/binaryTreeJava

This commit is contained in:
Marcos 2017-12-15 20:27:41 +01:00
commit 1fa5e1a8e3
132 changed files with 2546 additions and 964 deletions

View File

@ -0,0 +1,2 @@
## Relevant articles:
- [CAS SSO With Spring Security](http://www.baeldung.com/spring-security-cas-sso)

View File

@ -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)
- [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)
- [Generating Prime Numbers in Java](http://www.baeldung.com/java-generate-prime-numbers)

View File

@ -0,0 +1,23 @@
package com.baeldung.stream;
import java.util.Arrays;
import java.util.stream.IntStream;
class PrimitiveStreams {
int min(int[] integers) {
return Arrays.stream(integers).min().getAsInt();
}
int max(int... integers) {
return IntStream.of(integers).max().getAsInt();
}
int sum(int... integers) {
return IntStream.of(integers).sum();
}
double avg(int... integers) {
return IntStream.of(integers).average().getAsDouble();
}
}

View File

@ -38,23 +38,14 @@ public class CounterUtil {
public static void counterWithMutableInteger(Map<String, MutableInteger> counterMap) {
for (String country : COUNTRY_NAMES) {
MutableInteger oldValue = counterMap.get(country);
if (oldValue != null) {
oldValue.increment();
} else {
counterMap.put(country, new MutableInteger(1));
}
counterMap.compute(country, (k, v) -> v == null ? new MutableInteger(0) : v)
.increment();
}
}
public static void counterWithPrimitiveArray(Map<String, int[]> counterMap) {
for (String country : COUNTRY_NAMES) {
int[] oldCounter = counterMap.get(country);
if (oldCounter != null) {
oldCounter[0] += 1;
} else {
counterMap.put(country, new int[] { 1 });
}
counterMap.compute(country, (k, v) -> v == null ? new int[] { 0 } : v)[0]++;
}
}

View File

@ -0,0 +1,97 @@
package com.baeldung.stream;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class PrimitiveStreamsUnitTest {
private PrimitiveStreams streams = new PrimitiveStreams();
@Test
public void givenAnArrayOfIntegersWhenMinIsCalledThenCorrectMinIsReturned() {
int[] integers = new int[] {20, 98, 12, 7, 35};
int min = streams.min(integers); // returns 7
assertEquals(7, min);
}
@Test
public void givenAnArrayOfIntegersWhenMaxIsCalledThenCorrectMaxIsReturned() {
int max = streams.max(20, 98, 12, 7, 35);
assertEquals(98, max);
}
@Test
public void givenAnArrayOfIntegersWhenSumIsCalledThenCorrectSumIsReturned() {
int sum = streams.sum(20, 98, 12, 7, 35);
assertEquals(172, sum);
}
@Test
public void givenAnArrayOfIntegersWhenAvgIsCalledThenCorrectAvgIsReturned() {
double avg = streams.avg(20, 98, 12, 7, 35);
assertTrue(34.4 == avg);
}
@Test
public void givenARangeOfIntegersWhenIntStreamSumIsCalledThenCorrectSumIsReturned() {
int sum = IntStream.range(1, 10).sum();
assertEquals(45, sum);
}
@Test
public void givenARangeClosedOfIntegersWhenIntStreamSumIsCalledThenCorrectSumIsReturned() {
int sum = IntStream.rangeClosed(1, 10).sum();
assertEquals(55, sum);
}
@Test
public void givenARangeWhenForEachIsCalledThenTheIndicesWillBePrinted() {
IntStream.rangeClosed(1, 5).parallel().forEach(System.out::println);
}
@Test
public void givenAnArrayWhenSumIsCalledThenTheCorrectSumIsReturned() {
int sum = Arrays.asList(33,45).stream().mapToInt(a -> a).sum();
assertEquals(78, sum);
}
@Test
public void givenAnIntStreamThenGetTheEvenIntegers() {
List<Integer> evenInts = IntStream.rangeClosed(1, 10)
.filter(i -> i % 2 == 0)
.boxed()
.collect(Collectors.toList());
List<Integer> expected = IntStream.of(2, 4, 6, 8, 10).boxed().collect(Collectors.toList());
assertEquals(expected, evenInts);
}
class Person {
private int age;
Person(int age) {
this.age = age;
}
int getAge() {
return age;
}
}
}

View File

@ -18,3 +18,4 @@
- [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)
- [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)

View File

@ -31,3 +31,5 @@
- [Overview of the java.util.concurrent](http://www.baeldung.com/java-util-concurrent)
- [Semaphores in Java](http://www.baeldung.com/java-semaphore)
- [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)

View File

@ -10,9 +10,9 @@ import java.util.concurrent.*;
import static junit.framework.TestCase.assertTrue;
public class WaitingForThreadsToFinishTest {
public class WaitingForThreadsToFinishManualTest {
private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishTest.class);
private static final Logger LOG = LoggerFactory.getLogger(WaitingForThreadsToFinishManualTest.class);
private final static ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(10);
public void awaitTerminationAfterShutdown(ExecutorService threadPool) {
@ -142,66 +142,4 @@ public class WaitingForThreadsToFinishTest {
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
}
@Test
public void givenMultipleThreads_whenUsingCompletableFutures_thenMainThreadShouldWaitForAllToFinish() {
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello";
});
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Beautiful";
});
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "World";
});
long startProcessingTime = System.currentTimeMillis();
CompletableFuture<Void> combinedFuture = CompletableFuture.allOf(future1, future2, future3);
combinedFuture.join();
long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
assertTrue(totalProcessingTime >= 5000 && totalProcessingTime < 6000);
LOG.debug("Responses from all threads are available after " + totalProcessingTime + " milliseconds");
try {
String thread1Response = future1.get();
assertTrue(thread1Response.equals("Hello"));
String thread2Response = future2.get();
assertTrue(thread2Response.equals("Beautiful"));
String thread3Response = future3.get();
assertTrue(thread3Response.equals("World"));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
awaitTerminationAfterShutdown(WORKER_THREAD_POOL);
}
}

View File

@ -121,4 +121,8 @@
- [Copy a File with Java](http://www.baeldung.com/java-copy-file)
- [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 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)

View File

@ -5,12 +5,12 @@ import org.openjdk.jmh.annotations.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public class SearchArrayTest {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayLoop() {
int count = 1000;
@ -21,9 +21,6 @@ public class SearchArrayTest {
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayAllocNewList() {
int count = 1000;
@ -35,9 +32,6 @@ public class SearchArrayTest {
}
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayAllocNewSet() {
int count = 1000;
@ -49,9 +43,6 @@ public class SearchArrayTest {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayReuseList() {
int count = 1000;
@ -66,9 +57,6 @@ public class SearchArrayTest {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayReuseSet() {
int count = 1000;
@ -81,9 +69,6 @@ public class SearchArrayTest {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 5)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void searchArrayBinarySearch() {
int count = 1000;

View File

@ -0,0 +1,21 @@
package com.baeldung.interfaces;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class CommaSeparatedCustomers implements Customer.List {
private List<Customer> customers = new ArrayList<Customer>();
@Override
public void Add(Customer customer) {
customers.add(customer);
}
@Override
public String getCustomerNames() {
return customers.stream().map(customer -> customer.getName()).collect(Collectors.joining(","));
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.interfaces;
public class Customer {
public interface List {
void Add(Customer customer);
String getCustomerNames();
}
private String name;
public Customer(String name) {
this.name = name;
}
String getName() {
return name;
}
}

View File

@ -54,7 +54,7 @@ public class GenericFile {
}
public String getFileInfo() {
return String.format("File Name: %s\n" + " Extension: %s\n" + " Date Created: %s\n" + " Version: %s\n", this.getName(), this.getExtension(), this.getDateCreated(), this.getVersion());
return "Generic File Impl";
}
public Object read() {

View File

@ -30,7 +30,7 @@ public class ImageFile extends GenericFile {
}
public String getFileInfo() {
return String.format(" %s Height: %d\n Width: %d", super.getFileInfo(), this.getHeight(), this.getWidth());
return "Image File Impl";
}
public String read() {

View File

@ -21,7 +21,7 @@ public class TextFile extends GenericFile {
}
public String getFileInfo() {
return String.format(" %s Word Count: %d", super.getFileInfo(), wordCount);
return "Text File Impl";
}
public String read() {

View File

@ -0,0 +1,18 @@
package com.baeldung.interfaces;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class InnerInterfaceTests {
@Test
public void whenCustomerListJoined_thenReturnsJoinedNames() {
Customer.List customerList = new CommaSeparatedCustomers();
customerList.Add(new Customer("customer1"));
customerList.Add(new Customer("customer2"));
assertEquals("customer1,customer2", customerList.getCustomerNames());
}
}

View File

@ -1,3 +1,4 @@
### Relevant Articles:
- [Introduction to Drools](http://www.baeldung.com/drools)
- [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)

View File

@ -1,52 +0,0 @@
<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>
<artifactId>flyway</artifactId>
<version>1.0</version>
<name>flyway</name>
<packaging>pom</packaging>
<description>A sample project to demonstrate Flyway migrations</description>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modules>
<module>spring-flyway</module>
</modules>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway-maven-plugin.version}</version>
</plugin>
</plugins>
</build>
<properties>
<mysql.version>6.0.5</mysql.version>
<flyway-maven-plugin.version>4.0.3</flyway-maven-plugin.version>
<spring.boot.version>1.5.8.RELEASE</spring.boot.version>
</properties>
</project>

View File

@ -1,57 +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>
<artifactId>spring-flyway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-flyway</name>
<description>Spring Boot Test Flyway Migrations</description>
<parent>
<artifactId>flyway</artifactId>
<groupId>com.baeldung</groupId>
<version>1.0</version>
<relativePath>../../flyway</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,28 +0,0 @@
package com.baeldung.springflyway.entities;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Customer {
@Id
@GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String email;
}

View File

@ -1,14 +0,0 @@
package com.baeldung.springflyway.migration;
import org.flywaydb.core.api.migration.spring.SpringJdbcMigration;
import org.springframework.jdbc.core.JdbcTemplate;
public class V2__uk_lastname_customer implements SpringJdbcMigration {
final String CUSTOMER_LASTNAME_UK = "ALTER TABLE customer ADD CONSTRAINT uk_customer_lastname UNIQUE(last_name);";
@Override
public void migrate(final JdbcTemplate jdbcTemplate) throws Exception {
jdbcTemplate.execute(CUSTOMER_LASTNAME_UK);
}
}

View File

@ -1,11 +0,0 @@
package com.baeldung.springflyway.repositories;
import com.baeldung.springflyway.entities.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface CustomerRepository extends JpaRepository<Customer, Long> {
Optional<Customer> findByEmail(String email);
}

View File

@ -1,28 +0,0 @@
package com.baeldung.springflyway;
import com.baeldung.springflyway.entities.Customer;
import com.baeldung.springflyway.repositories.CustomerRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerRepositoryInitialMigrationTest {
@Autowired CustomerRepository customerRepository;
@Test
public void givenSchemaCreationMigration_whenTryingToCreateACustomer_thenSuccess() {
Customer customer = customerRepository.save(Customer
.builder()
.email("customer@email.com")
.build());
assertNotNull(customer.getId());
}
}

View File

@ -1,35 +0,0 @@
package com.baeldung.springflyway;
import com.baeldung.springflyway.entities.Customer;
import com.baeldung.springflyway.repositories.CustomerRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Optional;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerRepositoryInsertDataMigrationTest {
@Autowired CustomerRepository customerRepository;
@Test
public void givenASetInsertData_whenRunningMigrationsWithSuccess_thenASpecificCustomerIsFound() {
Optional<Customer> customerOptional = customerRepository.findByEmail("email@email.com");
assertTrue(customerOptional.isPresent());
}
@Test
public void givenASetInsertData_whenRunningMigrationsWithSuccess_thenASetOfCustomersIsFound() {
List<Customer> customers = customerRepository.findAll();
assertNotNull(customers);
assertEquals(customers.size(), 6);
}
}

View File

@ -1,25 +0,0 @@
package com.baeldung.springflyway;
import com.baeldung.springflyway.entities.Customer;
import com.baeldung.springflyway.repositories.CustomerRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerRepositoryNotNullConstraintMigrationTest {
@Autowired CustomerRepository customerRepository;
@Test(expected = DataIntegrityViolationException.class)
public void givenTheNotNullConstraintMigrations_whenInsertingACustomerWithNullEmail_thenThrowException() {
customerRepository.save(Customer
.builder()
.build());
}
}

View File

@ -1,29 +0,0 @@
package com.baeldung.springflyway;
import com.baeldung.springflyway.entities.Customer;
import com.baeldung.springflyway.repositories.CustomerRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(properties = {
"flyway.locations[0]=db/migration", "flyway.locations[1]=com/baeldung/springflyway/migration"
})
public class CustomerRepositoryUniqueConstraintJavaMigrationTest {
@Autowired CustomerRepository customerRepository;
@Test(expected = DataIntegrityViolationException.class)
public void givenTheUniqueConstraintMigrations_whenInsertingAnExistingLastNameCustomer_thenThrowException() {
customerRepository.save(Customer
.builder()
.lastName("LastName")
.build());
}
}

View File

@ -1,27 +0,0 @@
package com.baeldung.springflyway;
import com.baeldung.springflyway.entities.Customer;
import com.baeldung.springflyway.repositories.CustomerRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class CustomerRepositoryUniqueConstraintMigrationTest {
@Autowired CustomerRepository customerRepository;
@Test(expected = DataIntegrityViolationException.class)
public void givenTheUniqueConstraintMigrations_whenInsertingAnExistingEmailCustomer_thenThrowException() {
customerRepository.save(Customer
.builder()
.email("email@email.com")
.build());
}
}

View File

@ -1 +0,0 @@
spring.jpa.hibernate.ddl-auto=validate

View File

@ -1,6 +0,0 @@
create table if not exists customer (
id bigint AUTO_INCREMENT not null primary key,
first_name varchar(255) ,
last_name varchar(255) ,
email varchar(255)
);

View File

@ -1,6 +0,0 @@
insert into customer (first_name, last_name, email) values ('FirstName', 'LastName', 'email@email.com');
insert into customer (first_name, last_name, email) values ('FirstName1', 'LastName1', 'email1@email.com');
insert into customer (first_name, last_name, email) values ('FirstName2', 'LastName2', 'email2@email.com');
insert into customer (first_name, last_name, email) values ('FirstName3', 'LastName3', 'email3@email.com');
insert into customer (first_name, last_name, email) values ('FirstName4', 'LastName4', 'email4@email.com');
insert into customer (first_name, last_name, email) values ('FirstName5', 'LastName5', 'email5@email.com');

View File

@ -1 +0,0 @@
ALTER TABLE customer ALTER email SET NOT NULL;

View File

@ -1 +0,0 @@
ALTER TABLE customer ADD CONSTRAINT uk_customer_email UNIQUE(email);

View File

@ -1 +1,2 @@
## Relevant articles:
- [Introduction to Gradle](http://www.baeldung.com/gradle)

View File

@ -0,0 +1,14 @@
repositories{
mavenCentral()
}
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: com.baeldung.GreetingPlugin
dependencies {
compile gradleApi()
}
greeting {
greeter = "Stranger"
message = "Message from the build script!"
}

View File

@ -0,0 +1,17 @@
package com.baeldung;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
public class GreetingPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
GreetingPluginExtension extension = project.getExtensions().create("greeting", GreetingPluginExtension.class);
project.task("hello").doLast(task -> {
System.out.println("Hello, " + extension.getGreeter());
System.out.println("I have a message for You: " + extension.getMessage()); }
);
}
}

View File

@ -0,0 +1,22 @@
package com.baeldung;
public class GreetingPluginExtension {
private String greeter = "Baeldung";
private String message = "Message from Plugin!";
public String getGreeter() {
return greeter;
}
public void setGreeter(String greeter) {
this.greeter = greeter;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -2,3 +2,5 @@
- [Dynamic Mapping with Hibernate](http://www.baeldung.com/hibernate-dynamic-mapping)
- [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)

View File

@ -1,20 +1,7 @@
BASIC CRUD API with Spring Boot
================================
This is the code of a simple API for some CRUD operations realised for a seminar at [FGI](www.fgi-ud.org) using Spring Boot.
### Demo
* API: The online version **is**/**will be** hosted here: https://fgi-tcheck.herokuapp.com
* Mobile version is also opensource and located here: https://github.com/valdesekamdem/tcheck-mobile
### Features
#### Currently Implemented
* CRUD
* Student
#### To DO
* Validations of input with: [Spring Data Rest Validators](http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html)
This is the code of a simple API for some CRUD operations build using Spring Boot.
### Requirements
@ -49,7 +36,6 @@ Or create a new one via a POST:
$ curl -X POST -H "Content-Type:application/json" -d '{ "firstName" : "Dassi", "lastName" : "Orleando", "phoneNumber": "+237 545454545", "email": "mymail@yahoo.fr" }' localhost:8080/students
```
Now with default configurations it will be available at: [http://localhost:8080](http://localhost:8080)
Enjoy it :)

68
jmeter/jmeter.log Normal file
View File

@ -0,0 +1,68 @@
2017-12-13 04:50:16,291 INFO o.a.j.u.JMeterUtils: Setting Locale to en_US
2017-12-13 04:50:16,319 INFO o.a.j.JMeter: Loading user properties from: /Users/dassiorleando/projects/biz/baeldung/jmeter/apache-jmeter-3.3/bin/user.properties
2017-12-13 04:50:16,392 INFO o.a.j.JMeter: Loading system properties from: /Users/dassiorleando/projects/biz/baeldung/jmeter/apache-jmeter-3.3/bin/system.properties
2017-12-13 04:50:16,406 INFO o.a.j.JMeter: Setting JMeter property: jmeter.save.saveservice.output_format=xml
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: Copyright (c) 1998-2017 The Apache Software Foundation
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: Version 3.3 r1808647
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: java.version=1.8.0_152
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: os.name=Mac OS X
2017-12-13 04:50:16,451 INFO o.a.j.JMeter: os.arch=x86_64
2017-12-13 04:50:16,452 INFO o.a.j.JMeter: os.version=10.12.6
2017-12-13 04:50:16,452 INFO o.a.j.JMeter: file.encoding=UTF-8
2017-12-13 04:50:16,452 INFO o.a.j.JMeter: Max memory =536870912
2017-12-13 04:50:16,452 INFO o.a.j.JMeter: Available Processors =4
2017-12-13 04:50:16,461 INFO o.a.j.JMeter: Default Locale=English (United States)
2017-12-13 04:50:16,462 INFO o.a.j.JMeter: JMeter Locale=English (United States)
2017-12-13 04:50:16,462 INFO o.a.j.JMeter: JMeterHome=/Users/dassiorleando/projects/biz/baeldung/jmeter/apache-jmeter-3.3
2017-12-13 04:50:16,462 INFO o.a.j.JMeter: user.dir =/Users/dassiorleando/projects/biz/baeldung/tutorials/jmeter
2017-12-13 04:50:16,462 INFO o.a.j.JMeter: PWD =/Users/dassiorleando/projects/biz/baeldung/tutorials/jmeter
2017-12-13 04:50:16,466 INFO o.a.j.JMeter: IP: 192.168.10.100 Name: MBP FullName: 192.168.10.100
2017-12-13 04:50:16,472 INFO o.a.j.s.FileServer: Default base='/Users/dassiorleando/projects/biz/baeldung/tutorials/jmeter'
2017-12-13 04:50:16,473 INFO o.a.j.s.FileServer: Set new base='/Users/dassiorleando/projects/biz/baeldung/tutorials/jmeter/src/main/resources'
2017-12-13 04:50:17,022 INFO o.a.j.s.SaveService: Testplan (JMX) version: 2.2. Testlog (JTL) version: 2.2
2017-12-13 04:50:17,134 INFO o.a.j.s.SaveService: Using SaveService properties file encoding UTF-8
2017-12-13 04:50:17,142 INFO o.a.j.s.SaveService: Using SaveService properties version 3.2
2017-12-13 04:50:17,168 INFO o.a.j.s.SaveService: Loading file: src/main/resources/JMeter.jmx
2017-12-13 04:50:17,340 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/html is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-12-13 04:50:17,351 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xhtml+xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-12-13 04:50:17,352 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for application/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-12-13 04:50:17,352 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/xml is org.apache.jmeter.protocol.http.parser.LagartoBasedHtmlParser
2017-12-13 04:50:17,353 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/vnd.wap.wml is org.apache.jmeter.protocol.http.parser.RegexpHTMLParser
2017-12-13 04:50:17,353 INFO o.a.j.p.h.s.HTTPSamplerBase: Parser for text/css is org.apache.jmeter.protocol.http.parser.CssParser
2017-12-13 04:50:17,552 INFO o.a.j.JMeter: Creating summariser <summary>
2017-12-13 04:50:17,580 INFO o.a.j.e.StandardJMeterEngine: Running the test!
2017-12-13 04:50:17,581 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-12-13 04:50:17,582 INFO o.a.j.s.SampleEvent: List of sample_variables: []
2017-12-13 04:50:17,590 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must contain the string: '.functions.'
2017-12-13 04:50:17,590 INFO o.a.j.e.u.CompoundVariable: Note: Function class names must not contain the string: '.gui.'
2017-12-13 04:50:18,640 INFO o.a.j.JMeter: Running test (1513137018640)
2017-12-13 04:50:18,728 INFO o.a.j.e.StandardJMeterEngine: Starting ThreadGroup: 1 : Thread Group
2017-12-13 04:50:18,737 INFO o.a.j.e.StandardJMeterEngine: Starting 5 threads for group Thread Group.
2017-12-13 04:50:18,737 INFO o.a.j.e.StandardJMeterEngine: Thread will continue on error
2017-12-13 04:50:18,738 INFO o.a.j.t.ThreadGroup: Starting thread group... number=1 threads=5 ramp-up=1 perThread=200.0 delayedStart=false
2017-12-13 04:50:18,751 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-1
2017-12-13 04:50:18,753 INFO o.a.j.t.ThreadGroup: Started thread group number 1
2017-12-13 04:50:18,753 INFO o.a.j.e.StandardJMeterEngine: All thread groups have been started
2017-12-13 04:50:18,786 INFO o.a.j.p.h.s.HTTPHCAbstractImpl: Local host = MBP
2017-12-13 04:50:18,797 INFO o.a.j.p.h.s.HTTPHC4Impl: HTTP request retry count = 0
2017-12-13 04:50:18,812 INFO o.a.j.s.SampleResult: Note: Sample TimeStamps are START times
2017-12-13 04:50:18,812 INFO o.a.j.s.SampleResult: sampleresult.default.encoding is set to ISO-8859-1
2017-12-13 04:50:18,812 INFO o.a.j.s.SampleResult: sampleresult.useNanoTime=true
2017-12-13 04:50:18,812 INFO o.a.j.s.SampleResult: sampleresult.nanoThreadSleep=5000
2017-12-13 04:50:18,954 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-2
2017-12-13 04:50:19,152 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-3
2017-12-13 04:50:19,257 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-3
2017-12-13 04:50:19,257 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-3
2017-12-13 04:50:19,264 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-2
2017-12-13 04:50:19,264 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-1
2017-12-13 04:50:19,264 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-2
2017-12-13 04:50:19,265 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-1
2017-12-13 04:50:19,353 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-4
2017-12-13 04:50:19,365 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-4
2017-12-13 04:50:19,365 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-4
2017-12-13 04:50:19,557 INFO o.a.j.t.JMeterThread: Thread started: Thread Group 1-5
2017-12-13 04:50:19,573 INFO o.a.j.t.JMeterThread: Thread is done: Thread Group 1-5
2017-12-13 04:50:19,573 INFO o.a.j.t.JMeterThread: Thread finished: Thread Group 1-5
2017-12-13 04:50:19,573 INFO o.a.j.e.StandardJMeterEngine: Notifying test listeners of end of test
2017-12-13 04:50:19,575 INFO o.a.j.r.Summariser: summary = 5 in 00:00:01 = 5.4/s Avg: 155 Min: 10 Max: 388 Err: 4 (80.00%)

69
jmeter/pom.xml Normal file
View File

@ -0,0 +1,69 @@
<?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>
<artifactId>jmeter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>jmeter</name>
<description>Intro to Performance testing using JMeter</description>
<parent>
<artifactId>parent-boot-5</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-5</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<jmeter.version>2.6.0</jmeter.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.lazerycode.jmeter</groupId>
<artifactId>jmeter-maven-plugin</artifactId>
<version>${jmeter.version}</version>
<executions>
<execution>
<id>jmeter-tests</id>
<goals>
<goal>jmeter</goal>
</goals>
</execution>
</executions>
<configuration>
<testFilesDirectory>${project.basedir}/src/main/resources</testFilesDirectory>
<resultsDirectory>${project.basedir}/src/main/resources</resultsDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,6 @@
timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,Latency,IdleTime,Connect
1513134869133,1075,HTTP Request,Non HTTP response code: java.net.ConnectException,Non HTTP response message: Connection refused (Connection refused),Thread Group 1-4,text,false,"The operation lasted too long: It took 1,075 milliseconds, but should not have lasted longer than 10 milliseconds.",2058,0,5,5,0,0,1075
1513134869272,935,HTTP Request,Non HTTP response code: java.net.ConnectException,Non HTTP response message: Connection refused (Connection refused),Thread Group 1-1,text,false,"The operation lasted too long: It took 935 milliseconds, but should not have lasted longer than 10 milliseconds.",2058,0,5,5,0,0,935
1513134869133,1075,HTTP Request,Non HTTP response code: java.net.ConnectException,Non HTTP response message: Connection refused (Connection refused),Thread Group 1-3,text,false,"The operation lasted too long: It took 1,075 milliseconds, but should not have lasted longer than 10 milliseconds.",2058,0,5,5,0,0,1075
1513134869272,935,HTTP Request,Non HTTP response code: java.net.ConnectException,Non HTTP response message: Connection refused (Connection refused),Thread Group 1-2,text,false,"The operation lasted too long: It took 935 milliseconds, but should not have lasted longer than 10 milliseconds.",2058,0,5,5,0,0,934
1513134869133,1074,HTTP Request,Non HTTP response code: java.net.ConnectException,Non HTTP response message: Connection refused (Connection refused),Thread Group 1-5,text,false,"The operation lasted too long: It took 1,074 milliseconds, but should not have lasted longer than 10 milliseconds.",2058,0,5,5,0,0,1074
1 timeStamp elapsed label responseCode responseMessage threadName dataType success failureMessage bytes sentBytes grpThreads allThreads Latency IdleTime Connect
2 1513134869133 1075 HTTP Request Non HTTP response code: java.net.ConnectException Non HTTP response message: Connection refused (Connection refused) Thread Group 1-4 text false The operation lasted too long: It took 1,075 milliseconds, but should not have lasted longer than 10 milliseconds. 2058 0 5 5 0 0 1075
3 1513134869272 935 HTTP Request Non HTTP response code: java.net.ConnectException Non HTTP response message: Connection refused (Connection refused) Thread Group 1-1 text false The operation lasted too long: It took 935 milliseconds, but should not have lasted longer than 10 milliseconds. 2058 0 5 5 0 0 935
4 1513134869133 1075 HTTP Request Non HTTP response code: java.net.ConnectException Non HTTP response message: Connection refused (Connection refused) Thread Group 1-3 text false The operation lasted too long: It took 1,075 milliseconds, but should not have lasted longer than 10 milliseconds. 2058 0 5 5 0 0 1075
5 1513134869272 935 HTTP Request Non HTTP response code: java.net.ConnectException Non HTTP response message: Connection refused (Connection refused) Thread Group 1-2 text false The operation lasted too long: It took 935 milliseconds, but should not have lasted longer than 10 milliseconds. 2058 0 5 5 0 0 934
6 1513134869133 1074 HTTP Request Non HTTP response code: java.net.ConnectException Non HTTP response message: Connection refused (Connection refused) Thread Group 1-5 text false The operation lasted too long: It took 1,074 milliseconds, but should not have lasted longer than 10 milliseconds. 2058 0 5 5 0 0 1074

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="3.2" jmeter="3.3 r1808647">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="JMeter Jenkins" enabled="true">
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="JMeter" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<testResults version="1.2">
<httpSample t="83" it="0" lt="81" ct="1" ts="1513137019153" s="false" lb="HTTP Request" rc="200" rm="" tn="Thread Group 1-3" dt="text" by="502" sby="126" ng="3" na="3">
<assertionResult>
<name>Duration Assertion</name>
<failure>true</failure>
<error>false</error>
<failureMessage>The operation lasted too long: It took 83 milliseconds, but should not have lasted longer than 10 milliseconds.</failureMessage>
</assertionResult>
</httpSample>
<httpSample t="388" it="0" lt="382" ct="292" ts="1513137018851" s="false" lb="HTTP Request" rc="200" rm="" tn="Thread Group 1-1" dt="text" by="502" sby="126" ng="3" na="3">
<assertionResult>
<name>Duration Assertion</name>
<failure>true</failure>
<error>false</error>
<failureMessage>The operation lasted too long: It took 388 milliseconds, but should not have lasted longer than 10 milliseconds.</failureMessage>
</assertionResult>
</httpSample>
<httpSample t="281" it="0" lt="279" ct="189" ts="1513137018955" s="false" lb="HTTP Request" rc="200" rm="" tn="Thread Group 1-2" dt="text" by="502" sby="126" ng="3" na="3">
<assertionResult>
<name>Duration Assertion</name>
<failure>true</failure>
<error>false</error>
<failureMessage>The operation lasted too long: It took 281 milliseconds, but should not have lasted longer than 10 milliseconds.</failureMessage>
</assertionResult>
</httpSample>
<httpSample t="10" it="0" lt="10" ct="1" ts="1513137019354" s="true" lb="HTTP Request" rc="200" rm="" tn="Thread Group 1-4" dt="text" by="502" sby="126" ng="1" na="1">
<assertionResult>
<name>Duration Assertion</name>
<failure>false</failure>
<error>false</error>
</assertionResult>
</httpSample>
<httpSample t="13" it="0" lt="13" ct="1" ts="1513137019558" s="false" lb="HTTP Request" rc="200" rm="" tn="Thread Group 1-5" dt="text" by="502" sby="126" ng="1" na="1">
<assertionResult>
<name>Duration Assertion</name>
<failure>true</failure>
<error>false</error>
<failureMessage>The operation lasted too long: It took 13 milliseconds, but should not have lasted longer than 10 milliseconds.</failureMessage>
</assertionResult>
</httpSample>
</testResults>

View File

@ -1 +1,4 @@
## JSON B
## Relevant articles:
- [Introduction to the JSON Binding API (JSR 367) in Java](http://www.baeldung.com/java-json-binding-api)

2
junit5/README.md Normal file
View File

@ -0,0 +1,2 @@
## Relevant articles:
- [The Order of Tests in JUnit](http://www.baeldung.com/junit-5-test-order)

View File

@ -630,13 +630,30 @@
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>${googleclient.version}</version>
<version>${googleclient.version}</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-gson</artifactId>
<version>${googleclient.version}</version>
</dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-gson</artifactId>
<version>${googleclient.version}</version>
</dependency>
<!-- google api -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>${google-api.version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>${google-api.version}</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-sheets</artifactId>
<version>${google-sheets.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
@ -710,5 +727,7 @@
<cache.version>1.0.0</cache.version>
<hazelcast.version>3.8.4</hazelcast.version>
<caffeine.version>2.5.5</caffeine.version>
<google-api.version>1.23.0</google-api.version>
<google-sheets.version>v4-rev493-1.21.0</google-sheets.version>
</properties>
</project>

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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"]}}

View File

@ -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();
}
}

View File

@ -7,7 +7,7 @@ import org.neuroph.core.NeuralNetwork;
import static org.junit.Assert.*;
public class XORTest {
public class XORIntegrationTest {
private NeuralNetwork ann = null;
private void print(String input, double output, double actual) {

View File

@ -86,6 +86,9 @@ org.eclipse.osgi_3.12.1.v20170821-1548.jar
= = NOT GOOD = =
## Relevant articles:
- [Introduction to OSGi](http://www.baeldung.com/osgi)

View File

@ -1,4 +1,5 @@
###Relevant Articles:
- [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)
- [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)

View File

@ -15,6 +15,7 @@
- [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)
- [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
After importing the project into Eclipse, you may see the following error:

10
pom.xml
View File

@ -49,8 +49,6 @@
<module>core-java-8</module>
<module>core-java-concurrency</module>
<module>couchbase</module>
<module>cas/cas-server</module>
<module>cas/cas-secured-app</module>
<module>deltaspike</module>
<module>dozer</module>
@ -60,7 +58,6 @@
<!--<module>ejb</module>-->
<module>feign</module>
<module>flyway</module>
<!-- <module>testing-modules/gatling</module> --> <!-- not meant to run as part of the standard build -->
@ -141,8 +138,8 @@
<module>persistence-modules/solr</module>
<module>spark-java</module>
<!-- <module>spring-5</module>-->
<module>spring-5-reactive</module>
<module>spring-5-mvc</module>
<module>spring-acl</module>
<module>spring-activiti</module>
<module>spring-akka</module>
<module>spring-amqp</module>
@ -152,7 +149,7 @@
<module>spring-batch</module>
<module>spring-bom</module>
<module>spring-boot</module>
<module>spring-boot-keycloak</module>
<module>spring-boot-keycloak</module>
<module>spring-boot-bootstrap</module>
<module>spring-cloud-data-flow</module>
<module>spring-cloud</module>
@ -175,8 +172,9 @@
<module>spring-hibernate4</module>
<module>persistence-modules/spring-hibernate-5</module>
<module>spring-integration</module>
<module>spring-jenkins-pipeline</module>
<module>spring-jersey</module>
<module>spring-jmeter-jenkins</module>
<module>jmeter</module>
<module>spring-jms</module>
<module>spring-jooq</module>
<module>persistence-modules/spring-jpa</module>

12
spring-5-reactive-client/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
#folders#
.idea
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear

View File

@ -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)

View File

@ -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>

View File

@ -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;
}

View File

@ -0,0 +1,3 @@
logging.level.root=INFO
server.port=8081

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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>

12
spring-5-reactive/.gitignore vendored Normal file
View File

@ -0,0 +1,12 @@
#folders#
.idea
/target
/neoDb*
/data
/src/main/webapp/WEB-INF/classes
*/META-INF/*
# Packaged files #
*.jar
*.war
*.ear

View File

@ -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)

201
spring-5-reactive/pom.xml Normal file
View File

@ -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>

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -0,0 +1 @@
logging.level.root=INFO

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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 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)

View File

@ -2,7 +2,6 @@ package com.baeldung.web;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController

View File

@ -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>

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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 {
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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)
;

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}

View File

@ -2,4 +2,5 @@
- [Implementing a Custom Spring AOP Annotation](http://www.baeldung.com/spring-aop-annotation)
- [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)

View File

@ -0,0 +1,2 @@
## Relevant articles:
- [A Quick Guide to Using Keycloak with Spring Boot](http://www.baeldung.com/spring-boot-keycloak)

View File

@ -28,4 +28,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Spring Boot and Togglz Aspect](http://www.baeldung.com/spring-togglz)
- [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)
- [Quick Guide on data.sql and schema.sql Files in Spring Boot](http://www.baeldung.com/spring-boot-data-sql-and-schema-sql)

View File

@ -3,4 +3,4 @@
## Spring Cloud CLI
### 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)

Some files were not shown because too many files have changed in this diff Show More